quantum-espresso/Modules/hdf5_qe.f90

1042 lines
38 KiB
Fortran

! Copyright (C) 2003-2016 Quantum ESPRESSO group
! This file is distributed under the terms of the
! GNU General Public License. See the file `License'
! in the root directory of the present distribution,
! or http://www.gnu.org/copyleft/gpl.txt .
!
#if defined(__HDF5) && defined (__MPI)
module hdf5_qe
!
!! This module contains some common subroutines used to read and write
!! in HDF5 format the data produced by Quantum ESPRESSO package.
!
!! Written by: Nicola Varini 2016
USE HDF5
USE, intrinsic :: ISO_C_binding
USE Kinds, ONLY : DP
implicit none
TYPE HDF5_type
INTEGER(HID_T) :: file_id ! File identifier
INTEGER(HID_T) :: dset_id ! Dataset identifier
INTEGER(HID_T) :: filespace ! Dataspace identifier in file
INTEGER(HID_T) :: memspace ! Dataspace identifier in memory
INTEGER(HID_T) :: plist_id ! Property list identifier
INTEGER(HID_T) :: group_id ! Group identifier
CHARACTER(LEN=40) :: dsetname ! Dataset name
INTEGER :: rank
INTEGER(HSIZE_T), DIMENSION(2) :: counts, counts_g, offset
INTEGER(HSIZE_T), DIMENSION(1:2) :: size
INTEGER(HID_T) :: crp_list ! Dataset creation property identifier
INTEGER :: comm
INTEGER(HSIZE_T), DIMENSION(1:2) :: maxdims
INTEGER(HSIZE_T), DIMENSION(1:2) :: chunk_dim
character(len=256) filename
END TYPE HDF5_type
TYPE(HDF5_type), save :: evc_hdf5, evc_hdf5_write, evq_hdf5_write
TYPE(HDF5_type), save :: rho_hdf5_write, eig_hdf5_write
TYPE(HDF5_type), save :: g_hdf5_write, gk_hdf5_write
INTEGER, save :: off_npw, npw_g, idone_debug
INTERFACE add_attributes_hdf5
MODULE PROCEDURE add_attributes_hdf5_i, add_attributes_hdf5_r, &
add_attributes_hdf5_c, add_attributes_hdf5_boolean
END INTERFACE
INTERFACE read_attributes_hdf5
MODULE PROCEDURE read_attributes_hdf5_i, read_attributes_hdf5_r, read_attributes_hdf5_c, &
read_attributes_hdf5_boolean
END INTERFACE
contains
subroutine initialize_hdf5()
implicit none
integer :: error
call h5open_f(error)
end subroutine initialize_hdf5
subroutine finalize_hdf5(hdf5desc)
implicit none
type(HDF5_type), intent(in) :: hdf5desc
integer :: error
call h5pclose_f(hdf5desc%plist_id,error)
call h5close_f(error)
end subroutine finalize_hdf5
subroutine h5_write_gvecs(hdf5desc, filename, nr1, nr2, nr3, ngm, gamma_only, mill)
implicit none
type (hdf5_type), intent(inout) :: hdf5desc
character(len=*), intent (in) :: filename
integer, intent(in) :: nr1, nr2, nr3, ngm
logical, intent(in) :: gamma_only
integer,intent(in) :: mill (3,ngm)
continue
end subroutine h5_write_gvecs
subroutine setup_file_property_hdf5(hdf5desc ,filename, hyperslab, write, kpoint, ierr )
use parallel_include
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
character(len=*), intent(inout) :: filename
integer,optional,intent(out) :: ierr
logical, intent(in) :: hyperslab, write
integer, intent(in) :: kpoint
integer(HID_T) :: plist_id
integer :: error, info
character*12 kstring
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
info = MPI_INFO_NULL
if(hyperslab .eqv. .true. ) then
#if !defined (__HDF5_SERIAL)
CALL h5pcreate_f(H5P_FILE_ACCESS_F, hdf5desc%plist_id, error) ! Properties for file creation
CALL h5pset_fapl_mpio_f(hdf5desc%plist_id, hdf5desc%comm, info, error) ! Stores MPI IO communicator information to the file access property list
if(kpoint.eq.1)then
CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, hdf5desc%file_id, error, access_prp = hdf5desc%plist_id) ! create the file collectively
else
CALL h5fopen_f(filename, H5F_ACC_RDWR_F, hdf5desc%file_id, error, access_prp = hdf5desc%plist_id) ! create the file collectively
endif
CALL h5pclose_f(hdf5desc%plist_id, error)
#endif
else
if(write .eqv. .true.)then
if(kpoint.eq.1)then
!CALL h5pcreate_f(H5P_FILE_ACCESS_F, hdf5desc%plist_id, error)
!CALL h5pset_fapl_mpio_f(hdf5desc%plist_id, hdf5desc%comm, info, error)
!CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, hdf5desc%file_id, error, access_prp=hdf5desc%plist_id) ! create the file collectively
CALL h5fcreate_f(filename, H5F_ACC_TRUNC_F, hdf5desc%file_id, error)
endif
else
CALL h5fopen_f(filename, H5F_ACC_RDWR_F, hdf5desc%file_id, error)
IF (PRESENT(ierr) ) THEN
ierr = error
ELSE IF (error /= 0) THEN
CALL errore ('setup_file_property_hdf5','error opening '//filename,error)
END IF
endif
endif
end subroutine setup_file_property_hdf5
subroutine define_dataset_hdf5_hyperslab(hdf5desc, kpoint)
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer,intent(in) :: kpoint
integer :: error
character*12 :: kstring
write(kstring,'(I0)') kpoint
kstring=trim('KPOINT')//kstring
hdf5desc%dsetname = 'evc'
CALL h5gcreate_f(hdf5desc%file_id, kstring, hdf5desc%group_id, error)
CALL h5screate_simple_f(hdf5desc%rank, hdf5desc%counts_g, hdf5desc%filespace, error) !define HDF5 dataset
CALL h5dcreate_f(hdf5desc%group_id, hdf5desc%dsetname, H5T_NATIVE_DOUBLE, hdf5desc%filespace, &
hdf5desc%dset_id, error)
CALL h5sclose_f(hdf5desc%filespace, error)
CALL h5dclose_f(hdf5desc%dset_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
end subroutine define_dataset_hdf5_hyperslab
#if !defined (__HDF5_SERIAL)
subroutine write_data_hdf5(hdf5desc, data, kpoint)
USE kinds, ONLY : DP
USE ISO_C_BINDING
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
complex(kind=dp), target, intent(inout) :: data(:,:)
integer, intent(in) :: kpoint
integer :: error, datadim1, datadim2
real(kind=dp) :: tmp
integer(HID_T) :: complex_id, double_id
integer(HSIZE_T) :: double_size, complex_size
TYPE(C_PTR) :: f_ptr
character*12 :: kstring
write(kstring,'(I0)') kpoint
kstring=trim('KPOINT')//kstring
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5dopen_f(hdf5desc%group_id, hdf5desc%dsetname, hdf5desc%dset_id, error)
CALL h5screate_simple_f(hdf5desc%rank, hdf5desc%counts, hdf5desc%memspace, error)
CALL h5dget_space_f(hdf5desc%dset_id, hdf5desc%filespace, error)
CALL h5sselect_hyperslab_f(hdf5desc%filespace, H5S_SELECT_SET_F, hdf5desc%offset, hdf5desc%counts, error) ! create hyperslab to read from more than 1 proc
CALL h5pcreate_f(H5P_DATASET_XFER_F, hdf5desc%plist_id, error)
CALL h5pset_dxpl_mpio_f(hdf5desc%plist_id, H5FD_MPIO_COLLECTIVE_F, error)
f_ptr = C_LOC(data(1,1))
CALL h5dwrite_f(hdf5desc%dset_id, H5T_NATIVE_DOUBLE, f_ptr, error,&
file_space_id = hdf5desc%filespace, mem_space_id = hdf5desc%memspace, &
xfer_prp = hdf5desc%plist_id)
CALL h5dclose_f(hdf5desc%dset_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
end subroutine write_data_hdf5
#endif
subroutine read_data_hdf5(hdf5desc, data, kpoint)
type(HDF5_type), intent(inout) :: hdf5desc
complex(kind=dp),target, intent(inout) :: data(:,:)
integer,intent(in) :: kpoint
integer :: error
TYPE(C_PTR) :: f_ptr
character*12 :: kstring
write(kstring,'(I0)') kpoint
kstring=trim('KPOINT')//kstring
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5dopen_f(hdf5desc%group_id, hdf5desc%dsetname, hdf5desc%dset_id, error)
CALL h5dget_space_f(hdf5desc%dset_id, hdf5desc%filespace, error)
CALL h5sselect_hyperslab_f(hdf5desc%filespace, H5S_SELECT_SET_F, hdf5desc%offset, hdf5desc%counts, error)
CALL h5screate_simple_f(hdf5desc%rank, hdf5desc%counts, hdf5desc%memspace, error)
f_ptr = C_LOC(data(1,1))
CALL H5dread_f(hdf5desc%dset_id, H5T_NATIVE_DOUBLE, f_ptr, error, &
mem_space_id = hdf5desc%memspace, file_space_id = hdf5desc%filespace ,&
xfer_prp = hdf5desc%plist_id)
CALL h5dclose_f(hdf5desc%dset_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
end subroutine read_data_hdf5
SUBROUTINE prepare_index_hdf5(sendm,recm,globalm,comm,nproc)
USE parallel_include
USE mp, ONLY : mp_sum
IMPLICIT NONE
INTEGER, INTENT(IN) :: comm, nproc
INTEGER, INTENT(INOUT) :: sendm, recm, globalm
INTEGER :: errore
call mpi_scan(sendm,recm,1,MPI_INTEGER,MPI_SUM,comm,errore)
recm=recm-sendm
globalm=sendm
call mp_sum(globalm,comm)
END SUBROUTINE prepare_index_hdf5
subroutine prepare_for_writing_final(hdf5desc,comm,filename_input,kpoint,add_group)
USE io_files, ONLY : wfc_dir, prefix, tmp_dir
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
character(len=*), intent(in):: filename_input
integer, intent(in) :: comm
integer, intent(in), optional :: kpoint
logical, intent(in), optional :: add_group
character(len=256) filename
integer :: ik, error
logical :: add_group_internal = .true.
character*12 kstring
hdf5desc%comm=comm
hdf5desc%filename=filename_input
if ( present (add_group) ) add_group_internal = add_group
if(present(kpoint)) then
write(kstring,'(I0)') kpoint
kstring=trim('KPOINT')//kstring
IF ( add_group_internal) THEN
CALL setup_file_property_hdf5(hdf5desc,hdf5desc%filename ,.false.,.true.,kpoint)
ELSE
CALL setup_file_property_hdf5(hdf5desc,hdf5desc%filename ,.false.,.true.,1)
END IF
CALL h5fopen_f(hdf5desc%filename, H5F_ACC_RDWR_F, hdf5desc%file_id, error) ! create the file collectively
CALL h5gcreate_f(hdf5desc%file_id, kstring, hdf5desc%group_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
else
CALL setup_file_property_hdf5(hdf5desc,hdf5desc%filename ,.false.,.true.,1)
endif
end subroutine prepare_for_writing_final
subroutine prepare_for_reading_final(hdf5desc,comm,filename_input,kpoint, ierr)
USE io_files, ONLY : wfc_dir, prefix, tmp_dir
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
character(len=*), intent(in):: filename_input
integer, intent(in) :: comm
integer, intent(in), optional :: kpoint
integer, intent(out), optional :: ierr
character(len=256) filename
integer :: ik, ierr_
hdf5desc%comm=comm
hdf5desc%rank =1
!filename = trim(filename_input) //".wfchdf5"
filename=filename_input
if(present(kpoint)) then
CALL setup_file_property_hdf5(hdf5desc,filename ,.false.,.false.,KPOINT = kpoint, IERR = ierr_ )
else
CALL setup_file_property_hdf5(hdf5desc,filename ,.false.,.false.,1, IERR = ierr_)
end if
IF (PRESENT (ierr)) THEN
ierr = ierr_
ELSE
IF ( ierr_ /= 0 ) CALL errore ('prepare_for_reading_final', 'error while opening h5 file for reading',ierr_)
END IF
end subroutine prepare_for_reading_final
subroutine read_rho_hdf5(hdf5desc,dsetname,var)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in) :: dsetname
real(kind=DP), target, intent(in) :: var(:)
INTEGER(HID_T) :: dspace_id, dset_id, dtype_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
character*12 dset_name
TYPE(C_PTR) :: f_ptr
write(dset_name,'(I0)') dsetname
dset_name='K'//dset_name
counts=size(var)
CALL h5dopen_f(hdf5desc%file_id, dset_name, dset_id, error)
CALL h5dget_type_f(dset_id, dtype_id, error)
f_ptr = C_LOC(var(1))
CALL h5dread_f(dset_id, dtype_id, f_ptr, error)
CALL h5dclose_f(dset_id, error)
end subroutine read_rho_hdf5
subroutine write_rho_hdf5(hdf5desc,dsetname,var)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in) :: dsetname
real(kind=DP), target, intent(in) :: var(:)
INTEGER(HID_T) :: dspace_id, dset_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
character*12 dset_name
TYPE(C_PTR) :: f_ptr
write(dset_name,'(I0)') dsetname
dset_name='K'//dset_name
counts=size(var)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%file_id, dset_name, H5T_NATIVE_DOUBLE, dspace_id, &
dset_id, error)
f_ptr = C_LOC(var(1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
end subroutine write_rho_hdf5
subroutine write_eig(hdf5desc,var,kpoint)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in) :: kpoint
real(kind=DP), target, intent(in) :: var(:)
INTEGER(HID_T) :: dspace_id, dset_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
TYPE(C_PTR) :: f_ptr
character*12 kstring
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
counts=size(var)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5dcreate_f(hdf5desc%group_id, kstring, H5T_NATIVE_DOUBLE, dspace_id, &
dset_id, error)
f_ptr = C_LOC(var(1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
end subroutine write_eig
subroutine read_eig(hdf5desc,var,kpoint)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in) :: kpoint
real(kind=DP), target, intent(inout) :: var(:)
INTEGER(HID_T) :: dtype_id, dset_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
TYPE(C_PTR) :: f_ptr
character*12 kstring
character*100 errmsg
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
counts=size(var)
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5dopen_f(hdf5desc%group_id, kstring, dset_id, error)
CALL h5dget_type_f(dset_id, dtype_id, error)
f_ptr = C_LOC(var(1))
!CALL h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, error)
CALL h5dread_f(dset_id, dtype_id, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
end subroutine read_eig
subroutine write_evc(hdf5desc,dsetname,var,kpoint)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in) :: dsetname
integer, intent(in), optional :: kpoint
complex(kind=DP), target, intent(in) :: var(:)
INTEGER(HID_T) :: dspace_id, dset_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
character*12 dset_name
TYPE(C_PTR) :: f_ptr
character*12 kstring
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
write(dset_name,'(I0)') dsetname
dset_name='BAND'//dset_name
counts=size(var)*2
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
if(present(kpoint))CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
if(present(kpoint)) then
CALL h5dcreate_f(hdf5desc%group_id, dset_name, H5T_NATIVE_DOUBLE, dspace_id, &
dset_id, error)
else
CALL h5dcreate_f(hdf5desc%file_id, dset_name, H5T_NATIVE_DOUBLE, dspace_id, &
dset_id, error)
endif
f_ptr = C_LOC(var(1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
if(present(kpoint))CALL h5gclose_f(hdf5desc%group_id, error)
end subroutine write_evc
subroutine read_evc(hdf5desc,dsetname,var,kpoint)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in) :: dsetname, kpoint
complex(kind=DP), target ,intent(inout) :: var(:)
INTEGER(HID_T) :: dtype_id, dset_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
character*12 dset_name
TYPE(C_PTR) :: f_ptr
character*12 kstring
character*100 errmsg
write(dset_name,'(I0)') dsetname
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
dset_name='BAND'//dset_name
counts=size(var)*2
CALL h5gopen_f(hdf5desc%file_id, kstring, hdf5desc%group_id, error)
!if(error.ne.0) call errore('error in h5gopen_f',' ',error)
CALL h5dopen_f(hdf5desc%group_id, dset_name, dset_id, error)
!if(error.ne.0) call errore('error in h5dopen_f',' ',error)
!CALL h5dget_type_f(dset_id, dtype_id, error)
f_ptr = C_LOC(var(1))
CALL h5dread_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, error)
if(error.ne.0) call errore('error in h5dread_f',' ',error)
!CALL h5dread_f(dset_id, dtype_id, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
end subroutine read_evc
subroutine write_g(hdf5desc,var,kpoint)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in), optional :: kpoint
integer, target, intent(in) :: var(:,:)
INTEGER(HID_T) :: dspace_id, dset_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
TYPE(C_PTR) :: f_ptr
character*12 kstring
counts=size(var,1)*size(var,2)
if(present(kpoint))then
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5dcreate_f(hdf5desc%group_id, kstring, H5T_NATIVE_INTEGER, dspace_id, &
dset_id, error)
f_ptr = C_LOC(var(1,1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
else
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%file_id, 'Miller indexes', H5T_NATIVE_INTEGER, dspace_id, &
dset_id, error)
f_ptr = C_LOC(var(1,1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
endif
end subroutine write_g
subroutine write_gkhdf5(hdf5desc,xk,igwk,mill_g,kpoint)
USE kinds, ONLY : DP
implicit none
type(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in), optional :: kpoint
real(kind=DP), target, intent(in) :: xk(:)
integer, target, intent(in) :: igwk(:), mill_g(:,:)
INTEGER(HID_T) :: dspace_id, dset_id ! Dataspace identifier
integer :: error
INTEGER(HSIZE_T), DIMENSION(1) :: counts
TYPE(C_PTR) :: f_ptr
character*12 kstring
if(present(kpoint))then
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
write(kstring,'(I0)') kpoint
kstring='xk'//kstring
counts=size(xk)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%group_id, kstring, H5T_NATIVE_DOUBLE, dspace_id, &
dset_id, error)
f_ptr = C_LOC(xk(1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
write(kstring,'(I0)') kpoint
kstring='igwk'//kstring
counts=size(igwk)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%group_id, kstring, H5T_NATIVE_INTEGER, dspace_id, &
dset_id, error)
f_ptr = C_LOC(igwk(1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
write(kstring,'(I0)') kpoint
kstring='mill_g'//kstring
counts=size(mill_g)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%group_id, kstring, H5T_NATIVE_INTEGER, dspace_id, &
dset_id, error)
f_ptr = C_LOC(mill_g(1,1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
else
counts=size(xk)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%file_id, 'xk', H5T_NATIVE_DOUBLE, dspace_id, &
dset_id, error)
f_ptr = C_LOC(xk(1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_DOUBLE, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
counts=size(igwk)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%file_id, 'igwk', H5T_NATIVE_INTEGER, dspace_id, &
dset_id, error)
f_ptr = C_LOC(igwk(1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
counts=size(mill_g)
CALL h5screate_simple_f(1, counts, dspace_id, error) !create the dataspace
CALL h5dcreate_f(hdf5desc%group_id, 'mill_g', H5T_NATIVE_INTEGER, dspace_id, &
dset_id, error)
f_ptr = C_LOC(mill_g(1,1))
CALL h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, f_ptr, error)
CALL h5dclose_f(dset_id, error)
CALL h5sclose_f(dspace_id, error)
endif
end subroutine write_gkhdf5
subroutine initialize_io_hdf5(hdf5desc,comm, data, write,kpoint)
USE io_files, ONLY : wfc_dir, prefix, tmp_dir
USE kinds, ONLY : dp
USE mp_world, ONLY : nproc
implicit none
TYPE(HDF5_type), intent(inout) :: hdf5desc
complex(kind=dp), intent(in) :: data(:,:)
integer, intent(in) :: comm, kpoint
logical, intent(in) :: write
character(len=80) :: filename
integer :: npwx, nbnd
npwx=size(data(:,1))
nbnd=size(data(1,:))
filename=trim(tmp_dir) //TRIM(prefix) //".wfchdf5"
call initialize_hdf5_array(hdf5desc,comm,npwx,nbnd)
if(write .eqv. .true.)then
CALL setup_file_property_hdf5(hdf5desc, filename,.true.,.true.,kpoint)
else
CALL setup_file_property_hdf5(hdf5desc, filename,.false.,.false.,kpoint)
endif
CALL prepare_index_hdf5(npwx,off_npw,npw_g,hdf5desc%comm,nproc)
CALL set_index_hdf5(hdf5desc,data,off_npw,npw_g,2)
end subroutine initialize_io_hdf5
subroutine initialize_hdf5_array(hdf5desc,comm,n1,n2)
implicit none
integer, intent(in) :: n1, n2, comm
type(HDF5_type), intent(inout) :: hdf5desc
hdf5desc%dsetname="evc"
hdf5desc%comm=comm
hdf5desc%rank =2
hdf5desc%chunk_dim=(/n1,n2/)
hdf5desc%size(1) = n1*2
hdf5desc%size(2) = n2
hdf5desc%offset(1) = 0
hdf5desc%offset(2) = 0
end subroutine initialize_hdf5_array
SUBROUTINE set_index_hdf5(hdf5desc, var, offset, nglobal,tsize)
USE kinds, only : DP
implicit none
COMPLEX(DP), intent(in) :: var(:,:)
type(HDF5_type), intent(inout) :: hdf5desc
INTEGER, intent(in) :: offset, nglobal,tsize
hdf5desc%counts(1) = size(var(:,1))*tsize
hdf5desc%counts(2) = size(var(1,:))
hdf5desc%counts_g(1) = nglobal*tsize
hdf5desc%counts_g(2) = size(var(1,:))
hdf5desc%offset(1) = offset*tsize
hdf5desc%offset(2) = 0
END SUBROUTINE set_index_hdf5
SUBROUTINE add_attributes_hdf5_i(hdf5desc, attr_data, attr_name, kpoint)
implicit none
TYPE(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in) :: attr_data
integer, intent(in),optional :: kpoint
CHARACTER(LEN=*), intent(in) :: attr_name
character*12 kstring
integer :: error
INTEGER :: arank = 1 ! Attribure rank
INTEGER(HID_T) :: aspace_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: adims = (/1/) ! Attribute dimension
INTEGER(SIZE_T) :: attrlen ! Length of the attribute string
INTEGER(HID_T) :: atype_id ! Attribute Dataspace identifier
INTEGER(HID_T) :: attr_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: data_dims
data_dims(1) = 1
if(present(kpoint)) then
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5screate_simple_f(arank, adims, aspace_id, error)
CALL h5acreate_f(hdf5desc%group_id, attr_name, H5T_NATIVE_INTEGER, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, H5T_NATIVE_INTEGER, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
!
! Terminate access to the data space.
!
CALL h5sclose_f(aspace_id, error)
!
! End access to the dataset and release resources used by it.
!
CALL h5gclose_f(hdf5desc%group_id, error)
else
CALL h5screate_simple_f(arank, adims, aspace_id, error)
CALL h5acreate_f(hdf5desc%file_id, attr_name, H5T_NATIVE_INTEGER, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, H5T_NATIVE_INTEGER, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
!
! Terminate access to the data space.
!
CALL h5sclose_f(aspace_id, error)
endif
END SUBROUTINE add_attributes_hdf5_i
SUBROUTINE add_attributes_hdf5_r(hdf5desc, attr_data, attr_name, kpoint)
implicit none
TYPE(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in), optional :: kpoint
real(DP), intent(in) :: attr_data
CHARACTER(LEN=*), intent(in) :: attr_name
character*12 kstring
integer :: error
INTEGER :: arank = 1 ! Attribure rank
INTEGER(HID_T) :: aspace_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: adims = (/1/) ! Attribute dimension
INTEGER(SIZE_T) :: attrlen ! Length of the attribute string
INTEGER(HID_T) :: atype_id ! Attribute Dataspace identifier
INTEGER(HID_T) :: attr_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: data_dims
data_dims(1) = 1
if(present(kpoint)) then
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5screate_simple_f(arank, adims, aspace_id, error)
CALL h5acreate_f(hdf5desc%group_id, attr_name, H5T_NATIVE_DOUBLE, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, H5T_NATIVE_DOUBLE, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
!
! Terminate access to the data space.
!
CALL h5sclose_f(aspace_id, error)
!
! End access to the dataset and release resources used by it.
!
CALL h5gclose_f(hdf5desc%group_id, error)
else
CALL h5screate_simple_f(arank, adims, aspace_id, error)
CALL h5acreate_f(hdf5desc%file_id, attr_name, H5T_NATIVE_DOUBLE, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, H5T_NATIVE_DOUBLE, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
!
! Terminate access to the data space.
!
CALL h5sclose_f(aspace_id, error)
!
! End access to the dataset and release resources used by it.
!
endif
END SUBROUTINE add_attributes_hdf5_r
SUBROUTINE add_attributes_hdf5_c(hdf5desc, attr_data, attr_name, kpoint)
IMPLICIT NONE
TYPE(HDF5_type), intent(inout) :: hdf5desc
INTEGER, INTENT(IN), OPTIONAL :: kpoint
CHARACTER(LEN=*),TARGET, INTENT(IN) :: attr_data
CHARACTER(LEN=*), intent(in) :: attr_name
CHARACTER*100 kstring
INTEGER :: error
INTEGER :: arank = 1 ! Attribure rank
INTEGER(HID_T) :: aspace_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T) :: attrlen ! Length of the attribute string
INTEGER(HID_T) :: atype_id ! Attribute Dataspace identifier
INTEGER(HID_T) :: attr_id ! Attribute Dataspace identifier
TYPE(C_PTR) :: buf
!
buf = C_LOC(attr_data)
attrlen = LEN(TRIM(attr_data) )
CALL H5Screate_f( H5S_SCALAR_F, aspace_id, error)
CALL H5Tcopy_f ( H5T_FORTRAN_S1, atype_id, error )
CALL H5Tset_size_f( atype_id, attrlen, error)
IF(PRESENT(kpoint)) THEN
WRITE(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
!write(attrdata,'(I0)') attr_data
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5acreate_f(hdf5desc%group_id, attr_name, atype_id, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, atype_id, buf, error)
CALL h5aclose_f(attr_id, error)
!
! End access to the dataset and release resources used by it.
!
CALL h5gclose_f(hdf5desc%group_id, error)
ELSE
!write(attrdata,'(I0)') attr_data
CALL h5acreate_f(hdf5desc%file_id, attr_name, atype_id, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, atype_id, buf, error)
CALL h5aclose_f(attr_id, error)
!
! Terminate access to the data space.
!
ENDIF
CALL H5Sclose_f(aspace_id, error)
CALL H5Tclose_f(atype_id, error )
END SUBROUTINE add_attributes_hdf5_c
!
SUBROUTINE add_attributes_hdf5_boolean(hdf5desc, attr_data, attr_name, kpoint)
IMPLICIT NONE
TYPE(HDF5_type), intent(inout) :: hdf5desc
INTEGER, INTENT(IN), OPTIONAL :: kpoint
LOGICAL,INTENT(IN) :: attr_data
CHARACTER(LEN=*), intent(in) :: attr_name
CHARACTER*100 kstring
INTEGER :: error
INTEGER :: arank = 1 ! Attribure rank
INTEGER(HID_T) :: aspace_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T) :: attrlen ! Length of the attribute string
INTEGER(HID_T) :: atype_id ! Attribute Dataspace identifier
INTEGER(HID_T) :: attr_id ! Attribute Dataspace identifier
CHARACTER(LEN=7),TARGET :: string_data
TYPE(C_PTR) :: buf
!
IF (attr_data) THEN
string_data = '.TRUE.'
ELSE
string_data ='.FALSE.'
END IF
buf = C_LOC(string_data)
attrlen = LEN(TRIM(string_data) )
CALL H5Screate_f( H5S_SCALAR_F, aspace_id, error)
CALL H5Tcopy_f ( H5T_FORTRAN_S1, atype_id, error )
CALL H5Tset_size_f( atype_id, attrlen, error)
IF(PRESENT(kpoint)) THEN
WRITE(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
!write(attrdata,'(I0)') attr_data
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5acreate_f(hdf5desc%group_id, attr_name, atype_id, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, atype_id, buf, error)
CALL h5aclose_f(attr_id, error)
!
! End access to the dataset and release resources used by it.
!
CALL h5gclose_f(hdf5desc%group_id, error)
ELSE
!write(attrdata,'(I0)') attr_data
CALL h5acreate_f(hdf5desc%file_id, attr_name, atype_id, aspace_id, attr_id, error)
CALL h5awrite_f(attr_id, atype_id, buf, error)
CALL h5aclose_f(attr_id, error)
!
! Terminate access to the data space.
!
ENDIF
CALL H5Sclose_f(aspace_id, error)
CALL H5Tclose_f(atype_id, error )
END SUBROUTINE add_attributes_hdf5_boolean
SUBROUTINE read_attributes_hdf5_i(hdf5desc, attr_data, attr_name, kpoint, debug)
implicit none
TYPE(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in), optional :: kpoint, debug
integer, intent(out) :: attr_data
CHARACTER(LEN=*), intent(in) :: attr_name
character*12 kstring
integer :: error
INTEGER :: arank = 1 ! Attribure rank
INTEGER(HID_T) :: aspace_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: adims = (/1/) ! Attribute dimension
INTEGER(SIZE_T) :: attrlen ! Length of the attribute string
INTEGER(HID_T) :: atype_id ! Attribute Dataspace identifier
INTEGER(HID_T) :: attr_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: data_dims
data_dims(1) = 1
attrlen = 1
if(present(kpoint))then
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5aopen_name_f(hdf5desc%group_id,attr_name,attr_id,error)
CALL h5aread_f(attr_id, H5T_NATIVE_INTEGER, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
else
CALL h5aopen_name_f(hdf5desc%file_id,attr_name,attr_id,error)
CALL h5aget_type_f(attr_id, atype_id, error)
CALL h5aread_f(attr_id, atype_id, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
endif
END SUBROUTINE read_attributes_hdf5_i
SUBROUTINE read_attributes_hdf5_c(hdf5desc, attr_data, attr_name, kpoint, debug)
implicit none
TYPE(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in), optional :: kpoint, debug
CHARACTER(LEN=*),INTENT(OUT) :: attr_data
CHARACTER(LEN=*), intent(in) :: attr_name
character*12 kstring
integer :: error
INTEGER(HID_T) :: aspace_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T) :: attrlen ! Length of the attribute string
INTEGER(HID_T) :: atype_id ! Attribute Dataspace identifier
INTEGER(HID_T) :: attr_id ! Attribute Dataspace identifier
CHARACTER,TARGET,ALLOCATABLE :: chars(:)
TYPE(C_PTR) :: buf
IF(PRESENT( kpoint )) THEN
WRITE(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
CALL H5Gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL H5Aopen_by_name_f(hdf5desc%group_id,'.', TRIM(attr_name) , attr_id, error)
CALL extract_string
CALL H5Aclose_f(attr_id, error)
CALL H5Gclose_f(hdf5desc%group_id, error)
ELSE
CALL h5aopen_by_name_f(hdf5desc%file_id,'.',TRIM(attr_name), attr_id, error)
CALL extract_string
CALL h5aclose_f(attr_id, error)
ENDIF
CALL H5Tclose_f( atype_id, error )
CONTAINS
SUBROUTINE extract_string
IMPLICIT NONE
INTEGER :: i
CALL H5Aget_type_f (attr_id , atype_id, error )
CALL H5Tget_size_f (atype_id, attrlen, error )
IF ( attrlen .GT. LEN(attr_data) ) CALL infomsg ('read_attributes_hdf5',&
'string attribute on file too long, it will be truncated on reading')
ALLOCATE ( chars(attrlen) )
buf = C_LOC (chars)
CALL H5Aread_f( attr_id, atype_id, buf, error )
DO i =1, attrlen
IF ( i .GT. LEN( attr_data) ) EXIT
attr_data(i:i) = chars(i)
END DO
DEALLOCATE(chars)
buf = C_NULL_PTR
END SUBROUTINE extract_string
END SUBROUTINE read_attributes_hdf5_c
SUBROUTINE read_attributes_hdf5_boolean( hdf5desc, attr_data, attr_name, kpoint, debug)
IMPLICIT NONE
TYPE(HDF5_type), intent(inout) :: hdf5desc
INTEGER, INTENT(IN), OPTIONAL :: kpoint, debug
LOGICAL,INTENT(OUT) :: attr_data
CHARACTER(LEN=*), intent(in) :: attr_name
!
CHARACTER(LEN=10) :: attr_string
CALL read_attributes_hdf5_c( hdf5desc, attr_string, attr_name, kpoint, debug)
SELECT CASE (TRIM( attr_string) )
CASE ('.TRUE.' )
attr_data = .TRUE.
CASE ('.FALSE.')
attr_data = .FALSE.
CASE DEFAULT
attr_data = .FALSE.
CALL infomsg ( 'read_attributes_hdf5' , 'error reading attribute '//TRIM(attr_name)//' value set to .FALSE.')
END SELECT
END SUBROUTINE read_attributes_hdf5_boolean
SUBROUTINE read_attributes_hdf5_r(hdf5desc, attr_data, attr_name, kpoint)
implicit none
TYPE(HDF5_type), intent(inout) :: hdf5desc
integer, intent(in), optional :: kpoint
real(DP), intent(out) :: attr_data
CHARACTER(LEN=*), intent(in) :: attr_name
character*12 kstring
integer :: error
INTEGER :: arank = 1 ! Attribure rank
INTEGER(HID_T) :: aspace_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: adims = (/1/) ! Attribute dimension
INTEGER(SIZE_T) :: attrlen ! Length of the attribute string
INTEGER(HID_T) :: atype_id ! Attribute Dataspace identifier
INTEGER(HID_T) :: attr_id ! Attribute Dataspace identifier
INTEGER(HSIZE_T), DIMENSION(1) :: data_dims
data_dims(1) = 1
attrlen = 1
if(present(kpoint))then
write(kstring,'(I0)') kpoint
kstring='KPOINT'//kstring
CALL h5gopen_f(hdf5desc%file_id,kstring,hdf5desc%group_id,error)
CALL h5aopen_name_f(hdf5desc%group_id,attr_name,attr_id,error)
CALL h5aread_f(attr_id, H5T_NATIVE_DOUBLE, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
CALL h5gclose_f(hdf5desc%group_id, error)
else
CALL h5aopen_name_f(hdf5desc%file_id,attr_name,attr_id,error)
CALL h5aread_f(attr_id, H5T_NATIVE_DOUBLE, attr_data, data_dims, error)
CALL h5aclose_f(attr_id, error)
endif
END SUBROUTINE read_attributes_hdf5_r
SUBROUTINE hdf5_close(hdf5desc)
implicit none
TYPE(HDF5_type), intent(inout) :: hdf5desc
integer :: errore
CALL h5fclose_f(hdf5desc%file_id,errore)
END SUBROUTINE hdf5_close
SUBROUTINE write_attributes(hdf5desc, ngw, gamma_only, igwx, &
nbnd, ik, nk, ispin, nspin, scalef)
implicit none
INTEGER, INTENT(IN) :: ik, nk, ispin, nspin
REAL(DP), INTENT(IN) :: scalef
LOGICAL, INTENT(IN) :: gamma_only
INTEGER, INTENT(IN) :: nbnd, ngw, igwx
TYPE(HDF5_type), intent(inout) :: hdf5desc
CALL add_attributes_hdf5(hdf5desc,ngw,"ngw",ik)
CALL add_attributes_hdf5(evc_hdf5_write,gamma_only,"gamma_only",ik)
CALL add_attributes_hdf5(evc_hdf5_write,igwx,"igwx",ik)
CALL add_attributes_hdf5(evc_hdf5_write,nbnd,"nbnd",ik)
CALL add_attributes_hdf5(evc_hdf5_write,ik,"ik",ik)
CALL add_attributes_hdf5(evc_hdf5_write,nk,"nk",ik)
CALL add_attributes_hdf5(evc_hdf5_write,ispin,"ispin",ik)
CALL add_attributes_hdf5(evc_hdf5_write,nspin,"nspin",ik)
CALL add_attributes_hdf5(evc_hdf5_write,scalef,"scale_factor",ik)
END SUBROUTINE write_attributes
end module hdf5_qe
#else
module hdf5_qe
implicit none
integer :: pippo
end module hdf5_qe
#endif