quantum-espresso/Modules/xml_io_rism.f90

1554 lines
48 KiB
Fortran

!
! Copyright (C) 2015-2016 Satomichi Nishihara
!
! 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 xml_io_rism
!----------------------------------------------------------------------------
!
! ... this module contains subroutines used to read and write
! ... 1D- and 3D-RISM data in XML format
!
#if defined(__fox)
USE FoX_dom
USE FoX_wxml
#else
USE dom
USE wxml
#endif
USE constants, ONLY : eps8
USE fft_types, ONLY : fft_type_descriptor
USE io_files, ONLY : check_file_exist
USE kinds, ONLY : DP
USE lauefft, ONLY : lauefft_type
USE mp, ONLY : mp_rank, mp_sum, mp_get, mp_bcast, mp_barrier
USE parallel_include
!
IMPLICIT NONE
SAVE
PRIVATE
!
! ... public components
PUBLIC :: read_1drism_xml
PUBLIC :: write_1drism_xml
PUBLIC :: read_3drism_xml
PUBLIC :: write_3drism_xml
PUBLIC :: read_lauerism_xml
PUBLIC :: write_lauerism_xml
PUBLIC :: read_lauedipole_xml
PUBLIC :: write_lauedipole_xml
PUBLIC :: read_lauegxy0_xml
PUBLIC :: write_lauegxy0_xml
!
CONTAINS
!
!------------------------------------------------------------------------
SUBROUTINE write_1drism_xml(rism1d_file_base, zvv, name, ngrid, &
& nsite, ipp, npp, ionode, intra_group_comm)
!------------------------------------------------------------------------
!
! ... Writes 1D-RISM's correlation function, one site at a time.
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rism1d_file_base
REAL(DP), INTENT(IN) :: zvv(:,:)
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER, INTENT(IN) :: ngrid
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: ipp(:)
INTEGER, INTENT(IN) :: npp(:)
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: intra_group_comm
!
TYPE(xmlf_t) :: xf
INTEGER :: ierr
INTEGER :: isite
CHARACTER(LEN=8) :: isitestr
INTEGER :: rism1d_unit
CHARACTER(LEN=256) :: rism1d_file
CHARACTER(LEN=10) :: rism1d_extension
INTEGER :: io_group
INTEGER :: me_group
REAL(DP), ALLOCATABLE :: zvv1(:)
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
!
! ... decide file name and unit
rism1d_extension = '.xml'
!
rism1d_file = TRIM(rism1d_file_base) // TRIM(rism1d_extension)
rism1d_unit = find_free_unit()
!
! ... open file
IF (ionode) THEN
CALL xml_OpenFile (filename = TRIM(rism1d_file), XF = xf, UNIT = rism1d_unit, PRETTY_PRINT =.true., &
& REPLACE = .true., NAMESPACE = .true., IOSTAT = ierr)
CALL errore('write_1drism_xml', &
& 'cannot open ' // TRIM(rism1d_file) // ' file for writing', ierr)
END IF
!
! ... write header
IF (ionode) THEN
CALL xml_newElement(xf, "_1D-RISM")
!
CALL xml_NewElement(xf, "INFO")
CALL xml_AddAttribute(xf, "name", TRIM(name))
CALL xml_AddAttribute(xf, "ngrid", ngrid)
CALL xml_AddAttribute(xf, "nsite", nsite)
CALL xml_EndElement(xf, "INFO")
END IF
!
! ... find the index of the ionode
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
!
! ... write zvv for each site
ALLOCATE(zvv1(ngrid))
!
DO isite = 1, nsite
#if defined (__MPI)
CALL MPI_GATHERV(zvv(1, isite), npp(me_group + 1), &
& MPI_DOUBLE_PRECISION, zvv1, npp, ipp, &
& MPI_DOUBLE_PRECISION, io_group, intra_group_comm, ierr)
!
IF (ierr /= MPI_SUCCESS) THEN
CALL errore('write_1drism_xml', 'error at MPI_GATHERV', 1)
END IF
#else
zvv1(1:ngrid) = zvv(1:ngrid, isite)
#endif
!
IF (ionode) THEN
WRITE(isitestr,'(I0)') isite
CALL xml_NewElement(xf, "site." // TRIM(isitestr))
CALL xml_AddCharacters(xf, zvv1)
CALL xml_EndElement(xf, "site." // TRIM(isitestr))
END IF
END DO
!
DEALLOCATE(zvv1)
!
! ... close file
IF (ionode) THEN
CALL xml_EndElement(xf, "_1D-RISM")
CALL xml_Close(xf)
END IF
!
END SUBROUTINE write_1drism_xml
!
!------------------------------------------------------------------------
SUBROUTINE read_1drism_xml(rism1d_file_base, zvv, ngrid, &
& nsite, ipp, npp, ionode, ionode_id, intra_group_comm)
!------------------------------------------------------------------------
!
! ... Reads 1D-RISM's correlation function, one site at a time.
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rism1d_file_base
REAL(DP), INTENT(OUT) :: zvv(:,:)
INTEGER, INTENT(IN) :: ngrid
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: ipp(:)
INTEGER, INTENT(IN) :: npp(:)
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: ionode_id
INTEGER, INTENT(IN) :: intra_group_comm
!
TYPE(Node), POINTER :: doc
TYPE(Node), POINTER :: rismNode,infoNode,siteNode
TYPE(DOMException) :: ex
INTEGER :: ierr
INTEGER :: isite
CHARACTER(LEN=8) :: isitestr
CHARACTER(LEN=256) :: rism1d_file
INTEGER :: ngrid_
INTEGER :: nsite_
INTEGER :: io_group
INTEGER :: me_group
LOGICAL :: exist
REAL(DP), ALLOCATABLE :: zvv1(:)
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
!
! ... search file
rism1d_file = TRIM(rism1d_file_base) // ".xml"
exist = check_file_exist_1drism(TRIM(rism1d_file), ionode, ionode_id, intra_group_comm)
!
IF (.NOT. exist) THEN
CALL errore('read_1drism_xml', 'searching for ' // TRIM(rism1d_file), 10)
END IF
!
! ... open file
IF (ionode) THEN
doc => parseFile(TRIM(rism1d_file), EX=ex)
ierr = getExceptionCode(ex)
CALL errore('read_1drism_xml', &
& 'cannot open ' // TRIM(rism1d_file) // ' file for reading', ierr)
END IF
!
! ... read header
IF (ionode) THEN
rismNode => getFirstChild(doc)
!
infoNode => item(getElementsByTagname(rismNode, 'INFO'), 0)
CALL extractDataAttribute(infoNode, 'ngrid', ngrid_)
CALL extractDataAttribute(infoNode, 'nsite', nsite_)
!
IF (ngrid /= ngrid_) THEN
CALL errore('read_1drism_xml', 'number of grids do not match', 1)
END IF
!
IF (nsite /= nsite_) THEN
CALL errore('read_1drism_xml', 'number of sites do not match', 1)
END IF
END IF
!
! ... find the index of the ionode
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
!
! ... read zvv for each site
ALLOCATE(zvv1(ngrid))
!
DO isite = 1, nsite
IF (ionode) THEN
WRITE(isitestr,'(I0)') isite
siteNode => item(getElementsByTagname(rismNode, 'site.' // TRIM(isitestr)), 0)
CALL extractDataContent(siteNode, zvv1)
END IF
!
#if defined (__MPI)
CALL MPI_SCATTERV(zvv1, npp, ipp, &
& MPI_DOUBLE_PRECISION, zvv(1, isite), npp(me_group + 1), &
& MPI_DOUBLE_PRECISION, io_group, intra_group_comm, ierr)
!
IF (ierr /= MPI_SUCCESS) THEN
CALL errore('read_1drism_xml', 'error at MPI_SCATTERV', 1)
END IF
#else
zvv(1:ngrid, isite) = zvv1(1:ngrid)
#endif
END DO
!
DEALLOCATE(zvv1)
!
! ... close file
IF (ionode) THEN
CALL destroy(doc)
END IF
!
END SUBROUTINE read_1drism_xml
!
!------------------------------------------------------------------------
FUNCTION check_file_exist_1drism(filename, ionode, ionode_id, intra_group_comm)
!------------------------------------------------------------------------
!
!
IMPLICIT NONE
!
LOGICAL :: check_file_exist_1drism
!
CHARACTER(LEN=*), INTENT(IN) :: filename
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: ionode_id
INTEGER, INTENT(IN) :: intra_group_comm
!
LOGICAL :: lexists
!
IF (ionode) THEN
!
INQUIRE(FILE=TRIM(filename), EXIST=lexists)
!
END IF
!
CALL mp_bcast(lexists, ionode_id, intra_group_comm)
!
check_file_exist_1drism = lexists
!
END FUNCTION check_file_exist_1drism
!
!------------------------------------------------------------------------
SUBROUTINE write_3drism_xml(rism3d_file_base, zuv, name, &
& nsite, isite_start, isite_end, ecut, &
& dfft, ionode, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Writs 3D-RISM's correlation function (R-space).
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rism3d_file_base
REAL(DP), INTENT(IN) :: zuv(:,:)
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
REAL(DP), INTENT(IN) :: ecut
TYPE(fft_type_descriptor), INTENT(IN) :: dfft
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
!
INTEGER :: nr1, nr2, nr3
INTEGER :: nr1x, n12x
INTEGER :: ip
INTEGER :: i, j, jj, k, kk
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
INTEGER :: rism3d_unit
CHARACTER(LEN=256) :: rism3d_file
CHARACTER(LEN=10) :: rism3d_extension
INTEGER :: io_group_id
INTEGER :: io_group2, io_group3
INTEGER :: my_group_id
INTEGER :: me_group2, me_group3
INTEGER :: nproc_group3
INTEGER, ALLOCATABLE :: sowner(:)
INTEGER, ALLOCATABLE :: kowner(:)
REAL(DP), ALLOCATABLE :: zuv_plane(:)
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... get process info.
my_group_id = mp_rank(inter_group_comm)
me_group2 = dfft%mype2
me_group3 = dfft%mype3
nproc_group3 = dfft%nproc3
!
! ... FFT-box
nr1 = dfft%nr1
nr2 = dfft%nr2
nr3 = dfft%nr3
nr1x = dfft%nr1x
n12x = nr1x * dfft%my_nr2p
!
! ... allocate memory
ALLOCATE(sowner(nsite))
ALLOCATE(kowner(nr3))
ALLOCATE(zuv_plane(nr1 * nr2))
!
! ... decide file name and unit
rism3d_extension = '.dat'
!
rism3d_file = TRIM(rism3d_file_base) // TRIM(rism3d_extension)
rism3d_unit = find_free_unit()
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rism3d_unit, FILE=TRIM(rism3d_file), &
& FORM='unformatted', STATUS = 'replace', IOSTAT = ierr)
CALL errore('write_3drism_xml', &
& 'cannot open ' // TRIM(rism3d_file) // ' file for writing', ierr)
END IF
!
! ... write header
IF (ionode) THEN
WRITE(rism3d_unit) nsite, ecut, nr1, nr2, nr3
END IF
!
! ... find the index of the group that will write zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, dfft%comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within Y group
io_group2 = 0
IF (ionode) THEN
io_group2 = me_group2
END IF
CALL mp_sum(io_group2, dfft%comm)
CALL mp_sum(io_group2, inter_group_comm)
!
! ... find the index of the ionode within Z group
io_group3 = 0
IF (ionode) THEN
io_group3 = me_group3
END IF
CALL mp_sum(io_group3, dfft%comm)
CALL mp_sum(io_group3, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... find out the owner of each "z" plane
DO ip = 1, nproc_group3
kowner((dfft%i0r3p(ip) + 1):(dfft%i0r3p(ip) + dfft%nr3p(ip))) = ip - 1
END DO
!
! ... write zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
! ... write zuv for each "z" plane
DO k = 1, nr3
zuv_plane = 0.0_DP
!
IF (sowner(isite) == my_group_id) THEN
IF (kowner(k) == me_group3) THEN
kk = k - dfft%my_i0r3p
DO jj = 1, dfft%my_nr2p
j = jj + dfft%my_i0r2p
DO i = 1, nr1
zuv_plane(i + (j - 1) * nr1) = &
& zuv(i + (jj - 1) * nr1x + (kk - 1) * n12x, iisite)
END DO
END DO
CALL mp_sum(zuv_plane, dfft%comm2)
END IF
!
IF (kowner(k) /= io_group3 .AND. me_group2 == io_group2) THEN
CALL mp_get(zuv_plane, zuv_plane, me_group3, io_group3, &
& kowner(k), k, dfft%comm3)
END IF
END IF
!
IF (sowner(isite) /= io_group_id) THEN
CALL mp_get(zuv_plane, zuv_plane, my_group_id, io_group_id, &
& sowner(isite), isite, inter_group_comm)
END IF
!
IF (ionode) THEN
WRITE(rism3d_unit) zuv_plane
END IF
END DO
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rism3d_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
DEALLOCATE(kowner)
DEALLOCATE(zuv_plane)
!
END SUBROUTINE write_3drism_xml
!
!------------------------------------------------------------------------
SUBROUTINE read_3drism_xml(rism3d_file_base, zuv, &
& nsite, isite_start, isite_end, ecut, &
& dfft, ionode, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Reads 3D-RISM's correlation function (R-space).
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rism3d_file_base
REAL(DP), INTENT(OUT) :: zuv(:,:)
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
REAL(DP), INTENT(IN) :: ecut
TYPE(fft_type_descriptor), INTENT(IN) :: dfft
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
!
INTEGER :: nr1, nr2, nr3
INTEGER :: nr1x, n12x
INTEGER :: ip
INTEGER :: i, j, jj, k, kk
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
INTEGER :: rism3d_unit
CHARACTER(LEN=256) :: rism3d_file
INTEGER :: nsite_
REAL(DP) :: ecut_
INTEGER :: nr(3)
INTEGER :: io_group_id
INTEGER :: io_group3
INTEGER :: my_group_id
INTEGER :: me_group2, me_group3
INTEGER :: nproc_group3
LOGICAL :: exist
INTEGER, ALLOCATABLE :: sowner(:)
INTEGER, ALLOCATABLE :: kowner(:)
REAL(DP), ALLOCATABLE :: zuv_plane(:)
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... get process info.
my_group_id = mp_rank(inter_group_comm)
me_group3 = dfft%mype3
nproc_group3 = dfft%nproc3
!
! ... FFT-box
nr1 = dfft%nr1
nr2 = dfft%nr2
nr3 = dfft%nr3
nr1x = dfft%nr1x
n12x = nr1x * dfft%my_nr2p
!
! ... allocate memory
ALLOCATE(sowner(nsite))
ALLOCATE(kowner(nr3))
ALLOCATE(zuv_plane(nr1 * nr2))
!
! ... search file
rism3d_unit = find_free_unit()
rism3d_file = TRIM(rism3d_file_base) // ".dat"
exist = check_file_exist(TRIM(rism3d_file))
!
IF (.NOT. exist) THEN
CALL errore('read_3drism_xml', 'searching for ' // TRIM(rism3d_file), 10)
END IF
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rism3d_unit, FILE=TRIM(rism3d_file), &
& FORM='unformatted', STATUS = 'old', IOSTAT = ierr)
CALL errore('read_3drism_xml', &
& 'cannot open ' // TRIM(rism3d_file) // ' file for reading', ierr)
END IF
!
! ... read header
IF (ionode) THEN
READ(rism3d_unit) nsite_, ecut_, nr(1), nr(2), nr(3)
!
IF (nsite /= nsite_) THEN
CALL errore('read_3drism_xml', 'number of sites do not match', 1)
END IF
!
IF (ABS(ecut - ecut_) > eps8) THEN
CALL errore('read_3drism_xml', 'energy cutoff does not match', 1)
END IF
!
IF (nr1 /= nr(1) .OR. nr2 /= nr(2) .OR. nr3 /= nr(3)) THEN
CALL errore('read_3drism_xml', 'dimensions do not match', 1)
END IF
END IF
!
! ... find the index of the group that will read zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, dfft%comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within Z group
io_group3 = 0
IF (ionode) THEN
io_group3 = me_group3
END IF
CALL mp_sum(io_group3, dfft%comm)
CALL mp_sum(io_group3, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... find out the owner of each "z" plane
DO ip = 1, nproc_group3
kowner((dfft%i0r3p(ip) + 1):(dfft%i0r3p(ip) + dfft%nr3p(ip))) = ip - 1
END DO
!
! ... read zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
! ... read zuv for each "z" plane
DO k = 1, nr3
IF (ionode) THEN
READ(rism3d_unit) zuv_plane
END IF
!
IF (sowner(isite) /= io_group_id) THEN
CALL mp_get(zuv_plane, zuv_plane, my_group_id, sowner(isite), &
& io_group_id, isite, inter_group_comm)
END IF
!
IF (sowner(isite) == my_group_id) THEN
IF (kowner(k) /= io_group3) THEN
CALL mp_get(zuv_plane, zuv_plane, me_group3, kowner(k), &
& io_group3, k, dfft%comm3)
END IF
!
IF(kowner(k) == me_group3) THEN
kk = k - dfft%my_i0r3p
DO jj = 1, dfft%my_nr2p
j = jj + dfft%my_i0r2p
DO i = 1, nr1
zuv(i + (jj - 1) * nr1x + (kk - 1) * n12x, iisite) &
& = zuv_plane(i + (j - 1) * nr1)
END DO
END DO
END IF
END IF
!
END DO
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rism3d_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
DEALLOCATE(kowner)
DEALLOCATE(zuv_plane)
!
END SUBROUTINE read_3drism_xml
!
!------------------------------------------------------------------------
SUBROUTINE write_lauerism_xml(rismlaue_file_base, zuv, name, &
& nsite, isite_start, isite_end, ecut, gamma_only, &
& lfft, ionode, intra_group_comm, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Writs Laue-RISM's correlation function (Laue-rep., expanded Z-stick).
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rismlaue_file_base
COMPLEX(DP), INTENT(IN) :: zuv(:,:)
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
REAL(DP), INTENT(IN) :: ecut
LOGICAL, INTENT(IN) :: gamma_only
TYPE(lauefft_type), INTENT(IN) :: lfft
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
INTEGER, INTENT(IN) :: intra_group_comm
!
INTEGER :: irz
INTEGER :: igxy
INTEGER :: jgxy1
INTEGER :: jgxy2
INTEGER :: igx, igy
INTEGER :: mx, my
INTEGER :: nr1, nr2, nr3
INTEGER :: isign
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
REAL(DP) :: zreal
REAL(DP) :: zimag
INTEGER :: rismlaue_unit
CHARACTER(LEN=256) :: rismlaue_file
CHARACTER(LEN=10) :: rismlaue_extension
INTEGER :: io_group
INTEGER :: io_group_id
INTEGER :: me_group
INTEGER :: my_group_id
INTEGER, ALLOCATABLE :: sowner(:)
COMPLEX(DP), ALLOCATABLE :: zuv_site(:)
#if defined (__MPI)
COMPLEX(DP), ALLOCATABLE :: zuv_tmp(:)
#endif
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... set variables
nr1 = lfft%dfft%nr1
nr2 = lfft%dfft%nr2
nr3 = lfft%nrz
!
! ... allocate memory
ALLOCATE(sowner(nsite))
ALLOCATE(zuv_site(nr1 * nr2 * nr3))
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
my_group_id = mp_rank(inter_group_comm)
!
! ... decide file name and unit
rismlaue_extension = '.dat'
!
rismlaue_file = TRIM(rismlaue_file_base) // TRIM(rismlaue_extension)
rismlaue_unit = find_free_unit()
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rismlaue_unit, FILE=TRIM(rismlaue_file), &
& FORM='unformatted', STATUS = 'replace', IOSTAT = ierr)
CALL errore('write_lauerism_xml', &
& 'cannot open ' // TRIM(rismlaue_file) // ' file for writing', ierr)
END IF
!
! ... write header
IF (ionode) THEN
WRITE(rismlaue_unit) nsite, ecut, nr1, nr2, nr3
END IF
!
! ... find the index of the group that will write zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, intra_group_comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within its own group
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
CALL mp_sum(io_group, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... write zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
IF (sowner(isite) == my_group_id) THEN
!
CALL mp_barrier(intra_group_comm)
!
zuv_site = CMPLX(0.0_DP, 0.0_DP, kind=DP)
!
DO igxy = 1, lfft%ngxy
isign = 1
10 CONTINUE
!
mx = isign * lfft%millxy(1, igxy)
igx = mx + 1
IF (igx < 1) THEN
igx = igx + nr1
END IF
!
my = isign * lfft%millxy(2, igxy)
igy = my + 1
IF (igy < 1) THEN
igy = igy + nr2
END IF
!
jgxy1 = nr3 * (igxy - 1)
jgxy2 = nr3 * (nr2 * (igx - 1) + (igy - 1))
!
DO irz = 1, nr3
zreal = DBLE( zuv(irz + jgxy1, iisite))
zimag = AIMAG(zuv(irz + jgxy1, iisite))
zuv_site(irz + jgxy2) = CMPLX(zreal, DBLE(isign) * zimag, kind=DP)
END DO
!
IF (gamma_only .AND. isign > 0) THEN
isign = -1
GOTO 10
END IF
END DO
!
#if defined (__MPI)
#if defined (__FUJITSU)
CALL mp_sum(zuv_site, intra_group_comm)
!
#else
IF (me_group == io_group) THEN
ALLOCATE(zuv_tmp(nr1 * nr2 * nr3))
ELSE
ALLOCATE(zuv_tmp(1))
END IF
!
CALL MPI_REDUCE(zuv_site(1), zuv_tmp(1), nr1 * nr2 * nr3, MPI_DOUBLE_COMPLEX, &
& MPI_SUM, io_group, intra_group_comm, ierr)
!
IF (ierr /= MPI_SUCCESS) THEN
CALL errore('write_lauerism_xml', 'error at MPI_REDUCE', 1)
END IF
!
IF (me_group == io_group) THEN
zuv_site = zuv_tmp
END IF
DEALLOCATE(zuv_tmp)
!
#endif
#endif
!
END IF
!
IF (sowner(isite) /= io_group_id) THEN
IF (me_group == io_group) THEN
!
CALL mp_barrier(inter_group_comm)
!
CALL mp_get(zuv_site, zuv_site, my_group_id, io_group_id, &
& sowner(isite), isite, inter_group_comm)
END IF
END IF
!
IF (ionode) THEN
WRITE(rismlaue_unit) zuv_site
END IF
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rismlaue_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
DEALLOCATE(zuv_site)
!
END SUBROUTINE write_lauerism_xml
!
!------------------------------------------------------------------------
SUBROUTINE read_lauerism_xml(rismlaue_file_base, zuv, &
& nsite, isite_start, isite_end, ecut, &
& lfft, ionode, intra_group_comm, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Reads Laue-RISM's correlation function (Laue-rep., expanded Z-stick).
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rismlaue_file_base
COMPLEX(DP), INTENT(OUT) :: zuv(:,:)
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
REAL(DP), INTENT(IN) :: ecut
TYPE(lauefft_type), INTENT(IN) :: lfft
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
INTEGER, INTENT(IN) :: intra_group_comm
!
INTEGER :: irz
INTEGER :: igxy
INTEGER :: jgxy1
INTEGER :: jgxy2
INTEGER :: igx, igy
INTEGER :: mx, my
INTEGER :: nr1, nr2, nr3
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
INTEGER :: rismlaue_unit
CHARACTER(LEN=256) :: rismlaue_file
INTEGER :: nsite_
REAL(DP) :: ecut_
INTEGER :: nr(3)
INTEGER :: io_group
INTEGER :: io_group_id
INTEGER :: me_group
INTEGER :: my_group_id
LOGICAL :: exist
INTEGER, ALLOCATABLE :: sowner(:)
COMPLEX(DP), ALLOCATABLE :: zuv_site(:)
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... set variables
nr1 = lfft%dfft%nr1
nr2 = lfft%dfft%nr2
nr3 = lfft%nrz
!
! ... allocate memory
ALLOCATE(sowner(nsite))
ALLOCATE(zuv_site(nr1 * nr2 * nr3))
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
my_group_id = mp_rank(inter_group_comm)
!
! ... search file
rismlaue_unit = find_free_unit()
rismlaue_file = TRIM(rismlaue_file_base) // ".dat"
exist = check_file_exist(TRIM(rismlaue_file))
!
IF (.NOT. exist) THEN
CALL errore('read_lauerism_xml', 'searching for ' // TRIM(rismlaue_file), 10)
END IF
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rismlaue_unit, FILE=TRIM(rismlaue_file), &
& FORM='unformatted', STATUS = 'old', IOSTAT = ierr)
CALL errore('read_lauerism_xml', &
& 'cannot open ' // TRIM(rismlaue_file) // ' file for reading', ierr)
END IF
!
! ... read header
IF (ionode) THEN
READ(rismlaue_unit) nsite_, ecut_, nr(1), nr(2), nr(3)
!
IF (nsite /= nsite_) THEN
CALL errore('read_lauerism_xml', 'number of sites do not match', 1)
END IF
!
IF (ABS(ecut - ecut_) > eps8) THEN
CALL errore('read_lauerism_xml', 'energy cutoff does not match', 1)
END IF
!
IF (nr1 /= nr(1) .OR. nr2 /= nr(2) .OR. nr3 /= nr(3)) THEN
CALL errore('read_lauerism_xml', 'dimensions do not match', 1)
END IF
END IF
!
! ... find the index of the group that will read zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, intra_group_comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within its own group
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
CALL mp_sum(io_group, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... read zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
IF (ionode) THEN
READ(rismlaue_unit) zuv_site
END IF
!
IF (my_group_id == io_group_id) THEN
CALL mp_bcast(zuv_site, io_group, intra_group_comm)
END IF
!
IF (sowner(isite) /= io_group_id) THEN
!
CALL mp_barrier(inter_group_comm)
!
CALL mp_get(zuv_site, zuv_site, my_group_id, sowner(isite), &
& io_group_id, isite, inter_group_comm)
END IF
!
IF (sowner(isite) == my_group_id) THEN
!
DO igxy = 1, lfft%ngxy
mx = lfft%millxy(1, igxy)
igx = mx + 1
IF (igx < 1) THEN
igx = igx + nr1
END IF
!
my = lfft%millxy(2, igxy)
igy = my + 1
IF (igy < 1) THEN
igy = igy + nr2
END IF
!
jgxy1 = nr3 * (igxy - 1)
jgxy2 = nr3 * (nr2 * (igx - 1) + (igy - 1))
!
DO irz = 1, nr3
zuv(irz + jgxy1, iisite) = zuv_site(irz + jgxy2)
END DO
END DO
!
END IF
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rismlaue_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
DEALLOCATE(zuv_site)
!
END SUBROUTINE read_lauerism_xml
!
!------------------------------------------------------------------------
SUBROUTINE write_lauedipole_xml(rismlaue_file_base, zuv, name, &
& nsite, isite_start, isite_end, &
& ionode, intra_group_comm, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Writs Laue-RISM's dipole function.
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rismlaue_file_base
REAL(DP), INTENT(IN) :: zuv(:)
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
INTEGER, INTENT(IN) :: intra_group_comm
!
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
INTEGER :: rismlaue_unit
CHARACTER(LEN=256) :: rismlaue_file
CHARACTER(LEN=10) :: rismlaue_extension
INTEGER :: io_group
INTEGER :: io_group_id
INTEGER :: me_group
INTEGER :: my_group_id
INTEGER, ALLOCATABLE :: sowner(:)
REAL(DP) :: zuv_site
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... allocate memory
ALLOCATE(sowner(nsite))
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
my_group_id = mp_rank(inter_group_comm)
!
! ... decide file name and unit
rismlaue_extension = '.dat'
!
rismlaue_file = TRIM(rismlaue_file_base) // TRIM(rismlaue_extension)
rismlaue_unit = find_free_unit()
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rismlaue_unit, FILE=TRIM(rismlaue_file), &
& FORM='unformatted', STATUS = 'replace', IOSTAT = ierr)
CALL errore('write_lauedipole_xml', &
& 'cannot open ' // TRIM(rismlaue_file) // ' file for writing', ierr)
END IF
!
! ... write header
IF (ionode) THEN
WRITE(rismlaue_unit) nsite
END IF
!
! ... find the index of the group that will write zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, intra_group_comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within its own group
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
CALL mp_sum(io_group, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... write zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
IF (me_group == io_group) THEN
!
IF (sowner(isite) == my_group_id) THEN
!
zuv_site = zuv(iisite)
!
END IF
!
IF (sowner(isite) /= io_group_id) THEN
!
!CALL mp_barrier(inter_group_comm)
!
!CALL mp_get(zuv_site, zuv_site, my_group_id, io_group_id, &
! & sowner(isite), isite, inter_group_comm)
!
CALL mp_bcast(zuv_site, sowner(isite), inter_group_comm)
!
END IF
!
END IF
!
CALL mp_barrier(intra_group_comm)
!
IF (ionode) THEN
WRITE(rismlaue_unit) zuv_site
END IF
!
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rismlaue_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
!
END SUBROUTINE write_lauedipole_xml
!
!------------------------------------------------------------------------
SUBROUTINE read_lauedipole_xml(rismlaue_file_base, zuv, &
& nsite, isite_start, isite_end, &
& ionode, intra_group_comm, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Reads Laue-RISM's dipole function.
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rismlaue_file_base
REAL(DP), INTENT(OUT) :: zuv(:)
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
INTEGER, INTENT(IN) :: intra_group_comm
!
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
INTEGER :: rismlaue_unit
CHARACTER(LEN=256) :: rismlaue_file
INTEGER :: nsite_
INTEGER :: io_group
INTEGER :: io_group_id
INTEGER :: me_group
INTEGER :: my_group_id
LOGICAL :: exist
INTEGER, ALLOCATABLE :: sowner(:)
REAL(DP) :: zuv_site
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... allocate memory
ALLOCATE(sowner(nsite))
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
my_group_id = mp_rank(inter_group_comm)
!
! ... search file
rismlaue_unit = find_free_unit()
rismlaue_file = TRIM(rismlaue_file_base) // ".dat"
exist = check_file_exist(TRIM(rismlaue_file))
!
IF (.NOT. exist) THEN
CALL errore('read_lauedipole_xml', 'searching for ' // TRIM(rismlaue_file), 10)
END IF
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rismlaue_unit, FILE=TRIM(rismlaue_file), &
& FORM='unformatted', STATUS = 'old', IOSTAT = ierr)
CALL errore('read_lauedipole_xml', &
& 'cannot open ' // TRIM(rismlaue_file) // ' file for reading', ierr)
END IF
!
! ... read header
IF (ionode) THEN
READ(rismlaue_unit) nsite_
!
IF (nsite /= nsite_) THEN
CALL errore('read_lauedipole_xml', 'number of sites do not match', 1)
END IF
END IF
!
! ... find the index of the group that will read zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, intra_group_comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within its own group
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
CALL mp_sum(io_group, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... read zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
IF (ionode) THEN
READ(rismlaue_unit) zuv_site
END IF
!
IF (me_group == io_group) THEN
!
IF (sowner(isite) /= io_group_id) THEN
!
!CALL mp_barrier(inter_group_comm)
!
!CALL mp_get(zuv_site, zuv_site, my_group_id, sowner(isite), &
! & io_group_id, isite, inter_group_comm)
!
CALL mp_bcast(zuv_site, io_group_id, inter_group_comm)
!
END IF
!
END IF
!
CALL mp_barrier(intra_group_comm)
!
IF (sowner(isite) == my_group_id) THEN
!
CALL mp_bcast(zuv_site, io_group, intra_group_comm)
!
zuv(iisite) = zuv_site
!
END IF
!
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rismlaue_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
!
END SUBROUTINE read_lauedipole_xml
!
!------------------------------------------------------------------------
SUBROUTINE write_lauegxy0_xml(rismlaue_file_base, zuv, name, &
& nsite, isite_start, isite_end, &
& lfft, ionode, intra_group_comm, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Writs Laue-RISM's correlation function at Gxy = 0
! ... (Laue-rep., expanded Z-stick).
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rismlaue_file_base
REAL(DP), INTENT(IN) :: zuv(:,:)
CHARACTER(LEN=*), INTENT(IN) :: name
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
TYPE(lauefft_type), INTENT(IN) :: lfft
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
INTEGER, INTENT(IN) :: intra_group_comm
!
INTEGER :: nr3
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
INTEGER :: rismlaue_unit
CHARACTER(LEN=256) :: rismlaue_file
CHARACTER(LEN=10) :: rismlaue_extension
INTEGER :: io_group
INTEGER :: io_group_id
INTEGER :: me_group
INTEGER :: my_group_id
INTEGER, ALLOCATABLE :: sowner(:)
REAL(DP), ALLOCATABLE :: zuv_site(:)
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... set variables
nr3 = lfft%nrz
!
! ... allocate memory
ALLOCATE(sowner(nsite))
ALLOCATE(zuv_site(nr3))
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
my_group_id = mp_rank(inter_group_comm)
!
! ... decide file name and unit
rismlaue_extension = '.dat'
!
rismlaue_file = TRIM(rismlaue_file_base) // TRIM(rismlaue_extension)
rismlaue_unit = find_free_unit()
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rismlaue_unit, FILE=TRIM(rismlaue_file), &
& FORM='unformatted', STATUS = 'replace', IOSTAT = ierr)
CALL errore('write_lauegxy0_xml', &
& 'cannot open ' // TRIM(rismlaue_file) // ' file for writing', ierr)
END IF
!
! ... write header
IF (ionode) THEN
WRITE(rismlaue_unit) nsite, nr3
END IF
!
! ... find the index of the group that will write zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, intra_group_comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within its own group
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
CALL mp_sum(io_group, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... write zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
IF (sowner(isite) == my_group_id) THEN
!
CALL mp_barrier(intra_group_comm)
!
zuv_site = 0.0_DP
!
IF (lfft%gxystart > 1) THEN
zuv_site(1:nr3) = zuv(1:nr3, iisite)
END IF
!
CALL mp_sum(zuv_site, intra_group_comm)
!
END IF
!
IF (sowner(isite) /= io_group_id) THEN
IF (me_group == io_group) THEN
!
CALL mp_barrier(inter_group_comm)
!
CALL mp_get(zuv_site, zuv_site, my_group_id, io_group_id, &
& sowner(isite), isite, inter_group_comm)
END IF
END IF
!
IF (ionode) THEN
WRITE(rismlaue_unit) zuv_site
END IF
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rismlaue_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
DEALLOCATE(zuv_site)
!
END SUBROUTINE write_lauegxy0_xml
!
!------------------------------------------------------------------------
SUBROUTINE read_lauegxy0_xml(rismlaue_file_base, zuv, &
& nsite, isite_start, isite_end, &
& lfft, ionode, intra_group_comm, inter_group_comm)
!------------------------------------------------------------------------
!
! ... Reads Laue-RISM's correlation function at Gxy = 0
! ... (Laue-rep., expanded Z-stick).
!
IMPLICIT NONE
!
CHARACTER(LEN=*), INTENT(IN) :: rismlaue_file_base
REAL(DP), INTENT(OUT) :: zuv(:,:)
INTEGER, INTENT(IN) :: nsite
INTEGER, INTENT(IN) :: isite_start
INTEGER, INTENT(IN) :: isite_end
TYPE(lauefft_type), INTENT(IN) :: lfft
LOGICAL, INTENT(IN) :: ionode
INTEGER, INTENT(IN) :: inter_group_comm
INTEGER, INTENT(IN) :: intra_group_comm
!
INTEGER :: nr3
INTEGER :: ierr
INTEGER :: isite
INTEGER :: iisite
INTEGER :: rismlaue_unit
CHARACTER(LEN=256) :: rismlaue_file
INTEGER :: nsite_
INTEGER :: nr3_
INTEGER :: io_group
INTEGER :: io_group_id
INTEGER :: me_group
INTEGER :: my_group_id
LOGICAL :: exist
INTEGER, ALLOCATABLE :: sowner(:)
REAL(DP), ALLOCATABLE :: zuv_site(:)
!
INTEGER, EXTERNAL :: find_free_unit
!
! ... set variables
nr3 = lfft%nrz
!
! ... allocate memory
ALLOCATE(sowner(nsite))
ALLOCATE(zuv_site(nr3))
!
! ... get process info.
me_group = mp_rank(intra_group_comm)
my_group_id = mp_rank(inter_group_comm)
!
! ... search file
rismlaue_unit = find_free_unit()
rismlaue_file = TRIM(rismlaue_file_base) // ".dat"
exist = check_file_exist(TRIM(rismlaue_file))
!
IF (.NOT. exist) THEN
CALL errore('read_lauegxy0_xml', 'searching for ' // TRIM(rismlaue_file), 10)
END IF
!
! ... open file
IF (ionode) THEN
OPEN (UNIT = rismlaue_unit, FILE=TRIM(rismlaue_file), &
& FORM='unformatted', STATUS = 'old', IOSTAT = ierr)
CALL errore('read_lauegxy0_xml', &
& 'cannot open ' // TRIM(rismlaue_file) // ' file for reading', ierr)
END IF
!
! ... read header
IF (ionode) THEN
READ(rismlaue_unit) nsite_, nr3_
!
IF (nsite /= nsite_) THEN
CALL errore('read_lauegxy0_xml', 'number of sites do not match', 1)
END IF
!
IF (nr3 /= nr3_) THEN
CALL errore('read_lauegxy0_xml', 'dimensions do not match', 1)
END IF
END IF
!
! ... find the index of the group that will read zuv
io_group_id = 0
IF (ionode) THEN
io_group_id = my_group_id
END IF
CALL mp_sum(io_group_id, intra_group_comm)
CALL mp_sum(io_group_id, inter_group_comm)
!
! ... find the index of the ionode within its own group
io_group = 0
IF (ionode) THEN
io_group = me_group
END IF
CALL mp_sum(io_group, intra_group_comm)
CALL mp_sum(io_group, inter_group_comm)
!
! ... find out the owner of each solvent's site
sowner = 0
sowner(isite_start:isite_end) = my_group_id
CALL mp_sum(sowner, inter_group_comm)
!
! ... read zuv for each solvent's site
DO isite = 1, nsite
IF (sowner(isite) == my_group_id) THEN
iisite = isite - isite_start + 1
ELSE
iisite = -1
END IF
!
IF (ionode) THEN
READ(rismlaue_unit) zuv_site
END IF
!
IF (my_group_id == io_group_id) THEN
CALL mp_bcast(zuv_site, io_group, intra_group_comm)
END IF
!
IF (sowner(isite) /= io_group_id) THEN
!
CALL mp_barrier(inter_group_comm)
!
CALL mp_get(zuv_site, zuv_site, my_group_id, sowner(isite), &
& io_group_id, isite, inter_group_comm)
END IF
!
IF (sowner(isite) == my_group_id) THEN
!
IF (lfft%gxystart > 1) THEN
zuv(1:nr3, iisite) = zuv_site(1:nr3)
END IF
!
END IF
END DO
!
! ... close file
IF (ionode) THEN
CLOSE(rismlaue_unit)
END IF
!
! ... deallocate memory
DEALLOCATE(sowner)
DEALLOCATE(zuv_site)
!
END SUBROUTINE read_lauegxy0_xml
!
END MODULE xml_io_rism