MOM6
MOM_error_handler.F90
1 !> Routines for error handling and I/O management
3 
4 ! This file is part of MOM6. See LICENSE.md for the license.
5 
6 use mpp_mod, only : mpp_error, note, warning, fatal
7 use mpp_mod, only : mpp_pe, mpp_root_pe, stdlog, stdout
8 
9 implicit none ; private
10 
11 public mom_error, mom_mesg, note, warning, fatal, is_root_pe, stdlog, stdout
12 public mom_set_verbosity, mom_get_verbosity, mom_verbose_enough
13 public calltree_showquery, calltree_enter, calltree_leave, calltree_waypoint
14 public assert
15 
16 integer :: verbosity = 6
17 !< Verbosity level:
18 !! 0 - FATAL messages only
19 !! 1 - FATAL + WARNING messages only
20 !! 2 - FATAL + WARNING + NOTE messages only [default]
21 !! 3 - above + informational
22 !! 4 -
23 !! 5 -
24 !! 6 - above + call tree
25 !! 7 -
26 !! 8 -
27 !! 9 - anything and everything (also set with DEBUG=True)
28 
29 ! Note that this module default will only hold until the
30 ! VERBOSITY parameter is parsed and the given default imposed.
31 ! We set it to 6 here so that the call tree will print before
32 ! the parser has been initialized
33 ! Also note that this is a module variable rather than contained in
34 ! a type passed by argument (preferred for most data) for convenience
35 ! and to reduce obfuscation of code
36 
37 integer :: calltreeindentlevel = 0
38 !< The level of calling within the call tree
39 
40 contains
41 
42 !> This returns .true. if the current PE is the root PE.
43 function is_root_pe()
44  ! This returns .true. if the current PE is the root PE.
45  logical :: is_root_pe
46  is_root_pe = .false.
47  if (mpp_pe() == mpp_root_pe()) is_root_pe = .true.
48  return
49 end function is_root_pe
50 
51 !> This provides a convenient interface for writing an informative comment.
52 subroutine mom_mesg(message, verb, all_print)
53  character(len=*), intent(in) :: message !< A message to write out
54  integer, optional, intent(in) :: verb !< A level of verbosity for this message
55  logical, optional, intent(in) :: all_print !< If present and true, any PEs are
56  !! able to write this message.
57  ! This provides a convenient interface for writing an informative comment.
58  integer :: verb_msg
59  logical :: write_msg
60 
61  write_msg = is_root_pe()
62  if (present(all_print)) write_msg = write_msg .or. all_print
63 
64  verb_msg = 2 ; if (present(verb)) verb_msg = verb
65  if (write_msg .and. (verbosity >= verb_msg)) call mpp_error(note, message)
66 
67 end subroutine mom_mesg
68 
69 !> This provides a convenient interface for writing an mpp_error message
70 !! with run-time filter based on a verbosity.
71 subroutine mom_error(level, message, all_print)
72  integer, intent(in) :: level !< The verbosity level of this message
73  character(len=*), intent(in) :: message !< A message to write out
74  logical, optional, intent(in) :: all_print !< If present and true, any PEs are
75  !! able to write this message.
76  ! This provides a convenient interface for writing an mpp_error message
77  ! with run-time filter based on a verbosity.
78  logical :: write_msg
79 
80  write_msg = is_root_pe()
81  if (present(all_print)) write_msg = write_msg .or. all_print
82 
83  select case (level)
84  case (note)
85  if (write_msg.and.verbosity>=2) call mpp_error(note, message)
86  case (warning)
87  if (write_msg.and.verbosity>=1) call mpp_error(warning, message)
88  case (fatal)
89  if (verbosity>=0) call mpp_error(fatal, message)
90  case default
91  call mpp_error(level, message)
92  end select
93 end subroutine mom_error
94 
95 !> This subroutine sets the level of verbosity filtering MOM error messages
96 subroutine mom_set_verbosity(verb)
97  integer, intent(in) :: verb !< A level of verbosity to set
98  character(len=80) :: msg
99  if (verb>0 .and. verb<10) then
100  verbosity=verb
101  else
102  write(msg(1:80),'("Attempt to set verbosity outside of range (0-9). verb=",I0)') verb
103  call mom_error(fatal,msg)
104  endif
105 end subroutine mom_set_verbosity
106 
107 !> This subroutine gets the level of verbosity filtering MOM error messages
108 function mom_get_verbosity()
109  integer :: mom_get_verbosity
110  mom_get_verbosity = verbosity
111 end function mom_get_verbosity
112 
113 !> This tests whether the level of verbosity filtering MOM error messages is
114 !! sufficient to write a message of verbosity level verb
115 function mom_verbose_enough(verb)
116  integer, intent(in) :: verb !< A level of verbosity to test
117  logical :: mom_verbose_enough
118  mom_verbose_enough = (verbosity >= verb)
119 end function mom_verbose_enough
120 
121 !> Returns True, if the verbosity>=6 indicating to show the call tree
122 function calltree_showquery()
123  ! Local variables
124  logical :: calltree_showquery
125  calltree_showquery = (verbosity >= 6)
126 end function calltree_showquery
127 
128 !> Writes a message about entering a subroutine if call tree reporting is active
129 subroutine calltree_enter(mesg,n)
130  character(len=*), intent(in) :: mesg !< Message to write
131  integer, optional, intent(in) :: n !< An optional integer to write at end of message
132  ! Local variables
133  character(len=8) :: nasstring
134  calltreeindentlevel = calltreeindentlevel + 1
135  if (verbosity<6) return
136  if (is_root_pe()) then
137  nasstring = ''
138  if (present(n)) then
139  write(nasstring(1:8),'(i8)') n
140  call mpp_error(note, 'callTree: '// &
141  repeat(' ',calltreeindentlevel-1)//'loop '//trim(mesg)//trim(nasstring))
142  else
143  call mpp_error(note, 'callTree: '// &
144  repeat(' ',calltreeindentlevel-1)//'---> '//trim(mesg))
145  endif
146  endif
147 end subroutine calltree_enter
148 
149 !> Writes a message about leaving a subroutine if call tree reporting is active
150 subroutine calltree_leave(mesg)
151  character(len=*) :: mesg !< Message to write
152  if (calltreeindentlevel<1) write(0,*) 'callTree_leave: error callTreeIndentLevel=',calltreeindentlevel,trim(mesg)
153  calltreeindentlevel = calltreeindentlevel - 1
154  if (verbosity<6) return
155  if (is_root_pe()) call mpp_error(note, 'callTree: '// &
156  repeat(' ',calltreeindentlevel)//'<--- '//trim(mesg))
157 end subroutine calltree_leave
158 
159 !> Writes a message about reaching a milestone if call tree reporting is active
160 subroutine calltree_waypoint(mesg,n)
161  character(len=*), intent(in) :: mesg !< Message to write
162  integer, optional, intent(in) :: n !< An optional integer to write at end of message
163  ! Local variables
164  character(len=8) :: nasstring
165  if (calltreeindentlevel<0) write(0,*) 'callTree_waypoint: error callTreeIndentLevel=',calltreeindentlevel,trim(mesg)
166  if (verbosity<6) return
167  if (is_root_pe()) then
168  nasstring = ''
169  if (present(n)) then
170  write(nasstring(1:8),'(i8)') n
171  call mpp_error(note, 'callTree: '// &
172  repeat(' ',calltreeindentlevel)//'loop '//trim(mesg)//trim(nasstring))
173  else
174  call mpp_error(note, 'callTree: '// &
175  repeat(' ',calltreeindentlevel)//'o '//trim(mesg))
176  endif
177  endif
178 end subroutine calltree_waypoint
179 
180 !> Issues a FATAL error if the assertion fails, i.e. the first argument is false.
181 subroutine assert(logical_arg, msg)
182  logical, intent(in) :: logical_arg !< If false causes a FATAL error
183  character(len=*), intent(in) :: msg !< Message to issue in case of failed assertion
184 
185  if (.not. logical_arg) then
186  call mom_error(fatal, msg)
187  endif
188 
189 end subroutine assert
190 
191 end module mom_error_handler
mom_error_handler
Routines for error handling and I/O management.
Definition: MOM_error_handler.F90:2