mirror of https://gitlab.com/QEF/q-e.git
314 lines
9.0 KiB
Fortran
314 lines
9.0 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 .
|
|
!
|
|
!---------------------------------------------------------------------------
|
|
SUBROUTINE chempot(rismt, ierr)
|
|
!---------------------------------------------------------------------------
|
|
!
|
|
! ... calculate chemical potential of solvation
|
|
!
|
|
USE cell_base, ONLY : omega
|
|
USE constants, ONLY : K_BOLTZMANN_RY, fpi
|
|
USE kinds, ONLY : DP
|
|
USE mp, ONLY : mp_sum
|
|
USE err_rism, ONLY : IERR_RISM_NULL, IERR_RISM_INCORRECT_DATA_TYPE
|
|
USE rism, ONLY : rism_type, get_chempot_type, ITYPE_1DRISM, ITYPE_3DRISM, CHEMPOT_GF
|
|
USE solvmol, ONLY : get_nuniq_in_solVs, solVs, &
|
|
& iuniq_to_nsite, iuniq_to_isite, isite_to_isolV
|
|
!
|
|
IMPLICIT NONE
|
|
!
|
|
TYPE(rism_type), INTENT(INOUT) :: rismt
|
|
INTEGER, INTENT(OUT) :: ierr
|
|
!
|
|
INTEGER :: ichempot
|
|
INTEGER :: ir
|
|
INTEGER :: isite
|
|
INTEGER :: nq
|
|
INTEGER :: iq
|
|
INTEGER :: iiq
|
|
INTEGER :: iv
|
|
INTEGER :: nv
|
|
INTEGER :: isolV
|
|
REAL(DP) :: beta
|
|
REAL(DP) :: r
|
|
REAL(DP) :: dr
|
|
REAL(DP) :: fac
|
|
REAL(DP) :: rhov
|
|
REAL(DP), ALLOCATABLE :: weight(:)
|
|
LOGICAL :: lweight
|
|
!
|
|
! ... check data type
|
|
IF (rismt%itype /= ITYPE_1DRISM .AND. rismt%itype /= ITYPE_3DRISM) THEN
|
|
ierr = IERR_RISM_INCORRECT_DATA_TYPE
|
|
RETURN
|
|
END IF
|
|
!
|
|
IF (rismt%itype == ITYPE_1DRISM .AND. rismt%nr /= rismt%ng) THEN
|
|
ierr = IERR_RISM_INCORRECT_DATA_TYPE
|
|
RETURN
|
|
END IF
|
|
!
|
|
IF (rismt%itype == ITYPE_3DRISM) THEN
|
|
nq = get_nuniq_in_solVs()
|
|
!
|
|
IF (rismt%mp_site%nsite < nq) THEN
|
|
ierr = IERR_RISM_INCORRECT_DATA_TYPE
|
|
RETURN
|
|
END IF
|
|
END IF
|
|
!
|
|
! ... if no data, return as normally done
|
|
IF (rismt%nsite < 1) THEN
|
|
GOTO 100
|
|
END IF
|
|
!
|
|
! ... set variables
|
|
ichempot = get_chempot_type(rismt)
|
|
beta = 1.0_DP / K_BOLTZMANN_RY / rismt%temp
|
|
!
|
|
! ... calculate chemical potentials
|
|
IF (rismt%nr > 0) THEN
|
|
!
|
|
! ... set integral weight
|
|
IF (rismt%itype == ITYPE_1DRISM) THEN
|
|
ALLOCATE(weight(rismt%nr))
|
|
dr = rismt%rfft%rgrid(2) - rismt%rfft%rgrid(1)
|
|
!$omp parallel do default(shared) private(ir, r)
|
|
DO ir = 1, rismt%nr
|
|
r = rismt%rfft%rgrid(rismt%mp_task%ivec_start + ir - 1)
|
|
weight(ir) = fpi * r * r * dr
|
|
END DO
|
|
!$omp end parallel do
|
|
lweight = .TRUE.
|
|
ELSE
|
|
ALLOCATE(weight(1))
|
|
weight(1) = 1.0_DP
|
|
lweight = .FALSE.
|
|
END IF
|
|
!
|
|
! ... chemical potential for each site
|
|
DO isite = 1, rismt%nsite
|
|
CALL chempot_for_a_site(rismt%nr, ichempot, beta, rismt%hr(1, isite), rismt%csr(1, isite), &
|
|
& rismt%ulr(1, isite), weight, lweight, rismt%usol(isite))
|
|
CALL chempot_for_a_site(rismt%nr, CHEMPOT_GF, beta, rismt%hr(1, isite), rismt%csr(1, isite), &
|
|
& rismt%ulr(1, isite), weight, lweight, rismt%usol_GF(isite))
|
|
END DO
|
|
!
|
|
IF (rismt%itype == ITYPE_3DRISM) THEN
|
|
! ... weight of FFT mesh (for 3D-RISM)
|
|
fac = omega / DBLE(rismt%dfft%nr1 * rismt%dfft%nr2 * rismt%dfft%nr3)
|
|
rismt%usol = fac * rismt%usol
|
|
rismt%usol_GF = fac * rismt%usol_GF
|
|
!
|
|
! ... weight of solvent density (for 3D-RISM)
|
|
DO iq = rismt%mp_site%isite_start, rismt%mp_site%isite_end
|
|
iiq = iq - rismt%mp_site%isite_start + 1
|
|
iv = iuniq_to_isite(1, iq)
|
|
nv = iuniq_to_nsite(iq)
|
|
isolV = isite_to_isolV(iv)
|
|
rhov = DBLE(nv) * solVs(isolV)%density
|
|
rismt%usol( iiq) = rhov * rismt%usol( iiq)
|
|
rismt%usol_GF(iiq) = rhov * rismt%usol_GF(iiq)
|
|
END DO
|
|
END IF
|
|
!
|
|
! ... delete integral weight
|
|
DEALLOCATE(weight)
|
|
!
|
|
ELSE
|
|
!
|
|
rismt%usol = 0.0_DP
|
|
rismt%usol_GF = 0.0_DP
|
|
!
|
|
END IF
|
|
!
|
|
CALL mp_sum(rismt%usol, rismt%mp_task%itask_comm)
|
|
CALL mp_sum(rismt%usol_GF, rismt%mp_task%itask_comm)
|
|
!
|
|
! ... normally done
|
|
100 CONTINUE
|
|
ierr = IERR_RISM_NULL
|
|
!
|
|
END SUBROUTINE chempot
|
|
!
|
|
!---------------------------------------------------------------------------
|
|
SUBROUTINE chempot_for_a_site(nr, ichempot, beta, hr, csr, ulr, wr, lweight, usol)
|
|
!---------------------------------------------------------------------------
|
|
!
|
|
! ... calculate chemical potential for a site
|
|
!
|
|
USE kinds, ONLY : DP
|
|
USE rism, ONLY : CHEMPOT_HNC, CHEMPOT_KH, CHEMPOT_GF
|
|
!
|
|
IMPLICIT NONE
|
|
!
|
|
INTEGER, INTENT(IN) :: nr
|
|
INTEGER, INTENT(IN) :: ichempot
|
|
REAL(DP), INTENT(IN) :: beta
|
|
REAL(DP), INTENT(IN) :: hr(1:*)
|
|
REAL(DP), INTENT(IN) :: csr(1:*)
|
|
REAL(DP), INTENT(IN) :: ulr(1:*)
|
|
REAL(DP), INTENT(IN) :: wr(1:*)
|
|
LOGICAL, INTENT(IN) :: lweight
|
|
REAL(DP), INTENT(OUT) :: usol
|
|
!
|
|
INTEGER :: ir
|
|
REAL(DP), ALLOCATABLE :: tr(:)
|
|
!
|
|
REAL(DP), EXTERNAL :: ddot
|
|
!
|
|
ALLOCATE(tr(nr))
|
|
!
|
|
IF (ichempot == CHEMPOT_HNC) THEN
|
|
CALL chempot_HNC_x(nr, beta, hr, csr, ulr, tr)
|
|
!
|
|
ELSE IF (ichempot == CHEMPOT_KH) THEN
|
|
CALL chempot_KH_x(nr, beta, hr, csr, ulr, tr)
|
|
!
|
|
ELSE IF (ichempot == CHEMPOT_GF) THEN
|
|
CALL chempot_GF_x(nr, beta, hr, csr, ulr, tr)
|
|
!
|
|
ELSE
|
|
usol = 0.0_DP
|
|
DEALLOCATE(tr)
|
|
RETURN
|
|
END IF
|
|
!
|
|
IF (lweight) THEN
|
|
usol = ddot(nr, tr, 1, wr, 1)
|
|
ELSE
|
|
usol = 0.0_DP
|
|
!$omp parallel do default(shared) private(ir) reduction(+:usol)
|
|
DO ir = 1, nr
|
|
usol = usol + tr(ir)
|
|
END DO
|
|
!$omp end parallel do
|
|
END IF
|
|
!
|
|
usol = usol / beta
|
|
!
|
|
DEALLOCATE(tr)
|
|
!
|
|
END SUBROUTINE chempot_for_a_site
|
|
!
|
|
!---------------------------------------------------------------------------
|
|
SUBROUTINE chempot_HNC_x(nr, beta, hr, csr, ulr, tr)
|
|
!---------------------------------------------------------------------------
|
|
!
|
|
! ... HyperNetted-Chain model
|
|
! ... (J.P.Hansen et al., Theory of simple liquids. Academic Press, London, 1990.)
|
|
! ...
|
|
! ... / [ 1 1 ]
|
|
! ... kB * T * | dr [ --- h(r)^2 - c(r) - --- h(r) * c(r) ]
|
|
! ... / [ 2 2 ]
|
|
!
|
|
USE kinds, ONLY : DP
|
|
!
|
|
IMPLICIT NONE
|
|
!
|
|
INTEGER, INTENT(IN) :: nr
|
|
REAL(DP), INTENT(IN) :: beta
|
|
REAL(DP), INTENT(IN) :: hr(1:*)
|
|
REAL(DP), INTENT(IN) :: csr(1:*)
|
|
REAL(DP), INTENT(IN) :: ulr(1:*)
|
|
REAL(DP), INTENT(OUT) :: tr(1:*)
|
|
!
|
|
INTEGER :: ir
|
|
REAL(DP) :: cr0
|
|
REAL(DP) :: hr0
|
|
!
|
|
!$omp parallel do default(shared) private(ir, hr0, cr0)
|
|
DO ir = 1, nr
|
|
hr0 = hr(ir)
|
|
cr0 = csr(ir) - beta * ulr(ir)
|
|
!
|
|
tr(ir) = 0.5_DP * hr0 * hr0 - cr0 - 0.5_DP * hr0 * cr0
|
|
END DO
|
|
!$omp end parallel do
|
|
!
|
|
END SUBROUTINE chempot_HNC_x
|
|
!
|
|
!---------------------------------------------------------------------------
|
|
SUBROUTINE chempot_KH_x(nr, beta, hr, csr, ulr, tr)
|
|
!---------------------------------------------------------------------------
|
|
!
|
|
! ... Kovalenko and Hirata's model
|
|
! ... (A.Kovalenko, F.Hirata, J. Chem. Phys. 1999, 110, 10095-10112)
|
|
! ...
|
|
! ... / [ 1 1 ]
|
|
! ... kB * T * | dr [ --- h(r)^2 * Theta(-h(r)) - c(r) - --- h(r) * c(r) ]
|
|
! ... / [ 2 2 ]
|
|
!
|
|
USE kinds, ONLY : DP
|
|
!
|
|
IMPLICIT NONE
|
|
!
|
|
INTEGER, INTENT(IN) :: nr
|
|
REAL(DP), INTENT(IN) :: beta
|
|
REAL(DP), INTENT(IN) :: hr(1:*)
|
|
REAL(DP), INTENT(IN) :: csr(1:*)
|
|
REAL(DP), INTENT(IN) :: ulr(1:*)
|
|
REAL(DP), INTENT(OUT) :: tr(1:*)
|
|
!
|
|
INTEGER :: ir
|
|
REAL(DP) :: cr0
|
|
REAL(DP) :: hr0
|
|
!
|
|
!$omp parallel do default(shared) private(ir, hr0, cr0)
|
|
DO ir = 1, nr
|
|
hr0 = hr(ir)
|
|
cr0 = csr(ir) - beta * ulr(ir)
|
|
!
|
|
IF (hr0 < 0.0_DP) THEN
|
|
tr(ir) = 0.5_DP * hr0 * hr0 - cr0 - 0.5_DP * hr0 * cr0
|
|
ELSE
|
|
tr(ir) = -cr0 - 0.5_DP * hr0 * cr0
|
|
END IF
|
|
END DO
|
|
!$omp end parallel do
|
|
!
|
|
END SUBROUTINE chempot_KH_x
|
|
!
|
|
!---------------------------------------------------------------------------
|
|
SUBROUTINE chempot_GF_x(nr, beta, hr, csr, ulr, tr)
|
|
!---------------------------------------------------------------------------
|
|
!
|
|
! ... Gaussian Fluctuation model
|
|
! ... (D.Chandler et al., J. Chem. Phys. 1984, 81, 1975-1982)
|
|
! ...
|
|
! ... / [ 1 ]
|
|
! ... kB * T * | dr [ - c(r) - --- h(r) * c(r) ]
|
|
! ... / [ 2 ]
|
|
!
|
|
USE kinds, ONLY : DP
|
|
!
|
|
IMPLICIT NONE
|
|
!
|
|
INTEGER, INTENT(IN) :: nr
|
|
REAL(DP), INTENT(IN) :: beta
|
|
REAL(DP), INTENT(IN) :: hr(1:*)
|
|
REAL(DP), INTENT(IN) :: csr(1:*)
|
|
REAL(DP), INTENT(IN) :: ulr(1:*)
|
|
REAL(DP), INTENT(OUT) :: tr(1:*)
|
|
!
|
|
INTEGER :: ir
|
|
REAL(DP) :: cr0
|
|
REAL(DP) :: hr0
|
|
!
|
|
!$omp parallel do default(shared) private(ir, hr0, cr0)
|
|
DO ir = 1, nr
|
|
hr0 = hr(ir)
|
|
cr0 = csr(ir) - beta * ulr(ir)
|
|
!
|
|
tr(ir) = -cr0 - 0.5_DP * hr0 * cr0
|
|
END DO
|
|
!$omp end parallel do
|
|
!
|
|
END SUBROUTINE chempot_GF_x
|