MPI-AMRVAC 3.2
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_small_values.t
Go to the documentation of this file.
1!> Module for handling problematic values in simulations, such as negative
2!> pressures
4
5 use iso_fortran_env, only: int64
6
7 implicit none
8 private
9
10 !> How to handle small values
11 character(len=20), public :: small_values_method = "error"
12
13 !> Average over this many cells in each direction
14 integer, public :: small_values_daverage = 1
15
16 !> trace small values in the source file using traceback flag of compiler
17 logical, public :: trace_small_values=.false.
18
19 !> Whether to apply small value fixes to certain variables
20 logical, public, allocatable :: small_values_fix_iw(:)
21
22 public :: small_values_error
23 public :: small_values_average
24
25 ! Per-process state; access only through report_repair_warning's critical region.
26 type, public :: repair_warning_state
27 integer(int64) :: events = 0_int64, next_report = 10_int64
28 integer :: details = 0
30 public :: report_repair_warning
31
32contains
33
34 ! Counts repair events, not distinct cells. No communication in this local path.
35 subroutine report_repair_warning(state,label,events,edges,iw,xfirst,before,after)
36 use mod_global_parameters, only: mype, it
37 type(repair_warning_state), intent(inout) :: state
38 character(len=*), intent(in) :: label
39 integer(int64), intent(in) :: events, edges
40 integer, intent(in) :: iw
41 double precision, intent(in) :: xfirst(:), before, after
42 logical :: milestone
43
44 if(events<=0_int64) return
45 !$omp critical(amrvac_repair_warning)
46 ! Saturate rather than wrap on exceptionally long runs.
47 state%events=state%events+min(events,huge(state%events)-state%events)
48 milestone=.false.
49 if(state%next_report>0_int64) then
50 milestone=state%events>=state%next_report
51 do while(state%events>=state%next_report)
52 if(state%next_report>huge(state%next_report)/10_int64) then
53 state%next_report=0_int64
54 exit
55 end if
56 state%next_report=state%next_report*10_int64
57 end do
58 end if
59 if(state%details<3) then
60 state%details=state%details+1
61 write(*,*) 'WARNING ',label,': rank=',mype,' it=',it, &
62 ' events=',events,' edges=',edges,' cumulative_events=',state%events
63 write(*,*) ' first: variable=',iw,' x=',xfirst,' before=',before,' after=',after
64 if(state%details==3) write(*,*) ' Further detailed reports suppressed; cumulative milestones only.'
65 else if(milestone) then
66 write(*,*) 'WARNING ',label,': rank=',mype,' it=',it,' cumulative_events=',state%events
67 end if
68 !$omp end critical(amrvac_repair_warning)
69 end subroutine report_repair_warning
70
71 subroutine small_values_error(wprim, x, ixI^L, ixO^L, w_flag, subname)
73 use mod_geometry
74 integer, intent(in) :: ixi^l, ixo^l
75 double precision, intent(in) :: wprim(ixi^s, 1:nw)
76 double precision, intent(in) :: x(ixi^s, 1:ndim)
77 logical, intent(in) :: w_flag(ixi^s,1:nw)
78 character(len=*), intent(in) :: subname
79
80 double precision :: x^d
81 integer :: iw,iiw,ix^d
82
83 if (.not.crash) then
84 do iw=1,nw
85 {do ix^db= ixo^lim^db\}
86 if(w_flag(ix^d,iw)) then
87 write(*,*) "Error: small value of ", trim(prim_wnames(iw)),wprim(ix^d,iw),&
88 " encountered when call ", subname
89 write(*,*) "Iteration: ", it, " Time: ", global_time, "Processor: ",mype
90 write(*,*) "Location: ", x(ix^d,:)
91 select case (coordinate)
93 case (cylindrical)
94 {^ifoned
95 x1=x(ix^d,1)}
96 {^iftwod
97 select case (phi_)
98 case (2)
99 x1=x(ix^d,1)*cos(x(ix^d,2))
100 x2=x(ix^d,1)*sin(x(ix^d,2))
101 case default
102 x1=x(ix^d,1)
103 x2=x(ix^d,2)
104 end select}
105 {^ifthreed
106 x1=x(ix^d,1)*cos(x(ix^d,phi_))
107 x2=x(ix^d,1)*sin(x(ix^d,phi_))
108 x3=x(ix^d,z_)}
109 write(*,*) "Cartesian location: ", x^d
110 case (spherical)
111 x1=x(ix^d,1){^nooned*sin(x(ix^d,2))}{^ifthreed*cos(x(ix^d,3))}
112 {^iftwod
113 x2=x(ix^d,1)*cos(x(ix^d,2))}
114 {^ifthreed
115 x2=x(ix^d,1)*sin(x(ix^d,2))*sin(x(ix^d,3))
116 x3=x(ix^d,1)*cos(x(ix^d,2))}
117 write(*,*) "Cartesian location: ", x^d
118 case default
119 write(*,*) "No converter for coordinate=",coordinate
120 end select
121 write(*,*) "Cell number: ", ix^d
122 do iiw=1,nw
123 write(*,*) trim(prim_wnames(iiw)),": ",wprim(ix^d,iiw)
124 end do
125 ! use erroneous arithmetic operation to crash the run
126 if(trace_small_values) write(*,*) sqrt(wprim(ix^d,iw)-bigdouble)
127 write(*,*) "Saving status at the previous time step"
128 crash=.true.
129 end if
130 {end do^D&\}
131 end do
132 end if
133 end subroutine small_values_error
134
135 subroutine small_values_average(ixI^L, ixO^L, w, x, w_flag, windex)
137 integer, intent(in) :: ixi^l, ixo^l
138 logical, intent(in) :: w_flag(ixi^s,1:nw)
139 double precision, intent(inout) :: w(ixi^s, 1:nw)
140 double precision, intent(in) :: x(ixi^s, 1:ndim)
141 integer, optional, intent(in) :: windex
142 integer :: iw, kxo^l, ix^d, i, nwstart, nwend
143
144 type(repair_warning_state), save :: warning_state
145 integer(int64) :: fallback_events
146 integer :: first_iw
147 double precision :: first_x(ndim), first_before, first_after
148
149 fallback_events=0_int64
150 if(present(windex)) then
151 nwstart=windex
152 nwend=windex
153 else
154 nwstart=1
155 nwend=nw
156 end if
157
158 do iw = nwstart, nwend
159 {do ix^db= ixo^lim^db\}
160 ! point with local failure identified by w_flag
161 if (w_flag(ix^d,iw)) then
162 ! verify in cube with border width small_values_daverage the presence of
163 ! cells where all went ok
164 do i = 1, max(small_values_daverage, 1)
165 {kxomin^d= max(ix^d-i, iximin^d);
166 kxomax^d= min(ix^d+i, iximax^d);\}
167 ! in case cells are fine within smaller cube than
168 ! the userset small_values_daverage: use that smaller cube
169 if(any(w_flag(kxo^s,iw) .eqv. .false.)) exit
170 end do
171
172 if(any(w_flag(kxo^s,iw) .eqv. .false.)) then
173 ! within surrounding cube, cells without problem were found
174
175 ! faulty cells are corrected by averaging here
176 ! only average those which were ok and replace faulty cells
177 if(small_values_fix_iw(iw)) then
178 w(ix^d, iw) = sum(w(kxo^s, iw), w_flag(kxo^s,iw) .eqv. .false.)&
179 / count(w_flag(kxo^s,iw) .eqv. .false.)
180 end if
181 else
182 fallback_events=fallback_events+1_int64
183 if(fallback_events==1_int64) then
184 first_iw=iw
185 first_x=x(ix^d,1:ndim)
186 first_before=w(ix^d,iw)
187 end if
188 if(iw==iw_e) w(ix^d, iw)=small_pressure
189 if(iw==iw_rho) w(ix^d, iw)=small_density
190 if(fallback_events==1_int64) first_after=w(ix^d,iw)
191 end if
192 end if
193 {enddo^d&\}
194 end do
195 ! Other variables can remain unchanged in this existing fallback path.
196 if(fallback_events>0_int64) call report_repair_warning(warning_state, &
197 'small_values_average: no valid neighbours',fallback_events,0_int64, &
198 first_iw,first_x,first_before,first_after)
199 end subroutine small_values_average
200
201end module mod_small_values
Module with geometry-related routines (e.g., divergence, curl).
Definition mod_geometry.t:2
integer coordinate
Definition mod_geometry.t:7
integer, parameter cartesian
Definition mod_geometry.t:8
integer, parameter cylindrical
integer, parameter cartesian_expansion
integer, parameter cartesian_stretched
Definition mod_geometry.t:9
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision global_time
The global simulation time.
integer it
Number of time steps taken.
integer, parameter ndim
Number of spatial dimensions for grid variables.
integer mype
The rank of the current MPI task.
double precision, dimension(:), allocatable, parameter d
logical crash
Save a snapshot before crash a run met unphysical values.
Module for handling problematic values in simulations, such as negative pressures.
subroutine, public small_values_average(ixil, ixol, w, x, w_flag, windex)
subroutine, public report_repair_warning(state, label, events, edges, iw, xfirst, before, after)
integer, public small_values_daverage
Average over this many cells in each direction.
logical, public trace_small_values
trace small values in the source file using traceback flag of compiler
subroutine, public small_values_error(wprim, x, ixil, ixol, w_flag, subname)
logical, dimension(:), allocatable, public small_values_fix_iw
Whether to apply small value fixes to certain variables.
character(len=20), public small_values_method
How to handle small values.