78 #define OFFSET_TYPE INTEGER(KIND=MPI_OFFSET_KIND) 80 #define OFFSET_TYPE INTEGER 84 CHARACTER,
PARAMETER ::
lf = achar(10)
120 CLASS(fileio_binary),
INTENT(INOUT) :: this
121 CLASS(mesh_base),
INTENT(IN) :: Mesh
122 CLASS(physics_base),
INTENT(IN) :: Physics
123 CLASS(timedisc_base),
INTENT(IN) :: Timedisc
124 CLASS(sources_base),
POINTER :: Sources
125 TYPE(Dict_TYP),
POINTER :: config,IO
128 INTEGER,
DIMENSION(3) :: gsizes,lsizes,indices
130 CHARACTER(LEN=1),
DIMENSION(:),
POINTER :: mold
134 this%extension=
'bin' 135 CALL this%InitFileio(mesh,physics,timedisc,sources,config,io,
"binary",this%extension)
142 this%realsize =
SIZE(transfer(r, mold))
143 this%intsize =
SIZE(transfer(i, mold))
145 IF(this%realsize.GT.8) &
146 CALL this%Error(
"InitFileIO_binary",
"Only single and double precision are allowed")
148 WRITE(this%realfmt,
'(A,I1,A)',iostat=err)
'"',this%realsize,
'"' 151 IF(mesh%INUM.EQ.mesh%IMAX)
THEN 152 this%INUM = mesh%IMAX-mesh%IMIN+2
154 this%INUM = mesh%IMAX-mesh%IMIN+1
156 IF(mesh%JNUM.EQ.mesh%JMAX)
THEN 157 this%JNUM = mesh%JMAX-mesh%JMIN+2
159 this%JNUM = mesh%JMAX-mesh%JMIN+1
161 IF(mesh%KNUM.EQ.mesh%KMAX)
THEN 162 this%KNUM = mesh%KMAX-mesh%KMIN+2
164 this%KNUM = mesh%KMAX-mesh%KMIN+1
169 gsizes(1) = mesh%INUM
170 gsizes(2) = mesh%JNUM
171 gsizes(3) = mesh%KNUM
172 lsizes(1) = mesh%IMAX-mesh%IMIN+1
173 lsizes(2) = mesh%JMAX-mesh%JMIN+1
174 lsizes(3) = mesh%KMAX-mesh%KMIN+1
175 indices(1) = mesh%IMIN-1
176 indices(2) = mesh%JMIN-1
177 indices(3) = mesh%KMIN-1
178 this%bufsize = product(lsizes)
179 CALL mpi_type_create_subarray(3, gsizes, lsizes, indices, mpi_order_fortran,&
181 CALL mpi_type_commit(this%filetype,this%error_io)
185 gsizes(1) = mesh%INUM+1
186 gsizes(2) = mesh%JNUM+1
187 gsizes(3) = mesh%KNUM+1
188 lsizes(1) = this%INUM
189 lsizes(2) = this%JNUM
190 lsizes(3) = this%KNUM
191 indices(1) = mesh%IMIN-1
192 indices(2) = mesh%JMIN-1
193 indices(3)= mesh%KMIN-1
194 this%cbufsize = product(lsizes)
195 CALL mpi_type_create_subarray(3, gsizes, lsizes, indices, mpi_order_fortran,&
197 CALL mpi_type_commit(this%cfiletype,this%error_io)
209 CLASS(fileio_binary),
INTENT(INOUT) :: this
213 INTEGER(KIND=MPI_OFFSET_KIND) :: offset
221 CALL mpi_file_open(mpi_comm_world,this%GetFilename(),mpi_mode_rdonly, &
222 mpi_info_null,this%handle,this%error_io)
224 CALL mpi_file_seek(this%handle,this%offset,mpi_seek_set,this%error_io)
226 OPEN(this%unit,file=this%GetFilename(),status=
"OLD", &
227 access =
'STREAM' , &
228 action=
"READ",position=
"REWIND",iostat=this%error_io)
232 CALL mpi_file_open(mpi_comm_world,this%GetFilename(),ior(mpi_mode_rdonly,&
233 mpi_mode_append),mpi_info_null,this%handle,this%error_io)
236 CALL mpi_file_seek(this%handle,offset,mpi_seek_end,this%error_io)
237 CALL mpi_file_sync(this%handle,this%error_io)
239 OPEN(this%unit,file=this%GetFilename(),status=
"OLD", &
240 access =
'STREAM' , &
241 action=
"READ",position=
"APPEND",iostat=this%error_io)
245 CALL mpi_file_delete(this%GetFilename(),mpi_info_null,this%error_io)
246 CALL mpi_file_open(mpi_comm_world,this%GetFilename(),ior(mpi_mode_wronly,&
247 mpi_mode_create),mpi_info_null,this%handle,this%error_io)
249 OPEN(this%unit,file=this%GetFilename(),status=
"REPLACE",&
250 access =
'STREAM' , &
251 action=
"WRITE",position=
"REWIND",iostat=this%error_io)
255 CALL mpi_file_open(mpi_comm_world,this%GetFilename(),ior(mpi_mode_rdwr,&
256 mpi_mode_append),mpi_info_null,this%handle,this%error_io)
259 CALL mpi_file_seek(this%handle,offset,mpi_seek_end,this%error_io)
260 CALL mpi_file_sync(this%handle,this%error_io)
262 OPEN(this%unit,file=this%GetFilename(),status=
"OLD",&
263 access =
'STREAM' , &
264 action=
"READWRITE",position=
"APPEND",iostat=this%error_io)
267 CALL this%Error(
"OpenFile",
"Unknown access mode.")
277 SUBROUTINE writeheader(this,Mesh,Physics,Header,IO)
280 CLASS(fileio_binary),
INTENT(INOUT) :: this
281 CLASS(mesh_base),
INTENT(IN) :: Mesh
282 CLASS(physics_base),
INTENT(IN) :: Physics
283 TYPE(Dict_TYP),
POINTER :: Header,IO
285 CHARACTER(LEN=6) :: magic =
"FOSITE" 286 CHARACTER(LEN=1) :: version = achar(0)
287 CHARACTER(LEN=4) :: sizes
288 CHARACTER(LEN=13) :: sheader
290 WRITE(sizes,
'(I2,I2)') this%realsize, this%intsize
291 sheader = magic // this%endianness(1:2) // version // sizes
294 WRITE(this%unit) sheader
296 CALL mpi_file_set_view(this%handle,this%offset,mpi_byte,&
297 mpi_byte,
'native', mpi_info_null, this%error_io)
298 IF(this%GetRank().EQ.0) &
299 CALL mpi_file_write(this%handle,sheader,len(sheader),mpi_byte, &
300 this%status,this%error_io)
302 this%offset = this%offset + len(sheader)
354 SUBROUTINE writekey(this,key,type,bytes,dims)
357 CLASS(fileio_binary),
INTENT(INOUT) :: this
358 CHARACTER(LEN=*) :: key
359 INTEGER ::
type,bytes
360 INTEGER,
DIMENSION(5),
OPTIONAL :: dims
362 CHARACTER(LEN=1),
DIMENSION(:),
ALLOCATABLE :: buf
364 INTEGER :: keylen,l,b,o
366 INTENT(IN) :: key,
type,bytes
368 keylen = len_trim(key)
369 IF(
PRESENT(dims))
THEN 371 IF(dims(4).GT.1) l = 4
372 IF(dims(5).GT.1) l = 5
376 b = bytes + l * this%intsize
377 bufsize = (3+l) * this%intsize + keylen
378 ALLOCATE(buf(bufsize))
380 CALL append(buf,o,transfer(keylen,buf))
381 CALL append(buf,o,transfer(trim(key),buf))
382 CALL append(buf,o,transfer(
type,buf))
383 CALL append(buf,o,transfer(b,buf))
385 CALL append(buf,o,transfer(dims(1:l),buf))
390 CALL mpi_file_set_view(this%handle,this%offset,mpi_byte,&
391 mpi_byte,
'native', mpi_info_null, this%error_io)
392 IF (this%GetRank().EQ.0) &
393 CALL mpi_file_write(this%handle,buf,bufsize,mpi_byte, &
394 this%status,this%error_io)
397 this%offset = this%offset + bufsize
400 SUBROUTINE append(buffer,i,d)
403 CHARACTER(LEN=1),
DIMENSION(:) :: buffer,d
421 CHARACTER(LEN=*),
OPTIONAL :: path
423 CHARACTER(LEN=MAX_CHAR_LEN) :: str, key
428 IF(
PRESENT(path))
THEN 434 DO WHILE(
ASSOCIATED(node))
435 key = trim(str)//
"/"//trim(
getkey(node))
437 CALL this%WriteNode(mesh,key,node)
440 CALL this%WriteDataAttributes(mesh,
getchild(node), key)
449 CLASS(fileio_binary),
INTENT(INOUT) :: this
450 CLASS(mesh_base),
INTENT(IN) :: Mesh
451 CHARACTER(LEN=MAX_CHAR_LEN) :: key
452 TYPE(Dict_TYP),
POINTER :: node
455 TYPE(int_t) :: ptrint
456 REAL,
DIMENSION(:,:),
POINTER,
CONTIGUOUS :: ptr2
457 REAL,
DIMENSION(:,:,:),
POINTER :: ptr3
458 REAL,
DIMENSION(:,:,:,:),
POINTER :: ptr4
459 REAL,
DIMENSION(:,:,:,:,:),
POINTER :: ptr5
460 INTEGER,
DIMENSION(5) :: dims
462 CHARACTER(LEN=1),
DIMENSION(:),
POINTER :: val
464 offset_type :: omax,omin
470 NULLIFY(ptr2,ptr3,ptr4,ptr5)
474 CALL getattr(node,key,ptr2)
475 dims(1:2) = shape(ptr2)
477 CALL getattr(node,key,ptr3)
478 dims(1:3) = shape(ptr3)
480 CALL getattr(node,key,ptr4)
481 dims(1:4) = shape(ptr4)
483 CALL getattr(node,key,ptr5)
484 dims(1:5) = shape(ptr5)
487 IF(product(dims).GT.1)
THEN 488 CALL this%SetMeshDims(mesh,dims)
489 bytes = product(dims(1:3)) * this%realsize
491 product(dims)*this%realsize,dims)
494 IF(
ASSOCIATED(ptr4))
THEN 495 ptr3 => ptr4(:,:,:,k)
496 ELSE IF(
ASSOCIATED(ptr5))
THEN 497 ptr3 => ptr5(:,:,:,k,l)
498 ELSE IF(
ASSOCIATED(ptr2))
THEN 499 ptr3(1:dims(1),1:dims(2),1:1) => ptr2
502 IF(this%HasMeshDims(mesh,shape(ptr3)))
THEN 504 this%filetype,
'native', mpi_info_null, this%error_io)
505 CALL mpi_file_write_all(this%handle,ptr3,this%bufsize,&
508 ELSE IF(this%HasCornerDims(mesh,shape(ptr3)))
THEN 510 this%cfiletype,
'native', mpi_info_null, this%error_io)
511 CALL mpi_file_write_all(this%handle,ptr3(1:this%inum,1:this%jnum,1:this%knum),&
514 CALL mpi_file_set_view(this%handle,this%offset,mpi_byte,&
515 mpi_byte,
'native', mpi_info_null, this%error_io)
516 IF(this%GetRank().EQ.0)
THEN 517 CALL mpi_file_write(this%handle,ptr3,bytes,mpi_byte, &
518 this%status,this%error_io)
522 WRITE(this%unit) ptr3
524 this%offset = this%offset + bytes
530 CALL getattr(node,key,ptr0)
531 bytes = this%realsize
534 WRITE(this%unit) ptr0%p
536 CALL mpi_file_set_view(this%handle,this%offset,mpi_byte,&
537 mpi_byte,
'native', mpi_info_null, this%error_io)
538 IF(this%GetRank().EQ.0)
THEN 539 CALL mpi_file_write(this%handle,ptr0%p,bytes,mpi_byte, &
540 this%status,this%error_io)
544 CALL getattr(node,key,ptrint)
546 CALL this%WriteKey(key,
dict_int,bytes)
548 WRITE(this%unit) ptrint%p
550 CALL mpi_file_set_view(this%handle,this%offset,mpi_byte,&
551 mpi_byte,
'native', mpi_info_null, this%error_io)
552 IF(this%GetRank().EQ.0)
THEN 553 CALL mpi_file_write(this%handle,ptrint%p,bytes,mpi_byte, &
554 this%status,this%error_io)
559 IF(
ASSOCIATED(val))
THEN 569 CALL mpi_file_set_view(this%handle,this%offset,mpi_byte,&
570 mpi_byte,
'native', mpi_info_null, this%error_io)
571 IF(this%GetRank().EQ.0)
THEN 572 CALL mpi_file_write(this%handle,val,bytes,mpi_byte, &
573 this%status,this%error_io)
578 this%offset = this%offset + bytes
591 CALL mpi_allreduce(this%offset,omax,1,mpi_offset,mpi_max,&
592 mesh%comm_cart,this%error_io)
593 CALL mpi_allreduce(this%offset,omin,1,mpi_offset,mpi_min,&
594 mesh%comm_cart,this%error_io)
595 IF((this%offset.NE.omax).OR.(this%offset.NE.omin)) &
596 CALL this%Error(
"WriteNode_binary",&
597 "The offsets on different nodes are not in sync anymore." //
lf &
598 //
"The last key was '" // trim(key) //
"'.")
608 INTEGER,
DIMENSION(:) :: dims
613 IF(
SIZE(dims).GE.3)
THEN 614 res = (dims(1).EQ.(mesh%IMAX-mesh%IMIN+mesh%ip1).OR.mesh%INUM.EQ.1) &
615 .AND.(dims(2).EQ.(mesh%JMAX-mesh%JMIN+mesh%jp1).OR.mesh%JNUM.EQ.1) &
616 .AND.(dims(3).EQ.(mesh%KMAX-mesh%KMIN+mesh%kp1).OR.mesh%KNUM.EQ.1)
628 INTEGER,
DIMENSION(:) :: dims
633 IF(
SIZE(dims).GE.3)
THEN 634 res = (dims(1).EQ.(mesh%IMAX-mesh%IMIN+mesh%ip2).OR.mesh%INUM.EQ.1) &
635 .AND.(dims(2).EQ.(mesh%JMAX-mesh%JMIN+mesh%jp2).OR.mesh%JNUM.EQ.1) &
636 .AND.(dims(3).EQ.(mesh%KMAX-mesh%KMIN+mesh%kp2).OR.mesh%KNUM.EQ.1)
646 CLASS(fileio_binary),
INTENT(INOUT) :: this
647 CLASS(mesh_base),
INTENT(IN) :: Mesh
648 INTEGER,
DIMENSION(:) :: dims
650 INTENT(INOUT) :: dims
652 IF(this%HasMeshDims(mesh,dims))
THEN 656 ELSE IF(this%HasCornerDims(mesh,dims))
THEN 657 dims(1) = mesh%INUM+mesh%ip1
658 dims(2) = mesh%JNUM+mesh%jp1
659 dims(3) = mesh%KNUM+mesh%kp1
666 SUBROUTINE writedataset(this,Mesh,Physics,Fluxes,Timedisc,Header,IO)
669 CLASS(fileio_binary),
INTENT(INOUT) :: this
670 CLASS(mesh_base),
INTENT(IN) :: Mesh
671 CLASS(physics_base),
INTENT(INOUT) :: Physics
672 CLASS(fluxes_base),
INTENT(IN) :: Fluxes
673 CLASS(timedisc_base),
INTENT(IN) :: Timedisc
674 TYPE(Dict_TYP),
POINTER :: Header,IO
676 IF (
ASSOCIATED(timedisc%w))
THEN 677 IF (mesh%FARGO.EQ.3.AND.mesh%shear_dir.EQ.1)
THEN 678 CALL physics%AddBackgroundVelocityX(mesh,timedisc%w,timedisc%pvar,timedisc%cvar)
680 CALL physics%AddBackgroundVelocityY(mesh,timedisc%w,timedisc%pvar,timedisc%cvar)
686 CALL this%WriteHeader(mesh,physics,header,io)
687 CALL this%WriteDataAttributes(mesh,io)
688 CALL this%CloseFile()
718 CLASS(fileio_binary),
INTENT(INOUT) :: this
719 CHARACTER(LEN=*) :: res
720 CHARACTER(LEN=*) :: littlestr
721 CHARACTER(LEN=*) :: bigstr
723 INTEGER :: k,err,iTIPO
724 CHARACTER,
POINTER :: cTIPO(:)
730 k = bit_size(itipo)/8
731 ALLOCATE(ctipo(k),stat = err)
733 CALL this%Error(
"GetEndianness_binary",
"Unable to allocate memory.")
738 itipo = transfer(ctipo, itipo)
741 IF (btest(itipo,1))
THEN 742 write(res,
'(A)',iostat=err)bigstr
744 write(res,
'(A)',iostat=err)littlestr
753 CLASS(fileio_binary),
INTENT(INOUT) :: this
759 CALL mpi_file_close(this%handle,this%error_io)
761 CLOSE(this%unit,iostat=err)
770 CLASS(fileio_binary),
INTENT(INOUT) :: this
773 CALL mpi_type_free(this%cfiletype,this%error_io)
774 CALL mpi_type_free(this%filetype,this%error_io)
776 CALL this%Finalize_base()
subroutine finalize(this)
Destructor of common class.
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
type(logging_base), save this
subroutine openfile(this, action)
Specific routine to open a file for binary I/O.
subroutine writekey(this, key, type, bytes, dims)
Writes key structure This subroutine writes the the key, data type and data sizes. It is defined as following (suppose 4B Integer) | 4B length of key | *B key | 4B data type | 4B data size in bytes | If the data type is a 2D,3D or 4D array, 2, 3 or 4 (4 Byte) integers are appended with the shape information. There storage is included in the data size field. Therefore without knowing the data types, one can jump over the data to the next key structure.
subroutine writeheader(this, Mesh, Physics, Header, IO)
Write the file header The header is written in ASCII and is 13 Byte long. First a "magic" identifier ...
logical function hascornerdims(this, Mesh, dims)
type(dict_typ) function, pointer, public getchild(root)
Get the pointer to a direct child of the pointer 'root'.
integer function, public getdatatype(root)
Return the datatype of node 'root'.
integer, parameter, public dict_real_fourd
subroutine writenode(this, Mesh, key, node)
subroutine closefile(this)
routine to close a file
logical function, public haschild(root)
Check if the node 'root' has one or more children.
recursive subroutine writedataattributes(this, Mesh, config, path)
Writes data attributes to a file.
integer, parameter, public dict_real_p
function, public getkey(root)
Get the key of pointer 'root'.
subroutine getendianness(this, res, littlestr, bigstr)
Determines the endianness of the system.
subroutine writedataset(this, Mesh, Physics, Fluxes, Timedisc, Header, IO)
Writes all desired data arrays to a file.
logical function hasmeshdims(this, Mesh, dims)
base class for geometrical properties
integer, parameter, public dict_real_threed
module for binary file I/O
integer, parameter, public readend
readonly access at end
integer, parameter, public dict_int_p
integer, parameter, public dict_real_twod
subroutine initfileio_binary(this, Mesh, Physics, Timedisc, Sources, config, IO)
Constructor for the binary file I/O.
type(dict_typ) function, pointer, public getnext(root)
Get the pointer to the next child.
integer, parameter, public dict_int
integer, parameter, public dict_real_fived
Dictionary for generic data types.
integer, parameter, public append
read/write access at end
integer, parameter, public dict_real
subroutine setmeshdims(this, Mesh, dims)
pointer, public getdata(root)
Return the datatype of node 'root'.
base module for numerical flux functions
integer, parameter, public readonly
readonly access
character, parameter lf
line feed