2003-01-20 05:58:50 +08:00
|
|
|
!
|
2006-07-08 04:16:45 +08:00
|
|
|
! Copyright (C) 2001-2006 Quantum-ESPRESSO group
|
2003-01-20 05:58:50 +08:00
|
|
|
! 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 .
|
|
|
|
!
|
2004-06-26 01:25:37 +08:00
|
|
|
#include "f_defs.h"
|
2006-07-08 04:16:45 +08:00
|
|
|
!
|
|
|
|
!----------------------------------------------------------------------------
|
|
|
|
subroutine stres_gradcorr( rho, rho_core, nspin, nr1, nr2, nr3, nrx1, &
|
|
|
|
nrx2, nrx3, nrxx, nl, ngm, g, alat, omega, sigmaxc )
|
|
|
|
!----------------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
USE kinds, ONLY : DP
|
2006-02-10 23:02:48 +08:00
|
|
|
USE noncollin_module, ONLY : noncolin
|
2006-07-08 04:16:45 +08:00
|
|
|
USE scf, ONLY : rhog, rhog_core
|
|
|
|
use funct, ONLY : gcxc, gcx_spin, gcc_spin, gcc_spin_more, &
|
|
|
|
dft_is_gradient, get_igcc
|
|
|
|
!
|
|
|
|
IMPLICIT NONE
|
|
|
|
!
|
2003-01-20 05:58:50 +08:00
|
|
|
integer :: nspin, nr1, nr2, nr3, nrx1, nrx2, nrx3, nrxx, ngm, &
|
|
|
|
nl (ngm)
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: rho (nrxx, nspin), rho_core (nrxx), g (3, ngm), &
|
2003-01-20 05:58:50 +08:00
|
|
|
alat, omega, sigmaxc (3, 3)
|
2006-02-10 23:02:48 +08:00
|
|
|
integer :: k, l, m, ipol, is, nspin0
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) , allocatable :: grho (:,:,:)
|
|
|
|
real(DP), parameter :: epsr = 1.0d-6, epsg = 1.0d-10, e2 = 2.d0
|
|
|
|
real(DP) :: grh2, grho2 (2), sx, sc, v1x, v2x, v1c, v2c, fac, &
|
2005-04-08 22:51:37 +08:00
|
|
|
v1xup, v1xdw, v2xup, v2xdw, v1cup, v1cdw, v2cup, v2cdw, v2cud, &
|
|
|
|
zeta, rh, rup, rdw, grhoup, grhodw, grhoud, grup, grdw, &
|
2005-11-02 23:42:06 +08:00
|
|
|
sigma_gradcorr (3, 3), rhok
|
|
|
|
logical :: igcc_is_lyp
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2005-11-04 19:47:42 +08:00
|
|
|
if ( .not. dft_is_gradient() ) return
|
2006-02-10 23:02:48 +08:00
|
|
|
if (noncolin) call errore('stres_gradcorr', &
|
|
|
|
'noncollinear stress + GGA not implemented',1)
|
2005-11-02 23:42:06 +08:00
|
|
|
|
|
|
|
igcc_is_lyp = (get_igcc() == 3)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
sigma_gradcorr(:,:) = 0.d0
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
allocate (grho( 3, nrxx, nspin))
|
2006-02-10 23:02:48 +08:00
|
|
|
nspin0=nspin
|
|
|
|
if (nspin==4) nspin0=1
|
|
|
|
fac = 1.d0 / DBLE (nspin0)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! calculate the gradient of rho+rhocore in real space
|
|
|
|
!
|
2006-07-08 04:16:45 +08:00
|
|
|
DO is = 1, nspin0
|
|
|
|
!
|
|
|
|
rho(:,is) = fac * rho_core(:) + rho(:,is)
|
|
|
|
rhog(:,is) = fac * rhog_core(:) + rhog(:,is)
|
|
|
|
!
|
|
|
|
CALL gradrho( nrx1, nrx2, nrx3, nr1, nr2, nr3, &
|
|
|
|
nrxx, rhog(1,is), ngm, g, nl, grho(1,1,is) )
|
|
|
|
!
|
|
|
|
END DO
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (nspin.eq.1) then
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! This is the LDA case
|
|
|
|
!
|
|
|
|
! sigma_gradcor_{alpha,beta} ==
|
|
|
|
! omega^-1 \int (grad_alpha rho) ( D(rho*Exc)/D(grad_alpha rho) ) d3
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do k = 1, nrxx
|
2005-04-08 22:51:37 +08:00
|
|
|
grho2 (1) = grho(1,k,1)**2 + grho(2,k,1)**2 + grho(3,k,1)**2
|
2003-02-08 00:04:36 +08:00
|
|
|
if (abs (rho (k, 1) ) .gt.epsr.and.grho2 (1) .gt.epsg) then
|
2005-11-02 23:42:06 +08:00
|
|
|
call gcxc (rho (k, 1), grho2(1), sx, sc, v1x, v2x, v1c, v2c)
|
2003-02-08 00:04:36 +08:00
|
|
|
do l = 1, 3
|
|
|
|
do m = 1, l
|
2005-04-08 22:51:37 +08:00
|
|
|
sigma_gradcorr (l, m) = sigma_gradcorr (l, m) + &
|
|
|
|
grho(l,k,1) * grho(m,k,1) * e2 * (v2x + v2c)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! This is the LSDA case
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do k = 1, nrxx
|
2005-04-08 22:51:37 +08:00
|
|
|
grho2 (1) = grho(1,k,1)**2 + grho(2,k,1)**2 + grho(3,k,1)**2
|
|
|
|
grho2 (2) = grho(1,k,2)**2 + grho(2,k,2)**2 + grho(3,k,2)**2
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
if ( (abs (rho (k, 1) ) .gt.epsr.and.grho2 (1) .gt.epsg) .and. &
|
|
|
|
(abs (rho (k, 2) ) .gt.epsr.and.grho2 (2) .gt.epsg) ) then
|
|
|
|
call gcx_spin (rho (k, 1), rho (k, 2), grho2 (1), grho2 (2), &
|
|
|
|
sx, v1xup, v1xdw, v2xup, v2xdw)
|
2003-02-08 00:04:36 +08:00
|
|
|
rh = rho (k, 1) + rho (k, 2)
|
|
|
|
if (rh.gt.epsr) then
|
2005-11-02 23:42:06 +08:00
|
|
|
if ( igcc_is_lyp ) then
|
2005-04-08 22:51:37 +08:00
|
|
|
rup = rho (k, 1)
|
|
|
|
rdw = rho (k, 2)
|
|
|
|
grhoup = grho(1,k,1)**2 + grho(2,k,1)**2 + grho(3,k,1)**2
|
|
|
|
grhodw = grho(1,k,2)**2 + grho(2,k,2)**2 + grho(3,k,2)**2
|
|
|
|
grhoud = grho(1,k,1) * grho(1,k,2) + &
|
|
|
|
grho(2,k,1) * grho(2,k,2) + &
|
|
|
|
grho(3,k,1) * grho(3,k,2)
|
|
|
|
call gcc_spin_more(rup, rdw, grhoup, grhodw, grhoud, sc, &
|
|
|
|
v1cup, v1cdw, v2cup, v2cdw, v2cud)
|
|
|
|
else
|
|
|
|
zeta = (rho (k, 1) - rho (k, 2) ) / rh
|
|
|
|
|
|
|
|
grh2 = (grho (1, k, 1) + grho (1, k, 2) ) **2 + &
|
|
|
|
(grho (2, k, 1) + grho (2, k, 2) ) **2 + &
|
|
|
|
(grho (3, k, 1) + grho (3, k, 2) ) **2
|
|
|
|
call gcc_spin (rh, zeta, grh2, sc, v1cup, v1cdw, v2c)
|
|
|
|
v2cup = v2c
|
|
|
|
v2cdw = v2c
|
|
|
|
v2cud = v2c
|
|
|
|
end if
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
|
|
|
sc = 0.d0
|
|
|
|
v1cup = 0.d0
|
|
|
|
v1cdw = 0.d0
|
|
|
|
v2c = 0.d0
|
2005-04-08 22:51:37 +08:00
|
|
|
v2cup = 0.d0
|
|
|
|
v2cdw = 0.d0
|
|
|
|
v2cud = 0.d0
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
do l = 1, 3
|
|
|
|
do m = 1, l
|
2003-01-20 05:58:50 +08:00
|
|
|
! exchange
|
2005-04-08 22:51:37 +08:00
|
|
|
sigma_gradcorr (l, m) = sigma_gradcorr (l, m) + &
|
|
|
|
grho (l, k, 1) * grho (m, k, 1) * e2 * v2xup + &
|
|
|
|
grho (l, k, 2) * grho (m, k, 2) * e2 * v2xdw
|
2003-01-20 05:58:50 +08:00
|
|
|
! correlation
|
2005-04-08 22:51:37 +08:00
|
|
|
sigma_gradcorr (l, m) = sigma_gradcorr (l, m) + &
|
|
|
|
( grho (l, k, 1) * grho (m, k, 1) * v2cup + &
|
|
|
|
grho (l, k, 2) * grho (m, k, 2) * v2cdw + &
|
|
|
|
(grho (l, k, 1) * grho (m, k, 2) + &
|
|
|
|
grho (l, k, 2) * grho (m, k, 1) ) * v2cud ) * e2
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
do l = 1, 3
|
|
|
|
do m = 1, l - 1
|
|
|
|
sigma_gradcorr (m, l) = sigma_gradcorr (l, m)
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
|
|
|
|
enddo
|
2003-02-21 22:57:00 +08:00
|
|
|
#ifdef __PARA
|
2003-02-08 00:04:36 +08:00
|
|
|
call reduce (9, sigma_gradcorr)
|
2003-01-20 05:58:50 +08:00
|
|
|
#endif
|
|
|
|
|
2005-04-08 22:51:37 +08:00
|
|
|
call DSCAL (9, 1.d0 / (nr1 * nr2 * nr3), sigma_gradcorr, 1)
|
2003-01-20 05:58:50 +08:00
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
call DAXPY (9, 1.d0, sigma_gradcorr, 1, sigmaxc, 1)
|
2006-07-08 04:16:45 +08:00
|
|
|
|
|
|
|
DO is = 1, nspin0
|
|
|
|
!
|
|
|
|
rho(:,is) = rho(:,is) - fac * rho_core(:)
|
|
|
|
rhog(:,is) = rhog(:,is) - fac * rhog_core(:)
|
|
|
|
!
|
|
|
|
END DO
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
deallocate(grho)
|
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
|
|
|
|
end subroutine stres_gradcorr
|
|
|
|
|