2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! 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 .
|
|
|
|
!
|
|
|
|
!
|
|
|
|
!-----------------------------------------------------------------------
|
2003-02-08 00:04:36 +08:00
|
|
|
subroutine qvan2 (ngy, ih, jh, np, qmod, qg, ylmk0)
|
2003-01-20 05:58:50 +08:00
|
|
|
!-----------------------------------------------------------------------
|
|
|
|
!
|
|
|
|
! This routine computes the fourier transform of the Q function assum
|
|
|
|
! that the radial fourier trasform is already computed and stored
|
|
|
|
! in qrad.
|
|
|
|
!
|
|
|
|
! The formula implemented here is
|
|
|
|
!
|
|
|
|
! q(g,l,k) = sum_lm (-i)^l ap(lm,l,k) yr_lm(g^) qrad(g,l,l,k)
|
|
|
|
!
|
|
|
|
!
|
|
|
|
! here the dummy variables
|
|
|
|
!
|
|
|
|
#include "machine.h"
|
2003-02-08 00:04:36 +08:00
|
|
|
use pwcom
|
2003-01-20 05:58:50 +08:00
|
|
|
implicit none
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: ngy, ih, jh, np
|
2003-01-20 05:58:50 +08:00
|
|
|
! input: the number of G vectors to compute
|
|
|
|
! input: the first index of Q
|
|
|
|
! input: the second index of Q
|
|
|
|
! input: the number of the pseudopotential
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
real(kind=DP) :: ylmk0 (ngy, lqx * lqx), qmod (ngy)
|
2003-01-20 05:58:50 +08:00
|
|
|
! the spherical harmonics
|
|
|
|
! input: moduli of the q+g vectors
|
2003-02-08 00:04:36 +08:00
|
|
|
complex(kind=DP) :: qg (ngy)
|
2003-01-20 05:58:50 +08:00
|
|
|
! output: the fourier transform of interest
|
|
|
|
!
|
|
|
|
! here the local variables
|
|
|
|
!
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
complex(kind=DP) :: sig
|
2003-01-20 05:58:50 +08:00
|
|
|
! (-i)^L
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
integer :: nb, mb, nmb, ivl, jvl, ig, lp, l, lm, i0, i1, i2, i3
|
2003-01-20 05:58:50 +08:00
|
|
|
! the atomic index corresponding to ih
|
|
|
|
! the atomic index corresponding to jh
|
|
|
|
! combined index (nb,mb)
|
|
|
|
! the lm corresponding to ih
|
|
|
|
! the lm corresponding to jh
|
|
|
|
! counter on g vectors
|
|
|
|
! the actual LM
|
|
|
|
! the angular momentum L
|
|
|
|
! the possible LM's compatible with ih,j
|
|
|
|
! counters for interpolation table
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
real(kind=DP) :: sixth, dqi, qm, px, ux, vx, wx, uvx, pwx, work
|
2003-01-20 05:58:50 +08:00
|
|
|
! 1 divided by six
|
|
|
|
! 1 divided dq
|
|
|
|
! qmod/dq
|
|
|
|
! measures for interpolation table
|
|
|
|
! auxiliary variables for intepolation
|
|
|
|
! auxiliary variable
|
|
|
|
!
|
2003-11-19 02:33:31 +08:00
|
|
|
LOGICAL :: ltest
|
|
|
|
!
|
2003-01-20 05:58:50 +08:00
|
|
|
! compute the indices which correspond to ih,jh
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
sixth = 1.d0 / 6.d0
|
|
|
|
dqi = 1 / dq
|
|
|
|
nb = indv (ih, np)
|
|
|
|
mb = indv (jh, np)
|
|
|
|
if (nb.ge.mb) then
|
|
|
|
nmb = nb * (nb - 1) / 2 + mb
|
|
|
|
else
|
|
|
|
nmb = mb * (mb - 1) / 2 + nb
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
ivl = nhtol (ih, np) * nhtol (ih, np) + nhtom (ih, np)
|
|
|
|
jvl = nhtol (jh, np) * nhtol (jh, np) + nhtom (jh, np)
|
2003-02-21 22:57:00 +08:00
|
|
|
if (nb.gt.nbrx) call errore (' qvan2 ', ' nb.gt.nbrx ', nb)
|
|
|
|
if (mb.gt.nbrx) call errore (' qvan2 ', ' mb.gt.nbrx ', mb)
|
|
|
|
if (ivl.gt.nlx) call errore (' qvan2 ', ' ivl.gt.nlx ', ivl)
|
|
|
|
if (jvl.gt.nlx) call errore (' qvan2 ', ' jvl.gt.nlx ', jvl)
|
2003-02-08 00:04:36 +08:00
|
|
|
qg(:) = (0.d0, 0.d0)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! and make the sum over the non zero LM
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
do lm = 1, lpx (ivl, jvl)
|
|
|
|
lp = lpl (ivl, jvl, lm)
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! extraction of angular momentum l from lp:
|
|
|
|
!
|
2003-02-08 00:04:36 +08:00
|
|
|
if (lp.eq.1) then
|
|
|
|
l = 1
|
|
|
|
elseif ( (lp.ge.2) .and. (lp.le.4) ) then
|
|
|
|
l = 2
|
|
|
|
elseif ( (lp.ge.5) .and. (lp.le.9) ) then
|
|
|
|
l = 3
|
|
|
|
elseif ( (lp.ge.10) .and. (lp.le.16) ) then
|
|
|
|
l = 4
|
|
|
|
elseif ( (lp.ge.17) .and. (lp.le.25) ) then
|
|
|
|
l = 5
|
|
|
|
elseif ( (lp.ge.26) .and. (lp.le.36) ) then
|
2003-01-20 05:58:50 +08:00
|
|
|
l = 6
|
2003-02-08 00:04:36 +08:00
|
|
|
elseif ( (lp.ge.37) .and. (lp.le.49) ) then
|
2003-01-20 05:58:50 +08:00
|
|
|
l = 7
|
|
|
|
else
|
2003-02-21 22:57:00 +08:00
|
|
|
call errore (' qvan ', ' lp > 49 ', lp)
|
2003-01-20 05:58:50 +08:00
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
sig = (0.d0, - 1.d0) ** (l - 1)
|
|
|
|
sig = sig * ap (lp, ivl, jvl)
|
|
|
|
do ig = 1, ngy
|
2003-01-20 05:58:50 +08:00
|
|
|
!
|
|
|
|
! calculate quantites depending on the module of G only when needed
|
|
|
|
!
|
2003-11-19 02:33:31 +08:00
|
|
|
IF ( ig > 1 ) ltest = ABS( qmod(ig) - qmod(ig-1) ) > 1.0D-6
|
|
|
|
!
|
|
|
|
IF ( ig == 1 .OR. ltest ) THEN
|
2003-02-08 00:04:36 +08:00
|
|
|
qm = qmod (ig) * dqi
|
|
|
|
px = qm - int (qm)
|
|
|
|
ux = 1.d0 - px
|
|
|
|
vx = 2.d0 - px
|
|
|
|
wx = 3.d0 - px
|
|
|
|
i0 = qm + 1
|
|
|
|
i1 = i0 + 1
|
|
|
|
i2 = i0 + 2
|
|
|
|
i3 = i0 + 3
|
|
|
|
uvx = ux * vx * sixth
|
|
|
|
pwx = px * wx * 0.5d0
|
2003-01-20 05:58:50 +08:00
|
|
|
work = qrad (i0, nmb, l, np) * uvx * wx + &
|
|
|
|
qrad (i1, nmb, l, np) * pwx * vx - &
|
|
|
|
qrad (i2, nmb, l, np) * pwx * ux + &
|
|
|
|
qrad (i3, nmb, l, np) * px * uvx
|
|
|
|
endif
|
2003-02-08 00:04:36 +08:00
|
|
|
qg (ig) = qg (ig) + sig * ylmk0 (ig, lp) * work
|
2003-01-20 05:58:50 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
return
|
2003-01-20 05:58:50 +08:00
|
|
|
end subroutine qvan2
|
|
|
|
|