logging_base.f90
Go to the documentation of this file.
1!#############################################################################
2!# #
3!# fosite - 3D hydrodynamical simulation program #
4!# module: loggin_base.f90 #
5!# #
6!# Copyright (C) 2006-2014 #
7!# Tobias Illenseer <tillense@astrophysik.uni-kiel.de> #
8!# #
9!# This program is free software; you can redistribute it and/or modify #
10!# it under the terms of the GNU General Public License as published by #
11!# the Free Software Foundation; either version 2 of the License, or (at #
12!# your option) any later version. #
13!# #
14!# This program is distributed in the hope that it will be useful, but #
15!# WITHOUT ANY WARRANTY; without even the implied warranty of #
16!# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or #
17!# NON INFRINGEMENT. See the GNU General Public License for more #
18!# details. #
19!# #
20!# You should have received a copy of the GNU General Public License #
21!# along with this program; if not, write to the Free Software #
22!# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
23!# #
24!#############################################################################
25
26!----------------------------------------------------------------------------!
35!----------------------------------------------------------------------------!
37#ifdef PARALLEL
38#ifdef HAVE_MPI_MOD
39 USE mpi
40#endif
41#endif
42 IMPLICIT NONE
43#ifdef PARALLEL
44#ifdef HAVE_MPIF_H
45 include 'mpif.h'
46#endif
47#endif
48 !--------------------------------------------------------------------------!
49 PRIVATE
57 PRIVATE
58 INTEGER :: mod_type
59 CHARACTER(LEN=32) :: mod_name
60 INTEGER, PUBLIC :: err
61 LOGICAL :: isinitialized = .false.
62 INTEGER, POINTER :: myrank => null()
63 INTEGER, POINTER :: ppnum => null()
64 LOGICAL, POINTER :: parinit => null()
65 CONTAINS
66 PROCEDURE :: initlogging
67 final :: finalize
68 PROCEDURE :: gettype
69 PROCEDURE :: getname
70 PROCEDURE :: getrank
71 PROCEDURE :: getnumprocs
72 PROCEDURE :: initialized
73 PROCEDURE :: info
74 PROCEDURE :: warning
75 PROCEDURE :: error
76 END TYPE logging_base
77 ! these variables should be the same for all objects
78 ! of the current process
79#ifdef PARALLEL
80 INTEGER, SAVE :: default_mpi_real = mpi_real
81 INTEGER, SAVE :: default_mpi_2real = mpi_2real
82 INTEGER, SAVE :: default_mpi_complex = mpi_double_complex
83 REAL, PARAMETER :: dummy = 1.0
84#endif
85 REAL, SAVE :: nan_default_real
86 INTEGER, PARAMETER :: stderr = 0
87 INTEGER, PARAMETER :: stdout = 6
88 INTEGER, SAVE, TARGET :: myrank = 0
89 INTEGER, SAVE, TARGET :: ppnum = 1
90 LOGICAL, SAVE, TARGET :: parinit = .false.
91 CHARACTER(LEN=1), SAVE :: prefix = ' '
92 !--------------------------------------------------------------------------!
93 PUBLIC :: &
94 ! types
96#ifdef PARALLEL
100#endif
103 !--------------------------------------------------------------------------!
104
105CONTAINS
106
113 SUBROUTINE initlogging(this,t,n)
114 use, INTRINSIC :: ieee_arithmetic
115 IMPLICIT NONE
116 !------------------------------------------------------------------------!
117 CLASS(logging_base), INTENT(INOUT) :: this
118 INTEGER :: t
119 CHARACTER(LEN=*) :: n
120 !------------------------------------------------------------------------!
121 INTENT(IN) :: t,n
122 !------------------------------------------------------------------------!
123 this%mod_type = t
124 this%mod_name = n
125 this%myrank => myrank
126 this%ppnum => ppnum
127 this%parinit => parinit
128#ifdef PARALLEL
129 IF (.NOT.parinit) THEN
130 CALL mpi_comm_rank(mpi_comm_world,this%myrank,this%err)
131 CALL mpi_comm_size(mpi_comm_world,this%ppnum,this%err)
132 this%parinit = .true.
133 ! determine the default MPI data type for real numbers
134 SELECT CASE (selected_real_kind(precision(dummy)))
135 CASE(4)
136 default_mpi_real = mpi_real4
137 default_mpi_2real = mpi_2real
138 CASE(8)
139 default_mpi_real = mpi_real8
140 default_mpi_2real = mpi_2double_precision
141 CASE DEFAULT
142 CALL this%Warning("logging_base::InitLogging","Cannot determine default MPI real types.")
143 END SELECT
144 END IF
145#endif
146#ifndef DEBUG
147 nan_default_real = ieee_value(nan_default_real,ieee_quiet_nan)
148#else
150 CALL this%Warning("logging_base::InitLogging","Setting numbers to NaN for testing disabled in debug mode")
151#endif
152 this%err = 0
153 this%isinitialized = .true.
154 END SUBROUTINE initlogging
155
156
159 SUBROUTINE finalize(this)
160 IMPLICIT NONE
161 !------------------------------------------------------------------------!
162 TYPE(logging_base), INTENT(INOUT) :: this
163 !------------------------------------------------------------------------!
164 this%isinitialized = .false.
165 END SUBROUTINE finalize
166
167
170 PURE FUNCTION gettype(this) RESULT(t)
171 IMPLICIT NONE
172 !------------------------------------------------------------------------!
173 CLASS(logging_base), INTENT(IN) :: this
174 INTEGER :: t
175 !------------------------------------------------------------------------!
176 t = this%mod_type
177 END FUNCTION gettype
178
179
182 SUBROUTINE setprefix(val)
183 IMPLICIT NONE
184 !------------------------------------------------------------------------!
185 CHARACTER(LEN=1), INTENT(IN) :: val
186 !------------------------------------------------------------------------!
187 prefix = val
188 END SUBROUTINE setprefix
189
190
193 PURE FUNCTION getname(this) RESULT(n)
194 IMPLICIT NONE
195 !------------------------------------------------------------------------!
196 CLASS(logging_base), INTENT(IN) :: this
197 CHARACTER(LEN=32) :: n
198 !------------------------------------------------------------------------!
199 n = this%mod_name
200 END FUNCTION getname
201
202
209 PURE FUNCTION getrank(this) RESULT(r)
210 IMPLICIT NONE
211 !------------------------------------------------------------------------!
212 CLASS(logging_base), INTENT(IN) :: this
213 INTEGER :: r
214 !------------------------------------------------------------------------!
215 r = this%myrank
216 END FUNCTION getrank
217
218
223 PURE FUNCTION getnumprocs(this) RESULT(p)
224 IMPLICIT NONE
225 !------------------------------------------------------------------------!
226 CLASS(logging_base), INTENT(IN) :: this
227 INTEGER :: p
228 !------------------------------------------------------------------------!
229 p = this%ppnum
230 END FUNCTION getnumprocs
231
232
237 PURE FUNCTION initialized(this) RESULT(i)
238 IMPLICIT NONE
239 !------------------------------------------------------------------------!
240 CLASS(logging_base), INTENT(IN) :: this
241 LOGICAL :: i
242 !------------------------------------------------------------------------!
243 i = this%isinitialized
244#ifdef PARALLEL
245 IF (ASSOCIATED(this%parinit)) THEN
246 i = i.AND.this%parinit
247 ELSE
248 i = .false.
249 END IF
250#endif
251 END FUNCTION initialized
252
253
264 SUBROUTINE info(this,msg,rank,node_info,tostderr)
265 IMPLICIT NONE
266 !------------------------------------------------------------------------!
267 CLASS(logging_base), INTENT(IN) :: this
268 CHARACTER(LEN=*), INTENT(IN) :: msg
269 INTEGER, OPTIONAL, INTENT(IN) :: rank
270 LOGICAL, OPTIONAL, INTENT(IN) :: node_info
271 LOGICAL, OPTIONAL, INTENT(IN) :: tostderr
272 !------------------------------------------------------------------------!
273#ifdef PARALLEL
274 INTEGER :: ierr
275#endif
276 INTEGER :: print_rank,output_unit
277 LOGICAL :: print_node_info
278 !------------------------------------------------------------------------!
279 IF (PRESENT(rank)) THEN
280 print_rank = rank
281 ELSE
282 print_rank = 0
283 END IF
284 IF (PRESENT(node_info)) THEN
285 print_node_info = node_info
286 ELSE
287 print_node_info = .false.
288 END IF
289 ! output unit for printing, defaults to STDOUT
290 output_unit = stdout
291 IF (PRESENT(tostderr)) THEN
292 IF (tostderr) output_unit = stderr ! print on STDERR if requested
293 ENDIF
294#ifdef PARALLEL
295 IF (.NOT.parinit) CALL mpi_comm_rank(mpi_comm_world,myrank,ierr)
296#endif
297 ! use "myrank" here instead of "this%myrank"
298 ! because "this" might be uninitialized
299 IF (myrank.EQ.print_rank) THEN
300 WRITE (output_unit,'(A)',advance='NO') prefix
301#ifdef PARALLEL
302 IF (print_node_info) &
303 WRITE (output_unit,'(A,I4.4,A)',advance='NO') "NODE [", myrank, "] "
304#endif
305 WRITE (output_unit,'(A)') trim(msg)
306 ! Flush the output buffer, to make sure it is written even if the
307 ! program is invoked from a batch system.
308 ! This is Fortran 2003 standard! In Fortran 90/95 flush is implemented
309 ! as a subroutine, hence one needs a CALL statement, i.e.,
310 ! CALL FLUSH(output_unit)
311 FLUSH(output_unit)
312 END IF
313 END SUBROUTINE info
314
315
320 SUBROUTINE warning(this,modproc,msg,rank)
321 IMPLICIT NONE
322 !------------------------------------------------------------------------!
323 CLASS(logging_base), INTENT(IN) :: this
324 CHARACTER(LEN=*), INTENT(IN) :: modproc
325 CHARACTER(LEN=*), INTENT(IN) :: msg
326 INTEGER, OPTIONAL, INTENT(IN) :: rank
327 !------------------------------------------------------------------------!
328 CALL info(this,"WARNING in " // trim(modproc) // ": " // trim(msg),&
329 rank,node_info=.true.,tostderr=.true.)
330 END SUBROUTINE warning
331
332
338 SUBROUTINE error(this,modproc,msg,rank,node_info)
339 IMPLICIT NONE
340 !------------------------------------------------------------------------!
341 CLASS(logging_base), INTENT(IN) :: this
342 CHARACTER(LEN=*), INTENT(IN) :: modproc
343 CHARACTER(LEN=*), INTENT(IN) :: msg
344 INTEGER, OPTIONAL, INTENT(IN) :: rank
345 LOGICAL, OPTIONAL, INTENT(IN) :: node_info
346 !------------------------------------------------------------------------!
347#ifdef PARALLEL
348 INTEGER :: ierr
349#endif
350 !------------------------------------------------------------------------!
351 CALL info(this,"ERROR in " // trim(modproc) // ": " // trim(msg),&
352 rank=rank,node_info=node_info,tostderr=.true.)
353 ! abort execution
354#ifdef PARALLEL
355 CALL mpi_abort(mpi_comm_world,1,ierr)
356#else
357 stop 99
358#endif
359 END SUBROUTINE error
360
361END MODULE logging_base_mod
Basic fosite module.
character(len=1), save prefix
preceds info output
real, save nan_default_real
NaN real constant.
integer, target, save ppnum
MPI number of processes.
subroutine info(this, msg, rank, node_info, tostderr)
Print information on standard output.
real, parameter dummy
check default real type
subroutine finalize(this)
Destructor of logging_base class.
integer, save default_mpi_real
default real type for MPI
pure integer function getnumprocs(this)
Get the total number of MPI processes.
integer, parameter stdout
fortran stdout unit
integer, save default_mpi_complex
default real type for MPI
pure integer function gettype(this)
Get the module type number.
pure character(len=32) function getname(this)
Get the module name.
subroutine initlogging(this, t, n)
Constructor of the base class.
subroutine error(this, modproc, msg, rank, node_info)
Print error message on standard error and terminate the program.
pure integer function getrank(this)
Get the MPI rank.
subroutine warning(this, modproc, msg, rank)
Print warning message on standard error.
subroutine setprefix(val)
Set character preceding the info output.
logical, target, save parinit
MPI initialization status.
pure logical function initialized(this)
Query initialization status.
integer, target, save myrank
MPI rank.
integer, save default_mpi_2real
default 2real type for MPI
integer, parameter stderr
fortran stderr unit
common data structure