mirror of https://gitlab.com/QEF/q-e.git
212 lines
7.4 KiB
Fortran
212 lines
7.4 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 addusdynmat (dynwrk)
|
|
!-----------------------------------------------------------------------
|
|
!! This routine computes the additional terms which are contained in
|
|
!! \(\langle\psi\|V''\|\psi\rangle\) part of the dynamical matrix and
|
|
!! which are due to the change of the self consistent D term in the
|
|
!! pseudopotential.
|
|
!! There are four additional terms which we compute here.
|
|
!
|
|
|
|
USE kinds, only : DP
|
|
USE ions_base, ONLY : nat, ityp
|
|
USE noncollin_module, ONLY : noncolin, npol
|
|
USE uspp, ONLY: okvan, becsum
|
|
USE uspp_param, only: upf, nh
|
|
USE lsda_mod, ONLY : nspin
|
|
USE noncollin_module, ONLY : nspin_lsda, lspinorb
|
|
|
|
USE phus, ONLY : int1, int1_nc, int2, int2_so, int4, int4_nc, &
|
|
int5, int5_so, alphasum, alphasum_nc, becsum_nc
|
|
USE modes, ONLY : nmodes
|
|
|
|
implicit none
|
|
|
|
complex(DP) :: dynwrk (3 * nat, 3 * nat)
|
|
!! inp/out: the dynamical matrix
|
|
|
|
integer :: ipol, jpol, np, na, nb, nu_i, nu_j, ih, jh, ijh, dim, &
|
|
is, is1, is2, ijs
|
|
! counter on polarizations
|
|
! counter on pseudopotentials
|
|
! counter on atoms
|
|
! counter on modes
|
|
! counter on solid beta functions
|
|
! composed dimension of the beta
|
|
! counter on spin
|
|
|
|
complex(DP) :: term (3, 3), dyn1 (3 * nat, 3 * nat)
|
|
! auxiliary space
|
|
! auxiliary dynamical matrix
|
|
|
|
|
|
if (.not.okvan) return
|
|
call start_clock ('addusdynmat')
|
|
|
|
IF (noncolin) CALL set_int12_nc(1)
|
|
|
|
dyn1 (:,:) = (0.d0, 0.d0)
|
|
!
|
|
! We compute the four terms required
|
|
!
|
|
do na = 1, nat
|
|
np = ityp (na)
|
|
if (upf(np)%tvanp ) then
|
|
dim = (nh (np) * (nh (np) + 1) ) / 2
|
|
do ipol = 1, 3
|
|
nu_i = 3 * (na - 1) + ipol
|
|
do jpol = 1, 3
|
|
nu_j = 3 * (na - 1) + jpol
|
|
IF (noncolin) THEN
|
|
ijh=1
|
|
DO ih=1,nh(np)
|
|
DO jh=ih,nh(np)
|
|
ijs=0
|
|
DO is1=1,npol
|
|
DO is2=1,npol
|
|
ijs=ijs+1
|
|
dynwrk(nu_i, nu_j)=dynwrk(nu_i, nu_j) + &
|
|
int4_nc(ih,jh,ipol,jpol,na,ijs) * &
|
|
becsum_nc(ijh,na,is1,is2)
|
|
IF (ih.NE.jh) THEN
|
|
dynwrk(nu_i, nu_j)=dynwrk(nu_i, nu_j) + &
|
|
int4_nc(jh,ih,ipol,jpol,na,ijs) * &
|
|
CONJG(becsum_nc(ijh,na,is2,is1))
|
|
END IF
|
|
END DO
|
|
END DO
|
|
ijh=ijh+1
|
|
END DO
|
|
END DO
|
|
ELSE
|
|
do is = 1, nspin
|
|
do ijh = 1, dim
|
|
dynwrk(nu_i, nu_j)=dynwrk(nu_i, nu_j)+ &
|
|
int4(ijh,ipol,jpol,na,is) * becsum(ijh,na,is)
|
|
enddo
|
|
enddo
|
|
END IF
|
|
enddo
|
|
enddo
|
|
!
|
|
! The second term requires an exchange of the components.
|
|
!
|
|
term (:,:) = (0.d0, 0.d0)
|
|
do ipol = 1, 3
|
|
do jpol = 1, 3
|
|
ijh = 0
|
|
do ih = 1, nh (np)
|
|
do jh = ih, nh (np)
|
|
ijh = ijh + 1
|
|
IF (noncolin) THEN
|
|
ijs=0
|
|
do is1 = 1, npol
|
|
do is2 = 1, npol
|
|
ijs=ijs+1
|
|
term(ipol,jpol) = term(ipol,jpol) + &
|
|
int1_nc(ih,jh,ipol,na,ijs)* &
|
|
alphasum_nc(ijh,jpol,na,is1,is2)
|
|
IF (ih.ne.jh) THEN
|
|
term(ipol,jpol) = term(ipol,jpol) + &
|
|
int1_nc(jh,ih,ipol,na,ijs)* &
|
|
CONJG(alphasum_nc(ijh,jpol,na,is2,is1))
|
|
ENDIF
|
|
enddo
|
|
enddo
|
|
ELSE
|
|
do is = 1, nspin
|
|
term(ipol,jpol) = term(ipol,jpol) + &
|
|
CONJG(int1(ih,jh,ipol,na,is))*alphasum(ijh,jpol,na,is)
|
|
enddo
|
|
END IF
|
|
enddo
|
|
enddo
|
|
enddo
|
|
enddo
|
|
!
|
|
! And then we add the appropriate terms to the dynamical matrix
|
|
!
|
|
do ipol = 1, 3
|
|
nu_i = 3 * (na - 1) + ipol
|
|
do jpol = 1, 3
|
|
nu_j = 3 * (na - 1) + jpol
|
|
dynwrk (nu_i, nu_j) = dynwrk (nu_i, nu_j) + &
|
|
term (ipol, jpol) + term (jpol, ipol)
|
|
enddo
|
|
enddo
|
|
!
|
|
! the other two terms do not contain a delta ss'
|
|
!
|
|
do nb = 1, nat
|
|
do ipol = 1, 3
|
|
nu_i = 3 * (nb - 1) + ipol
|
|
do jpol = 1, 3
|
|
nu_j = 3 * (na - 1) + jpol
|
|
ijh = 0
|
|
do ih = 1, nh (np)
|
|
do jh = ih, nh (np)
|
|
ijh = ijh + 1
|
|
IF (lspinorb) THEN
|
|
ijs=0
|
|
do is1 = 1, npol
|
|
do is2 = 1, npol
|
|
ijs=ijs+1
|
|
dyn1(nu_i,nu_j)=dyn1(nu_i,nu_j) + &
|
|
int2_so(ih,jh,ipol,nb,na,ijs) * &
|
|
alphasum_nc(ijh,jpol,na,is1,is2) + &
|
|
int5_so(ih,jh,ipol,jpol,nb,na,ijs) * &
|
|
becsum_nc(ijh,na,is1,is2)
|
|
IF (ih.ne.jh) THEN
|
|
dyn1(nu_i,nu_j)=dyn1(nu_i,nu_j) + &
|
|
int2_so(jh,ih,ipol,nb,na,ijs) * &
|
|
CONJG(alphasum_nc(ijh,jpol,na,is2,is1))+&
|
|
int5_so(jh,ih,ipol,jpol,nb,na,ijs) * &
|
|
CONJG(becsum_nc(ijh,na,is2,is1))
|
|
END IF
|
|
enddo
|
|
enddo
|
|
ELSE
|
|
do is = 1, nspin_lsda
|
|
dyn1(nu_i,nu_j)=dyn1(nu_i,nu_j) + &
|
|
CONJG(int2(ih,jh,ipol,nb,na)) * &
|
|
alphasum(ijh,jpol,na,is) + &
|
|
int5(ijh,ipol,jpol,nb,na) * &
|
|
becsum(ijh,na,is)
|
|
enddo
|
|
END IF
|
|
enddo
|
|
enddo
|
|
enddo
|
|
enddo
|
|
enddo
|
|
endif
|
|
|
|
enddo
|
|
do nu_i = 1, nmodes
|
|
do nu_j = 1, nmodes
|
|
dynwrk (nu_i, nu_j) = dynwrk (nu_i, nu_j) + &
|
|
dyn1 (nu_i, nu_j) + CONJG(dyn1 (nu_j, nu_i) )
|
|
enddo
|
|
enddo
|
|
deallocate (int4)
|
|
deallocate (int5)
|
|
|
|
IF (noncolin) THEN
|
|
call set_int12_nc(0)
|
|
deallocate(int4_nc)
|
|
if (lspinorb) deallocate(int5_so)
|
|
END IF
|
|
|
|
|
|
call stop_clock ('addusdynmat')
|
|
return
|
|
end subroutine addusdynmat
|