fileio_gnuplot.f90
Go to the documentation of this file.
1 !#############################################################################
2 !# #
3 !# fosite - 3D hydrodynamical simulation program #
4 !# module: fileio_gnuplot.f90 #
5 !# #
6 !# Copyright (C) 2008-2017 #
7 !# Tobias Illenseer <tillense@astrophysik.uni-kiel.de> #
8 !# Björn Sperling <sperling@astrophysik.uni-kiel.de> #
9 !# Jannes Klee <jklee@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 !#############################################################################
30 !----------------------------------------------------------------------------!
43 !----------------------------------------------------------------------------!
45  USE fileio_base_mod
47  USE mesh_base_mod
50  USE fluxes_base_mod
52  USE common_dict
53  IMPLICIT NONE
54  !--------------------------------------------------------------------------!
55  PRIVATE
56  ! exclude interface block from doxygen processing
58 ! INTERFACE Error
59 ! MODULE PROCEDURE Error_gnuplot, Error_common
60 ! END INTERFACE
61  ! Private Attributes section starts here:
63  INTEGER, PARAMETER :: HLEN = 10000
64  INTEGER, PARAMETER :: DEFAULT_DECS = 5
66  CHARACTER, PARAMETER :: SP = achar(32)
67  CHARACTER, PARAMETER :: LF = achar(10)
68  CHARACTER*2, PARAMETER :: RECSEP = sp // sp
69  CHARACTER*2, PARAMETER :: LINSEP = sp // lf
70  CHARACTER*2, PARAMETER :: BLKSEP = lf // lf
72  CHARACTER(LEN=30), PARAMETER :: &
73  header_string = "# Data output of fosite" // linsep
74  CHARACTER(LEN=HLEN) :: header_buf
76  !--------------------------------------------------------------------------!
77  TYPE, EXTENDS(fileio_base) :: fileio_gnuplot
78 
79  CONTAINS
80  ! methods
81  PROCEDURE :: initfileio_gnuplot
82  PROCEDURE :: finalize
83  PROCEDURE :: writeheader
84 ! PROCEDURE :: ReadHeader
85 ! PROCEDURE :: WriteTimestamp
86 ! PROCEDURE :: ReadTimestamp
87  PROCEDURE :: writedataset
88  PROCEDURE :: readdataset
89  PROCEDURE :: openfile
90  PROCEDURE :: closefile
91  PROCEDURE :: adjusttimestep
92  PROCEDURE :: inctime
93  PROCEDURE :: getfilename
94  PROCEDURE :: getfilestatus
95  END TYPE
96 
98  !--------------------------------------------------------------------------!
99  PUBLIC :: &
100  ! types
101  fileio_typ, &
102  ! constants
104  ascii, bin, &
105  file_exists
106  !--------------------------------------------------------------------------!
107 
108 CONTAINS
109 
115  SUBROUTINE initfileio(this,Mesh,Physics,fmt,fmtname,fpath,filename,extension, &
116  stoptime,dtwall,count,fcycles,sepfiles,unit)
117  IMPLICIT NONE
118  !------------------------------------------------------------------------!
119  CLASS(fileio_base) :: this
120  CLASS(mesh_base) :: Mesh
121  CLASS(physics_base) :: Physics
122  INTEGER :: fmt
123  CHARACTER(LEN=*) :: fmtname
124  CHARACTER(LEN=*) :: fpath
125  CHARACTER(LEN=*) :: filename
126  CHARACTER(LEN=*) :: extension
127  REAL :: stoptime
128  INTEGER :: dtwall
129  INTEGER :: count
130  INTEGER :: fcycles
131  LOGICAL :: sepfiles
132  INTEGER, OPTIONAL :: unit
133  !------------------------------------------------------------------------!
134  INTENT(IN) :: mesh,physics,fmt,fmtname,fpath,filename,extension,stoptime, &
135  dtwall,count,fcycles,sepfiles,unit
136  INTENT(INOUT) :: this
137  !------------------------------------------------------------------------!
138  ! basic FileIO initialization
139  CALL this%InitFileIO_common(fmt,fmtname,fpath,filename,extension,fcycles,sepfiles,unit)
140 
141  this%stoptime = stoptime
142  this%dtwall = dtwall
143  this%time = 0.
144  this%count = count
145  this%step = 0
146  ! count the number of output columns, i.e. fields per data point
147 
148 #ifdef PARALLEL
149  ! check data type extents in files
150  ! first try to create a new dummy file
151  CALL mpi_file_open(mpi_comm_world,getfilename(this),ior(ior(mpi_mode_rdwr,&
152  mpi_mode_create),ior(mpi_mode_excl,mpi_mode_delete_on_close)),&
153  mpi_info_null,this%handle,this%error)
154  ! maybe file exists
155  IF (this%error.NE.0) CALL mpi_file_open(mpi_comm_world,getfilename(this),&
156  mpi_mode_rdonly,mpi_info_null,this%handle,this%error)
157  ! then check the data type sizes
158  ! extent of integer in file
159  IF (this%error.EQ.0) CALL mpi_file_get_type_extent(this%handle,mpi_integer,&
160  this%intext,this%error)
161  ! extent of real in file
162  IF (this%error.EQ.0) CALL mpi_file_get_type_extent(this%handle,default_mpi_real,&
163  this%realext,this%error)
164  IF (this%error.NE.0) CALL error(this,"InitFileIO","unable to check file properties")
165  CALL mpi_file_close(this%handle,this%error)
166 #endif
167  END SUBROUTINE initfileio
168 
169 
174  SUBROUTINE initfileio_gnuplot(this,Mesh,Physics,IO,fmt,fpath,filename,stoptime,dtwall,&
175  count,fcycles,unit,config)
176  IMPLICIT NONE
177  !------------------------------------------------------------------------!
178  CLASS(fileio_base) :: this
179  CLASS(mesh_base) :: Mesh
180  CLASS(physics_base) :: Physics
181  TYPE(Dict_TYP),POINTER :: IO
183  TYPE(Dict_TYP),POINTER,OPTIONAL :: config
184  INTEGER :: fmt
185  CHARACTER(LEN=*) :: fpath
186  CHARACTER(LEN=*) :: filename
187  REAL :: stoptime
188  INTEGER :: dtwall
189  INTEGER :: count
190  INTEGER :: fcycles
191  INTEGER :: unit
192  !------------------------------------------------------------------------!
193  TYPE(Dict_TYP), POINTER :: node
194  REAL, DIMENSION(:,:), POINTER :: dummy2
195  REAL, DIMENSION(:,:,:), POINTER :: dummy3
196  INTEGER :: cartcoords
197  INTEGER :: depth
198  INTEGER :: err
199 #ifdef PARALLEL
200  INTEGER :: i
201  INTEGER, DIMENSION(Mesh%IMAX-Mesh%IMIN+1) :: blocklen,indices
202 #endif
203  !------------------------------------------------------------------------!
204  INTENT(IN) :: mesh,physics,fmt,fpath,filename,stoptime,dtwall,count,fcycles,&
205  unit
206  INTENT(INOUT) :: this
207  !------------------------------------------------------------------------!
208  CALL this%InitFileIO(mesh,physics,fmt,"GNUPLOT",fpath,filename,"dat",stoptime,&
209  dtwall,count,fcycles,.false.,unit)
210 
211  CALL getattr(config, "/datafile/decimals", this%DECS, default_decs)
212  ! compute length of character field for real number output
213  ! and check if linebuffer is large enough
214  ! flen = 1 (sign) + 1 (one digit) + 1 (decimal point) + decs (decimal places)
215  ! + 1 (E character) + 1 (sign of exponent) + 2 (exponent digits) + 2 (spaces)
216  this%FLEN = this%DECS + 9
217  this%maxcols = len(this%linebuf)/this%FLEN-1
218 
219  ALLOCATE(this%output(this%maxcols),stat=err)
220  IF (this%error.NE.0) &
221  CALL this%Error("InitFileIO_gnuplot","memory allocation failed for this%output")
222 
223  ! check if cartesian coordinates are selected for output;
224  ! default: curvilinear coordinates (0)
225  CALL getattr(config, "/datafile/cartcoords", cartcoords, 0)
226  depth = 1
227  node => config
228  CALL writeheaderstring(header_buf,node,depth)
229  IF (cartcoords.EQ.0) THEN
230  CALL getattr(io,"/mesh/bary_curv",dummy3)
231  ELSE
232  CALL getattr(io,"/mesh/bary_centers",dummy3)
233  END IF
234  ! pointer to sub-array: set lower bounds
235  ! use special function for bound remapping
236  IF (mesh%INUM.EQ.1) THEN
237  ! use format string as temp
238  WRITE (this%fmtstr,'(A5,I2,A1)')'(A1,A',this%FLEN-3,')'
239  WRITE(this%linebuf,trim(this%fmtstr))'#','y'
240  this%output(1)%val => dummy3(:,:,2)
241  this%COLS = 1
242  ELSE IF (mesh%JNUM.EQ.1) THEN
243  WRITE (this%fmtstr,'(A5,I2,A1)')'(A1,A',this%FLEN-3,')'
244  WRITE(this%linebuf,trim(this%fmtstr))'#','x'
245  this%output(1)%val => dummy3(:,:,1)
246  this%COLS = 1
247  ELSE
248  WRITE (this%fmtstr,'(A5,I2,A2,I2,A1)')'(A1,A',this%FLEN-3,',A',this%FLEN-1,')'
249  WRITE(this%linebuf,trim(this%fmtstr))'#','x','y'
250  this%output(1)%val => dummy3(:,:,1)
251  this%output(2)%val => dummy3(:,:,2)
252  this%COLS = 2
253  END IF
254 
255  ! set output-pointer and count the number of output columns
256  WRITE (this%fmtstr,'(A,I2,A1)')'(A',this%FLEN-1,')'
257  node => io
258  CALL this%GetOutputPointer(mesh,node,this%COLS)
259 
260  ! length of one output line
261  this%linelen = this%COLS * this%FLEN
262  IF (this%linelen.GT.len(this%linebuf)) &
263  CALL this%Error("InitFileIO_gnuplot", &
264  "linebuffer to small; reducing decimals or number of output fields may help")
265 
266  header_buf = trim(header_string) // trim(header_buf) // this%linebuf(1:this%linelen)
267 
268  ! local domain size
269  this%inum = mesh%IMAX - mesh%IMIN + 1
270  this%jnum = mesh%JMAX - mesh%JMIN + 1
271 
272 !#ifdef PARALLEL
273 ! ! create new data type handle for one line
274 ! CALL MPI_Type_contiguous(this%linelen,MPI_CHARACTER,this%basictype,this%error)
275 ! CALL MPI_Type_commit(this%basictype,this%error)
276 !
277 ! ! number of output blocks
278 ! this%blocknum = Mesh%IMAX - Mesh%IMIN + 1
279 ! ! size of the output buffer
280 ! this%bufsize = Mesh%JMAX - Mesh%JMIN + 1
281 !
282 ! ! allocate memory for output buffer and displacement records
283 ! ALLOCATE(this%outbuf(this%linelen,Mesh%JMIN:Mesh%JMAX), &
284 ! STAT=err)
285 ! IF (this%error.NE.0) THEN
286 ! CALL Error(this,"InitFileIO_gnuplot","memory allocation failed for this%outbuf")
287 ! END IF
288 !
289 ! blocklen(:) = this%bufsize
290 ! DO i=Mesh%IMIN,Mesh%IMAX
291 ! indices(i-Mesh%IMIN+1) = (i-1)*Mesh%JNUM + Mesh%JMIN - 1
292 ! END DO
293 !
294 ! ! new file type for the staggered data
295 ! CALL MPI_Type_indexed(this%blocknum,blocklen,indices, &
296 ! this%basictype,this%filetype,this%error)
297 ! CALL MPI_Type_commit(this%filetype,this%error)
298 !#endif
299  ! write the format string for one entry in the data file:
300  ! FLEN-2 characters for the number and 2 for the separators
301  WRITE (this%fmtstr,'(A3,I2,A,I2.2,A5)') '(ES', this%FLEN-2, '.', this%DECS,',A,A)'
302  ! write format string for one output line
303  WRITE (this%linefmt, '(A,I0,A)') "(A", this%linelen-1, ")"
304  END SUBROUTINE initfileio_gnuplot
305 
306 
309  RECURSIVE SUBROUTINE writeheaderstring(string,root,k,prefix)
310  IMPLICIT NONE
311  !------------------------------------------------------------------------!
312  TYPE(dict_typ), POINTER :: root,node,subnode
313  CHARACTER(LEN=*) :: string
314  CHARACTER(LEN=*), OPTIONAL :: prefix
315  CHARACTER(LEN=128) :: buf
316  !------------------------------------------------------------------------!
317  INTEGER :: idummy, k
318  LOGICAL :: ldummy
319  CHARACTER(LEN=128) :: cdummy
320  REAL :: rdummy
321  !------------------------------------------------------------------------!
322  INTENT(INOUT) :: string,k
323  !------------------------------------------------------------------------!
324 
325  node => root
326  DO WHILE(ASSOCIATED(node))
327  SELECT CASE(getdatatype(node))
328  CASE(dict_int)
329  CALL getattr(node,getkey(node),idummy)
330  WRITE(buf,'(A1,A25,I14,A)')'#',trim(getkey(node))//": ",idummy, linsep
331  WRITE(string(k:),'(A)')buf
332  k = k + len(trim(buf))
333  CASE(dict_real)
334  CALL getattr(node,getkey(node),rdummy)
335  WRITE(buf,'(A1,A25,ES14.5,A)')'#',trim(getkey(node))//": ",rdummy, linsep
336  WRITE(string(k:),'(A)')buf
337  k = k + len(trim(buf))
338  CASE(dict_char)
339 ! CALL GetAttr(node,GetKey(node),cdummy)
340 ! WRITE(buf,'(A1,A25,A,A)')'#',TRIM(GetKey(node))//": ",TRIM(cdummy), LINSEP
341 ! WRITE(string(k:),'(A)')buf
342 ! k = k + LEN(TRIM(buf))
343  CASE(dict_bool)
344  CALL getattr(node,getkey(node),ldummy)
345  WRITE(buf,'(A1,A25,L14,A)')'#',trim(getkey(node))//": ",ldummy, linsep
346  WRITE(string(k:),'(A)')buf
347  k = k + len(trim(buf))
348  END SELECT
349  IF(haschild(node)) THEN
350  IF (present(prefix)) THEN
351  WRITE(buf,'(A)')'# ['//trim(prefix)//'/'//trim(getkey(node))//']' // linsep
352  ELSE
353  WRITE(buf,'(A)')'# ['//trim(getkey(node))//']' // linsep
354  END IF
355  WRITE(string(k:),'(A)')buf
356  k = k + len(trim(buf))
357  IF (present(prefix)) THEN
358  buf = trim(prefix)//'/'//trim(getkey(node))
359  ELSE
360  buf = trim(getkey(node))
361  END IF
362  subnode => getchild(node)
363  CALL writeheaderstring(string,subnode,k,trim(buf))
364  END IF
365  node => getnext(node)
366  END DO
367  END SUBROUTINE writeheaderstring
368 
373  RECURSIVE SUBROUTINE getoutputpointer(this,Mesh,node,k)
374  IMPLICIT NONE
375  !------------------------------------------------------------------------!
376  CLASS(fileio_base) :: this
377  CLASS(mesh_base) :: mesh
378  TYPE(dict_typ), POINTER :: node
379  INTEGER :: k
380  !------------------------------------------------------------------------!
381  TYPE(dict_typ), POINTER :: dir
382  REAL, DIMENSION(:,:), POINTER :: dummy2
383  REAL, DIMENSION(:,:,:), POINTER :: dummy3
384  REAL, DIMENSION(:,:,:,:), POINTER :: dummy4
385  INTEGER, DIMENSION(4) :: dims
386  INTEGER :: dim3,dim4,i,j
387  !------------------------------------------------------------------------!
388  INTENT(IN) :: mesh
389  INTENT(INOUT) :: this,k
390  !------------------------------------------------------------------------!
391  ! reset error code
392  this%error = 0
393  DO WHILE(ASSOCIATED(node))
394  ! check for directory and exclude any coordinates (these are handled elsewhere)
395  IF(haschild(node)) THEN
396  ! recursion
397  CALL getattr(node,getkey(node),dir)
398  CALL getoutputpointer(this,mesh,dir,k)
399  ELSE IF (hasdata(node).AND. .NOT.(getkey(node).EQ."bary_curv".OR. &
400  getkey(node).EQ."bary_centers".OR.getkey(node).EQ."corners")) THEN
401  WRITE(this%linebuf(k*this%FLEN:),trim(this%fmtstr))trim(getkey(node))
402  ! value found!
403  SELECT CASE(getdatatype(node))
404  CASE(dict_real_twod)
405  CALL getattr(node,getkey(node),dummy2)
406  dims(1:2) = shape(dummy2)
407  IF((dims(1).EQ.mesh%IMAX-mesh%IMIN+1).AND.&
408  (dims(2).EQ.mesh%JMAX-mesh%JMIN+1)) THEN
409  k = k+1
410  IF (k .GT. this%maxcols) THEN
411  this%error = 1
412  EXIT
413  END IF
414  this%output(k)%val=> dummy2
415  END IF
416  CASE(dict_real_threed)
417  CALL getattr(node,getkey(node),dummy3)
418  dims(1:3) = shape(dummy3)
419  IF((dims(1).EQ.mesh%IMAX-mesh%IMIN+1).AND.&
420  (dims(2).EQ.mesh%JMAX-mesh%JMIN+1)) THEN
421  dim3 = SIZE(dummy3, dim = 3)
422  IF (k+dim3 .GT. this%maxcols) THEN
423  this%error = 1
424  EXIT
425  END IF
426  DO i=k+1, k+dim3
427  this%output(i)%val => dummy3(:,:,i-k)
428  END DO
429  k = k+dim3
430  END IF
431  CASE(dict_real_fourd)
432  CALL getattr(node,getkey(node),dummy4)
433  dims(1:4) = shape(dummy4)
434  IF((dims(1).EQ.mesh%IMAX-mesh%IMIN+1).AND.&
435  (dims(2).EQ.mesh%JMAX-mesh%JMIN+1)) THEN
436  dim3 = SIZE(dummy4, dim = 3)
437  dim4 = SIZE(dummy4, dim = 4)
438  IF (k+dim3*dim4 .GT. this%maxcols) THEN
439  this%error = 1
440  EXIT
441  END IF
442  DO j=1,dim4
443  DO i=1,dim3
444  this%output(k+j+(i-1)*dim4)%val => dummy4(:,:,i,j)
445  END DO
446  END DO
447  k = k+dim3*dim4
448  END IF
449  CASE DEFAULT
450  !do nothing (wrong type)
451  END SELECT
452  END IF
453  node=>getnext(node)
454  END DO
455  IF (this%error.NE.0) &
456  CALL error(this,"GetOutputPointer_gnuplot","number of output fields exceeds upper limit")
457  END SUBROUTINE getoutputpointer
458 
459 
463  PURE SUBROUTINE adjusttimestep(this,time,dt,dtcause)
464  IMPLICIT NONE
465  !------------------------------------------------------------------------!
466  CLASS(fileio_base) :: this
467  REAL :: time
468  REAL :: dt
469  INTEGER :: dtcause
470  !------------------------------------------------------------------------!
471  INTENT(IN) :: this
472  INTENT(INOUT) :: time,dt,dtcause
473  !------------------------------------------------------------------------!
474  IF ((time+dt)/this%time.GT.1.0) THEN
475  dt = this%time - time
476  dtcause = dtcause_fileio
477  ELSE IF((time+1.5*dt)/this%time.GT.1.0) THEN
478  dt = 0.5*(this%time - time)
479  dtcause = dtcause_fileio
480  END IF
481  END SUBROUTINE adjusttimestep
482 
485  PURE SUBROUTINE inctime(this)
486  IMPLICIT NONE
487  !------------------------------------------------------------------------!
488  CLASS(fileio_base), INTENT(INOUT) :: this
489  !------------------------------------------------------------------------!
490  this%time = this%time + abs(this%stoptime) / this%count
491  this%step = this%step + 1
492  END SUBROUTINE inctime
493 
496  SUBROUTINE openfile(this,action,fformat)
497  IMPLICIT NONE
498  !------------------------------------------------------------------------!
499  CLASS(fileio_base) :: this
500  INTEGER :: action
501  CHARACTER(LEN=*) :: fformat
502  !------------------------------------------------------------------------!
503 #ifdef PARALLEL
504  INTEGER(KIND=MPI_OFFSET_KIND) :: offset
505 #endif
506  !------------------------------------------------------------------------!
507  INTENT(IN) :: action,fformat
508  INTENT(INOUT) :: this
509  !------------------------------------------------------------------------!
510  SELECT CASE(action)
511  CASE(readonly)
512 #ifdef PARALLEL
513  CALL mpi_file_open(mpi_comm_world,getfilename(this),mpi_mode_rdonly, &
514  mpi_info_null,this%handle,this%error)
515  this%offset = 0
516  CALL mpi_file_seek(this%handle,this%offset,mpi_seek_set,this%error)
517 #else
518  OPEN(this%unit,file=getfilename(this),form=fformat,status="OLD", &
519  action="READ",position="REWIND",iostat=this%error)
520  !REWIND (UNIT=this%unit,IOSTAT=this%error)
521 #endif
522  CASE(readend)
523 #ifdef PARALLEL
524  CALL mpi_file_open(mpi_comm_world,getfilename(this),ior(mpi_mode_rdonly,&
525  mpi_mode_append),mpi_info_null,this%handle,this%error)
526  ! opening in append mode doesn't seem to work for pvfs2, hence ...
527  offset = 0
528  CALL mpi_file_seek(this%handle,offset,mpi_seek_end,this%error)
529  CALL mpi_file_sync(this%handle,this%error)
530 #else
531  OPEN(this%unit,file=getfilename(this),form=fformat,status="OLD", &
532  action="READ",position="APPEND",iostat=this%error)
533 #endif
534  CASE(replace)
535 #ifdef PARALLEL
536  CALL mpi_file_delete(getfilename(this),mpi_info_null,this%error)
537  CALL mpi_file_open(mpi_comm_world,getfilename(this),ior(mpi_mode_wronly,&
538  mpi_mode_create),mpi_info_null,this%handle,this%error)
539 #else
540  OPEN(this%unit,file=getfilename(this),form=fformat,status="REPLACE",&
541  action="WRITE",position="REWIND",iostat=this%error)
542 #endif
543  CASE(append)
544 #ifdef PARALLEL
545  CALL mpi_file_open(mpi_comm_world,getfilename(this),ior(mpi_mode_rdwr,&
546  mpi_mode_append),mpi_info_null,this%handle,this%error)
547  ! opening in append mode doesn't seem to work for pvfs2, hence ...
548  offset = 0
549  CALL mpi_file_seek(this%handle,offset,mpi_seek_end,this%error)
550  CALL mpi_file_sync(this%handle,this%error)
551 #else
552  OPEN(this%unit,file=getfilename(this),form=fformat,status="OLD",&
553  action="READWRITE",position="APPEND",iostat=this%error)
554 #endif
555  CASE DEFAULT
556  CALL error(this,"OpenFile","Unknown access mode.")
557  END SELECT
558  END SUBROUTINE openfile
559 
560 
563  SUBROUTINE openfile_gnuplot(this,action)
564  IMPLICIT NONE
565  !------------------------------------------------------------------------!
566  CLASS(fileio_base) :: this
567  INTEGER :: action
568  !------------------------------------------------------------------------!
569  INTENT(IN) :: action
570  INTENT(INOUT) :: this
571  !------------------------------------------------------------------------!
572  CALL this%OpenFile(action,ascii)
573  END SUBROUTINE openfile_gnuplot
574 
575 
578  SUBROUTINE closefile_gnuplot(this)
579  IMPLICIT NONE
580  !------------------------------------------------------------------------!
581  CLASS(fileio_base) :: this
582  !------------------------------------------------------------------------!
583  INTENT(INOUT) :: this
584  !------------------------------------------------------------------------!
585 #ifdef PARALLEL
586  CALL mpi_file_close(this%handle,this%error)
587 #else
588  CLOSE(this%unit,iostat=this%error)
589 #endif
590  END SUBROUTINE closefile_gnuplot
591 
594  SUBROUTINE writeheader(this)
595  IMPLICIT NONE
596  !------------------------------------------------------------------------!
597  CLASS(fileio_base) :: this
598  !------------------------------------------------------------------------!
599  INTENT(INOUT) :: this
600  !------------------------------------------------------------------------!
601  IF (getrank(this).EQ.0) THEN
602 #ifdef PARALLEL
603  CALL mpi_file_write(this%handle,trim(header_buf),len(trim(header_buf)), &
604  mpi_character,this%status,this%error)
605 #else
606  WRITE (this%unit,fmt='(A)',iostat=this%error) trim(header_buf) !(1:HLEN-1)
607 #endif
608  END IF
609  END SUBROUTINE writeheader
610 
613  SUBROUTINE readheader_gnuplot(this,success)
614  IMPLICIT NONE
615  !------------------------------------------------------------------------!
616  CLASS(fileio_base) :: this
617  LOGICAL :: success
618  !------------------------------------------------------------------------!
619  INTENT(OUT) :: success
620  INTENT(INOUT) :: this
621  !------------------------------------------------------------------------!
622 #ifdef PARALLEL
623  IF (getrank(this).EQ.0) THEN
624  END IF
625 #else
626 #endif
627  success = .false.
628  END SUBROUTINE readheader_gnuplot
629 
632  SUBROUTINE writetimestamp_gnuplot(this,time)
633  IMPLICIT NONE
634  !------------------------------------------------------------------------!
635  CLASS(fileio_base) :: this
636  REAL :: time
637  !------------------------------------------------------------------------!
638  INTENT(IN) :: time
639  INTENT(INOUT) :: this
640  !------------------------------------------------------------------------!
641  IF (getrank(this).EQ.0) THEN
642 #ifdef PARALLEL
643 #else
644 #endif
645  END IF
646 !!$ CALL Warning(this,"WriteTimestamp_gnuplot",&
647 !!$ "function is not implemented")
648  END SUBROUTINE writetimestamp_gnuplot
649 
652  SUBROUTINE readtimestamp_gnuplot(this,time)
653  IMPLICIT NONE
654  !------------------------------------------------------------------------!
655  CLASS(fileio_base) :: this
656  REAL :: time
657  !------------------------------------------------------------------------!
658  INTENT(OUT) :: time
659  INTENT(INOUT) :: this
660  !------------------------------------------------------------------------!
661  IF (getrank(this).EQ.0) THEN
662 #ifdef PARALLEL
663 #else
664 #endif
665  END IF
666  time = 0.0
667 !!$ CALL Warning(this,"ReadTimestamp_gnuplot",&
668 !!$ "function is not implemented")
669  END SUBROUTINE readtimestamp_gnuplot
670 
673  SUBROUTINE writedataset(this,Mesh)
674  IMPLICIT NONE
675  !------------------------------------------------------------------------!
676  CLASS(fileio_base) :: this
677  CLASS(mesh_base) :: Mesh
678  !------------------------------------------------------------------------!
679  INTEGER :: i,j,k,l
680 #ifdef PARALLEL
681  INTEGER(KIND=MPI_OFFSET_KIND) :: offset
682  INTEGER :: request
683 #endif
684  !------------------------------------------------------------------------!
685  INTENT(IN) :: mesh
686  INTENT(INOUT) :: this
687  !------------------------------------------------------------------------!
688 
689  IF (ASSOCIATED(timedisc%w)) THEN
690  IF (mesh%FARGO.EQ.3.AND.mesh%SN_shear) THEN
691  CALL physics%AddBackgroundVelocityX(mesh,timedisc%w,timedisc%pvar,timedisc%cvar)
692  ELSE
693  CALL physics%AddBackgroundVelocityY(mesh,timedisc%w,timedisc%pvar,timedisc%cvar)
694  END IF
695  END IF
696 
697 
698 #ifdef PARALLEL
699  ! be sure to write at the end by getting the offset from the file's size
700  CALL mpi_file_get_size(this%handle,offset,this%error)
701  ! very importan
702  CALL mpi_barrier(mpi_comm_world,this%error)
703  ! write _one_ line feed at the beginning of each time step
704  IF (getrank(this).EQ.0) THEN
705  CALL mpi_file_write_at(this%handle, offset, lf, 1, mpi_character, &
706  this%status, this%error)
707  END IF
708  ! add the initial line feed and the general offset (depends on Mesh%IMIN)
709  offset = offset + 1
710  ! create the file view
711  CALL mpi_file_set_view(this%handle,offset,this%basictype,this%filetype, &
712  'native',mpi_info_null,this%error)
713 #else
714  ! write _one_ line feed at the beginning of each time step
715  WRITE (this%unit,fmt='(A)',advance='NO') lf
716 #endif
717 
718  DO k=1,this%cols
719  ! trim the data for gnuplot output
720  WHERE (abs(this%output(k)%val(:,:)).LT.max(tiny(this%output(k)%val(:,:)),1.0d-99))
721  this%output(k)%val(:,:) = 0.0e+00
722  END WHERE
723  END DO
724 
725  ! start i,j from 1 to rank local size, because RemapBounds has not been
726  ! used/cannot be used.
727  DO i=1,this%inum
728  DO j=1,this%jnum
729  ! write positions to line buffer
730  DO k=1,this%COLS-1
731  WRITE (this%linebuf((k-1)*this%FLEN+1:k*this%FLEN),trim(this%fmtstr)) &
732  this%output(k)%val(i,j), recsep
733  END DO
734 
735  IF ((j.EQ.mesh%JNUM).AND.((mesh%JNUM.GT.1).OR.(mesh%INUM.EQ.i))) THEN
736  ! finish the block
737  WRITE (this%linebuf((this%COLS-1)*this%FLEN+1:this%linelen),trim(this%fmtstr)) &
738  this%output(this%COLS)%val(i,j), blksep
739  ELSE
740  ! finish the line
741  WRITE (this%linebuf((this%COLS-1)*this%FLEN+1:this%linelen),trim(this%fmtstr)) &
742  this%output(this%COLS)%val(i,j), linsep
743  END IF
744 
745 #ifdef PARALLEL
746  ! write line buffer to output buffer
747  DO k=1,this%linelen
748  this%outbuf(k,j-1+mesh%JMIN) = this%linebuf(k:k)
749  END DO
750 #else
751  ! write line buffer to output file
752  WRITE (this%unit,fmt=trim(this%linefmt),advance='YES') this%linebuf(1:this%linelen-1)
753 #endif
754  END DO
755 #ifdef PARALLEL
756  !*****************************************************************!
757  ! This collective call doesn't work for pvfs2 -> bug in ROMIO ?
758 !!$ CALL MPI_File_write_all(this%handle,this%binout,this%bufsize,&
759 !!$ this%basictype, this%status, this%error)
760  !*****************************************************************!
761  ! so we use these two commands instead
762  CALL mpi_file_iwrite(this%handle,this%outbuf,this%bufsize,this%basictype,&
763  request,this%error)
764  CALL mpi_wait(request,this%status,this%error)
765 #endif
766  END DO
767  END SUBROUTINE writedataset
768 
771  SUBROUTINE readdataset_gnuplot(this,Mesh,Physics,Timedisc)
772  IMPLICIT NONE
773  !------------------------------------------------------------------------!
774  CLASS(fileio_base) :: this
775  CLASS(mesh_base) :: Mesh
776  CLASS(physics_base) :: Physics
777  CLASS(timedisc_base) :: Timedisc
778  !------------------------------------------------------------------------!
779  INTENT(IN) :: mesh,physics,timedisc
780  INTENT(INOUT) :: this
781  !------------------------------------------------------------------------!
782  END SUBROUTINE readdataset_gnuplot
783 
784 
787  SUBROUTINE error(this,modproc,msg)
788  IMPLICIT NONE
789  !------------------------------------------------------------------------!
790  CLASS(fileio_base), INTENT(INOUT) :: this
791  CHARACTER(LEN=*), INTENT(IN) :: modproc
792  CHARACTER(LEN=*), INTENT(IN) :: msg
793  !------------------------------------------------------------------------!
794  IF (initialized(this)) &
795  CALL this%CloseFile_gnuplot()
796  CALL this%Error_fileio(modproc,msg)
797  END SUBROUTINE error
798 
801  SUBROUTINE finalize(this)
802  IMPLICIT NONE
803  !------------------------------------------------------------------------!
804  CLASS(fileio_gnuplot) :: this
805  !------------------------------------------------------------------------!
806 #ifdef PARALLEL
807  DEALLOCATE(this%outbuf)
808 #endif
809  DEALLOCATE(this%output)
810  CALL this%Finalize_base()
811  END SUBROUTINE finalize
812 
813 END MODULE fileio_gnuplot_mod
subroutine finalize(this)
Destructor of common class.
subroutine error(this, modproc, msg, rank, node_info)
Print error message on standard error and terminate the program.
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
type(logging_base), save this
subroutine writedataset(this, Mesh)
Writes all desired data arrays to a file.
type(dict_typ) function, pointer, public getchild(root)
Get the pointer to a direct child of the pointer &#39;root&#39;.
integer function, public getdatatype(root)
Return the datatype of node &#39;root&#39;.
character(len=9), parameter ascii
for ASCII data
integer, parameter, public dict_real_fourd
recursive subroutine getoutputpointer(this, Mesh, node, k)
Creates a list of all data arrays which will be written to file.
logical function, public haschild(root)
Check if the node &#39;root&#39; has one or more children.
integer, parameter, public dtcause_fileio
smallest ts due to fileio
integer, parameter, public dict_char
Definition: common_dict.f90:96
function, public getkey(root)
Get the key of pointer &#39;root&#39;.
pure subroutine inctime(this)
Increments the counter for timesteps and sets the time for next output.
subroutine openfile_gnuplot(this, action)
Specific routine to open a file for gnuplot I/O.
base class for geometrical properties
integer, parameter, public dict_real_threed
integer, parameter, public readend
readonly access at end
subroutine initfileio_gnuplot(this, Mesh, Physics, IO, fmt, fpath, filename, stoptime, dtwall, count, fcycles, unit, config)
Constructor for the GNUPLOT file I/O.
I/O for GNUPLOT readable tabular files.
integer, parameter, public dict_real_twod
Definition: common_dict.f90:99
character(len=11), parameter bin
for BINARY data
subroutine initfileio(this, Mesh, Physics, Timedisc, Sources, config, IO, fmtname, fext)
Generic constructor for file I/O.
type(dict_typ) function, pointer, public getnext(root)
Get the pointer to the next child.
integer, parameter, public dict_int
Definition: common_dict.f90:94
recursive subroutine writeheaderstring(string, root, k, prefix)
Creates a string with the configuration (from the dictionary)
subroutine writeheader(this)
Writes the configuration as a header to the file.
subroutine readheader_gnuplot(this, success)
Reads the header (not yet implemented)
pure integer function getrank(this)
Get the MPI rank.
pure logical function initialized(this)
Query initialization status.
Basic physics module.
Dictionary for generic data types.
Definition: common_dict.f90:61
subroutine writetimestamp_gnuplot(this, time)
Writes the timestep (not yet implemented)
logical function, public hasdata(root)
Checks if the node &#39;root&#39; has data associated.
subroutine readdataset_gnuplot(this, Mesh, Physics, Timedisc)
Reads the data arrays from file (not yet implemented)
integer, parameter, public append
read/write access at end
subroutine readtimestamp_gnuplot(this, time)
Reads the timestep (not yet implemented)
real function adjusttimestep(this, maxerr, dtold)
adjust the time step
subroutine closefile_gnuplot(this)
routine to close a file
integer, parameter, public dict_real
Definition: common_dict.f90:95
base module for numerical flux functions
Definition: fluxes_base.f90:39
character(len=1), save prefix
preceds info output
integer, parameter, public dict_bool
Definition: common_dict.f90:97
integer, parameter, public readonly
readonly access
character(len=256) function getfilename(this, fn)
Get the current file name.
subroutine openfile(this, action, fformat)
Generic routine to open a file.