mirror of https://gitlab.com/QEF/q-e.git
131 lines
3.6 KiB
Fortran
131 lines
3.6 KiB
Fortran
!
|
|
! Copyright (C) 2001 PWSCF 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 .
|
|
!
|
|
!
|
|
!-----------------------------------------------------------------------
|
|
subroutine dvscf (nu_i, dvloc, xq_x)
|
|
!-----------------------------------------------------------------------
|
|
!
|
|
! It reads the variation of the charge density from a file and
|
|
! calculates the variation of the local part of the variation of the
|
|
! K-S potential.
|
|
!
|
|
USE ions_base, ONLY : nat, ityp, tau
|
|
USE kinds, ONLY : DP
|
|
USE fft_base, ONLY : dfftp
|
|
USE fft_interfaces, ONLY : fwfft, invfft
|
|
use pwcom
|
|
USE uspp_param, ONLY: upf
|
|
use phcom
|
|
use d3com
|
|
!
|
|
implicit none
|
|
integer :: nu_i
|
|
! input: mode under consideration
|
|
real (DP) :: xq_x (3)
|
|
! input: coordinates of the q point
|
|
complex (DP) :: dvloc (dfftp%nnr)
|
|
! output: local part of the variation
|
|
! of the K_S potential
|
|
!
|
|
! Local variables
|
|
!
|
|
|
|
integer :: iudrho_x, ig, ir, mu, na, nt
|
|
! unit containing the charge variation
|
|
! countes
|
|
|
|
real (DP) :: qg2, gtau
|
|
! the modulus of (q+G)^2
|
|
! auxiliary variable: g*tau
|
|
|
|
complex (DP) :: guexp
|
|
! auxiliary variable: g*u*exp(gtau)
|
|
|
|
real (DP), pointer :: vloc_x (:,:)
|
|
! the local potential at G+q
|
|
complex (DP), pointer :: u_x(:,:), drc_x (:,:)
|
|
complex (DP), allocatable :: aux1 (:), aux2 (:)
|
|
! the transformation modes patterns
|
|
! contain drho_core for all atomic types
|
|
logical :: q_eq_zero
|
|
! true if xq equal zero
|
|
|
|
allocate (aux1( dfftp%nnr))
|
|
allocate (aux2( dfftp%nnr))
|
|
|
|
q_eq_zero = xq_x(1) == 0.d0 .and. xq_x(2) == 0.d0 .and. xq_x(3) == 0.d0
|
|
if (q_eq_zero) then
|
|
u_x => ug0
|
|
if (nlcc_any) drc_x => d0rc
|
|
vloc_x => vlocg0
|
|
iudrho_x = iud0rho
|
|
else
|
|
u_x => u
|
|
if (nlcc_any) drc_x => drc
|
|
vloc_x => vlocq
|
|
iudrho_x = iudrho
|
|
endif
|
|
|
|
call davcio_drho (aux2, lrdrho, iudrho_x, nu_i, - 1)
|
|
|
|
! call dv_of_drho (nu_i, aux2(1), .true.)
|
|
|
|
! dvloc = aux2(:)
|
|
|
|
! deallocate (aux1, aux2)
|
|
|
|
! return
|
|
|
|
dvloc (:) = aux2(:) * dmuxc(:,1,1)
|
|
CALL fwfft ('Dense', aux2, dfftp)
|
|
|
|
aux1 (:) = (0.d0, 0.d0)
|
|
do ig = 1, ngm
|
|
qg2 = (g(1,ig)+xq_x(1))**2 + (g(2,ig)+xq_x(2))**2 + (g(3,ig)+xq_x(3))**2
|
|
if (qg2 > 1.d-8) then
|
|
aux1(nl(ig)) = e2 * fpi * aux2(nl(ig)) / (tpiba2 * qg2)
|
|
endif
|
|
enddo
|
|
|
|
if (nlcc_any) aux2 (:) = (0.d0, 0.d0)
|
|
do na = 1, nat
|
|
mu = 3 * (na - 1)
|
|
if (abs(u_x(mu+1,nu_i)) + abs(u_x(mu+2,nu_i)) + &
|
|
abs(u_x(mu+3,nu_i)) > 1.0d-12) then
|
|
nt = ityp (na)
|
|
do ig = 1, ngm
|
|
|
|
gtau = tpi * ( (g(1,ig) + xq_x(1)) * tau(1,na) + &
|
|
(g(2,ig) + xq_x(2)) * tau(2,na) + &
|
|
(g(3,ig) + xq_x(3)) * tau(3,na) )
|
|
|
|
guexp = tpiba * ( (g(1,ig) + xq_x(1)) * u_x(mu+1,nu_i) + &
|
|
(g(2,ig) + xq_x(2)) * u_x(mu+2,nu_i) + &
|
|
(g(3,ig) + xq_x(3)) * u_x(mu+3,nu_i) ) * &
|
|
(0.d0,-1.d0) * CMPLX(cos(gtau),-sin(gtau),kind=DP)
|
|
aux1 (nl(ig)) = aux1 (nl(ig)) + vloc_x (ig,nt) * guexp
|
|
if (upf(nt)%nlcc) then
|
|
aux2 (nl(ig)) = aux2 (nl(ig)) + drc_x(ig,nt) * guexp
|
|
end if
|
|
enddo
|
|
endif
|
|
|
|
enddo
|
|
CALL invfft ('Dense', aux1, dfftp)
|
|
dvloc (:) = dvloc(:) + aux1 (:)
|
|
if (nlcc_any) then
|
|
CALL invfft ('Dense', aux2, dfftp)
|
|
dvloc (:) = dvloc(:) + aux2 (:) * dmuxc(:,1,1)
|
|
endif
|
|
|
|
if (doublegrid) call cinterpolate (dvloc, dvloc, - 1)
|
|
deallocate (aux1)
|
|
deallocate (aux2)
|
|
return
|
|
end subroutine dvscf
|