Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
exceptions.F90
Go to the documentation of this file.
2
3 use iso_c_binding
4 use iso_fortran_env, only : output_unit
5 use logfiles, only : logs, log_general, log_all
6 implicit none
7
8 private
9
11
12 logical (c_bool), parameter :: true = .true._c_bool
13 logical (c_bool), parameter :: false = .false._c_bool
14
15 interface assert
16 module procedure :: assert_4bit
17 module procedure :: assert_1bit
18 end interface assert
19
21 module procedure :: bounds_check_integer_1d
22 module procedure :: bounds_check_float_1d
23 module procedure :: bounds_check_double_1d
24 module procedure :: bounds_check_integer_2d
25 module procedure :: bounds_check_float_2d
26 module procedure :: bounds_check_double_2d
27 end interface index_values_valid
28
29 integer (c_int), public :: number_of_fatal_warnings = 0
30 integer (c_int), parameter :: max_fatal_warnings = 50
31 character (len=256) :: warning_text( max_fatal_warnings )
32 logical (c_bool), public :: halt_upon_fatal_error = true
33
34contains
35
36 function bounds_check_integer_1d( array_vals, array_index ) result(bounds_ok)
37
38 integer (c_int), intent(in) :: array_vals(:)
39 integer (c_int), intent(in) :: array_index
40 logical (c_bool) :: bounds_ok
41
42 bounds_ok = false
43
44 if ( lbound(array_vals,1) <= array_index &
45 .and. ubound(array_vals,1) >= array_index ) bounds_ok = true
46
47 end function bounds_check_integer_1d
48
49!------------------------------------------------------------------------------------------------
50
51 function bounds_check_float_1d( array_vals, array_index ) result(bounds_ok)
52
53 real (c_float), intent(in) :: array_vals(:)
54 integer (c_int), intent(in) :: array_index
55 logical (c_bool) :: bounds_ok
56
57 bounds_ok = false
58
59 if ( lbound(array_vals,1) <= array_index &
60 .and. ubound(array_vals,1) >= array_index ) bounds_ok = true
61
62 end function bounds_check_float_1d
63
64!------------------------------------------------------------------------------------------------
65
66 function bounds_check_double_1d( array_vals, array_index ) result(bounds_ok)
67
68 real (c_double), intent(in) :: array_vals(:)
69 integer (c_int), intent(in) :: array_index
70 logical (c_bool) :: bounds_ok
71
72 bounds_ok = false
73
74 if ( lbound(array_vals,1) <= array_index &
75 .and. ubound(array_vals,1) >= array_index ) bounds_ok = true
76
77 end function bounds_check_double_1d
78
79!------------------------------------------------------------------------------------------------
80
81 function bounds_check_integer_2d( array_vals, array_index1, &
82 array_index2 ) result(bounds_ok)
83
84 integer (c_int), intent(in) :: array_vals(:,:)
85 integer (c_int), intent(in) :: array_index1
86 integer (c_int), intent(in) :: array_index2
87 logical (c_bool) :: bounds_ok
88
89 bounds_ok = false
90
91 if ( lbound(array_vals,1) <= array_index1 &
92 .and. ubound(array_vals,1) >= array_index1 &
93 .and. lbound(array_vals,2) <= array_index2 &
94 .and. ubound(array_vals,2) >= array_index2 ) bounds_ok = true
95
96 end function bounds_check_integer_2d
97
98!------------------------------------------------------------------------------------------------
99
100 function bounds_check_float_2d( array_vals, array_index1, &
101 array_index2 ) result(bounds_ok)
102
103 real (c_float), intent(in) :: array_vals(:,:)
104 integer (c_int), intent(in) :: array_index1
105 integer (c_int), intent(in) :: array_index2
106 logical (c_bool) :: bounds_ok
107
108 bounds_ok = false
109
110 if ( lbound(array_vals,1) <= array_index1 &
111 .and. ubound(array_vals,1) >= array_index1 &
112 .and. lbound(array_vals,2) <= array_index2 &
113 .and. ubound(array_vals,2) >= array_index2 ) bounds_ok = true
114
115 end function bounds_check_float_2d
116
117!------------------------------------------------------------------------------------------------
118
119 function bounds_check_double_2d( array_vals, array_index1, &
120 array_index2 ) result(bounds_ok)
121
122 real (c_double), intent(in) :: array_vals(:,:)
123 integer (c_int), intent(in) :: array_index1
124 integer (c_int), intent(in) :: array_index2
125 logical (c_bool) :: bounds_ok
126
127 bounds_ok = false
128
129 if ( lbound(array_vals,1) <= array_index1 &
130 .and. ubound(array_vals,1) >= array_index1 &
131 .and. lbound(array_vals,2) <= array_index2 &
132 .and. ubound(array_vals,2) >= array_index2 ) bounds_ok = true
133
134 end function bounds_check_double_2d
135
136!------------------------------------------------------------------------------------------------
137
138 subroutine die(sMessage, sModule, iLine, sHints, sCalledBy, iCalledByLine )
139
140 character (len=*), intent(in) :: smessage
141 character (len=*), intent(in), optional :: smodule
142 integer (c_int), intent(in), optional :: iline
143 character (len=*), intent(in), optional :: shints
144 character (len=*), intent(in), optional :: scalledby
145 integer (c_int), intent(in), optional :: icalledbyline
146
147! integer (c_int), intent(in), optional :: iLU
148
149 ! [ LOCALS ]
150 character (len=6) :: slinenum
151
152 call logs%set_loglevel( log_all )
153
154 if (halt_upon_fatal_error) call logs%set_echo( .true._c_bool )
155
156 call logs%write( "error condition: "//trim(smessage), itab=12, ilinesbefore=1 )
157
158 if ( present( scalledby ) ) &
159 call logs%write( "called by: "//trim(scalledby), itab=18 )
160
161 if (present(icalledbyline)) then
162 write(slinenum, fmt="(i0)") icalledbyline
163 call logs%write( "line number: "//trim(slinenum), itab=16 )
164 endif
165
166 if (present(smodule)) &
167 call logs%write( "module: "//trim(smodule), itab=21 )
168
169 if (present(iline)) then
170 write(slinenum, fmt="(i0)") iline
171 call logs%write( "line number: "//trim(slinenum), itab=16 )
172 endif
173
174 if (present(shints)) then
175 if ( len_trim(shints) > 0 ) &
176 call logs%write( "==> "//trim(shints), itab=12 )
177 endif
178
179 call logs%write("", ilinesafter=1)
180
181 if (halt_upon_fatal_error) then
182 call logs%write( "** ERROR -- PROGRAM EXECUTION HALTED **", ilinesbefore=1, ilinesafter=1 )
183 stop
184 endif
185
186 end subroutine die
187
188!------------------------------------------------------------------------------------------------
189
191
192 ! [ LOCALS ]
193 character (len=6) :: snumwarnings
194 character (len=6) :: smaxwarnings
195 character (len=6) :: sindex
196 integer (c_int) :: iindex
197 character (len=10) :: sbigs
198 character (len=1) :: slittles
199
200 if ( number_of_fatal_warnings >= 1 ) then
201
202 if ( number_of_fatal_warnings > 1 ) then
203 sbigs = "S WERE"
204 slittles = "s"
205 else
206 sbigs = " WAS"
207 slittles = ""
208 endif
209
210 call logs%set_loglevel( log_all )
211 call logs%set_echo( .true._c_bool )
212
213 write(unit=snumwarnings, fmt="(i0)") number_of_fatal_warnings
214 call logs%write( "** "//trim(adjustl(snumwarnings))//" FATAL WARNING"//trim(sbigs) &
215 //" DETECTED IN INPUT **", ilinesbefore=1, ilinesafter=1 )
216
217 call logs%write( "# Summary of fatal warning"//trim(slittles)//" #" )
218 call logs%write( "-------------------------------", ilinesafter=1 )
219
220 do iindex = 1, number_of_fatal_warnings
221 if (iindex <= max_fatal_warnings ) then
222 write(unit=sindex, fmt="(i0)") iindex
223 call logs%write( trim(adjustl(sindex))//": "//trim(warning_text(iindex)), ilinesbefore=1)
224 endif
225 enddo
226
228 write(unit=smaxwarnings, fmt="(i0)") max_fatal_warnings
229 call logs%write( "*There were more than "//trim(adjustl(smaxwarnings))//" fatal warnings. " &
230 //" Only a partial list of warnings is shown above.*", ilinesbefore=1, ilinesafter=1, itab=2 )
231 endif
232
233 call die( smessage="Fatal warning"//trim(slittles)//" associated with input.", &
234 shints="Address the problem"//trim(slittles)//" listed above and try again." )
235
236 endif
237
238 end subroutine check_for_fatal_warnings
239
240!------------------------------------------------------------------------------------------------
241
242 subroutine warn(sMessage, sModule, iLine, sHints, lFatal, iLogLevel, lEcho)
243
244 character (len=*), intent(in) :: smessage
245 character (len=*), intent(in), optional :: smodule
246 integer (c_int), intent(in), optional :: iline
247 character (len=*), intent(in), optional :: shints
248 logical (c_bool), intent(in), optional :: lfatal
249 integer (c_int), intent(in), optional :: iloglevel
250 logical (c_bool), intent(in), optional :: lecho
251! integer (c_int), intent(in), optional :: iLU
252
253 ! [ LOCALS ]
254 character (len=32) :: sbuf
255
256 if ( present( iloglevel ) ) call logs%set_loglevel( iloglevel )
257 if ( present( lecho ) ) call logs%set_echo( lecho )
258
259 if (present(lfatal)) then
260 if (lfatal) then
262 call logs%write(" ** WARNING fatal error: **", itab=6, ilinesbefore=1)
263 call logs%write( trim(smessage), itab=16 )
264
265 if (number_of_fatal_warnings <= ubound( warning_text,1 ) ) &
266 warning_text( number_of_fatal_warnings ) = trim(smessage)
267 else
268 call logs%write(" ** WARNING **", itab=10, ilinesbefore=1)
269 call logs%write( trim(smessage), itab=16 )
270 endif
271 else
272 call logs%write(" ** WARNING **", itab=10, ilinesbefore=1)
273 call logs%write( trim(smessage), itab=16 )
274 endif
275
276 if (present(smodule)) &
277 call logs%write("module: "//trim(smodule), itab=18 )
278
279 if (present(iline)) then
280 write(sbuf, fmt="(i0)") iline
281 call logs%write("line no: "//trim(sbuf), itab=18 )
282 endif
283
284 if (present(shints)) then
285 if ( len_trim(shints) > 0 ) &
286 call logs%write(" ==> "//trim(shints), itab=9, ilinesbefore=1 )
287 endif
288
289 call logs%write("", ilinesafter=1)
290
291 end subroutine warn
292
293!------------------------------------------------------------------------------------------------
294
295 subroutine assert_1bit(lCondition, sMessage, sModule, iLine, sCalledBy, iCalledByLine, sHints )
296
297 logical (c_bool), intent(in) :: lCondition
298 character (len=*), intent(in) :: sMessage
299 character (len=*), intent(in), optional :: sHints
300 character (len=*), intent(in), optional :: sCalledBy
301 integer (c_int), intent(in), optional :: iCalledByLine
302 character (len=*), intent(in), optional :: sModule
303 integer (c_int), intent(in), optional :: iLine
304
305 character (len=256) :: sHints_l
306
307 if (.not. lcondition) then
308
309 if ( present( shints ) ) then
310 shints_l = trim( shints )
311 else
312 shints_l = ""
313 endif
314
315 if (present( scalledby ) .and. present( icalledbyline ) &
316 .and. present(smodule) .and. present(iline) ) then
317 call die( smessage=smessage, scalledby=scalledby, icalledbyline=icalledbyline, &
318 smodule=smodule, iline=iline, shints=shints_l )
319 elseif ( present(smodule) .and. present(iline) ) then
320 call die( smessage=smessage, smodule=smodule, iline=iline, shints=shints_l )
321 elseif ( present(smodule) ) then
322 call die( smessage=smessage, smodule=smodule, shints=shints_l )
323 else
324 call die( smessage=smessage, shints=shints_l )
325 endif
326
327 endif
328
329 end subroutine assert_1bit
330
331!------------------------------------------------------------------------------------------------
332
333subroutine assert_4bit(lCondition, sMessage, sModule, iLine, sCalledBy, iCalledByLine, sHints )
334
335 logical (4), intent(in) :: lCondition
336 character (len=*), intent(in) :: sMessage
337 character (len=*), intent(in), optional :: sHints
338 character (len=*), intent(in), optional :: sCalledBy
339 integer (c_int), intent(in), optional :: iCalledByLine
340 character (len=*), intent(in), optional :: sModule
341 integer (c_int), intent(in), optional :: iLine
342
343 character (len=256) :: sHints_l
344
345 if (.not. lcondition) then
346
347 if ( present( shints ) ) then
348 shints_l = trim( shints )
349 else
350 shints_l = ""
351 endif
352
353 if (present( scalledby ) .and. present( icalledbyline ) &
354 .and. present(smodule) .and. present(iline) ) then
355 call die( smessage=smessage, scalledby=scalledby, icalledbyline=icalledbyline, &
356 smodule=smodule, iline=iline, shints=shints_l )
357 elseif ( present(smodule) .and. present(iline) ) then
358 call die( smessage=smessage, smodule=smodule, iline=iline, shints=shints_l )
359 elseif ( present(smodule) ) then
360 call die( smessage=smessage, smodule=smodule, shints=shints_l )
361 else
362 call die( smessage=smessage, shints=shints_l )
363 endif
364
365 endif
366
367end subroutine assert_4bit
368
369!------------------------------------------------------------------------------------------------
370
371end module exceptions
integer(c_int), parameter max_fatal_warnings
subroutine, public check_for_fatal_warnings()
integer(c_int), public number_of_fatal_warnings
logical(c_bool) function bounds_check_double_2d(array_vals, array_index1, array_index2)
logical(c_bool) function bounds_check_integer_2d(array_vals, array_index1, array_index2)
subroutine assert_4bit(lcondition, smessage, smodule, iline, scalledby, icalledbyline, shints)
logical(c_bool), public halt_upon_fatal_error
logical(c_bool), parameter false
character(len=256), dimension(max_fatal_warnings) warning_text
subroutine, public warn(smessage, smodule, iline, shints, lfatal, iloglevel, lecho)
subroutine assert_1bit(lcondition, smessage, smodule, iline, scalledby, icalledbyline, shints)
logical(c_bool) function bounds_check_double_1d(array_vals, array_index)
logical(c_bool) function bounds_check_float_2d(array_vals, array_index1, array_index2)
logical(c_bool) function bounds_check_float_1d(array_vals, array_index)
logical(c_bool) function bounds_check_integer_1d(array_vals, array_index)
logical(c_bool), parameter true
subroutine, public die(smessage, smodule, iline, shints, scalledby, icalledbyline)
type(logfile_t), public logs
Definition logfiles.F90:62
@ log_general
Definition logfiles.F90:22