fileio_vtk.f90
Go to the documentation of this file.
1 !#############################################################################
2 !# #
3 !# fosite - 3D hydrodynamical simulation program #
4 !# module: fileio_vtk.f90 #
5 !# #
6 !# Copyright (C) 2010-2017 #
7 !# Björn Sperling <sperling@astrophysik.uni-kiel.de> #
8 !# Tobias Illenseer <tillense@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 !#############################################################################
27 !----------------------------------------------------------------------------!
51 !----------------------------------------------------------------------------!
53  USE fileio_base_mod
55  USE mesh_base_mod
57  USE fluxes_base_mod
60  USE common_dict
61 #ifdef PARALLEL
62 #ifdef HAVE_MPI_MOD
63  USE mpi
64 #endif
65 #endif
66  IMPLICIT NONE
67 #ifdef PARALLEL
68 #ifdef HAVE_MPIF_H
69  include 'mpif.h'
70 #endif
71 #endif
72  !--------------------------------------------------------------------------!
73  PRIVATE
74  !--------------------------------------------------------------------------!
75  INTEGER, PARAMETER :: maxcomp = 9
77  INTEGER, PARAMETER :: maxcols = 40
78  INTEGER, PARAMETER :: maxkey = 64
79  CHARACTER, PARAMETER :: lf = achar(10)
81 ! CHARACTER(LEN=16),DIMENSION(6),PARAMETER :: fluxkey = (/'bflux_WEST ', &
82 ! 'bflux_EAST ', &
83 ! 'bflux_SOUTH ', &
84 ! 'bflux_NORTH ', &
85 ! 'bflux_BOTTOM', &
86 ! 'bflux_TOP ' /)
87 
88  !--------------------------------------------------------------------------!
89  TYPE, EXTENDS(fileio_base) :: fileio_vtk
90  PRIVATE
91  INTEGER :: ip1,jp1,kp1
92  CONTAINS
93  ! methods
94  PROCEDURE :: initfileio_vtk
95  PROCEDURE :: openfile
96  PROCEDURE :: closefile
97  PROCEDURE :: writeheader
98  PROCEDURE :: readheader
99  PROCEDURE :: writetimestamp
100  PROCEDURE :: writeparaviewfile
101  PROCEDURE :: readtimestamp
102  PROCEDURE :: writedataset
103  PROCEDURE :: getprecision
104  PROCEDURE :: getoutputlist
105  PROCEDURE :: getendianness
106  PROCEDURE :: finalize
107  END TYPE
108  !--------------------------------------------------------------------------!
109  PUBLIC :: &
110  fileio_vtk
111 
112  !--------------------------------------------------------------------------!
113 CONTAINS
118  SUBROUTINE initfileio_vtk(this,Mesh,Physics,Timedisc,Sources,config,IO)
119  IMPLICIT NONE
120  !------------------------------------------------------------------------!
121  CLASS(fileio_vtk), INTENT(INOUT) :: this
122  CLASS(mesh_base), INTENT(IN) :: Mesh
123  CLASS(physics_base), INTENT(IN) :: Physics
124  CLASS(timedisc_base),INTENT(IN) :: Timedisc
125  CLASS(sources_base), INTENT(IN), POINTER :: Sources
126  TYPE(Dict_TYP), INTENT(IN), POINTER :: config
127  TYPE(Dict_TYP), INTENT(IN), POINTER :: IO
128  !------------------------------------------------------------------------!
129  TYPE(Dict_TYP), POINTER :: node
130  INTEGER :: k,i,j,err
131 #ifdef PARALLEL
132  INTEGER, DIMENSION(:), POINTER :: sendbuf,recvbuf
133  INTEGER :: n
134 #endif
135  REAL, DIMENSION(:,:,:,:,:), POINTER :: corners
136  !------------------------------------------------------------------------!
137 #ifdef PARALLEL
138  this%multfiles = .true.
139 #endif
140  ! start init form base class in beginning
141  CALL this%InitFileIO(mesh,physics,timedisc,sources,config,io,"VTK","vts")
142 
143  ! some sanity checks
144  IF (this%cycles .NE. this%count+1) CALL this%Error('InitFileIO','VTK need filecycles = count+1')
145 
146  ! determine dimensions for the coordinate array
147  IF (abs(mesh%xmax-mesh%xmin).LT.2*epsilon(mesh%xmin) &
148  .OR.(mesh%INUM.EQ.1.AND.mesh%ROTSYM.EQ.1)) THEN
149  ! suppress x-direction in output
150  this%IP1 = 0
151  ELSE
152  this%IP1 = 1
153  END IF
154  IF (abs(mesh%ymax-mesh%ymin).LT.2*epsilon(mesh%ymin) &
155  .OR.(mesh%JNUM.EQ.1.AND.mesh%ROTSYM.EQ.2)) THEN
156  ! suppress y-direction in output
157  this%JP1 = 0
158  ELSE
159  this%JP1 = 1
160  END IF
161  IF (abs(mesh%zmax-mesh%zmin).LT.2*epsilon(mesh%zmin) &
162  .OR.(mesh%KNUM.EQ.1.AND.mesh%ROTSYM.EQ.3)) THEN
163  ! suppress z-direction in output
164  this%KP1 = 0
165  ELSE
166  this%KP1 = 1
167  END IF
168 
169  ! allocate memory for auxilliary data fields
170  ALLOCATE(this%binout(maxcomp, &
171  mesh%IMIN:mesh%IMAX, &
172  mesh%JMIN:mesh%JMAX, &
173  mesh%KMIN:mesh%KMAX), &
174  this%vtkcoords(3, &
175  mesh%IMIN:mesh%IMAX+this%IP1, &
176  mesh%JMIN:mesh%JMAX+this%JP1, &
177  mesh%KMIN:mesh%KMAX+this%KP1), &
178  this%output(maxcols), &
179  this%tsoutput(maxcols), &
180  this%bflux(physics%VNUM,6), &
181  stat = err)
182  IF (err.NE.0) &
183  CALL this%Error("InitFileio_vtk", "Unable to allocate memory.")
184 
185  ! determine extend and endianness of real numbers
186  CALL this%GetPrecision(this%realsize)
187  ! save size of floats to string: realfmt
188  WRITE(this%linebuf,fmt='(I4)',iostat=this%error_io) 8*this%realsize
189  WRITE(this%realfmt,fmt='(A)',iostat=this%error_io) '"Float' &
190  // trim(adjustl(this%linebuf)) // '"'
191  CALL this%GetEndianness(this%endianness,'"LittleEndian"','"BigEndian"')
192 
193  ! sanity check in case someone ignores the comment in
194  ! fileio_common.f90 regarding the KIND type of this variable
195  IF (bit_size(this%output(1)%numbytes) .NE. 4*8) &
196  CALL this%Error("InitFileio_vtk", "output%numbytes must be a 4 byte integer !!!")
197 
198 #ifdef PARALLEL
199  ! allocate memory for this%extent, send & receive buffers;
200  ! recvbuf and this%extent are only needed on the receiver node (rank 0)
201  ! but parallel profiling using scalasca with mpich3 crashes
202  ! if recvbuf is not allocated on each node hence we allocate a minimal
203  ! array of size 1 on all nodes except for the receiver node;
204  ! remark: according to the MPI-2 standard recvbuf must only be allocated
205  ! on the receiver node
206  IF (this%GetRank() .EQ. 0 ) THEN
207  n = this%GetNumProcs()
208  ALLOCATE(this%extent(0:(n-1)),sendbuf(6),recvbuf(6*n),stat = this%error_io)
209  ELSE
210  ! see comment above
211  ALLOCATE(sendbuf(6),recvbuf(1),stat = this%error_io)
212  END IF
213  IF (this%error_io.NE.0) &
214  CALL this%Error( "InitFileio_vtk", "Unable to allocate memory.")
215 
216  ! store information about grid extent on each node
218  sendbuf(1) = mesh%IMIN
219  sendbuf(2) = mesh%IMAX+this%IP1
220  sendbuf(3) = mesh%JMIN
221  sendbuf(4) = mesh%JMAX+this%JP1
222  sendbuf(5) = mesh%KMIN
223  sendbuf(6) = mesh%KMAX+this%KP1
224 
225  ! gather information about grid extent on each node at the rank 0 node
226  CALL mpi_gather(sendbuf, 6, mpi_integer, recvbuf, 6, mpi_integer, &
227  0, mpi_comm_world, this%error_io)
228 
229  ! store information about grid extent at the rank 0 node
230  IF (this%GetRank() .EQ. 0 ) THEN
231  DO i=0,n-1
232  WRITE(this%extent(i),fmt='(6(I7))',iostat=this%error_io)&
233  recvbuf(i*6+1),recvbuf(i*6+2),recvbuf(i*6+3),recvbuf(i*6+4),recvbuf(i*6+5),recvbuf(i*6+6)
234  END DO
235  END IF
236  ! free buffer memory
237  DEALLOCATE(sendbuf,recvbuf,stat=this%error_io)
238 #endif
239 
240  ! check whether mesh coordinates should be cartesian or curvilinear
241  IF (this%cartcoords) THEN
242  corners => mesh%RemapBounds(mesh%cart%corners)
243  ELSE
244  corners => mesh%RemapBounds(mesh%curv%corners)
245  END IF
246 
247  ! store mesh corners in appropriate array for VTK coordinate output
248  DO k=mesh%KMIN,mesh%KMAX+mesh%KP1
249  DO j=mesh%JMIN,mesh%JMAX+mesh%JP1
250  DO i=mesh%IMIN,mesh%IMAX+mesh%IP1
251  this%vtkcoords(1:3,i,j,k) = corners(i,j,k,1,1:3)
252  END DO
253  END DO
254  END DO
255 
256  ! add coordinates in 1D/2D simulations with non-vanishing extent
257  IF (mesh%INUM.EQ.1.AND.this%IP1.EQ.1) THEN
258  ! no transport in x-direction, but x-extent > 0
259  i = mesh%IMIN
260  DO k=mesh%KMIN,mesh%KMAX+mesh%KP1
261  DO j=mesh%JMIN,mesh%JMAX+mesh%JP1
262  this%vtkcoords(1:3,i+1,j,k) = corners(i,j,k,2,1:3)
263  END DO
264  END DO
265  END IF
266 
267  IF (mesh%JNUM.EQ.1.AND.this%JP1.EQ.1) THEN
268  ! no transport in y-direction, but y-extent > 0
269  j = mesh%JMIN
270  DO k=mesh%KMIN,mesh%KMAX+mesh%KP1
271  DO i=mesh%IMIN,mesh%IMAX+mesh%IP1
272  this%vtkcoords(1:3,i,j+1,k) = corners(i,j,k,3,1:3)
273  END DO
274  END DO
275  END IF
276 
277  IF (mesh%KNUM.EQ.1.AND.this%KP1.EQ.1) THEN
278  ! no transport in z-direction, but z-extent > 0
279  k = mesh%KMIN
280  DO j=mesh%JMIN,mesh%JMAX+mesh%JP1
281  DO i=mesh%IMIN,mesh%IMAX+mesh%IP1
282  this%vtkcoords(1:3,i,j,k+1) = corners(i,j,k,5,1:3)
283  END DO
284  END DO
285  END IF
286 
287  ! byte offset, i.e. extent of coordinate data + 4 bytes for storing
288  ! the size information which must be a 4 byte integer number
289  this%offset = SIZE(this%vtkcoords)*this%realsize + 4
290 
291  ! create list of output data arrays
292  node => io
293  this%cols = 0
294  this%tscols = 0
295  CALL this%GetOutputlist(mesh,node,this%cols,this%tscols)
296 
297  IF (this%GetRank().EQ.0) CALL this%WriteParaviewFile()
298  END SUBROUTINE initfileio_vtk
299 
300  SUBROUTINE writeparaviewfile(this)
301  IMPLICIT NONE
302  !------------------------------------------------------------------------!
303  CLASS(fileio_vtk), INTENT(INOUT) :: this
304  !------------------------------------------------------------------------!
305  INTEGER :: k
306  REAL :: ftime
307  CHARACTER(LEN=256) :: basename
308 #ifdef PARALLEL
309  INTEGER :: i
310 #endif
311  !------------------------------------------------------------------------!
312  ! write a pvd-file: this is a "master" file of all timesteps of all ranks
313  CALL this%OpenFile(replace,'pvd')
314 
315  ! write vtk header
316  WRITE(this%unit+200,fmt='(A)',iostat=this%error_io) &
317  '<?xml version="1.0"?>'//lf &
318  //'<VTKFile type="Collection" version="0.1" byte_order=' &
319  //this%endianness//'>'//lf &
320  //repeat(' ',2)//'<Collection>'
321 
322  ! write entries for each time step
323  DO k=0,this%cycles-1
324  this%step=k ! we need this to get the correct file name with time step appended
325  ! ATTENTION: remember to reset the this%step (see below)
326  ftime = this%stoptime*k/(this%cycles-1)
327 #ifdef PARALLEL
328  ! in parallel mode each node generates its own file
329  DO i=0,this%GetNumProcs()-1
330  basename=this%GetBasename(i)
331  IF (this%error_io.EQ. 0) WRITE(this%unit+200,fmt='(A,E11.5,A,I4.4,A)',iostat=this%error_io) &
332  repeat(' ',4)//'<DataSet timestep="',&
333  ftime,'" part="', i ,'" file="'//trim(basename)//'"/>'
334  END DO
335 #else
336  basename=this%GetBasename()
337  IF (this%error_io.EQ. 0) WRITE(this%unit+200,fmt='(A,E11.5,A)',iostat=this%error_io) &
338  repeat(' ',4)//'<DataSet timestep="',ftime,'" part="0" file="' &
339  //trim(basename)//'"/>'
340 #endif
341  END DO
342  ! reset the step (see comment above)
343  this%step=0
344 
345  IF (this%error_io.EQ. 0) WRITE(this%unit+200,fmt='(A)',iostat=this%error_io) &
346  repeat(' ',2)//'</Collection>'//lf//'</VTKFile>'
347  IF (this%error_io.GT.0) CALL this%Error("InitFileIO_vtk","cannot write pvd-file")
348 
349  CALL this%CloseFile('pvd')
350  END SUBROUTINE writeparaviewfile
351 
352 
358  SUBROUTINE getprecision(this,realsize)
359  IMPLICIT NONE
360  !------------------------------------------------------------------------!
361  CLASS(fileio_vtk), INTENT(INOUT) :: this
362  INTEGER :: realsize
363  !------------------------------------------------------------------------!
364  CHARACTER(LEN=4) :: cTIPO4
365  CHARACTER(LEN=8) :: cTIPO8
366  CHARACTER(LEN=16) :: cTIPO16
367  REAL :: rTIPO1, rTIPO2
368  INTEGER :: k,iTIPO
369  !------------------------------------------------------------------------!
370  INTENT(OUT) :: realsize
371  !------------------------------------------------------------------------!
372 
373  !endianness
374  k = bit_size(itipo)/8
375  !HOW big is a REAL?
376  rtipo1 = acos(0.0)
377  ctipo4 = transfer(rtipo1,ctipo4)
378  rtipo2 = transfer(ctipo4,rtipo2)
379  IF (rtipo2 == rtipo1) THEN
380  realsize = 4
381  ELSE
382  ctipo8 = transfer(rtipo1,ctipo8)
383  rtipo2 = transfer(ctipo8,rtipo2)
384  IF (rtipo2 == rtipo1) THEN
385  realsize = 8
386  ELSE
387  ctipo16 = transfer(rtipo1,ctipo16)
388  rtipo2 = transfer(ctipo16,rtipo2)
389  IF (rtipo2 == rtipo1) THEN
390  realsize = 16
391  ELSE
392  CALL this%Error("GetPrecision_vtk", "Could not estimate size of float type")
393  END IF
394  END IF
395  END IF
396 
397  END SUBROUTINE getprecision
398 
402  SUBROUTINE getendianness(this, res, littlestr, bigstr)
403  IMPLICIT NONE
404  !------------------------------------------------------------------------!
405  CLASS(fileio_vtk), INTENT(INOUT) :: this
406  CHARACTER(LEN=*) :: res
407  CHARACTER(LEN=*) :: littlestr
408  CHARACTER(LEN=*) :: bigstr
409  !------------------------------------------------------------------------!
410  INTEGER :: k,iTIPO
411  CHARACTER, POINTER :: cTIPO(:)
412  !------------------------------------------------------------------------!
413  INTENT(IN) :: littlestr, bigstr
414  INTENT(OUT) :: res
415  !------------------------------------------------------------------------!
416 
417  !endianness
418  k = bit_size(itipo)/8
419  ALLOCATE(ctipo(k),stat = this%error_io)
420  IF (this%error_io.NE.0) &
421  CALL this%Error("GetEndianness", "Unable to allocate memory.")
422  ctipo(1)='A'
423  !cTIPO(2:k-1) = That's of no importance.
424  ctipo(k)='B'
425 
426  itipo = transfer(ctipo, itipo)
427  DEALLOCATE(ctipo)
428  !Test of 'B'=b'01000010' ('A'=b'01000001')
429  IF (btest(itipo,1)) THEN
430  write(res,'(A)',iostat=this%error_io)bigstr
431  ELSE
432  write(res,'(A)',iostat=this%error_io)littlestr
433  END IF
434  END SUBROUTINE getendianness
435 
436 
441  RECURSIVE SUBROUTINE getoutputlist(this,Mesh,node,k,l,prefix)
442  IMPLICIT NONE
443  !------------------------------------------------------------------------!
444  CLASS(fileio_vtk), INTENT(INOUT) :: this
445  CLASS(mesh_base), INTENT(IN) :: mesh
446  TYPE(dict_typ), POINTER :: node
447  INTEGER, INTENT(INOUT) :: k
448  INTEGER, INTENT(INOUT) :: l
450  CHARACTER(LEN=*), OPTIONAL, INTENT(INOUT) :: prefix
451  !------------------------------------------------------------------------!
452  TYPE(dict_typ), POINTER :: dir
453  CHARACTER(LEN=MAXKEY) :: key
454  TYPE(real_t) :: dummy1
455  REAL, DIMENSION(:,:), POINTER :: dummy2
456  REAL, DIMENSION(:,:,:), POINTER :: dummy3
457  REAL, DIMENSION(:,:,:,:), POINTER :: dummy4
458  INTEGER, DIMENSION(4) :: dims
459  INTEGER :: n
460  !------------------------------------------------------------------------!
461  DO WHILE(ASSOCIATED(node))
462  IF(haschild(node)) THEN
463  ! recursion
464  IF(PRESENT(prefix)) THEN
465  key = trim(prefix)//'/'//trim(getkey(node))
466  ELSE
467  key = '/'//trim(getkey(node))
468  END IF
469  dir => getchild(node)
470  CALL this%GetOutputlist(mesh,dir,k,l,key)
471  ELSE IF (hasdata(node).AND.&
472  .NOT.(getkey(node).EQ."time")) THEN ! skip time, this is handled in WriteTimestep
473  IF (k+1 .GT. maxcols) CALL this%Error("GetOutputlist","reached MAXCOLS")
474  ! check shape of output
475  dims = 0
476  SELECT CASE(getdatatype(node))
477  CASE(dict_real_twod)
478  CALL getattr(node,trim(getkey(node)),dummy2)
479  dims(1:2) = shape(dummy2)
480  dims(3:4) = 1
481  CASE(dict_real_threed)
482  CALL getattr(node,trim(getkey(node)),dummy3)
483  dims(1:3) = shape(dummy3)
484  dims(4) = 1
485  CASE(dict_real_fourd)
486  CALL getattr(node,trim(getkey(node)),dummy4)
487  dims(1:4) = shape(dummy4)
488  CASE(dict_real_p)
489  CALL getattr(node,getkey(node),dummy1)
490  IF (ASSOCIATED(dummy1%p)) THEN
491  l=l+1
492  this%tsoutput(l)%val => dummy1%p
493  this%tsoutput(l)%key = trim(getkey(node))
494  IF (PRESENT(prefix)) THEN
495  this%tsoutput(l)%key = trim(prefix) // '/' // this%tsoutput(l)%key
496  END IF
497  END IF
498  END SELECT
499  ! only register output if it contains mesh data
500  ! if not => reset k
501  ! TODO: HACKATHON 3D - Dritte Meshdimension abfragen.
502  IF ((dims(1).EQ.(mesh%IMAX-mesh%IMIN+1)).AND.&
503  (dims(2).EQ.(mesh%JMAX-mesh%JMIN+1)).AND.&
504  (dims(3).EQ.(mesh%KMAX-mesh%KMIN+1))) THEN
505  ! increase output index
506  k = k + 1
507  ! store name of the output array
508  this%output(k)%key = trim(getkey(node))
509  ! prepend prefix if present
510  IF (PRESENT(prefix)) THEN
511  this%output(k)%key = trim(prefix) // '/' // this%output(k)%key
512  END IF
513  ! allocate memory for pointer to output arrays
514  ALLOCATE(this%output(k)%p(dims(4)),stat=this%error_io)
515  IF (this%error_io.NE.0) &
516  CALL this%Error( "GetOutputlist", "Unable to allocate memory.")
517  ! set pointer to output arrays
518  IF (dims(4).EQ.1) THEN
519  ! 3D data
520  this%output(k)%p(1)%val => dummy3
521  this%output(k)%numbytes = SIZE(dummy3)*this%realsize
522  ELSE
523  ! 4D data (for example pvars - density,xvel,yvel)
524  DO n=1,dims(4)
525  this%output(k)%p(n)%val => dummy4(:,:,:,n)
526  this%output(k)%numbytes = SIZE(dummy4)*this%realsize
527  END DO
528  END IF
529  END IF
530  END IF
531  node=>getnext(node)
532  END DO
533  END SUBROUTINE getoutputlist
534 
537  SUBROUTINE openfile(this,action,ftype)
538  IMPLICIT NONE
539  !------------------------------------------------------------------------!
540  CLASS(fileio_vtk), INTENT(INOUT) :: this
541  INTEGER, INTENT(IN) :: action
542  CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: ftype
543  !------------------------------------------------------------------------!
544  CHARACTER(LEN=32) :: sta,act,pos,fext
545  !------------------------------------------------------------------------!
546  this%error_io=1
547  SELECT CASE(action)
548  CASE(readonly)
549  sta = 'OLD'
550  act = 'READ'
551  pos = 'REWIND'
552  CASE(readend)
553  sta = 'OLD'
554  act = 'READ'
555  pos = 'APPEND'
556  CASE(replace)
557  sta = 'REPLACE'
558  act = 'WRITE'
559  pos = 'REWIND'
560  CASE(append)
561  sta = 'OLD'
562  act = 'READWRITE'
563  pos = 'APPEND'
564  CASE DEFAULT
565  CALL this%Error("OpenFile","Unknown access mode.")
566  END SELECT
567 
568  ! check file type to open
569  IF (PRESENT(ftype)) THEN
570  fext=trim(ftype)
571  ELSE
572  ! default
573  fext='vts'
574  END IF
575 
576  SELECT CASE(trim(fext))
577  CASE('vts')
578  ! open the VTS file
579  OPEN(this%unit, file=this%GetFilename(),status=trim(sta), &
580  access = 'STREAM' , &
581  action=trim(act),position=trim(pos),iostat=this%error_io)
582 #ifdef PARALLEL
583  CASE('pvts')
584  ! open PVTS file (only parallel mode)
585  IF (this%GetRank().EQ.0) THEN
586  this%extension='pvts' ! change file name extension
587  OPEN(this%unit+100, file=this%GetFilename(-1),status=trim(sta), &
588  form='FORMATTED',action=trim(act),position=trim(pos),iostat=this%error_io)
589  this%extension='vts' ! reset default extension
590  END IF
591 #endif
592  CASE('pvd')
593  OPEN(this%unit+200, file=trim(this%filename)//'.'//trim(fext),status=trim(sta), &
594  form='FORMATTED',action=trim(act),position=trim(pos),iostat=this%error_io)
595  CASE DEFAULT
596  CALL this%Error("OpenFile","Unknown file type")
597  END SELECT
598 
599  IF (this%error_io.GT.0) &
600  CALL this%Error("OpenFile","cannot open " // trim(this%extension) // "-file")
601  END SUBROUTINE openfile
602 
605  SUBROUTINE closefile(this,ftype)
606  IMPLICIT NONE
607  !------------------------------------------------------------------------!
608  CLASS(fileio_vtk), INTENT(INOUT) :: this
609  CHARACTER(LEN=*), OPTIONAL :: ftype
610  !------------------------------------------------------------------------!
611  CHARACTER(LEN=4) :: fext
612  !------------------------------------------------------------------------!
613  INTENT(IN) :: ftype
614  !------------------------------------------------------------------------!
615  this%error_io=1
616  ! check file type to open
617  IF (PRESENT(ftype)) THEN
618  fext=trim(ftype)
619  ELSE
620  ! default
621  fext='vts'
622  END IF
623 
624  ! close file depending on the file type
625  SELECT CASE(trim(fext))
626  CASE('vts')
627  CLOSE(this%unit,iostat=this%error_io)
628 #ifdef PARALLEL
629  CASE('pvts')
630  IF (this%GetRank() .EQ. 0 ) THEN
631  CLOSE(this%unit+100,iostat=this%error_io)
632  END IF
633 #endif
634  CASE('pvd')
635  CLOSE(this%unit+200,iostat=this%error_io)
636  CASE DEFAULT
637  CALL this%Error("OpenFile","Unknown file type")
638  END SELECT
639  ! set default extension
640 
641  IF(this%error_io .NE. 0) &
642  CALL this%Error( "CloseFileIO", "cannot close "//trim(fext)//"-file")
643  END SUBROUTINE closefile
644 
645 ! !> Extract a subkey of a string (obsolete)
646 ! !!
647 ! !! Extract a subkey from a string (key) of type "abcd/SUBKEY/efgh"
648 ! FUNCTION GetSubKey(key) RESULT(subkey)
649 ! IMPLICIT NONE
650 ! !------------------------------------------------------------------------!
651 ! CHARACTER(LEN=*) :: key
652 ! !------------------------------------------------------------------------!
653 ! CHARACTER(LEN=MAXKEY) :: subkey
654 ! !------------------------------------------------------------------------!
655 ! INTENT(IN) :: key
656 ! !------------------------------------------------------------------------!
657 ! ! format of key like: "abcd/SUBKEY/efgh"
658 ! subkey = key(SCAN(key,"/",.TRUE.)+1:)
659 ! END FUNCTION GetSubKey
660 
663  SUBROUTINE writeheader(this,Mesh,Physics,Header,IO)
664  IMPLICIT NONE
665  !------------------------------------------------------------------------!
666  CLASS(fileio_vtk), INTENT(INOUT) :: this
667  CLASS(mesh_base), INTENT(IN) :: Mesh
668  CLASS(physics_base), INTENT(IN) :: Physics
669  TYPE(Dict_TYP), POINTER :: IO
670  TYPE(Dict_TYP), POINTER :: Header
671  !------------------------------------------------------------------------!
672  CALL this%OpenFile(replace)
673 
674  this%error_io = 1
675  ! write header in vts files
676  WRITE(this%linebuf,fmt='(A,6(I7),A)') '<?xml version="1.0"?>' //lf// &
677  '<VTKFile type="StructuredGrid" version="0.1" byte_order='&
678  //this%endianness//'>'//lf//&
679  ' <StructuredGrid WholeExtent="',&
680  mesh%IMIN,mesh%IMAX+this%IP1,mesh%JMIN,mesh%JMAX+this%JP1, &
681  mesh%KMIN,mesh%KMAX+this%KP1,'">'//lf// &
682 ! Mesh%IMIN,Mesh%IMAX+1,Mesh%JMIN,Mesh%JMAX+1,Mesh%KMIN,Mesh%KMAX+1,'">'//LF// &
683  ' <FieldData>'//lf// &
684  ' <InformationKey type="String" Name="fosite version" format="ascii">'//lf// &
685  ' '//trim(version)//lf// &
686  ' </InformationKey>'//lf
687  WRITE(this%unit,iostat=this%error_io) trim(this%linebuf)
688 
689 #ifdef PARALLEL
690  ! write header in pvts file (only rank 0)
691  IF (this%GetRank() .EQ. 0 ) THEN
692  CALL this%OpenFile(replace,'pvts')
693  WRITE(this%unit+100,fmt='(A,6(I7),A)',iostat=this%error_io) '<?xml version="1.0"?>' //lf// &
694  '<VTKFile type="PStructuredGrid" version="0.1" byte_order='&
695  //this%endianness//'>'//lf//&
696  ' <PStructuredGrid WholeExtent="',&
697  1,mesh%INUM+this%IP1,1,mesh%JNUM+this%JP1,1,mesh%KNUM+this%KP1,'">'//lf//&
698  ' <PFieldData>'//lf// &
699  ' <InformationKey type="String" Name="fosite version" format="ascii">'//lf// &
700  ' '//trim(version)//lf//&
701  ' </InformationKey>'
702  CALL this%CloseFile('pvts')
703  END IF
704 #endif
705  IF (this%error_io.GT.0) CALL this%Error("WriteHeader","cannot write (P)VTS file header")
706 
707  CALL this%CloseFile()
708  END SUBROUTINE writeheader
709 
712  SUBROUTINE readheader(this,success)
713  IMPLICIT NONE
714  !------------------------------------------------------------------------!
715  CLASS(fileio_vtk), INTENT(INOUT) :: this
716  LOGICAL :: success
717  !------------------------------------------------------------------------!
718  INTENT(OUT) :: success
719  !------------------------------------------------------------------------!
720  CALL this%OpenFile(readonly)
721  success = .false.
722  CALL this%CloseFile()
723  END SUBROUTINE readheader
724 
727  SUBROUTINE writetimestamp(this,time)
728  IMPLICIT NONE
729  !------------------------------------------------------------------------!
730  CLASS(fileio_vtk) :: this
731  REAL :: time
732  !------------------------------------------------------------------------!
733  INTENT(IN) :: time
734  !------------------------------------------------------------------------!
735  CALL this%OpenFile(append)
736 
737  WRITE(this%linebuf,fmt='(A,ES14.7,A)') &
738  ' <DataArray type="Float64" Name="TIME" NumberOfTuples="1" format="ascii">'//lf// &
739  repeat(' ',8),time,lf//&
740  ' </DataArray>'//lf
741  WRITE(this%unit,iostat=this%error_io) trim(this%linebuf)
742 #ifdef PARALLEL
743  ! write time stamp in PVTS file in parallel mode
744  IF (this%GetRank() .EQ. 0 ) THEN
745  CALL this%OpenFile(append,'pvts')
746  WRITE(this%unit+100,fmt='(A)',advance='NO',iostat=this%error_io) trim(this%linebuf)
747  CALL this%CloseFile('pvts')
748  END IF
749 
750  CALL this%CloseFile()
751 #endif
752 
753  END SUBROUTINE writetimestamp
754 
757  SUBROUTINE readtimestamp(this,time)
758  IMPLICIT NONE
759  !------------------------------------------------------------------------!
760  CLASS(fileio_vtk), INTENT(INOUT) :: this
761  REAL :: time
762  !------------------------------------------------------------------------!
763  INTENT(OUT) :: time
764  !------------------------------------------------------------------------!
765  CALL this%OpenFile(readonly)
766  time = 0.0
767  CALL this%CloseFile()
768  END SUBROUTINE readtimestamp
769 
772  SUBROUTINE writedataset(this,Mesh,Physics,Fluxes,Timedisc,Header,IO)
773  IMPLICIT NONE
774  !------------------------------------------------------------------------!
775  CLASS(fileio_vtk), INTENT(INOUT) :: this
776  CLASS(mesh_base), INTENT(IN) :: Mesh
777  CLASS(physics_base), INTENT(INOUT) :: Physics
778  CLASS(fluxes_base), INTENT(IN) :: Fluxes
779  CLASS(timedisc_base), INTENT(IN) :: Timedisc
780  TYPE(Dict_TYP), POINTER :: Header
781  TYPE(Dict_TYP), POINTER :: IO
782  !------------------------------------------------------------------------!
783  INTEGER :: k,m
784  INTEGER :: n, offset
785 #ifdef PARALLEL
786  CHARACTER(LEN=256) :: basename
787  INTEGER :: i
788 #endif
789  !------------------------------------------------------------------------!
790  ! this part is formerly from fileio_generic.f90
791  ! calculate boundary fluxes, if they were requested for write
792 ! IF(ASSOCIATED(Timedisc%bflux)) THEN
793 ! print *, "test"
794 ! DO k=1,4
795 ! Timedisc%bflux(:,k) = Fluxes%GetBoundaryFlux(Mesh,Physics,k)
796 ! END DO
797 !#ifdef PARALLEL
798 ! CALL MPI_BCAST(Timedisc%bflux, Physics%VNUM*4, DEFAULT_MPI_REAL, 0, &
799 ! Mesh%comm_cart, ierror)
800 !#endif
801 ! END IF
802 
803  IF (ASSOCIATED(timedisc%w)) THEN
804  IF (mesh%FARGO.EQ.3.AND.mesh%shear_dir.EQ.1) THEN
805  CALL physics%AddBackgroundVelocityX(mesh,timedisc%w,timedisc%pvar,timedisc%cvar)
806  ELSE
807  CALL physics%AddBackgroundVelocityY(mesh,timedisc%w,timedisc%pvar,timedisc%cvar)
808  END IF
809  END IF
810 
811 
812  ! write the header if either this is the first data set we write or
813  ! each data set is written into a new file
814  IF ((this%step.EQ.0).OR.(this%cycles.GT.0)) THEN
815  CALL this%WriteHeader(mesh,physics,header,io)
816  END IF
817  ! write the time stamp
818  CALL this%WriteTimestamp(timedisc%time)
819  CALL this%OpenFile(append)
820 
821  !------------------------------------------------------------------------!
822  ! REMARK: VTS/PVTS data files are opened in unformated or stream mode,
823  ! hence we always write the formated data into a line buffer
824  ! and then write the line buffer to the data file
825  ! -----------------------------------------------------------------------!
826  ! 1. META data
827  ! -----------------------------------------------------------------------!
828  ! a) global information; currently only scalar real numbers supported
829 #ifdef PARALLEL
830  IF (this%GetRank() .EQ. 0 ) THEN
831  CALL this%OpenFile(append,'pvts')
832  IF(this%error_io .NE. 0) CALL this%Error( "WriteDataset", "Can't open pvts file")
833  END IF
834 #endif
835  ! loop over all time step data registred in GetOutputlist
836  DO k=1,this%TSCOLS
837  WRITE(this%linebuf,fmt='(A,ES14.7,A)') &
838  ' <DataArray type="Float64" Name="'//trim(this%tsoutput(k)%key)// &
839  '" NumberOfTuples="1" format="ascii">'//lf// &
840  repeat(' ',8),this%tsoutput(k)%val,lf//&
841  ' </DataArray>'//lf
842  WRITE(this%unit,iostat=this%error_io) trim(this%linebuf)
843 #ifdef PARALLEL
844  ! write time step data in PVTS file in parallel mode
845  IF (this%GetRank() .EQ. 0 ) THEN
846  WRITE(this%unit+100,fmt='(A)',advance='NO',iostat=this%error_io) trim(this%linebuf)
847  END IF
848 #endif
849  END DO
850 
852 
853 ! simple hack to write positions of the binary star system
854 ! IF (HasKey(IO, "/sources/grav/binary/binpos/value"))THEN
855 ! CALL GetAttr(IO, "/sources/grav/binary/binpos", dummy2)
856 !
857 ! WRITE(this%tslinebuf,fmt='(ES14.7,A,ES14.7)',IOSTAT=this%error_io)&
858 ! dummy2(1,1), repeat(' ',4),dummy2(2,1)
859 !
860 ! WRITE(this%unit, IOSTAT=this%error_io)&
861 ! LF//repeat(' ',6)//'<DataArray type="Float64" Name="position primary"' &
862 ! //' NumberOfTuples="2" format="ascii">' &
863 ! //LF//repeat(' ',8)//TRIM(this%tslinebuf) &
864 ! //LF//repeat(' ',6)//'</DataArray>'
865 !
866 ! #ifdef PARALLEL
867 ! IF (GetRank(this) .EQ. 0 ) &
868 ! WRITE(this%unit+100, IOSTAT=this%error_io)&
869 ! LF//repeat(' ',6)//'<DataArray type="Float64" Name="position primary"' &
870 ! //' NumberOfTuples="2" format="ascii">' &
871 ! //LF//repeat(' ',8)//TRIM(this%tslinebuf) &
872 ! //LF//repeat(' ',6)//'</DataArray>'
873 !
874 ! #endif
875 !
876 ! WRITE(this%tslinebuf,fmt='(ES14.7,A,ES14.7)',IOSTAT=this%error_io)&
877 ! dummy2(1,2), repeat(' ',4),dummy2(2,2)
878 !
879 ! WRITE(this%unit, IOSTAT=this%error_io)&
880 ! LF//repeat(' ',6)//'<DataArray type="Float64" Name="position secondary"' &
881 ! //' NumberOfTuples="2" format="ascii">' &
882 ! //LF//repeat(' ',8)//TRIM(this%tslinebuf) &
883 ! //LF//repeat(' ',6)//'</DataArray>'
884 !
885 ! #ifdef PARALLEL
886 ! IF (GetRank(this) .EQ. 0 ) &
887 ! WRITE(this%unit+100, IOSTAT=this%error_io)&
888 ! LF//repeat(' ',6)//'<DataArray type="Float64" Name="position secondary"' &
889 ! //' NumberOfTuples="2" format="ascii">' &
890 ! //LF//repeat(' ',8)//TRIM(this%tslinebuf) &
891 ! //LF//repeat(' ',6)//'</DataArray>'
892 ! #endif
893 !
894 ! END IF
895 
896  ! -----------------------------------------------------------------------!
897  ! b) coordinates
898  WRITE(this%linebuf,fmt='(A,(6(I7)),A)')&
899  ' </FieldData>'//lf// &
900  ' <Piece Extent="', &
901  mesh%IMIN,mesh%IMAX+this%IP1,mesh%JMIN,mesh%JMAX+this%JP1,&
902  mesh%KMIN,mesh%KMAX+this%KP1,'">'//lf// &
903  ' <Points>'//lf//&
904  ' <DataArray type='//this%realfmt//' NumberOfComponents="3"'//&
905  ' Name="Point" format="appended" offset="0">'//lf// &
906  ' </DataArray>'//lf// &
907  ' </Points>'//lf// &
908  ' <CellData>'//lf
909  WRITE(this%unit,iostat=this%error_io) trim(this%linebuf)
910 
911 #ifdef PARALLEL
912  IF (this%GetRank() .EQ. 0 ) THEN
913  WRITE(this%unit+100,fmt='(A)',iostat=this%error_io)&
914  repeat(' ',4)//'</PFieldData>' &
915  //lf//repeat(' ',4)//'<PPoints>' &
916  //lf//repeat(' ',6)//'<DataArray type='//this%realfmt &
917  //' NumberOfComponents="3" Name="Point"/>' &
918  //lf//repeat(' ',4)//'</PPoints>' &
919  //lf//repeat(' ',4)//'<PCellData>'
920  END IF
921 #endif
922 
923  ! -----------------------------------------------------------------------!
924  ! c) output data fields
925  offset = 0
926  DO k = 1, this%cols
927  WRITE(this%linebuf,fmt='(A,I3,A,I8,A)')&
928  repeat(' ',6)//'<DataArray type='//this%realfmt//&
929  ' NumberOfComponents="', SIZE(this%output(k)%p), &
930  '" Name="'//trim(this%output(k)%key)//&
931  '" format="appended" offset="',this%offset+offset,'"/>'//lf
932  WRITE(this%unit,iostat=this%error_io) trim(this%linebuf)
933 
934 #ifdef PARALLEL
935  IF (this%GetRank() .EQ. 0 ) THEN
936  WRITE(this%unit+100,fmt='(A,I3,A)',iostat=this%error_io)&
937  repeat(' ',6)//'<DataArray type='//this%realfmt//&
938  ' NumberOfComponents="', SIZE(this%output(k)%p),&
939  '" Name="'//trim(this%output(k)%key)//'"/>'
940  END IF
941 #endif
942  ! add size of data set (in bytes) + 4 (4 byte integer for size information)
943  ! -> "jump address" for next data set in the file in bytes
944  offset = offset + this%output(k)%numbytes + 4
945  END DO
946 
947  WRITE(this%unit,iostat=this%error_io)&
948  repeat(' ',6)//'</CellData>' &
949  //lf//repeat(' ',4)//'</Piece>' &
950  //lf//repeat(' ',2)//'</StructuredGrid>' &
951  //lf//repeat(' ',2)//'<GlobalData>'
952 
953 #ifdef PARALLEL
954  IF (this%GetRank() .EQ. 0 ) THEN
955  WRITE(this%unit+100,fmt='(A)',iostat=this%error_io) repeat(' ',4)//'</PCellData>'
956 
957  DO i=0,this%GetNumProcs()-1
958  basename=this%GetBasename(i)
959  WRITE(this%unit+100,fmt='(A)',iostat=this%error_io) &
960  repeat(' ',4)//'<Piece Extent="'//trim(this%extent(i))&
961  //'" Source="'//trim(basename)//'"/>'
962  END DO
963 
964  WRITE(this%unit+100,fmt='(A)',iostat=this%error_io)&
965  repeat(' ',2)//'</PStructuredGrid>' &
966  //lf//'</VTKFile>'
967 
968  END IF
969 #endif
970 
971  ! -----------------------------------------------------------------------!
972  ! d) boundary fluxes
973 ! DO i=1,4
974 ! ! in PARALLEL mode the result is sent to process with rank 0
975 ! this%bflux(:,i) = GetBoundaryFlux(Fluxes,Mesh,Physics,i)
976 !
977 ! WRITE(this%unit,IOSTAT=this%error_io)&
978 ! LF//repeat(' ',4)//'<DataArray type='//this%realfmt//&
979 ! 'Name="'//TRIM(fluxkey(i))//'" format="ascii" >' &
980 ! //LF//repeat(' ',6)
981 ! DO k=1,Physics%VNUM
982 ! WRITE(this%linebuf((k-1)*20+1:k*20),fmt='(E16.9,A)',IOSTAT=this%error_io)&
983 ! this%bflux(k,i),repeat(' ',4)
984 ! END DO
985 !
986 ! WRITE(this%unit,IOSTAT=this%error_io)TRIM(this%linebuf(1:Physics%VNUM*20)) &
987 ! //LF//repeat(' ',4)//'</DataArray>'
988 ! END DO
989 
990  ! end META data
991  ! -----------------------------------------------------------------------------------!
992 
993  WRITE(this%unit,iostat=this%error_io)&
994  lf//repeat(' ',2)//'</GlobalData>' &
995  //lf//'<AppendedData encoding="raw">' &
996  //lf//'_'
997 
998 #ifdef PARALLEL
999  IF (this%GetRank() .EQ. 0 ) THEN
1000  CALL this%CloseFile('pvts')
1001  IF(this%error_io .NE. 0) CALL this%Error( "WriteDataset", "Can't close pvts file")
1002  END IF
1003 #endif
1004 
1005  ! -----------------------------------------------------------------------!
1006  ! 2. REAL data
1007  ! -----------------------------------------------------------------------!
1008  ! TODO: Hier nochmal rübergucken für 3D
1009  ! a) coordinates:
1010  ! (i) size of data array in bytes (must be a 4 byte integer)
1011  ! (ii) coordinate data array (generated in InitFileio)
1012  WRITE(this%unit,iostat=this%error_io) int(this%offset,4),this%vtkcoords(:,:,:,:)
1013  IF (this%error_io.GT.0) &
1014  CALL this%Error( "WriteDataset", "cannot write coordinates")
1015 
1016  ! -----------------------------------------------------------------------!
1017  ! b) data fields
1018  ! (i) size of data array in bytes (must be a 4 byte integer);
1019  ! this is determined in GetOutputlist and storen in
1020  ! this%output(:)%numbytes
1021  ! (ii) the data given by a list of pointers which is also
1022  ! generated in GetOutputlist
1023  ! loop over all output data fields
1024  DO k = 1, this%cols
1025  ! reorganize the data to comply with VTK style ordering
1026  n = SIZE(this%output(k)%p) ! get first dimension
1027  DO m=1,n
1028  this%binout(m,:,:,:)=this%output(k)%p(m)%val(:,:,:)
1029  END DO
1030 
1031  WRITE(this%unit,iostat=this%error_io) this%output(k)%numbytes, &
1032  this%binout(1:n,:,:,:)
1033 
1034  IF (this%error_io.GT.0) &
1035  CALL this%Error( "WriteDataset", "cannot write data")
1036  END DO
1037  WRITE(this%unit,iostat=this%error_io)lf//repeat(' ',2)//&
1038  '</AppendedData>'//lf//'</VTKFile>'//lf
1039 
1040  CALL this%CloseFile()
1041  CALL this%IncTime()
1042  END SUBROUTINE writedataset
1043 
1046  SUBROUTINE finalize(this)
1047  IMPLICIT NONE
1048  !------------------------------------------------------------------------!
1049  CLASS(fileio_vtk), INTENT(INOUT) :: this
1050  !------------------------------------------------------------------------!
1051  INTEGER :: k
1052  !------------------------------------------------------------------------!
1053  !------------------------------------------------------------------------!
1054  DO k=1,this%cols
1055  IF (ASSOCIATED(this%output(k)%p)) DEALLOCATE(this%output(k)%p)
1056  END DO
1057  DEALLOCATE(this%binout,this%vtkcoords,this%output,this%tsoutput,this%bflux)
1058  CALL this%Finalize_base()
1059  END SUBROUTINE finalize
1060 
1061 END MODULE fileio_vtk_mod
subroutine finalize(this)
Destructor of common class.
generic source terms module providing functionaly common to all source terms
subroutine readheader(this, success)
Reads the header (not yet implemented)
Definition: fileio_vtk.f90:713
integer, parameter, public replace
read/write access replacing file
I/O for VTK files in XML format (vtkStructuredGrid)
Definition: fileio_vtk.f90:52
Generic file I/O module.
Definition: fileio_base.f90:54
type(logging_base), save this
integer, parameter maxcols
max of different output arrays
Definition: fileio_vtk.f90:77
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;.
integer, parameter, public dict_real_fourd
subroutine getendianness(this, res, littlestr, bigstr)
Determines the endianness of the system.
Definition: fileio_vtk.f90:403
logical function, public haschild(root)
Check if the node &#39;root&#39; has one or more children.
integer, parameter, public dict_real_p
subroutine initfileio_vtk(this, Mesh, Physics, Timedisc, Sources, config, IO)
Constructor for the VTK file I/O.
Definition: fileio_vtk.f90:119
function, public getkey(root)
Get the key of pointer &#39;root&#39;.
subroutine readtimestamp(this, time)
Reads the timestep (not yet implemented)
Definition: fileio_vtk.f90:758
subroutine getprecision(this, realsize)
Determines precision of real numbers in bytes.
Definition: fileio_vtk.f90:359
base class for geometrical properties
subroutine writeheader(this, Mesh, Physics, Header, IO)
Writes XML header to file.
Definition: fileio_vtk.f90:664
integer, parameter, public dict_real_threed
integer, parameter, public readend
readonly access at end
subroutine writedataset(this, Mesh, Physics, Fluxes, Timedisc, Header, IO)
Writes all desired data arrays to a file.
Definition: fileio_vtk.f90:773
integer, parameter maxcomp
max. of allowed components 9 is a tensor (rank 2, dim 3)
Definition: fileio_vtk.f90:75
subroutine writeparaviewfile(this)
Definition: fileio_vtk.f90:301
integer, parameter, public dict_real_twod
Definition: common_dict.f90:99
type(dict_typ) function, pointer, public getnext(root)
Get the pointer to the next child.
Basic physics module.
Dictionary for generic data types.
Definition: common_dict.f90:61
logical function, public hasdata(root)
Checks if the node &#39;root&#39; has data associated.
subroutine writetimestamp(this, time)
Writes the timestep.
Definition: fileio_vtk.f90:728
subroutine openfile(this, action, ftype)
Specific routine to open a file for vtk I/O.
Definition: fileio_vtk.f90:538
integer, parameter, public append
read/write access at end
base module for numerical flux functions
Definition: fluxes_base.f90:39
recursive subroutine getoutputlist(this, Mesh, node, k, l, prefix)
Creates a list of all data arrays which will be written to file.
Definition: fileio_vtk.f90:442
character(len=1), save prefix
preceds info output
character, parameter lf
line feed
Definition: fileio_vtk.f90:79
integer, parameter maxkey
max length of keyname
Definition: fileio_vtk.f90:78
integer, parameter, public readonly
readonly access
subroutine closefile(this, ftype)
Specific routine to close a file for vtk I/O.
Definition: fileio_vtk.f90:606