fileio_base.f90
Go to the documentation of this file.
1 !#############################################################################
2 !# #
3 !# fosite - 3D hydrodynamical simulation program #
4 !# module: fileio_generic.f90 #
5 !# #
6 !# Copyright (C) 2008-2014 #
7 !# Tobias Illenseer <tillense@astrophysik.uni-kiel.de> #
8 !# Björn Sperling <sperling@astrophysik.uni-kiel.de> #
9 !# Manuel Jung <mjung@astrophysik.uni-kiel.de> #
10 !# #
11 !# This program is free software; you can redistribute it and/or modify #
12 !# it under the terms of the GNU General Public License as published by #
13 !# the Free Software Foundation; either version 2 of the License, or (at #
14 !# your option) any later version. #
15 !# #
16 !# This program is distributed in the hope that it will be useful, but #
17 !# WITHOUT ANY WARRANTY; without even the implied warranty of #
18 !# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or #
19 !# NON INFRINGEMENT. See the GNU General Public License for more #
20 !# details. #
21 !# #
22 !# You should have received a copy of the GNU General Public License #
23 !# along with this program; if not, write to the Free Software #
24 !# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
25 !# #
26 !#############################################################################
38 #ifdef HAVE_NETCDF
39 !! \key{ncfmt,INTEGER,netcdf format type}
40 #endif
41 !----------------------------------------------------------------------------!
53 !----------------------------------------------------------------------------!
56  USE common_dict
57  USE fluxes_base_mod
60  USE mesh_base_mod
62 #ifdef PARALLEL
63 #ifdef HAVE_MPI_MOD
64  USE mpi
65 #endif
66 #endif
67  IMPLICIT NONE
68 #ifdef PARALLEL
69 #ifdef HAVE_MPIF_H
70  include 'mpif.h'
71 #endif
72 #endif
73  !--------------------------------------------------------------------------!
74  PRIVATE
75  !--------------------------------------------------------------------------!
76  ! Private Attributes section starts here:
79  INTEGER, PARAMETER :: fextlen = 4
80  INTEGER, PARAMETER :: fmltlen = 5
81  INTEGER, PARAMETER :: fcyclen = 5
82  INTEGER, PARAMETER :: fnamlen = 256
83  INTEGER, PARAMETER :: fpatlen = 1024
86 #ifdef PARALLEL
87  CHARACTER(LEN=FMLTLEN), SAVE :: fmextstr = ""
88 #endif
89  INTEGER, PARAMETER :: maxmltfiles = 1000
93  INTEGER, PARAMETER :: maxcycles = 10000
95  CHARACTER(LEN=32), SAVE :: cycfmt
96  !--------------------------------------------------------------------------!
99  REAL, DIMENSION(:,:,:), POINTER :: val
100  END TYPE
101 
103  REAL, DIMENSION(:,:), POINTER :: val
104  TYPE(valptr_typ), DIMENSION(:), POINTER :: p
105  CHARACTER(LEN=128) :: key
106  INTEGER(KIND=4) :: numbytes
107  END TYPE output_typ
108 
111  REAL, POINTER :: val
112  CHARACTER(LEN=128) :: key
113  END TYPE tsoutput_typ
114 
116  TYPE, ABSTRACT,EXTENDS(logging_base) :: fileio_base
118  TYPE(logging_base) :: format
119  CHARACTER(LEN=512) :: linebuf
120  CHARACTER(LEN=512) :: tslinebuf
121  CHARACTER(LEN=FNAMLEN) :: filename
122  CHARACTER(LEN=FPATLEN) :: path
123  CHARACTER(LEN=FEXTLEN) :: extension
124  LOGICAL :: cartcoords
125  INTEGER :: unit
126  INTEGER :: error_io
127  INTEGER :: step
128  INTEGER :: count
129  INTEGER :: cycles
130  INTEGER :: dtwall
131  INTEGER :: realsize
132  INTEGER :: intsize
133  INTEGER :: inum,jnum,& !< mesh extent
134  knum
135 #ifndef PARALLEL
136  INTEGER(KIND=8) :: offset
137 #endif
138  REAL :: stoptime
139  REAL :: starttime
140  REAL :: time
141  REAL, DIMENSION(:,:,:,:), POINTER :: &
142  binout
145  CHARACTER(LEN=32) :: buf
146  CHARACTER(LEN=12) :: realfmt
147  CHARACTER(LEN=14) :: endianness
148  CHARACTER(LEN=14) :: endian
149  REAL, DIMENSION(:,:,:,:), POINTER :: &
150  vtkcoords
153  CHARACTER(LEN=512) :: heading
154  CHARACTER(LEN=512) :: tsheading
155  CHARACTER(LEN=64) :: fmtstr
156  CHARACTER(LEN=64) :: linefmt
157  INTEGER :: cols
158  INTEGER :: tscols
159  INTEGER :: maxcols
161  INTEGER :: decs
162  INTEGER :: flen
163  INTEGER :: linelen
164  INTEGER :: tslinelen
165 #ifdef HAVE_HDF5_MOD
166 
168  INTEGER(HID_T) :: fid
169  INTEGER(HID_T) :: xferid
170 #endif
171  TYPE(output_typ),DIMENSION(:), POINTER :: &
172  output
173  TYPE(tsoutput_typ),DIMENSION(:), POINTER :: &
174  tsoutput
175  REAL, DIMENSION(:,:) , POINTER :: &
176  bflux
177  REAL :: walltime
178 #ifdef PARALLEL
179 
180  LOGICAL :: multfiles
181  INTEGER :: handle
182  INTEGER :: bufsize
183  INTEGER :: cbufsize
184  INTEGER :: basictype
185  INTEGER :: filetype
186  INTEGER, DIMENSION(MPI_STATUS_SIZE) :: &
187  status
188  INTEGER(KIND=MPI_OFFSET_KIND) :: offset
191  INTEGER :: blocknum
192  INTEGER(KIND=MPI_ADDRESS_KIND) :: &
193  realext, & !< real data type extent
194  intext
195  CHARACTER, DIMENSION(:,:), POINTER :: &
196  outbuf
199  LOGICAL :: first
202  CHARACTER(LEN=64), DIMENSION(:), POINTER :: &
203  extent
205  INTEGER :: cfiletype
206  INTEGER, DIMENSION(:), POINTER :: &
207  disp
208 #endif
209  CONTAINS
210  ! methods
211  PROCEDURE :: initfileio
212  procedure(writeheader), DEFERRED :: writeheader
213  procedure(writedataset), DEFERRED:: writedataset
214  PROCEDURE :: adjusttimestep
215  PROCEDURE :: finalize_base
216  procedure(finalize), DEFERRED :: finalize
217  PROCEDURE :: getfilename
218  PROCEDURE :: getbasename
219  PROCEDURE :: makemultstr
220  PROCEDURE :: inctime
221  END TYPE fileio_base
222 
223  ! Interfaces
224  abstract INTERFACE
225  SUBROUTINE writedataset(this,Mesh,Physics,Fluxes,Timedisc,Header,IO)
227  IMPLICIT NONE
228  CLASS(fileio_base), INTENT(INOUT) :: this
229  CLASS(mesh_base), INTENT(IN) :: Mesh
230  CLASS(physics_base), INTENT(INOUT) :: Physics
231  CLASS(fluxes_base), INTENT(IN) :: Fluxes
232  CLASS(timedisc_base), INTENT(IN) :: Timedisc
233  TYPE(Dict_TYP), POINTER :: Header,IO
234  END SUBROUTINE
235  SUBROUTINE writeheader(this,Mesh,Physics,Header,IO)
237  IMPLICIT NONE
238  CLASS(fileio_base), INTENT(INOUT) :: this
239  CLASS(mesh_base), INTENT(IN) :: Mesh
240  CLASS(physics_base), INTENT(IN) :: Physics
241  TYPE(Dict_TYP), POINTER :: Header,IO
242  END SUBROUTINE
243  SUBROUTINE finalize(this)
244  IMPORT fileio_base
245  IMPLICIT NONE
246  CLASS(fileio_base), INTENT(INOUT) :: this
247  END SUBROUTINE
248  END INTERFACE
249  !--------------------------------------------------------------------------!
250 
253 ! INTEGER, PARAMETER :: FILE_EXISTS = B'00000001' !< file status for existing files
254  INTEGER, PARAMETER :: readonly = 1
255  INTEGER, PARAMETER :: readend = 2
256  INTEGER, PARAMETER :: replace = 3
257  INTEGER, PARAMETER :: append = 4
260  CHARACTER(LEN=9), PARAMETER :: ascii = "formatted"
261  CHARACTER(LEN=11), PARAMETER :: bin = "unformatted"
263 
264  ! file formats
265  INTEGER, PARAMETER :: binary = 1
266  INTEGER, PARAMETER :: gnuplot = 2
267  INTEGER, PARAMETER :: vtk = 4
268 ! INTEGER, PARAMETER :: NPY = 5
269 ! INTEGER, PARAMETER :: HDF = 6
270  INTEGER, PARAMETER :: xdmf = 7
271  !--------------------------------------------------------------------------!
272  INTEGER, SAVE :: lastunit = 10
273 
274  !--------------------------------------------------------------------------!
275  PUBLIC :: &
276  ! types
278  ! constants
279  binary, gnuplot, vtk, xdmf, &
281 #ifdef PARALLEL
283 #endif
284 ! FILE_EXISTS, &
285  ascii, bin
286 
287 
288 CONTAINS
289 
290 
293  SUBROUTINE initfileio(this,Mesh,Physics,Timedisc,Sources,config,IO, &
294  fmtname,fext)
295  IMPLICIT NONE
296  !------------------------------------------------------------------------!
297  CLASS(fileio_base), INTENT(INOUT) :: this
298  CLASS(mesh_base), INTENT(IN) :: Mesh
299  CLASS(physics_base), INTENT(IN) :: Physics
300  CLASS(timedisc_base),INTENT(IN) :: Timedisc
301  CLASS(sources_base), INTENT(IN), POINTER :: Sources
302  TYPE(Dict_TYP), INTENT(IN), POINTER :: config
303  TYPE(Dict_TYP), INTENT(IN), POINTER :: IO
304  CHARACTER(LEN=*), INTENT(IN) :: fmtname
305  CHARACTER(LEN=*), INTENT(IN) :: fext
306  !------------------------------------------------------------------------!
307  INTEGER :: fileformat
308  CHARACTER(LEN=MAX_CHAR_LEN) :: fname
309  CHARACTER(LEN=MAX_CHAR_LEN) :: fpath
310  !INTEGER :: fcycles !< fcycles number of file cycles
311  INTEGER :: unit
312  LOGICAL :: success
313  CHARACTER(LEN=32) :: timestamp
314  INTEGER :: count_def, fcycles_def, dtwall_def
315  INTEGER :: cartcoords
316  REAL :: stoptime_def
317  REAL :: time
318  TYPE(Dict_TYP),POINTER :: oldconfig => null()
319  !------------------------------------------------------------------------!
320  ! wall clock time between successive outputs
321  ! this is mainly intended for log file outputs
322  CALL getattr(config, "dtwall" , dtwall_def, 3600) !default is one hour
323 
324  ! number of output steps
325  CALL getattr(config, "count" , count_def, 1)
326 
327  ! number of data files
328  ! fcycles = 0 : one data file, append data
329  ! fcycles = 1 : one data file, overwrite data
330  ! fcycles = X > 1 : X data files
331  CALL getattr(config, "filecycles", fcycles_def, count_def+1)
332 
333  ! stop time for output defaults to simulation stop time
334  CALL getattr(config, "stoptime" , stoptime_def, timedisc%stoptime)
335  CALL getattr(config, "fileformat", fileformat)
336  CALL getattr(config, "filename" , fname)
337  fpath = ""
338  CALL getattr(config, "filepath" , fpath, fpath)
339  CALL getattr(config, "unit" , unit , lastunit+1)
340  lastunit = unit
341  CALL getattr(config, "walltime" , this%walltime, huge(1.0))
342 
343  ! mesh coordinates are cartesian by default (cartcoords == 1)
344  ! set to 0 for curvilinear coordinates (currently supported in gnuplot and vtk)
345  CALL getattr(config, "cartcoords", cartcoords, 1)
346  IF (cartcoords.EQ.0) THEN
347  this%cartcoords = .false.
348  ELSE
349  this%cartcoords = .true.
350  END IF
351 
352  ! InitLogging after reading fileformat from config
353  CALL this%InitLogging(fileformat,fmtname)
354 
355  ! check cycles
356  IF (fcycles_def.GT.maxcycles) &
357  CALL this%Error("InitFileIO","file cycles exceed limits")
358  ! check file name length
359  IF (len_trim(fname).GT.fnamlen) &
360  CALL this%Error("InitFileIO","file name too long")
361  ! check file path length
362  IF (len_trim(fpath).GT.fpatlen) &
363  CALL this%Error("InitFileIO","file path too long")
364  ! check file name extension
365  IF (len_trim(fext).GT.fextlen-1) &
366  CALL this%Error("InitFileIO","file name extension too long")
367 
368  ! format string for writing file names with explicit time step
369  WRITE (cycfmt, "('(A,I',I1,'.',I1,',A)')") fcyclen-1,fcyclen-1
370 
371 #ifdef PARALLEL
372  ! turn on multiple file output if requested
373  IF (this%multfiles) THEN
374  ! check number of parallel processes
375  IF (this%GetNumProcs().GT.maxmltfiles) &
376  CALL this%Error("InitFileIO","number of processes for multiple file output exceeds limits")
377  fmextstr = this%MakeMultstr()
378  END IF
379 #endif
380 
381  this%path = trim(fpath)
382  this%filename = trim(fname)
383  this%extension = trim(fext)
384  this%cycles = fcycles_def
385  this%unit = unit
386  this%stoptime = stoptime_def
387  this%starttime = timedisc%time ! from beginning of simulation
388  this%dtwall = dtwall_def
389  this%count = count_def
390  this%offset = 0
391  this%error_io = 0
392 
393  CALL getattr(config, "step", this%step, 0)
394 
395  ! compute the (actual) output time
396  this%time = timedisc%time
397 
398  ! print some information
399  CALL this%Info(" FILEIO---> file name: " // trim(this%GetFilename()))
400  IF (success) THEN
401  WRITE (timestamp,'(ES10.4)') timedisc%time
402  CALL this%Info(" time stamp: " // trim(timestamp))
403  END IF
404 
405  ! time for next output
406  IF (timedisc%time.GT.0.0) CALL this%IncTime()
407  IF (ASSOCIATED(oldconfig)) CALL deletedict(oldconfig)
408  END SUBROUTINE initfileio
409 
412  PURE SUBROUTINE inctime(this)
413  IMPLICIT NONE
414  !------------------------------------------------------------------------!
415  CLASS(fileio_base), INTENT(INOUT) :: this
416  !------------------------------------------------------------------------!
417  this%time = this%time + abs(this%stoptime - this%starttime) / this%count
418  this%step = this%step + 1
419  END SUBROUTINE inctime
420 
421 
425  PURE SUBROUTINE adjusttimestep(this,time,dt,dtcause)
426  IMPLICIT NONE
427  !------------------------------------------------------------------------!
428  CLASS(fileio_base), INTENT(IN) :: this
429  REAL :: time
430  REAL :: dt
431  INTEGER :: dtcause
432  !------------------------------------------------------------------------!
433  INTENT(INOUT) :: time,dt,dtcause
434  !------------------------------------------------------------------------!
435  IF ((time+dt)/this%time.GT.1.0) THEN
436  dt = this%time - time
437  dtcause = dtcause_fileio
438  ELSE IF((time+1.5*dt)/this%time.GT.1.0) THEN
439  dt = 0.5*(this%time - time)
440  dtcause = dtcause_fileio
441  END IF
442  END SUBROUTINE adjusttimestep
443 
444 
448  FUNCTION makemultstr(this,fn) RESULT (multstr)
449  IMPLICIT NONE
450  !------------------------------------------------------------------------!
451  CLASS(fileio_base), INTENT(IN) :: this
452  INTEGER, OPTIONAL, INTENT(IN) :: fn
453  CHARACTER(LEN=FMLTLEN) :: multstr
454  !------------------------------------------------------------------------!
455 #ifdef PARALLEL
456  INTEGER :: fn_l
457  CHARACTER(LEN=32) :: mextfmt
458 #endif
459  !------------------------------------------------------------------------!
460 #ifdef PARALLEL
461  IF (PRESENT(fn)) THEN
462  fn_l = fn
463  ELSE
464  fn_l = this%GetRank()
465  END IF
466  ! with fn < 0 you can suppress a label
467  IF (this%multfiles .AND. fn_l .GE. 0) THEN
468  WRITE (mextfmt, "('(A2,I',I1,'.',I1,')')") fmltlen-2,fmltlen-2
469 
470  WRITE (multstr, mextfmt) "-r", fn_l
471  ELSE
472  multstr = ""
473  END IF
474 #else
475  multstr = ""
476 #endif
477  END FUNCTION makemultstr
478 
479 
483  FUNCTION getbasename(this,fn) RESULT (fname)
484  IMPLICIT NONE
485  !------------------------------------------------------------------------!
486  CLASS(fileio_base), INTENT(IN) :: this
487  INTEGER, OPTIONAL, INTENT(IN) :: fn
488  CHARACTER(LEN=256) :: fname
489  !------------------------------------------------------------------------!
490  CHARACTER(LEN=FCYCLEN+2) :: cycstr
491  !------------------------------------------------------------------------!
492  IF (this%cycles.GT.0) THEN
493  ! generate a file name with time step
494  WRITE (cycstr, fmt=trim(cycfmt)) "_", modulo(this%step,this%cycles), "."
495  WRITE (fname,"(A,A,A,A)") trim(this%filename),&
496  trim(makemultstr(this,fn)),trim(cycstr),trim(this%extension)
497  ELSE
498  ! file name + extension
499  WRITE (fname,"(A,A,A,A)") trim(this%filename),&
500  trim(makemultstr(this,fn)),".",trim(this%extension)
501  END IF
502  END FUNCTION getbasename
503 
506  FUNCTION getfilename(this,fn) RESULT (fname)
507  IMPLICIT NONE
508  !------------------------------------------------------------------------!
509  CLASS(fileio_base), INTENT(IN) :: this
510  INTEGER, OPTIONAL, INTENT(IN) :: fn
511  CHARACTER(LEN=256) :: fname
512  !------------------------------------------------------------------------!
513  fname = trim(this%path) // trim(getbasename(this,fn))
514  END FUNCTION getfilename
515 
518  SUBROUTINE finalize_base(this)
519  IMPLICIT NONE
520  !------------------------------------------------------------------------!
521  CLASS(fileio_base),INTENT(INOUT) :: this
522  !------------------------------------------------------------------------!
523  IF (.NOT.this%Initialized()) &
524  CALL this%Error("CloseFileIO","not initialized")
525  END SUBROUTINE finalize_base
526 
527 END MODULE fileio_base_mod
subroutine finalize(this)
Destructor of common class.
output-pointer for time step scalar data (gnuplot)
generic source terms module providing functionaly common to all source terms
integer, parameter, public replace
read/write access replacing file
integer, save default_mpi_real
default real type for MPI
Generic file I/O module.
Definition: fileio_base.f90:54
subroutine finalize_base(this)
type(logging_base), save this
integer, parameter, public gnuplot
character(len=9), parameter ascii
for ASCII data
Basic fosite module.
common data structure
integer, parameter fcyclen
length of timestep string
Definition: fileio_base.f90:81
integer, parameter, public binary
integer, parameter, public dtcause_fileio
smallest ts due to fileio
integer, parameter fnamlen
file name length (without any extension)
Definition: fileio_base.f90:82
pure subroutine inctime(this)
Increments the counter for timesteps and sets the time for next output.
character(len=32), save cycfmt
format string for cycles
Definition: fileio_base.f90:95
integer, parameter, public readend
readonly access at end
integer, parameter maxmltfiles
max. number files per time step (parallel mode with one file per node)
Definition: fileio_base.f90:89
output-pointer for array data (binary,gnuplot,vtk)
Definition: fileio_base.f90:98
character(len=11), parameter bin
for BINARY data
named integer constants for flavour of state vectors
recursive subroutine, public deletedict(root)
Delete the dictionary &#39;root&#39; and all subnodes.
subroutine initfileio(this, Mesh, Physics, Timedisc, Sources, config, IO, fmtname, fext)
Generic constructor for file I/O.
Basic physics module.
integer, parameter, public xdmf
integer, parameter fpatlen
file path length (without file name)
Definition: fileio_base.f90:83
Dictionary for generic data types.
Definition: common_dict.f90:61
integer, parameter, public append
read/write access at end
integer, parameter, public vtk
real function adjusttimestep(this, maxerr, dtold)
adjust the time step
integer, parameter fextlen
file name extension length
Definition: fileio_base.f90:79
integer, parameter maxcycles
max. number of data files (not counting multiple files per time step in parallel mode) ...
Definition: fileio_base.f90:93
base module for numerical flux functions
Definition: fluxes_base.f90:39
integer, parameter fmltlen
length of multi process string (parallel mode only)
Definition: fileio_base.f90:80
character(len=fmltlen), save fmextstr
multi process string, overwritten below
Definition: fileio_base.f90:87
integer, parameter, public readonly
readonly access
integer, save lastunit
character(len=256) function getbasename(this, fn)
Get the current file name without path e.g. important for vtk (pvts files)
character(len=fmltlen) function makemultstr(this, fn)
Get a file label (multiples files in parallel mode) without filenumber => use GetRank; with filenumbe...
character(len=256) function getfilename(this, fn)
Get the current file name.