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