MPI-AMRVAC 3.1
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 implicit none
6 private
7
8 !> How to handle small values
9 character(len=20), public :: small_values_method = "error"
10
11 !> Average over this many cells in each direction
12 integer, public :: small_values_daverage = 1
13
14 !> trace small values in the source file using traceback flag of compiler
15 logical, public :: trace_small_values=.false.
16
17 !> Whether to apply small value fixes to certain variables
18 logical, public, allocatable :: small_values_fix_iw(:)
19
20 public :: small_values_error
21 public :: small_values_average
22
23contains
24
25 subroutine small_values_error(wprim, x, ixI^L, ixO^L, w_flag, subname)
27 use mod_geometry
28 integer, intent(in) :: ixi^l, ixo^l
29 double precision, intent(in) :: wprim(ixi^s, 1:nw)
30 double precision, intent(in) :: x(ixi^s, 1:ndim)
31 logical, intent(in) :: w_flag(ixi^s,1:nw)
32 character(len=*), intent(in) :: subname
33
34 double precision :: x^d
35 integer :: iw,iiw,ix^d
36
37 if (.not.crash) then
38 do iw=1,nw
39 {do ix^db= ixo^lim^db\}
40 if(w_flag(ix^d,iw)) then
41 write(*,*) "Error: small value of ", trim(prim_wnames(iw)),wprim(ix^d,iw),&
42 " encountered when call ", subname
43 write(*,*) "Iteration: ", it, " Time: ", global_time, "Processor: ",mype
44 write(*,*) "Location: ", x(ix^d,:)
45 select case (coordinate)
47 case (cylindrical)
48 {^ifoned
49 x1=x(ix^d,1)}
50 {^iftwod
51 select case (phi_)
52 case (2)
53 x1=x(ix^d,1)*cos(x(ix^d,2))
54 x2=x(ix^d,1)*sin(x(ix^d,2))
55 case default
56 x1=x(ix^d,1)
57 x2=x(ix^d,2)
58 end select}
59 {^ifthreed
60 x1=x(ix^d,1)*cos(x(ix^d,phi_))
61 x2=x(ix^d,1)*sin(x(ix^d,phi_))
62 x3=x(ix^d,z_)}
63 write(*,*) "Cartesian location: ", x^d
64 case (spherical)
65 x1=x(ix^d,1){^nooned*sin(x(ix^d,2))}{^ifthreed*cos(x(ix^d,3))}
66 {^iftwod
67 x2=x(ix^d,1)*cos(x(ix^d,2))}
68 {^ifthreed
69 x2=x(ix^d,1)*sin(x(ix^d,2))*sin(x(ix^d,3))
70 x3=x(ix^d,1)*cos(x(ix^d,2))}
71 write(*,*) "Cartesian location: ", x^d
72 case default
73 write(*,*) "No converter for coordinate=",coordinate
74 end select
75 write(*,*) "Cell number: ", ix^d
76 do iiw=1,nw
77 write(*,*) trim(prim_wnames(iiw)),": ",wprim(ix^d,iiw)
78 end do
79 ! use erroneous arithmetic operation to crash the run
80 if(trace_small_values) write(*,*) sqrt(wprim(ix^d,iw)-bigdouble)
81 write(*,*) "Saving status at the previous time step"
82 crash=.true.
83 end if
84 {end do^D&\}
85 end do
86 end if
87 end subroutine small_values_error
88
89 subroutine small_values_average(ixI^L, ixO^L, w, x, w_flag, windex)
91 integer, intent(in) :: ixi^l, ixo^l
92 logical, intent(in) :: w_flag(ixi^s,1:nw)
93 double precision, intent(inout) :: w(ixi^s, 1:nw)
94 double precision, intent(in) :: x(ixi^s, 1:ndim)
95 integer, optional, intent(in) :: windex
96 integer :: iw, kxo^l, ix^d, i, nwstart, nwend
97
98 if(present(windex)) then
99 nwstart=windex
100 nwend=windex
101 else
102 nwstart=1
103 nwend=nw
104 end if
105
106 do iw = nwstart, nwend
107 {do ix^db= ixo^lim^db\}
108 ! point with local failure identified by w_flag
109 if (w_flag(ix^d,iw)) then
110 ! verify in cube with border width small_values_daverage the presence of
111 ! cells where all went ok
112 do i = 1, max(small_values_daverage, 1)
113 {kxomin^d= max(ix^d-i, iximin^d);
114 kxomax^d= min(ix^d+i, iximax^d);\}
115 ! in case cells are fine within smaller cube than
116 ! the userset small_values_daverage: use that smaller cube
117 if(any(w_flag(kxo^s,iw) .eqv. .false.)) exit
118 end do
119
120 if(any(w_flag(kxo^s,iw) .eqv. .false.)) then
121 ! within surrounding cube, cells without problem were found
122
123 ! faulty cells are corrected by averaging here
124 ! only average those which were ok and replace faulty cells
125 if(small_values_fix_iw(iw)) then
126 w(ix^d, iw) = sum(w(kxo^s, iw), w_flag(kxo^s,iw) .eqv. .false.)&
127 / count(w_flag(kxo^s,iw) .eqv. .false.)
128 end if
129 else
130 write(*,*) "no cells without error were found in cube of size", &
132 write(*,*) "at location:", x(ix^d, 1:ndim)
133 write(*,*) "at index:", ix^d
134 write(*,*) "w numer:", iw
135 !write(*,*) "Saving status at the previous time step"
136 !crash=.true.
137 write(*,*) "replace with small values"
138 if(iw==iw_e) w(ix^d, iw)=small_pressure
139 if(iw==iw_rho) w(ix^d, iw)=small_density
140 end if
141 end if
142 {enddo^d&\}
143 end do
144 end subroutine small_values_average
145
146end 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)
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.