! ! 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