source: trunk/LMDZ.MARS/libf/phymars/check_fields.F90 @ 2545

Last change on this file since 2545 was 2541, checked in by emillour, 4 years ago

Mars GCM:
Add possibility of additional tests (NaNs?, but also of unrealistic values) of
fields at the begining of physics (i.e. coming from the dynamics) and at the
end of the physics integration. These are respectively triggered by seting
flags "check_physics_inputs" and "check_physics_outputs" to .true.
EM

File size: 4.8 KB
Line 
1module check_fields_mod
2
3  real,parameter :: default_temp_min=50.  ! minimum reasonable temperature (K)
4  real,parameter :: default_temp_max=350. ! maximum reasonable temperature (K)
5
6  real,parameter :: default_wind_max=500. ! maximum reasonable wind magnitude (m/s)
7
8  real,parameter :: default_ps_min=80.  ! minimum reasonable surface pressure (Pa)
9  real,parameter :: default_ps_max=2000. ! maximum reasonable surface pressure (Pa)
10
11contains
12
13subroutine check_physics_fields(message,temp,u,v,pplev)
14use dimphy, only: klon, klev
15implicit none
16character(len=*),intent(in):: message
17real,intent(in) :: temp(klon,klev)
18real,intent(in) :: u(klon,klev) ! zonal wind (m/s)
19real,intent(in) :: v(klon,klev) ! meridional wind (m/s)
20real,intent(in) :: pplev(klon,klev+1) ! pressure at level interfaces (Pa)
21
22character(len=50) :: name="check_physics_fields"
23logical ok_t,ok_w,ok_ps
24
25! 1. Initialisations
26ok_t=.true.
27ok_w=.true.
28ok_ps=.true.
29
30! 2. Check temperature, winds and surface pressure
31call check_temperature(temp,ok_t)
32call check_winds(u,v,ok_w)
33call check_ps(pplev(:,1),ok_ps)
34
35if ((.not.ok_t).or.(.not.ok_w).or.(.not.ok_ps)) then
36  ! Something is wrong, might as well stop here
37  call abort_physic(trim(name),trim(message)//" Invalid field values",1)
38endif
39
40end subroutine check_physics_fields
41
42
43subroutine check_temperature(temp,ok,temp_min,temp_max)
44use dimphy, only: klon, klev
45implicit none
46real,intent(in) :: temp(klon,klev)
47logical,intent(out) :: ok ! returns .true. if everything OK, .false. otherwise
48real,intent(in),optional :: temp_min ! user provided acceptable minimum
49real,intent(in),optional :: temp_max ! user provided acceptable maximum
50
51character(len=50) :: name="check_temperature"
52real :: tmin,tmax
53integer :: i,k
54
55! 0. Check optional inputs
56if (present(temp_min)) then
57  tmin=temp_min
58else
59  tmin=default_temp_min
60endif
61
62if (present(temp_max)) then
63  tmax=temp_max
64else
65  tmax=default_temp_max
66endif
67
68! 1. initializations
69ok=.true.
70
71! 2. do the checking
72do i=1,klon
73  do k=1,klev
74    ! look for NaN
75    if (temp(i,k).ne.temp(i,k)) then
76      ok=.false.
77      write(*,*)trim(name)//" temp(i,k)=",temp(i,k)," for i=",i," k=",k
78    endif
79    ! check for temperatures too low
80    if (temp(i,k).lt.tmin) then
81      ok=.false.
82      write(*,*)trim(name)//" temp(i,k)=",temp(i,k)," for i=",i," k=",k,&
83      "<",tmin
84    endif
85    ! check for temperatures too high
86    if (temp(i,k).gt.tmax) then
87      ok=.false.
88      write(*,*)trim(name)//" temp(i,k)=",temp(i,k)," for i=",i," k=",k,&
89      ">",tmax
90    endif
91  enddo
92enddo
93
94end subroutine check_temperature
95
96subroutine check_winds(u,v,ok,wind_max)
97use dimphy, only: klon, klev
98implicit none
99real,intent(in) :: u(klon,klev) ! zonal wind (m/s)
100real,intent(in) :: v(klon,klev) ! meridional wind (m/s)
101logical,intent(out) :: ok ! returns .true. if everything OK, .false. otherwise
102real,intent(in),optional :: wind_max ! user provided acceptable maximum magnitude
103
104character(len=50) :: name="check_winds"
105real :: wmax
106integer :: i,k
107
108! 0. Check optional inputs
109
110if (present(wind_max)) then
111  wmax=wind_max
112else
113  wmax=default_wind_max
114endif
115
116! 1. initializations
117ok=.true.
118
119! 2. do the checking
120do i=1,klon
121  do k=1,klev
122    ! look for NaN
123    if (u(i,k).ne.u(i,k)) then
124      ok=.false.
125      write(*,*)trim(name)//" u(i,k)=",u(i,k)," for i=",i," k=",k
126    endif
127    if (v(i,k).ne.v(i,k)) then
128      ok=.false.
129      write(*,*)trim(name)//" v(i,k)=",v(i,k)," for i=",i," k=",k
130    endif
131    ! check for magnitudes too high
132    if (abs(u(i,k)).gt.wmax) then
133      ok=.false.
134      write(*,*)trim(name)//" u(i,k)=",u(i,k)," for i=",i," k=",k,&
135      ">",wmax
136    endif
137    if (abs(v(i,k)).gt.wmax) then
138      ok=.false.
139      write(*,*)trim(name)//" v(i,k)=",v(i,k)," for i=",i," k=",k,&
140      ">",wmax
141    endif
142  enddo
143enddo
144
145end subroutine check_winds
146
147subroutine check_ps(ps,ok,ps_min,ps_max)
148use dimphy, only: klon
149implicit none
150real,intent(in) :: ps(klon)
151logical,intent(out) :: ok ! returns .true. if everything OK, .false. otherwise
152real,intent(in),optional :: ps_min ! user provided acceptable minimum
153real,intent(in),optional :: ps_max ! user provided acceptable maximum
154
155character(len=50) :: name="check_ps"
156real :: pmin,pmax
157integer :: i
158
159! 0. Check optional inputs
160if (present(ps_min)) then
161  pmin=ps_min
162else
163  pmin=default_ps_min
164endif
165
166if (present(ps_max)) then
167  pmax=ps_max
168else
169  pmax=default_ps_max
170endif
171
172! 1. initializations
173ok=.true.
174
175! 2. do the checking
176do i=1,klon
177  ! look for NaN
178  if (ps(i).ne.ps(i)) then
179    ok=.false.
180    write(*,*)trim(name)//" ps(i)=",ps(i)," for i=",i
181  endif
182  ! check for pressures too low
183  if (ps(i).lt.pmin) then
184    ok=.false.
185    write(*,*)trim(name)//" ps(i)=",ps(i)," for i=",i,"<",pmin
186  endif
187  ! check for pressures too high
188  if (ps(i).gt.pmax) then
189    ok=.false.
190    write(*,*)trim(name)//" ps(i)=",ps(i)," for i=",i,">",pmax
191  endif
192enddo
193
194end subroutine check_ps
195
196end module check_fields_mod
Note: See TracBrowser for help on using the repository browser.