!> !> @file zappend.tpl !> !> @brief !> !> @copyright !> Copyright (©) 2021 EPFL (Ecole Polytechnique Fédérale de Lausanne) !> SPC (Swiss Plasma Center) !> !> futils is free software: you can redistribute it and/or modify it under !> the terms of the GNU Lesser General Public License as published by the Free !> Software Foundation, either version 3 of the License, or (at your option) !> any later version. !> !> futils is distributed in the hope that it will be useful, but WITHOUT ANY !> WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS !> FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. !> !> You should have received a copy of the GNU Lesser General Public License !> along with this program. If not, see . !> !> @authors !> (in alphabetical order) !> @author Trach-Minh Tran !> INTEGER, INTENT(in) :: fid CHARACTER(len=*), INTENT(in) :: name INTEGER, INTENT(in), OPTIONAL :: pardim INTEGER, INTENT(in), OPTIONAL :: ionode INTEGER, DIMENSION(:), INTENT(in), OPTIONAL :: offset ! INTEGER(HID_T) :: id, did, dspace_id, memspace_id, plist_id INTEGER(HSIZE_T), DIMENSION(SIZE(SHAPE(array))+1) :: & & dims, maxdims, starts, counts, offset_out INTEGER(HSIZE_T), DIMENSION(SIZE(SHAPE(array))) :: ddims INTEGER :: n, rank, rank_array, ierr INTEGER :: pdim, s, nlocal, nglobal LOGICAL :: nlio INTEGER(HID_T) :: realpart, impart ! id = file_id(fid) ! file id ! ! Am I the io node ? nlio = .TRUE. IF( ispara(fid) .AND. PRESENT(ionode) ) THEN ! Ignore "ionode" if not parallel IO nlio = mpi_rank(fid) .EQ. ionode END IF ! ! Data transfer property (default is H5FD_MPIO_INDEPENDENT_F) CALL h5pcreate_f(H5P_DATASET_XFER_F, plist_id, ierr) CALL h5pset_preserve_f(plist_id, .TRUE., ierr) ! ! Get dims/rank of dataset CALL h5dopen_f(id, name, did, ierr) CALL h5dget_space_f(did, dspace_id, ierr) CALL h5sget_simple_extent_dims_f(dspace_id, dims, maxdims, ierr) rank = ierr CALL h5sclose_f(dspace_id, ierr) ! ! Memory dataspace ddims = SHAPE(array) rank_array = SIZE(ddims) CALL h5screate_simple_f(rank_array, ddims, memspace_id, ierr) ! ! Determine slab of output array written counts(1:rank-1) = ddims(1:rank-1) IF( rank .EQ. rank_array ) THEN counts(rank) = ddims(rank_array) ELSE IF( rank .EQ. rank_array+1 ) THEN counts(rank) = 1 ELSE WRITE(*, '(a,a)') "Data shape mismatch for", name(1:LEN_TRIM(name)) WRITE(*,'(a,10i6)') 'rank, rank_array', rank, rank_array STOP END IF IF(PRESENT(offset)) THEN offset_out(1:rank-1) = offset(1:rank-1) offset_out(rank) = 0 ELSE offset_out = 0 END IF ! ! Extend the array in the time direction if writing a full slice. IF (.NOT.PRESENT(offset)) THEN dims(rank) = dims(rank) + counts(rank) CALL h5dextend_f(did, dims, ierr) CALL h5dget_space_f(did, dspace_id, ierr) END IF ! ! Starting coordinates for write starts(1:rank-1) = offset_out(1:rank-1) starts(rank) = dims(rank) - counts(rank) + offset_out(rank) ! ! Collective write partitionned array IF(ispara(fid) .AND. PRESENT(pardim) ) THEN ! Ignore "pardim" if not parallel IO pdim = pardim nlocal = ddims(pdim) CALL part1d( file_comm(fid), nlocal, s, nglobal) starts(pdim) = s CALL h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, ierr) END IF CALL h5dget_space_f(did, dspace_id, ierr) ! ! Write to the end of dataset CALL h5sselect_hyperslab_f(dspace_id, H5S_SELECT_SET_F, starts, counts, & & ierr) IF( nlio) THEN CALL mem_complex(H5T_NATIVE_DOUBLE, realpart, impart) temp = REAL(array) CALL h5dwrite_f(did, realpart, temp, ddims, ierr, memspace_id, & & dspace_id, plist_id) temp = AIMAG(array) CALL h5dwrite_f(did, impart, temp, ddims, ierr, memspace_id, dspace_id, & & plist_id) CALL h5tclose_f(realpart, ierr) CALL h5tclose_f(impart, ierr) END IF ! CALL h5pclose_f(plist_id, ierr) CALL h5dclose_f(did, ierr) CALL h5sclose_f(dspace_id, ierr) CALL h5sclose_f(memspace_id, ierr)