mirror of https://gitlab.com/QEF/q-e.git
293 lines
11 KiB
Fortran
293 lines
11 KiB
Fortran
!
|
|
! Copyright (C) 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 .
|
|
!
|
|
!----------------------------------------------------------------------------
|
|
MODULE io_base
|
|
!----------------------------------------------------------------------------
|
|
!
|
|
! ... this module contains some common subroutines used to read and write
|
|
! ... data produced by the Quantum ESPRESSO package
|
|
!
|
|
USE iotk_module
|
|
!
|
|
USE kinds, ONLY : DP
|
|
USE io_files, ONLY : tmp_dir, prefix, iunpun, xmlpun
|
|
USE io_global, ONLY : stdout
|
|
!
|
|
IMPLICIT NONE
|
|
!
|
|
CHARACTER(iotk_attlenx) :: attr
|
|
!
|
|
PRIVATE
|
|
PUBLIC :: write_wfc, read_wfc
|
|
!
|
|
CONTAINS
|
|
!
|
|
!------------------------------------------------------------------------
|
|
SUBROUTINE write_wfc( iuni, ik, nk, ispin, nspin, wfc, ngw, &
|
|
gamma_only, nbnd, igl, ngwl, filename, scalef, &
|
|
ionode_in_group, root_in_group, intra_group_comm)
|
|
!------------------------------------------------------------------------
|
|
!
|
|
USE mp_wave, ONLY : mergewf
|
|
USE mp, ONLY : mp_size, mp_rank, mp_max
|
|
!
|
|
#if defined __HDF5
|
|
USE hdf5_qe, ONLY : prepare_for_writing_final, add_attributes_hdf5, &
|
|
write_evc, h5fclose_f, evc_hdf5_write
|
|
USE mp_pools, ONLY : inter_pool_comm ! FIXME: must disappear
|
|
USE HDF5
|
|
#endif
|
|
|
|
IMPLICIT NONE
|
|
!
|
|
INTEGER, INTENT(IN) :: iuni
|
|
INTEGER, INTENT(IN) :: ik, nk, ispin, nspin
|
|
COMPLEX(DP), INTENT(IN) :: wfc(:,:)
|
|
INTEGER, INTENT(IN) :: ngw
|
|
LOGICAL, INTENT(IN) :: gamma_only
|
|
INTEGER, INTENT(IN) :: nbnd
|
|
INTEGER, INTENT(IN) :: ngwl
|
|
INTEGER, INTENT(IN) :: igl(:)
|
|
CHARACTER(LEN=*), INTENT(IN) :: filename
|
|
REAL(DP), INTENT(IN) :: scalef
|
|
! scale factor, usually 1.0 for pw and 1/SQRT( omega ) for CP
|
|
LOGICAL, INTENT(IN) :: ionode_in_group
|
|
INTEGER, INTENT(IN) :: root_in_group, intra_group_comm
|
|
!
|
|
INTEGER :: j, ierr
|
|
INTEGER :: igwx, npwx, npol
|
|
INTEGER :: me_in_group, nproc_in_group, my_group
|
|
COMPLEX(DP), ALLOCATABLE :: wtmp(:)
|
|
!
|
|
INTEGER :: gammaonly
|
|
|
|
me_in_group = mp_rank( intra_group_comm )
|
|
nproc_in_group = mp_size( intra_group_comm )
|
|
!
|
|
igwx = MAXVAL( igl(1:ngwl) )
|
|
CALL mp_max( igwx, intra_group_comm )
|
|
npol = 1
|
|
IF ( nspin == 4 ) npol = 2
|
|
npwx = SIZE( wfc, 1 ) / npol
|
|
ALLOCATE( wtmp( MAX( npol*igwx, 1 ) ) )
|
|
!
|
|
wtmp = 0.0_DP
|
|
!
|
|
IF ( ionode_in_group ) THEN
|
|
#if defined __HDF5
|
|
CALL prepare_for_writing_final ( evc_hdf5_write, inter_pool_comm, &
|
|
TRIM(filename)//'.hdf5',ik)
|
|
CALL add_attributes_hdf5(evc_hdf5_write,ngw,"ngw",ik)
|
|
gammaonly = 0
|
|
IF (gamma_only) gammaonly = 1
|
|
CALL add_attributes_hdf5(evc_hdf5_write,gammaonly,"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)
|
|
!
|
|
#else
|
|
!
|
|
CALL iotk_open_write( iuni, FILE = TRIM(filename)//'.dat', &
|
|
ROOT="WFC", BINARY = .TRUE. )
|
|
!
|
|
CALL iotk_write_attr( attr, "ngw", ngw, FIRST = .TRUE. )
|
|
CALL iotk_write_attr( attr, "igwx", igwx )
|
|
CALL iotk_write_attr( attr, "gamma_only", gamma_only )
|
|
CALL iotk_write_attr( attr, "nbnd", nbnd )
|
|
CALL iotk_write_attr( attr, "ik", ik )
|
|
CALL iotk_write_attr( attr, "nk", nk )
|
|
CALL iotk_write_attr( attr, "ispin", ispin )
|
|
CALL iotk_write_attr( attr, "nspin", nspin )
|
|
CALL iotk_write_attr( attr, "scale_factor", scalef )
|
|
!
|
|
CALL iotk_write_empty( iuni, "INFO", attr )
|
|
#endif
|
|
!
|
|
END IF
|
|
!
|
|
DO j = 1, nbnd
|
|
!
|
|
IF ( npol == 2 ) THEN
|
|
!
|
|
! Quick-and-dirty noncolinear case - mergewf should be modified
|
|
!
|
|
CALL mergewf( wfc(1:npwx, j), wtmp(1:igwx), ngwl, igl,&
|
|
me_in_group, nproc_in_group, root_in_group, intra_group_comm )
|
|
CALL mergewf( wfc(npwx+1:2*npwx,j), wtmp(igwx+1:2*igwx), ngwl, igl,&
|
|
me_in_group, nproc_in_group, root_in_group, intra_group_comm )
|
|
!
|
|
ELSE
|
|
!
|
|
CALL mergewf( wfc(:,j), wtmp, ngwl, igl, me_in_group, &
|
|
nproc_in_group, root_in_group, intra_group_comm )
|
|
!
|
|
END IF
|
|
!
|
|
IF ( ionode_in_group ) &
|
|
#ifdef __HDF5
|
|
CALL write_evc(evc_hdf5_write,j, wtmp(1:npol*igwx), ik)
|
|
#else
|
|
CALL iotk_write_dat &
|
|
( iuni, "evc" // iotk_index( j ), wtmp(1:npol*igwx))
|
|
#endif
|
|
!
|
|
END DO
|
|
IF ( ionode_in_group ) &
|
|
#if defined __HDF5
|
|
CALL h5fclose_f(evc_hdf5_write%file_id, ierr)
|
|
#else
|
|
CALL iotk_close_write( iuni )
|
|
#endif
|
|
!
|
|
DEALLOCATE( wtmp )
|
|
!
|
|
RETURN
|
|
!
|
|
END SUBROUTINE write_wfc
|
|
!
|
|
!------------------------------------------------------------------------
|
|
SUBROUTINE read_wfc( iuni, ik, nk, ispin, nspin, wfc, ngw, nbnd, &
|
|
igl, ngwl, filename, scalef, &
|
|
ionode_in_group, root_in_group, intra_group_comm)
|
|
!------------------------------------------------------------------------
|
|
!
|
|
USE mp_wave, ONLY : splitwf
|
|
USE mp, ONLY : mp_bcast, mp_size, mp_rank, mp_max
|
|
!
|
|
#if defined __HDF5
|
|
USE hdf5_qe
|
|
#endif
|
|
|
|
IMPLICIT NONE
|
|
!
|
|
INTEGER, INTENT(IN) :: iuni
|
|
COMPLEX(DP), INTENT(OUT) :: wfc(:,:)
|
|
INTEGER, INTENT(IN) :: ik, nk
|
|
INTEGER, INTENT(INOUT) :: ngw, nbnd, ispin, nspin
|
|
INTEGER, INTENT(IN) :: ngwl
|
|
INTEGER, INTENT(IN) :: igl(:)
|
|
CHARACTER(LEN=*), INTENT(IN) :: filename
|
|
REAL(DP), INTENT(OUT) :: scalef
|
|
LOGICAL, INTENT(IN) :: ionode_in_group
|
|
INTEGER, INTENT(IN) :: root_in_group, intra_group_comm
|
|
!
|
|
INTEGER :: j
|
|
COMPLEX(DP), ALLOCATABLE :: wtmp(:)
|
|
INTEGER :: ierr
|
|
INTEGER :: igwx, igwx_, npwx, npol, ik_, nk_
|
|
INTEGER :: me_in_group, nproc_in_group
|
|
!
|
|
!
|
|
me_in_group = mp_rank( intra_group_comm )
|
|
nproc_in_group = mp_size( intra_group_comm )
|
|
!
|
|
igwx = MAXVAL( igl(1:ngwl) )
|
|
CALL mp_max( igwx, intra_group_comm )
|
|
!
|
|
ierr = 0
|
|
!
|
|
#if !defined __HDF5
|
|
IF ( ionode_in_group ) CALL iotk_open_read( iuni, &
|
|
FILE = TRIM(filename)//'.dat', BINARY = .TRUE., IERR = ierr )
|
|
!
|
|
CALL mp_bcast( ierr, root_in_group, intra_group_comm )
|
|
CALL errore( 'read_wfc ', &
|
|
'cannot open restart file for reading', ierr )
|
|
!
|
|
#endif
|
|
IF ( ionode_in_group ) THEN
|
|
!
|
|
#if defined __HDF5
|
|
CALL prepare_for_reading_final(evc_hdf5_write,evc_hdf5_write%comm, &
|
|
TRIM(filename)//'.hdf5',ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,ngw,"ngw",ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,nbnd,"nbnd",ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,ik_,"ik",ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,nk_,"ik",ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,ispin,"ispin",ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,nspin,"nspin",ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,igwx_,"igwx",ik)
|
|
CALL read_attributes_hdf5(evc_hdf5_write,scalef,"scale_factor",ik)
|
|
#else
|
|
CALL iotk_scan_empty( iuni, "INFO", attr )
|
|
!
|
|
CALL iotk_scan_attr( attr, "ngw", ngw )
|
|
CALL iotk_scan_attr( attr, "nbnd", nbnd )
|
|
CALL iotk_scan_attr( attr, "ik", ik_ )
|
|
CALL iotk_scan_attr( attr, "nk", nk_ )
|
|
CALL iotk_scan_attr( attr, "ispin", ispin )
|
|
CALL iotk_scan_attr( attr, "nspin", nspin )
|
|
CALL iotk_scan_attr( attr, "igwx", igwx_ )
|
|
CALL iotk_scan_attr( attr, "scale_factor", scalef )
|
|
!
|
|
#endif
|
|
END IF
|
|
!
|
|
CALL mp_bcast( ngw, root_in_group, intra_group_comm )
|
|
CALL mp_bcast( nbnd, root_in_group, intra_group_comm )
|
|
CALL mp_bcast( ik_, root_in_group, intra_group_comm )
|
|
CALL mp_bcast( nk_, root_in_group, intra_group_comm )
|
|
CALL mp_bcast( ispin, root_in_group, intra_group_comm )
|
|
CALL mp_bcast( nspin, root_in_group, intra_group_comm )
|
|
CALL mp_bcast( igwx_, root_in_group, intra_group_comm )
|
|
CALL mp_bcast( scalef, root_in_group, intra_group_comm )
|
|
!
|
|
npol = 1
|
|
IF ( nspin == 4 ) npol = 2
|
|
ALLOCATE( wtmp( npol*MAX( igwx_, igwx ) ) )
|
|
npwx = SIZE( wfc, 1 ) / npol
|
|
!
|
|
DO j = 1, nbnd
|
|
!
|
|
IF ( j <= SIZE( wfc, 2 ) ) THEN
|
|
!
|
|
IF ( ionode_in_group ) THEN
|
|
#if defined __HDF5
|
|
CALL read_evc(evc_hdf5_write,j,wtmp(1:npol*igwx_),ik)
|
|
#else
|
|
CALL iotk_scan_dat( iuni, &
|
|
"evc" // iotk_index(j), wtmp(1:npol*igwx_) )
|
|
|
|
#endif
|
|
!
|
|
IF ( igwx > igwx_ ) wtmp((npol*igwx_+1):npol*igwx) = 0.0_DP
|
|
!
|
|
END IF
|
|
!
|
|
IF ( npol == 2 ) THEN
|
|
CALL splitwf( wfc(1:npwx, j), wtmp(1:igwx_ ), &
|
|
ngwl, igl, me_in_group, nproc_in_group, root_in_group, &
|
|
intra_group_comm )
|
|
CALL splitwf( wfc(npwx+1:2*npwx,j), wtmp(igwx_+1:2*igwx_), &
|
|
ngwl, igl, me_in_group, nproc_in_group, root_in_group, &
|
|
intra_group_comm )
|
|
ELSE
|
|
CALL splitwf( wfc(:,j), wtmp, ngwl, igl, me_in_group, &
|
|
nproc_in_group, root_in_group, intra_group_comm )
|
|
END IF
|
|
!
|
|
END IF
|
|
!
|
|
END DO
|
|
!
|
|
#if !defined __HDF5
|
|
IF ( ionode_in_group ) CALL iotk_close_read( iuni )
|
|
#endif
|
|
!
|
|
DEALLOCATE( wtmp )
|
|
!
|
|
RETURN
|
|
!
|
|
END SUBROUTINE read_wfc
|
|
!
|
|
END MODULE io_base
|