mirror of https://gitlab.com/QEF/q-e.git
4435 lines
117 KiB
Fortran
4435 lines
117 KiB
Fortran
#include "f_defs.h"
|
||
!-----------------------------------------------------------------------
|
||
subroutine wf(clwf,c,bec,eigr,eigrb,taub,irb,b1,b2,b3,Uall,becdr,what1,wfc,jw,ibrav)
|
||
!-----------------------------------------------------------------------
|
||
!
|
||
! this routine calculates overlap matrices
|
||
!
|
||
! routine makes use of c(-g)=c*(g) and beta(-g)=beta*(g)
|
||
!
|
||
use constants
|
||
use ions_base, only : nsp, na, nas=>nax
|
||
use parameters, only : natx, nsx
|
||
!use gvec
|
||
use gvecs
|
||
use cvan
|
||
use cell_base, only : omega, a1, a2, a3, alat
|
||
use elct
|
||
use gvecb
|
||
use gvecw, only : ngw, ng0
|
||
use small_box
|
||
! use parms
|
||
use smooth_grid_dimensions , nnrs => nnrsx
|
||
use control_flags
|
||
use qgb_mod
|
||
use wfparm
|
||
use wfparm2
|
||
use grid_dimensions, only : nr1, nr2, nr3
|
||
use smallbox_grid_dimensions ,nnrb => nnrbx
|
||
use uspp_param, only: nh, nhm
|
||
use uspp, only : nhsa=> nkb
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
!
|
||
logical what1
|
||
! integer, intent(in) :: nas
|
||
integer, intent(in) :: irb(3,natx,nsx),jw, ibrav
|
||
! integer, intent(in) :: irb(3,nax,nsx),jw, ibrav
|
||
! integer :: irb(3,nax,nsx),jw, ibrav
|
||
real(kind=8), intent(inout) :: bec(nhsa,n), becdr(nhsa,n,3)
|
||
real(kind=8), intent(in) :: b1(3),b2(3),b3(3),taub(3,nas)
|
||
real(kind=8) :: becwf(nhsa,n) , becdrwf(nhsa,n), temp3(nhsa,n)
|
||
complex(kind=8), intent(inout) :: c(ngw,nx)
|
||
complex(kind=8), intent(in) :: eigr(ngw,nas,nsp),eigrb(ngb,nas,nsp)
|
||
complex(kind=8) :: cwf(ngw,nx), bec2(n), bec3(n), bec2up(nupdwn(1))
|
||
complex(kind=8) :: bec2dw(nupdwn(2)), bec3up(nupdwn(1)), bec3dw(nupdwn(2))
|
||
complex(kind=8),allocatable :: c_m(:,:),c_p(:,:),c_psp(:,:),c2(:,:)
|
||
complex(kind=8),allocatable :: c_msp(:,:)
|
||
real(kind=8), intent(inout) :: Uall(n,n)
|
||
integer, allocatable :: tagz(:)
|
||
!
|
||
integer :: inl, jnl, iss, isa, is, ia, ijv, i, j, k, l, &
|
||
ig, ierr, ti, tj, tk, iv, jv, inw, iqv, ibig1, ibig2, ibig3, &
|
||
ir1, ir2, ir3, ir, b5(3), b6(3), clwf, m,ib,jb, total, nstat, jj
|
||
integer :: ngpww, irb3
|
||
real(kind=8) :: t1, t2, t3, taup(3), pi2
|
||
real(kind=8), allocatable, dimension(:, :) :: Uspin
|
||
complex(kind=8) :: ci, ct1, ct2, ct3, qvt, alpha, beta1
|
||
complex(kind=8), allocatable, dimension(:, :) :: X, X1,Xsp,X2,X3
|
||
complex(kind=8), allocatable, dimension(:, :, :) :: O, Ospin, Oa
|
||
real(kind=8), parameter :: autoaf=0.529177d0
|
||
real(kind=8) alen,blen,clen
|
||
|
||
complex(kind=8), allocatable, dimension(:) :: qv
|
||
!
|
||
!
|
||
integer,allocatable :: f3(:), f4(:)
|
||
real(kind=8), allocatable :: gr(:,:), mt(:), W(:,:), wr(:)
|
||
integer :: adjust,ini, ierr1,nnn
|
||
complex(kind=8) :: U2(n,n)
|
||
complex(kind=8) :: boxdotgridcplx
|
||
external boxdotgridcplx
|
||
|
||
!
|
||
#ifdef __PARA
|
||
integer proc, ntot, ncol, mc, ngpwpp(nproc)
|
||
integer ncol1,nz1, nz_1
|
||
integer nmin(3), nmax(3), n1,n2,nzx,nz,nz_
|
||
integer nmin1(3), nmax1(3)
|
||
integer root, rdispls(nproc), recvcount(nproc), sendcount(nproc), sdispls(nproc)
|
||
integer rdispls2(nproc), recvcount2(nproc), sendcount2(nproc), sdispls2(nproc)
|
||
integer rdispls1(nproc), recvcount1(nproc), sendcount1(nproc), sdispls1(nproc)
|
||
complex*16, allocatable:: psitot(:,:), psitot_pl(:,:)
|
||
complex*16, allocatable:: psitot1(:), psitot_p(:)
|
||
complex*16, allocatable:: psitot_mi(:,:)
|
||
complex*16, allocatable:: psitot_m(:)
|
||
integer , allocatable :: ns(:)
|
||
#else
|
||
#endif
|
||
|
||
|
||
|
||
integer igx,igy,igz
|
||
real(kind=8) wfcx, wfcy, wfcz
|
||
real(kind=8) wfc(3,n)
|
||
|
||
real(kind=8) te(6)
|
||
!
|
||
ci=(0.d0,1.d0)
|
||
alpha=(1.d0,0.d0)
|
||
beta1=(0.d0,0.d0)
|
||
pi2=2.d0*pi
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Now Entering wf..."
|
||
end if
|
||
|
||
!
|
||
!
|
||
!set up the weights and the G vectors for wannie-function calculation
|
||
|
||
te=0.d0
|
||
!
|
||
select case (ibrav)
|
||
|
||
case (0)
|
||
!free cell used for cpr
|
||
nw=6
|
||
allocate(wfg(nw,3), weight(nw))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
call tric_wts(b1,b2,b3,alat,weight) !**** assigns weights for the triclinic/cpr case
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,2)=1
|
||
wfg(5,2)=1
|
||
wfg(5,3)=1
|
||
wfg(6,1)=1
|
||
wfg(6,3)=1
|
||
go to 99
|
||
|
||
case (1)
|
||
!cubic P [sc]
|
||
nw=3
|
||
allocate(tagz(nw))
|
||
allocate(wfg(3,3), weight(3))
|
||
weight=1.d0
|
||
wfg=0
|
||
tagz=1
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
tagz(3)=0
|
||
go to 99
|
||
|
||
case(2)
|
||
!cubic F [fcc]
|
||
nw=4
|
||
allocate (tagz(nw))
|
||
allocate(wfg(4,3), weight(4))
|
||
weight=0.25d0
|
||
wfg=0
|
||
tagz=1
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,:)=-1
|
||
tagz(3)=0
|
||
go to 99
|
||
|
||
case(3)
|
||
!cubic I [bcc]
|
||
nw=6
|
||
allocate(wfg(6,3), weight(6))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
weight=0.25d0
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,2)=1
|
||
wfg(5,2)=1
|
||
wfg(5,3)=1
|
||
wfg(6,1)=-1
|
||
wfg(6,3)=1
|
||
go to 99
|
||
|
||
case(4)
|
||
!hexagonal and trigonal P
|
||
nw=4
|
||
allocate(wfg(4,3), weight(4))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
weight(1)=0.5d0
|
||
weight(2)=0.5d0
|
||
weight(3)=1.d0/(b3(3)**2)
|
||
weight(4)=0.5d0
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,2)=-1
|
||
go to 99
|
||
|
||
case(5)
|
||
!trigonal R
|
||
nw=6
|
||
allocate(wfg(6,3), weight(6))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
t1=1.d0-1.d0/(b2(2)**2*1.5d0)
|
||
weight(1)=1.d0
|
||
weight(2)=1.d0+2.d0*t1
|
||
weight(3)=1.d0
|
||
weight(4)=t1
|
||
weight(5)=-t1
|
||
weight(6)=-t1
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,3)=1
|
||
wfg(5,2)=-1
|
||
wfg(5,3)=1
|
||
wfg(6,1)=1
|
||
wfg(6,2)=-1
|
||
go to 99
|
||
|
||
case(6)
|
||
!tetragonal P[st]
|
||
nw=3
|
||
allocate(wfg(3,3), weight(3))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
weight(1)=1.d0
|
||
weight(2)=1.d0
|
||
weight(3)=1.d0/(b3(3)**2)
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
go to 99
|
||
|
||
case(7)
|
||
!tetragonal I [bct]
|
||
nw=6
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
allocate(wfg(6,3), weight(6))
|
||
t1=0.25d0/(b2(3)**2)
|
||
weight(1)=0.5d0-t1
|
||
weight(2)=t1
|
||
weight(3)=t1
|
||
weight(4)=t1
|
||
weight(5)=weight(1)
|
||
weight(6)=t1
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,3)=1
|
||
wfg(5,2)=1
|
||
wfg(5,3)=-1
|
||
wfg(6,1)=1
|
||
wfg(6,2)=1
|
||
go to 99
|
||
|
||
case(8)
|
||
!orthorhombic P
|
||
nw=3
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
allocate(wfg(3,3), weight(3))
|
||
weight(1)=1.d0
|
||
weight(2)=1.d0/(b2(2)**2)
|
||
weight(3)=1.d0/(b3(3)**2)
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
go to 99
|
||
|
||
case(9)
|
||
!one face centered orthorhombic C
|
||
if (b1(2).eq.1) then
|
||
nw=3
|
||
allocate(wfg(3,3), weight(3))
|
||
allocate(tagz(nw))
|
||
wfg=0
|
||
weight(1)=0.5d0
|
||
weight(2)=0.5d0
|
||
else
|
||
if (b1(2).gt.1) then
|
||
write(6, *) "Please make celldm(2) not less than 1"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
stop
|
||
else
|
||
nw=4
|
||
allocate(wfg(4,3), weight(4))
|
||
allocate(tagz(nw))
|
||
wfg=0
|
||
weight(1)=0.5d0
|
||
weight(2)=0.5d0
|
||
weight(4)=(1.d0/(b1(2)**2)-1.d0)/4.d0
|
||
wfg(4,1)=1
|
||
wfg(4,2)=1
|
||
end if
|
||
end if
|
||
weight(3)=1.d0/(b3(3)**2)
|
||
tagz=1
|
||
tagz(3)=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
go to 99
|
||
|
||
case(10)
|
||
!all face centered orthorhombic F
|
||
if (b1(2).eq.-1.and.b1(3).eq.1) then
|
||
write(6, *) "Please change ibrav to 2"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
stop
|
||
end if
|
||
if ((b1(1).gt.b1(3)).or.(b1(1)+b1(2).lt.0)) then
|
||
write(6, *) "Please make celldm(2) >= 1 >= celldm(3)"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
stop
|
||
end if
|
||
if (b1(3).eq.1) then
|
||
nw=5
|
||
allocate(wfg(5,3), weight(5))
|
||
allocate(tagz(nw))
|
||
else
|
||
nw=6
|
||
allocate(wfg(6,3), weight(6))
|
||
allocate(tagz(nw))
|
||
end if
|
||
weight=0.25d0/(b1(3)**2)
|
||
wfg=0
|
||
tagz=1
|
||
tagz(3)=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,:)=1
|
||
weight(5)=0.25d0/(b1(2)**2)-weight(1)
|
||
wfg(5,2)=1
|
||
wfg(5,3)=1
|
||
if (b1(3).ne.1) then
|
||
weight(6)=0.25d0-weight(1)
|
||
wfg(6,1)=1
|
||
wfg(6,2)=1
|
||
end if
|
||
go to 99
|
||
|
||
case(11)
|
||
!body centered orthohombic I
|
||
if ((b1(3).eq.1).and.(b2(2).eq.1)) then
|
||
write(6, *) "Please change ibrav to 3"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
stop
|
||
end if
|
||
if ((b1(3).eq.1).or.(b2(2).eq.1)) then
|
||
write(6, *) "Please change ibrav to 7"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
stop
|
||
end if
|
||
nw=6
|
||
allocate(wfg(6,3), weight(6))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
t1=0.25d0
|
||
t2=t1/(b2(2)**2)
|
||
t3=t1/(b1(3)**2)
|
||
weight(1)=t1-t2+t3
|
||
weight(2)=t1+t2-t3
|
||
weight(3)=-t1+t2+t3
|
||
weight(4)=weight(3)
|
||
weight(5)=weight(1)
|
||
weight(6)=weight(2)
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,2)=1
|
||
wfg(5,2)=1
|
||
wfg(5,3)=1
|
||
wfg(6,1)=-1
|
||
wfg(6,3)=1
|
||
go to 99
|
||
|
||
case(12)
|
||
!monoclinic P
|
||
nw=4
|
||
allocate(wfg(4,3), weight(4))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
t1=-b1(2)/b2(2)
|
||
k=nint(t1)
|
||
if ((k.eq.0).and.(t1.ge.0)) k=1
|
||
if ((k.eq.0).and.(t1.le.0)) k=-1
|
||
weight(4)=t1/dfloat(k)
|
||
weight(1)=1.d0-weight(4)
|
||
t2=t1/sqrt(1.d0-1.d0/(1.d0+b1(2)**2))
|
||
weight(2)=t2**2-t1*k
|
||
weight(3)=1.d0/(b3(3)**2)
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,2)=k
|
||
go to 99
|
||
|
||
case(13)
|
||
!one face centered monoclinic C
|
||
nw=6
|
||
allocate(wfg(6,3), weight(6))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
t1=-b1(2)/b3(2)
|
||
k=nint(t1)
|
||
if ((k.eq.0).and.(t1.ge.0)) k=1
|
||
if ((k.eq.0).and.(t1.le.0)) k=-1
|
||
t2=1.d0/(4.d0*b1(1)**2)
|
||
t3=1.d0/(b3(2)**2)
|
||
weight(1)=2.d0*t2*(1.d0-t1)
|
||
weight(2)=weight(1)
|
||
weight(3)=t3+4.d0*t2*t1*(t1-k)
|
||
weight(4)=1.d0-2.d0*t2
|
||
weight(5)=2.d0*t1*t2/dfloat(k)
|
||
weight(6)=weight(5)
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,2)=-1
|
||
wfg(5,1)=1
|
||
wfg(5,3)=k
|
||
wfg(6,2)=1
|
||
wfg(6,3)=k
|
||
go to 99
|
||
|
||
case default
|
||
!free cell used for cpr
|
||
nw=6
|
||
allocate(wfg(nw,3), weight(nw))
|
||
allocate(tagz(nw))
|
||
tagz=1
|
||
tagz(3)=0
|
||
call tric_wts(b1,b2,b3,alat,weight) !**** assigns weights for the triclinic/cpr case
|
||
wfg=0
|
||
wfg(1,1)=1
|
||
wfg(2,2)=1
|
||
wfg(3,3)=1
|
||
wfg(4,1)=1
|
||
wfg(4,2)=1
|
||
wfg(5,2)=1
|
||
wfg(5,3)=1
|
||
wfg(6,1)=1
|
||
wfg(6,3)=1
|
||
go to 99
|
||
|
||
!ibrav=14: triclinic P
|
||
|
||
! write(6, *) "not available to calculate wannier-function for this ibrav"
|
||
!#ifdef __PARA
|
||
! call mpi_finalize(i)
|
||
!#endif
|
||
! stop
|
||
end select
|
||
|
||
!
|
||
! set up matrix O
|
||
!
|
||
99 allocate(O(nw, n, n), X(n,n),Oa(nw, n, n))
|
||
if(nspin.eq.2.and.nvb.gt.0) then
|
||
allocate(X2(nupdwn(1),nupdwn(1)))
|
||
allocate(X3(nupdwn(2),nupdwn(2)))
|
||
end if
|
||
|
||
|
||
! do inw=1,nw
|
||
! do i=1,ngw
|
||
! write(6,*) indexplus(i,inw), tagp(i,inw)
|
||
! write(6,*) indexminus(i,inw), tag(i,inw)
|
||
! end do
|
||
! end do
|
||
|
||
|
||
|
||
#ifdef __PARA
|
||
|
||
allocate (ns(nproc))
|
||
do i=1,nproc
|
||
ns(i)=0
|
||
end do
|
||
|
||
if(n.eq.nproc) then
|
||
do i=1,n
|
||
ns(i)=1
|
||
end do
|
||
else
|
||
i=0
|
||
1 do j=1,nproc
|
||
ns(j)=ns(j)+1
|
||
i=i+1
|
||
if(i.ge.n) go to 2
|
||
end do
|
||
if(i.lt.n) go to 1
|
||
end if
|
||
2 if(iprsta.gt.4) then
|
||
do j=1,nproc
|
||
write(6,*) ns(j)
|
||
end do
|
||
end if
|
||
|
||
total = 0
|
||
do proc=1,nproc
|
||
ngpwpp(proc)=(dfftp%nwl(proc)+1)/2
|
||
total=total+ngpwpp(proc)
|
||
! nstat=ns(proc)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "I am proceessor", proc, "and i have ",ns(me)," states."
|
||
end if
|
||
end do
|
||
nstat=ns(me)
|
||
|
||
allocate(psitot(total,nstat))
|
||
allocate(psitot1(total*nstat))
|
||
allocate(psitot_pl(total,nstat))
|
||
allocate(psitot_p(total*nstat))
|
||
allocate(psitot_mi(total,nstat))
|
||
allocate(psitot_m(total*nstat))
|
||
|
||
allocate(c_p(ngw,nx))
|
||
allocate(c_m(ngw,nx))
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "All allocations done"
|
||
end if
|
||
|
||
|
||
do proc=1,nproc
|
||
sendcount(proc)=ngpwpp(me)*ns(proc)
|
||
recvcount(proc)=ngpwpp(proc)*ns(me)
|
||
end do
|
||
sdispls(1)=0
|
||
rdispls(1)=0
|
||
|
||
do proc=2,nproc
|
||
sdispls(proc)=sdispls(proc-1)+sendcount(proc-1)
|
||
rdispls(proc)=rdispls(proc-1)+recvcount(proc-1)
|
||
end do
|
||
!
|
||
! Step 1. Communicate to all Procs so that each proc has all
|
||
! G-vectors and some states instead of all states and some
|
||
! G-vectors. This information is stored in the 1-d array
|
||
! psitot1.
|
||
!
|
||
|
||
call MPI_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('WF','ierr<>0',ierr)
|
||
call MPI_alltoallv(c, sendcount, sdispls, MPI_DOUBLE_COMPLEX, &
|
||
& psitot1, recvcount, rdispls, MPI_DOUBLE_COMPLEX, &
|
||
& MPI_COMM_WORLD,ierr)
|
||
if (ierr.ne.0) call errore('WF','alltoallv 1',ierr)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Step 1. Communicate to all Procs ... Done, wf"
|
||
end if
|
||
#endif
|
||
if(clwf.eq.5) then
|
||
#ifdef __PARA
|
||
call write_psi(c,jw)
|
||
call MPI_finalize(ierr)
|
||
write(6,*) "State written", jw
|
||
STOP
|
||
end if
|
||
#else
|
||
do i=1,ngw
|
||
write(22,*) c(i,jw)
|
||
end do
|
||
write(6,*) "State written", jw
|
||
STOP
|
||
end if
|
||
#endif
|
||
|
||
#ifdef __PARA
|
||
!
|
||
! Step 2. Convert the 1-d array psitot1 into a 2-d array consistent with the
|
||
! original notation c(ngw,n). Psitot contains ntot = SUM_Procs(ngw) G-vecs
|
||
! and nstat states instead of all n states
|
||
!
|
||
|
||
ngpww=0
|
||
do proc=1,nproc
|
||
do i=1,ns(me)
|
||
do j=1,ngpwpp(proc)
|
||
psitot(j+ngpww,i)=psitot1(rdispls(proc)+j+(i-1)*ngpwpp(proc))
|
||
end do
|
||
end do
|
||
ngpww=ngpww+ngpwpp(proc)
|
||
end do
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Step 2. Convert the 1-d array psitot1 into a 2-d array... Done, wf"
|
||
end if
|
||
|
||
!
|
||
! Step 3. do the translation of the 2-d array to get the transtalted
|
||
! arrays psitot_pl and psittot_mi, corresponding to G+G' and -G+G'
|
||
!
|
||
|
||
do inw=1,nw
|
||
!
|
||
! Intermediate Check. If the translation is only along the z-direction
|
||
! no interprocessor communication and data rearrangement is required
|
||
! because each processor contains all the G- components in the z-dir.
|
||
!
|
||
if(tagz(inw).eq.0) then
|
||
do i=1,n
|
||
do ig=1,ngw
|
||
if(indexplusz(ig).eq.-1) then
|
||
c_p(ig,i)=(0.d0,0.d0)
|
||
else
|
||
c_p(ig,i)=c(indexplusz(ig),i)
|
||
end if
|
||
if(indexminusz(ig).eq.-1) then
|
||
c_m(ig,i)=(0.d0,0.d0)
|
||
else
|
||
c_m(ig,i)=conjg(c(indexminusz(ig),i))
|
||
end if
|
||
end do
|
||
end do
|
||
else
|
||
do i=1,ns(me)
|
||
do ig=1,total
|
||
if(indexplus(ig,inw).eq.-1) then
|
||
psitot_pl(ig,i)=(0.d0,0.d0)
|
||
else
|
||
if(tagp(ig,inw).eq.1) then
|
||
psitot_pl(ig,i)=conjg(psitot(indexplus(ig,inw),i))
|
||
else
|
||
psitot_pl(ig,i)=psitot(indexplus(ig,inw),i)
|
||
end if
|
||
end if
|
||
if(indexminus(ig,inw).eq.-1) then
|
||
psitot_mi(ig,i)=(0.d0,0.d0)
|
||
else
|
||
if(tag(ig,inw).eq.1) then
|
||
psitot_mi(ig,i)=conjg(psitot(indexminus(ig,inw),i))
|
||
else
|
||
psitot_mi(ig,i)=psitot(indexminus(ig,inw),i)
|
||
end if
|
||
end if
|
||
end do
|
||
end do
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Step 3. do the translation of the 2-d array...Done, wf"
|
||
end if
|
||
!
|
||
! Step 4. Convert the 2-d arrays psitot_p and psitot_m into 1-d
|
||
! arrays
|
||
!
|
||
ngpww=0
|
||
do proc=1,nproc
|
||
do i=1,ns(me)
|
||
do j=1,ngpwpp(proc)
|
||
psitot_p(rdispls(proc)+j+(i-1)*ngpwpp(proc))=psitot_pl(j+ngpww,i)
|
||
psitot_m(rdispls(proc)+j+(i-1)*ngpwpp(proc))=psitot_mi(j+ngpww,i)
|
||
end do
|
||
end do
|
||
ngpww=ngpww+ngpwpp(proc)
|
||
end do
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Convert the 2-d arrays psitot_p and psitot_m into 1-d arrays...Done, wf"
|
||
end if
|
||
!
|
||
! Step 5. Redistribute among processors. The result is stored in 2-d
|
||
! arrays c_p and c_m consistent with the notation c(ngw,n), such that
|
||
! c_p(j,i) contains the coefficient for c(j,i) corresponding to G+G'
|
||
! and c_m(j,i) contains the coefficient for c(j,i) corresponding to -G+G'
|
||
!
|
||
c_p = 0.0d0 ! call ZERO(2*ngw*nx,c_p)
|
||
call MPI_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('WF','ierr<>0',ierr)
|
||
call MPI_alltoallv(psitot_p, recvcount, rdispls, MPI_DOUBLE_COMPLEX, &
|
||
& c_p, sendcount , sdispls, MPI_DOUBLE_COMPLEX, &
|
||
& MPI_COMM_WORLD,ierr)
|
||
if (ierr.ne.0) call errore('WF','alltoallv 2',ierr)
|
||
|
||
c_m = 0.0d0 ! call ZERO(2*ngw*nx,c_m)
|
||
call MPI_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('WF','ierr<>0',ierr)
|
||
call MPI_alltoallv(psitot_m, recvcount, rdispls, MPI_DOUBLE_COMPLEX, &
|
||
& c_m, sendcount, sdispls, MPI_DOUBLE_COMPLEX, &
|
||
& MPI_COMM_WORLD,ierr)
|
||
if (ierr.ne.0) call errore('WF','alltoallv 3',ierr)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Step 5. Redistribute among processors...Done, wf"
|
||
end if
|
||
end if
|
||
#else
|
||
allocate(c_p(ngw,nx))
|
||
allocate(c_m(ngw,nx))
|
||
do inw=1,nw
|
||
if(tagz(inw).eq.0) then
|
||
do i=1,n
|
||
do ig=1,ngw
|
||
if(indexplusz(ig).eq.-1) then
|
||
c_p(ig,i)=(0.d0,0.d0)
|
||
else
|
||
c_p(ig,i)=c(indexplusz(ig),i)
|
||
end if
|
||
if(indexminusz(ig).eq.-1) then
|
||
c_m(ig,i)=(0.d0,0.d0)
|
||
else
|
||
c_m(ig,i)=conjg(c(indexminusz(ig),i))
|
||
end if
|
||
end do
|
||
end do
|
||
else
|
||
do i=1,n
|
||
do ig=1,ngw
|
||
if(indexplus(ig,inw).eq.-1) then
|
||
c_p(ig,i)=(0.d0,0.d0)
|
||
else
|
||
if(tagp(ig,inw).eq.1) then
|
||
c_p(ig,i)=conjg(c(indexplus(ig,inw),i))
|
||
else
|
||
c_p(ig,i)=c(indexplus(ig,inw),i)
|
||
end if
|
||
end if
|
||
if(indexminus(ig,inw).eq.-1) then
|
||
c_m(ig,i)=(0.d0,0.d0)
|
||
else
|
||
if(tag(ig,inw).eq.1) then
|
||
c_m(ig,i)=conjg(c(indexminus(ig,inw),i))
|
||
else
|
||
c_m(ig,i)=c(indexminus(ig,inw),i)
|
||
end if
|
||
end if
|
||
end do
|
||
end do
|
||
end if
|
||
#endif
|
||
|
||
!
|
||
! Step 6. Calculate Overlaps
|
||
!
|
||
! Augmentation Part first
|
||
|
||
allocate( qv( nnrb ) )
|
||
|
||
X=(0.d0, 0.d0)
|
||
!
|
||
!
|
||
do is = 1, nvb
|
||
do ia =1, na(is)
|
||
ijv = 0
|
||
do iv = 1, nh(is)
|
||
inl = ish(is) + (iv-1)*na(is) + ia
|
||
ijv = ijv + 1
|
||
qv( 1 : nnrb ) = 0.0d0
|
||
do ig=1,ngb
|
||
qv(npb(ig))=eigrb(ig,ia,is)*qgb(ig,ijv,is)
|
||
qv(nmb(ig))=conjg(eigrb(ig,ia,is)*qgb(ig,ijv,is))
|
||
end do
|
||
#ifdef __PARA
|
||
irb3=irb(3,ia,is)
|
||
#endif
|
||
call ivfftb(qv,nr1b,nr2b,nr3b,nr1bx,nr2bx,nr3bx,irb3)
|
||
iqv=1
|
||
qvt=(0.d0,0.d0)
|
||
qvt=boxdotgridcplx(irb(1,ia,is),qv,expo(1,inw))
|
||
|
||
#ifdef __PARA
|
||
call reduce(2, qvt)
|
||
#endif
|
||
!
|
||
if (nspin.eq.1) then
|
||
bec2(1:n)=(0.d0,0.d0)
|
||
bec2(1:n)=bec(inl,1:n)*alpha
|
||
call ZSYRK('U','T',n,1,qvt,bec2,1,alpha,X,n)
|
||
else
|
||
X2=(0.d0,0.d0)
|
||
X3=(0.d0,0.d0)
|
||
bec2up(1:nupdwn(1))=(0.d0,0.d0)
|
||
bec2up(1:nupdwn(1))=bec(inl,1:nupdwn(1))
|
||
call ZSYRK('U','T',nupdwn(1),1,qvt,bec2up,1,alpha,X2,nupdwn(1))
|
||
bec2dw(1:nupdwn(2))=(0.d0,0.d0)
|
||
bec2dw(1:nupdwn(2))=bec(inl,iupdwn(2):n)
|
||
call ZSYRK('U','T',nupdwn(2),1,qvt,bec2dw,1,alpha,X3,nupdwn(2))
|
||
do i = 1, nupdwn(1)
|
||
do j=i, nupdwn(1)
|
||
X(i,j)=X(i,j)+X2(i,j)
|
||
end do
|
||
end do
|
||
do i = 1,nupdwn(2)
|
||
do j=i,nupdwn(2)
|
||
X(i+nupdwn(1),j+nupdwn(1)) =X(i+nupdwn(1),j+nupdwn(1)) + X3(i,j)
|
||
end do
|
||
end do
|
||
end if
|
||
do jv = iv + 1, nh(is)
|
||
jnl = ish(is) + (jv-1)*na(is) + ia
|
||
ijv = ijv + 1
|
||
qv( 1:nnrb ) = 0.0d0 ! call zero(2*nnrb,qv)
|
||
do ig=1,ngb
|
||
qv(npb(ig))=eigrb(ig,ia,is)*qgb(ig,ijv,is)
|
||
qv(nmb(ig))=conjg(eigrb(ig,ia,is)*qgb(ig,ijv,is))
|
||
end do
|
||
call ivfftbold(qv,nr1b,nr2b,nr3b,nr1bx,nr2bx,nr3bx,irb3)
|
||
iqv=1
|
||
qvt=0.d0
|
||
qvt=boxdotgridcplx(irb(1,ia,is),qv,expo(1,inw))
|
||
#ifdef __PARA
|
||
call reduce(2, qvt)
|
||
#endif
|
||
!
|
||
if (nspin.eq.1) then
|
||
bec2(1:n)=(0.d0,0.d0)
|
||
bec3(1:n)=(0.d0,0.d0)
|
||
bec2(1:n)=bec(inl,1:n)*alpha
|
||
bec3(1:n)=bec(jnl,1:n)*alpha
|
||
call ZSYR2K('U','T',n,1,qvt,bec2,1,bec3,1,alpha,X,n)
|
||
else
|
||
X2=(0.d0,0.d0)
|
||
X3=(0.d0,0.d0)
|
||
bec2up(1:nupdwn(1))=(0.d0,0.d0)
|
||
bec3up(1:nupdwn(1))=(0.d0,0.d0)
|
||
bec2up(1:nupdwn(1))=bec(inl,1:nupdwn(1))*alpha
|
||
bec3up(1:nupdwn(1))=bec(jnl,1:nupdwn(1))*alpha
|
||
call ZSYR2K('U','T',nupdwn(1),1,qvt,bec2up,1,bec3up,1,alpha,X2,nupdwn(1))
|
||
bec2dw(1:nupdwn(2))=(0.d0,0.d0)
|
||
bec3dw(1:nupdwn(2))=(0.d0,0.d0)
|
||
bec2dw(1:nupdwn(2))=bec(inl,iupdwn(2):n)*alpha
|
||
bec3dw(1:nupdwn(2))=bec(jnl,iupdwn(2):n)*alpha
|
||
call ZSYR2K('U','T',nupdwn(2),1,qvt,bec2dw,1,bec3dw,1,alpha,X3,nupdwn(2))
|
||
do i = 1, nupdwn(1)
|
||
do j=i, nupdwn(1)
|
||
X(i,j)=X(i,j)+X2(i,j)
|
||
end do
|
||
end do
|
||
do i = 1,nupdwn(2)
|
||
do j=i,nupdwn(2)
|
||
X(i+nupdwn(1),j+nupdwn(1)) =X(i+nupdwn(1),j+nupdwn(1)) + X3(i,j)
|
||
end do
|
||
end do
|
||
end if
|
||
end do
|
||
end do
|
||
end do
|
||
end do
|
||
t1=omega/dfloat(nr1*nr2*nr3)
|
||
X=X*t1
|
||
do i=1, n
|
||
do j=i+1, n
|
||
X(j, i)=X(i, j)
|
||
end do
|
||
end do
|
||
Oa(inw, :, :)=X(:, :)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Augmentation Part Done"
|
||
end if
|
||
|
||
deallocate( qv )
|
||
|
||
! Then Soft Part
|
||
if(nspin.eq.1) then
|
||
! Spin Unpolarized calculation
|
||
X=0.d0
|
||
if(ng0.eq.2) then
|
||
c_m(1,:)=0.d0
|
||
end if
|
||
! cwf(:,:)=beta1
|
||
! cwf(:,:)=c(:,:)
|
||
call ZGEMM('c','N',n,n,ngw,alpha,c,ngw,c_p,ngw,alpha,X,n)
|
||
call ZGEMM('T','N',n,n,ngw,alpha,c,ngw,c_m,ngw,alpha,X,n)
|
||
#ifdef __PARA
|
||
call reduce (2*n*n,X)
|
||
#endif
|
||
O(inw,:,:)=Oa(inw,:,:)+X(:,:)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Soft Part Done"
|
||
end if
|
||
|
||
else
|
||
! Spin Polarized case
|
||
! Up Spin First
|
||
allocate(Xsp(n,nupdwn(1)))
|
||
allocate(c_psp(ngw,nupdwn(1)))
|
||
allocate(c_msp(ngw,nupdwn(1)))
|
||
Xsp=0.d0
|
||
c_psp=0.d0
|
||
c_msp=0.d0
|
||
do i=1,nupdwn(1)
|
||
c_psp(:,i)=c_p(:,i)
|
||
c_msp(:,i)=c_m(:,i)
|
||
end do
|
||
if(ng0.eq.2) then
|
||
c_msp(1,:)=0.d0
|
||
end if
|
||
! cwf(:,:)=beta1
|
||
! cwf(:,:)=c(:,:,1,1)
|
||
call ZGEMM('c','N',n,nupdwn(1),ngw,alpha,c,ngw,c_psp,ngw,alpha,Xsp,n)
|
||
call ZGEMM('T','N',n,nupdwn(1),ngw,alpha,c,ngw,c_msp,ngw,alpha,Xsp,n)
|
||
#ifdef __PARA
|
||
call reduce (2*n*nupdwn(1),Xsp)
|
||
#endif
|
||
do i=1,nupdwn(1)
|
||
do j=1,n
|
||
X(j,i)=Xsp(j,i)
|
||
end do
|
||
end do
|
||
deallocate(Xsp,c_psp,c_msp)
|
||
! Then Down Spin
|
||
allocate(Xsp(n,iupdwn(2):n))
|
||
allocate(c_psp(ngw,iupdwn(2):n))
|
||
allocate(c_msp(ngw,iupdwn(2):n))
|
||
Xsp=0.d0
|
||
c_psp=0.d0
|
||
c_msp=0.d0
|
||
do i=iupdwn(2),n
|
||
c_psp(:,i)=c_p(:,i)
|
||
c_msp(:,i)=c_m(:,i)
|
||
end do
|
||
if(ng0.eq.2) then
|
||
c_msp(1,:)=0.d0
|
||
end if
|
||
! cwf(:,:)=beta1
|
||
! cwf(:,:)=c(:,:,1,1)
|
||
call ZGEMM('c','N',n,nupdwn(2),ngw,alpha,c,ngw,c_psp,ngw,alpha,Xsp,n)
|
||
call ZGEMM('T','N',n,nupdwn(2),ngw,alpha,c,ngw,c_msp,ngw,alpha,Xsp,n)
|
||
#ifdef __PARA
|
||
call reduce (2*n*nupdwn(2),Xsp)
|
||
#endif
|
||
do i=iupdwn(2),n
|
||
do j=1,n
|
||
X(j,i)=Xsp(j,i)
|
||
end do
|
||
end do
|
||
deallocate(Xsp,c_psp,c_msp)
|
||
O(inw,:,:)=Oa(inw,:,:)+X(:,:)
|
||
end if
|
||
end do
|
||
#ifdef __PARA
|
||
deallocate(ns)
|
||
#endif
|
||
|
||
if(clwf.eq.2) then
|
||
! output the overlap matrix to fort.38
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
rewind 38
|
||
write(38, '(i5, 2i2, i3, f9.5)') n, nw, nspin, ibrav, alat
|
||
if (nspin.eq.2) then
|
||
write(38, '(i5)') nupdwn(1)
|
||
end if
|
||
write(38, *) a1
|
||
write(38, *) a2
|
||
write(38, *) a3
|
||
write(38, *) b1
|
||
write(38, *) b2
|
||
write(38, *) b3
|
||
do inw=1, nw
|
||
write(38, *) wfg(inw, :), weight(inw)
|
||
end do
|
||
do inw=1, nw
|
||
do i=1, n
|
||
do j=1, n
|
||
write(38, *) O(inw, i, j)
|
||
end do
|
||
end do
|
||
end do
|
||
do i=1, n
|
||
do j=1, n
|
||
write(38, *) Uall(i, j)
|
||
end do
|
||
end do
|
||
close(38)
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
#ifdef __PARA
|
||
call Mpi_finalize(ierr)
|
||
#endif
|
||
STOP
|
||
end if
|
||
|
||
if(clwf.eq.3.or.clwf.eq.4) then
|
||
if(nspin.eq.1) then
|
||
if(.not.what1) then
|
||
if(wfsd) then
|
||
call wfsteep(n,O,Uall,b1,b2,b3)
|
||
else
|
||
call ddyn(n,O,Uall,b1,b2,b3)
|
||
end if
|
||
end if
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Out from DDYN"
|
||
end if
|
||
else
|
||
allocate(Uspin(nupdwn(1), nupdwn(1)), Ospin(nw, nupdwn(1), nupdwn(1)))
|
||
do i=1, nupdwn(1)
|
||
do j=1, nupdwn(1)
|
||
Uspin(i, j)=Uall(i, j)
|
||
Ospin(:, i, j)=O(:, i, j)
|
||
end do
|
||
end do
|
||
if(.not.what1) then
|
||
if(wfsd) then
|
||
call wfsteep(nupdwn(1), Ospin, Uspin,b1,b2,b3)
|
||
else
|
||
call ddyn(nupdwn(1), Ospin, Uspin,b1,b2,b3)
|
||
end if
|
||
end if
|
||
do i=1, nupdwn(1)
|
||
do j=1, nupdwn(1)
|
||
Uall(i, j)=Uspin(i, j)
|
||
O(:,i,j) =Ospin(:,i,j)
|
||
end do
|
||
end do
|
||
deallocate(Uspin, Ospin)
|
||
allocate(Uspin(nupdwn(2), nupdwn(2)), Ospin(nw, nupdwn(2), nupdwn(2)))
|
||
do i=1, nupdwn(2)
|
||
do j=1, nupdwn(2)
|
||
Uspin(i, j)=Uall(i+nupdwn(1), j+nupdwn(1))
|
||
Ospin(:, i, j)=O(:, i+nupdwn(1), j+nupdwn(1))
|
||
end do
|
||
end do
|
||
if(.not.what1) then
|
||
if(wfsd) then
|
||
call wfsteep(nupdwn(2), Ospin, Uspin,b1,b2,b3)
|
||
else
|
||
call ddyn(nupdwn(2), Ospin, Uspin,b1,b2,b3)
|
||
end if
|
||
end if
|
||
do i=1, nupdwn(2)
|
||
do j=1, nupdwn(2)
|
||
Uall(i+nupdwn(1), j+nupdwn(1))=Uspin(i, j)
|
||
O(:,i+nupdwn(1),j+nupdwn(1))=Ospin(:,i,j)
|
||
end do
|
||
end do
|
||
deallocate(Uspin, Ospin)
|
||
end if
|
||
end if
|
||
|
||
! Update C and bec
|
||
cwf=beta1
|
||
! cwf(:,:)=c(:,:,1,1)
|
||
becwf=0.0
|
||
U2=Uall*alpha
|
||
call ZGEMM('N','N',ngw,n,n,alpha,c,ngw,U2,n,beta1,cwf,ngw)
|
||
! call ZGEMM('N','N',ngw,n,n,alpha,cwf,ngw,U2,n,beta1,cwf,ngw)
|
||
call DGEMM('N','N',nhsa,n,n,alpha,bec,nhsa,Uall,n,beta1,becwf,nhsa)
|
||
U2=beta1
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Updating Wafefunctions and Bec"
|
||
end if
|
||
|
||
|
||
! do inw=1, 3
|
||
! do i=1, nhsa
|
||
! do j=1, n
|
||
! temp3(i,j)=becdr(i,j,inw)
|
||
! becdrwf(i,j)=0.d0
|
||
! do nnn=1,n
|
||
! becdrwf(i,j)=becdrwf(i,j)+temp3(i,nnn)*Uall(nnn,j)
|
||
! end do
|
||
! end do
|
||
! end do
|
||
! do i=1,nhsa
|
||
! do j=1,n
|
||
! becdr(i,j,inw)=becdrwf(i,j)
|
||
! end do
|
||
! end do
|
||
! end do
|
||
|
||
c(:,:)=cwf(:,:)
|
||
bec(:,:)=becwf(:,:)
|
||
|
||
! do i=1,n
|
||
! do j=1,ngw
|
||
! c(j,i)=cwf(j,i)
|
||
! end do
|
||
! do k=1,nhsa
|
||
! bec(k,i)=becwf(k,i)
|
||
! end do
|
||
! end do
|
||
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Wafefunctions and Bec Updated"
|
||
end if
|
||
|
||
!
|
||
! calculate wannier-function centers
|
||
!
|
||
allocate(wr(nw), W(nw, nw),gr(nw,3),f3(nw),f4(nw),mt(nw))
|
||
do inw=1, nw
|
||
gr(inw, :)=wfg(inw,1)*b1(:)+wfg(inw,2)*b2(:)+wfg(inw,3)*b3(:)
|
||
end do
|
||
!
|
||
! set up a matrix with the element (i,j) is G_i<5F>G_j<5F>weight(j)
|
||
! to check the correctness of choices on G vectors
|
||
!
|
||
do i=1, nw
|
||
do j=1, nw
|
||
W(i,j)=SUM(gr(i,:)*gr(j,:))*weight(j)
|
||
! write(6, *) i,j,W(i,j)
|
||
end do
|
||
end do
|
||
! write(24, *) "wannier function centers: (unit:\AA)"
|
||
do i=1, n
|
||
mt=-aimag(log(O(:,i,i)))/pi2
|
||
wfc(1, i)=SUM(mt*weight*gr(:,1))
|
||
wfc(2, i)=SUM(mt*weight*gr(:,2))
|
||
wfc(3, i)=SUM(mt*weight*gr(:,3))
|
||
do inw=1, nw
|
||
wr(inw)=SUM(wfc(:,i)*gr(inw,:))-mt(inw)
|
||
end do
|
||
mt=wr
|
||
f3=0
|
||
adjust=0
|
||
!
|
||
! balance the phase factor if necessary
|
||
!
|
||
#ifdef VARIABLECELL
|
||
#else
|
||
! do while(SUM((mt-f3)**2).gt.0.01d0)
|
||
! f4=f3
|
||
! f3=nint(mt-mt(1))
|
||
! if (adjust.gt.200) f3=f3-1
|
||
! if (adjust.gt.100.and.adjust.le.200) f3=f3+1
|
||
! mt=wr+matmul(W, f3)
|
||
! if(iprsta.gt.4) then
|
||
! write(6,*) "mt:", mt
|
||
! write(6,*) "f3:", f3
|
||
! end if
|
||
! adjust=adjust+1
|
||
! if (adjust.gt.300) stop "unable to balance the phase!"
|
||
! end do
|
||
#endif
|
||
wfc(1,i)=(wfc(1,i)+SUM(mt*weight*gr(:,1)))*alat
|
||
wfc(2,i)=(wfc(2,i)+SUM(mt*weight*gr(:,2)))*alat
|
||
wfc(3,i)=(wfc(3,i)+SUM(mt*weight*gr(:,3)))*alat
|
||
end do
|
||
|
||
! if (ibrav.eq.1.or.ibrav.eq.6.or.ibrav.eq.8) then
|
||
! do i=1, n
|
||
! if (wfc(1, i).lt.0) wfc(1, i)=wfc(1, i)+a1(1)
|
||
! if (wfc(2, i).lt.0) wfc(2, i)=wfc(2, i)+a2(2)
|
||
! if (wfc(3, i).lt.0) wfc(3, i)=wfc(3, i)+a3(3)
|
||
! end do
|
||
! end if
|
||
! if(what1) then
|
||
! alen=a1(1)+a2(1)+a3(1)
|
||
! blen=a1(2)+a2(2)+a3(2)
|
||
! clen=a1(3)+a2(3)+a3(3)
|
||
! do i=1, n
|
||
! do while (wfc(1,i).lt.0.)
|
||
! wfc(1,i)=wfc(1,i)+alen
|
||
! end do
|
||
! do while (wfc(2,i).lt.0.)
|
||
! wfc(2,i)=wfc(2,i)+blen
|
||
! end do
|
||
! do while (wfc(3,i).lt.0.)
|
||
! wfc(3,i)=wfc(3,i)+clen
|
||
! end do
|
||
! do while (wfc(1,i).gt.alen)
|
||
! wfc(1,i)=wfc(1,i)-alen
|
||
! end do
|
||
! do while (wfc(2,i).gt.blen)
|
||
! wfc(2,i)=wfc(2,i)-blen
|
||
! end do
|
||
! do while (wfc(3,i).gt.clen)
|
||
! wfc(3,i)=wfc(3,i)-clen
|
||
! end do
|
||
! end do
|
||
! end if
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
if(.not.what1) then
|
||
do i=1,n
|
||
write(26, '(3f11.6)') wfc(:,i)*autoaf
|
||
end do
|
||
end if
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
if(nspin.eq.2.and.nvb.gt.0) then
|
||
deallocate(X2,X3)
|
||
end if
|
||
deallocate(wr, W,mt,f3,f4,gr)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "deallocated wr, w, f3, f4, gr"
|
||
end if
|
||
#ifdef __PARA
|
||
deallocate (psitot)
|
||
deallocate (psitot1)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "deallocated psitot, psitot1"
|
||
end if
|
||
deallocate (psitot_pl)
|
||
deallocate (psitot_p)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "deallocated psitot_pl,psuitot_p"
|
||
end if
|
||
deallocate (psitot_mi)
|
||
deallocate (psitot_m)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "deallocated psitot_mi,psitot_m"
|
||
end if
|
||
deallocate(c_p)
|
||
deallocate(c_m)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "deallocated c_p, c_m"
|
||
end if
|
||
#else
|
||
deallocate(c_p,c_m)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "deallocated c_p,c_m"
|
||
end if
|
||
#endif
|
||
deallocate(X,O,Oa,wfg,weight,tagz)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "deallocated X,O,Oa,wfg,weight,tagz"
|
||
end if
|
||
! deallocate(Oac,Oa,Osc,Os,mr1,mc1)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Now Leaving subroutine wf..."
|
||
end if
|
||
|
||
return
|
||
end subroutine wf
|
||
!------------------------------------------------------------------------
|
||
subroutine ddyn(m,Omat,Umat,b1,b2,b3)
|
||
! This part of the subroutine wf has been added by Manu. It performes
|
||
! Damped Dynamics on the A matrix to get the Unitary transformation to
|
||
! obtain the wannier function at time(t+delta). It also updates the
|
||
! quantities bec and becdr
|
||
!
|
||
! MANU
|
||
! November 26, 2001
|
||
!--------------------------------------------------------------------------
|
||
|
||
use wfparm2
|
||
use wfparm
|
||
use cell_base
|
||
use constants
|
||
use elct
|
||
use control_flags, only: iprsta
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
|
||
integer :: f3(nw), f4(nw), i,j,inw
|
||
integer ,intent(in) :: m
|
||
real(kind=8), intent(in) :: b1(3),b2(3),b3(3)
|
||
real(kind=8), intent(inout) :: Umat(m,m)
|
||
complex(kind=8), intent(inout) :: Omat(nw,m,m)
|
||
complex(kind=8) :: U2(m,m),U3(m,m)
|
||
integer :: adjust,ini, ierr1,nnn
|
||
real(kind=8), allocatable, dimension(:) :: wr
|
||
real(kind=8), allocatable, dimension(:,:) :: W
|
||
real(kind=8) :: t0, fric,U(m,m), t2
|
||
real(kind=8) :: A(m,m),oldt0,Wm(m,m),U1(m,m)
|
||
real(kind=8) :: Aminus(m,m), Aplus(m,m),f2(4*m)
|
||
! real(kind=8) :: Aminus(m,m), Aplus(m,m),f2(4*m)
|
||
real(kind=8) :: temp(m,m)
|
||
complex(kind=8) :: d(m,m), alpha, beta1, ci
|
||
complex(kind=8) :: f1(2*m-1), wp(m*(m+1)/2),z(m,m)
|
||
complex(kind=8), allocatable, dimension(:, :) :: X1
|
||
complex(kind=8), allocatable, dimension(:, :, :) :: Oc
|
||
real(kind=8) , allocatable , dimension(:) :: mt
|
||
real(kind=8), parameter :: autoaf=0.529177d0
|
||
real(kind=8) :: spread, sp, pi2
|
||
real(kind=8) :: wfc(3,n), gr(nw,3)
|
||
|
||
alpha=(1.d0,0.d0)
|
||
beta1=(0.d0,0.d0)
|
||
ci =(0.d0,1.d0)
|
||
pi2 =2.d0*pi
|
||
|
||
allocate(mt(nw))
|
||
allocate(X1(m,m))
|
||
allocate(Oc(nw,m,m))
|
||
|
||
fric=friction
|
||
allocate (W(m,m),wr(m))
|
||
|
||
Umat=0.d0
|
||
do i=1,m
|
||
Umat(i,i)=1.d0
|
||
end do
|
||
|
||
U2=Umat*alpha
|
||
|
||
!
|
||
! update Oc using the initial guess of Uspin
|
||
!
|
||
do inw=1, nw
|
||
X1(:, :)=Omat(inw, :, :)
|
||
U3=beta1
|
||
! call ZGEMUL(U2, m, 'T', X1, m, 'N', U3, m, m,m,m)
|
||
call ZGEMM ('T', 'N', m,m,m,alpha,U2,m,X1,m,beta1,U3,m)
|
||
X1=beta1
|
||
! call ZGEMUL(U3, m, 'N', U2, m, 'N', X1, m, m,m,m)
|
||
call ZGEMM ('N','N', m,m,m,alpha,U3,m,U2,m,beta1,X1,m)
|
||
Oc(inw, :, :)=X1(:, :)
|
||
end do
|
||
|
||
U2=beta1
|
||
U3=beta1
|
||
|
||
oldt0=0.d0
|
||
A=0.d0
|
||
Aminus=A
|
||
temp=Aminus
|
||
|
||
|
||
! START ITERATIONS HERE
|
||
|
||
do ini=1, nsteps
|
||
|
||
t0=0.d0 !use t0 to store the value of omega
|
||
do inw=1, nw
|
||
do i=1, m
|
||
t0=t0+real(conjg(Oc(inw, i, i))*Oc(inw, i, i))
|
||
end do
|
||
end do
|
||
|
||
if(ABS(t0-oldt0).lt.tolw) then
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(27,*) "MLWF Generated at Step",ini
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "MLWF Generated at Step",ini
|
||
end if
|
||
go to 241
|
||
end if
|
||
|
||
if(adapt) then
|
||
if(oldt0.lt.t0) then
|
||
fric=fric/2.
|
||
A=Aminus
|
||
Aminus=temp
|
||
end if
|
||
end if
|
||
|
||
! calculate d(omega)/dA and store result in W
|
||
! this is the force for the damped dynamics
|
||
!
|
||
|
||
W=0.d0
|
||
do inw=1, nw
|
||
t2=weight(inw)
|
||
do i=1,m
|
||
do j=1,m
|
||
W(i,j)=W(i,j)+t2*real(Oc(inw,i,j)*conjg(Oc(inw,i,i) &
|
||
-Oc(inw,j,j))+conjg(Oc(inw,j,i))*(Oc(inw,i,i)-Oc(inw,j,j)))
|
||
end do
|
||
end do
|
||
end do
|
||
|
||
|
||
! the verlet scheme to calculate A(t+dt)
|
||
|
||
Aplus=0.d0
|
||
|
||
do i=1,m
|
||
do j=i+1,m
|
||
Aplus(i,j)=Aplus(i,j)+(2*dt/(2*dt+fric))*(2*A(i,j) &
|
||
-Aminus(i,j)+(dt*dt/q)*W(i,j)) + (fric/(2*dt+fric))*Aminus(i,j)
|
||
enddo
|
||
enddo
|
||
|
||
Aplus=Aplus-transpose(Aplus)
|
||
Aplus=(Aplus-A)
|
||
|
||
do i=1, m
|
||
do j=i,m
|
||
wp(i + (j-1)*j/2) = cmplx(0.0, Aplus(i,j))
|
||
end do
|
||
end do
|
||
|
||
#if ! defined __AIX
|
||
call zhpev('V','U',m,wp,wr,z,m,f1,f2,ierr1)
|
||
#else
|
||
call zhpev(21, wp, wr, z, m, m, f2, 4*m)
|
||
ierr1 = 0
|
||
#endif
|
||
|
||
if (ierr1.ne.0) then
|
||
write(6,*) "failed to diagonalize W!"
|
||
stop
|
||
end if
|
||
|
||
d=0.d0
|
||
do i=1, m
|
||
d(i, i)=exp(ci*wr(i)*dt)
|
||
end do !d=exp(d)
|
||
|
||
! U=z*exp(d)*z+
|
||
!
|
||
U3=beta1
|
||
! call ZGEMUL(z, m, 'N', d, m, 'N', U3, m, m,m,m)
|
||
call ZGEMM ('N', 'N', m,m,m,alpha,z,m,d,m,beta1,U3,m)
|
||
U2=beta1
|
||
! call ZGEMUL(U3, m, 'N', z, m, 'c', U2, m, m,m,m)
|
||
call ZGEMM ('N','c', m,m,m,alpha,U3,m,z,m,beta1,U2,m)
|
||
U=real(U2)
|
||
U2=beta1
|
||
U3=beta1
|
||
|
||
temp=Aminus
|
||
Aminus=A
|
||
A=Aplus
|
||
|
||
|
||
! update Umat
|
||
!
|
||
! call DGEMUL(Umat, m, 'N', U, m, 'N', U1, m, m,m,m)
|
||
U1=beta1
|
||
call DGEMM ('N', 'N', m,m,m,alpha,Umat,m,U,m,beta1,U1,m)
|
||
|
||
Umat=U1
|
||
|
||
! update Oc
|
||
!
|
||
U2=Umat*alpha
|
||
U3=beta1
|
||
do inw=1, nw
|
||
X1(:, :)=Omat(inw, :, :)
|
||
! call ZGEMUL(U2, m, 'T', X1, m, 'N', U3, m, m,m,m)
|
||
call ZGEMM ('T', 'N', m,m,m,alpha,U2,m,X1,m,beta1,U3,m)
|
||
X1=beta1
|
||
! call ZGEMUL(U3, m, 'N', U2, m, 'N', X1, m, m,m,m)
|
||
call ZGEMM ('N','N',m,m,m,alpha,U3,m,U2,m,beta1,X1,m)
|
||
Oc(inw, :, :)=X1(:, :)
|
||
end do
|
||
U2=beta1
|
||
U3=beta1
|
||
|
||
if(ABS(t0-oldt0).ge.tolw.and.ini.ge.nsteps) then
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(27,*) "MLWF Not generated after",ini,"Steps."
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "MLWF Not generated after",ini,"Steps."
|
||
end if
|
||
go to 241
|
||
end if
|
||
|
||
oldt0=t0
|
||
|
||
end do
|
||
|
||
241 deallocate(wr, W)
|
||
spread=0.0
|
||
do i=1, m
|
||
mt=1.d0-real(Oc(:,i,i)*conjg(Oc(:,i,i)))
|
||
sp= (alat*autoaf/pi2)**2*SUM(mt*weight)
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(25, '(f10.7)') sp
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
if(sp.lt.0.d0) then
|
||
write(6,*) "Something wrong WF Spread negative. The Program will Stop."
|
||
#ifdef __PARA
|
||
call MPI_FINALIZE(ierr1)
|
||
#endif
|
||
STOP
|
||
end if
|
||
spread=spread+sp
|
||
end do
|
||
spread=spread/m
|
||
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(24, '(f10.7)') spread
|
||
write(27,*) "Average spread = ", spread
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
Omat=Oc
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Average spread = ", spread
|
||
end if
|
||
|
||
!
|
||
! calculate wannier-function centers
|
||
!
|
||
! allocate(wr(nw), W(nw, nw))
|
||
! do inw=1, nw
|
||
! gr(inw, :)=wfg(inw,1)*b1(:)+wfg(inw,2)*b2(:)+wfg(inw,3)*b3(:)
|
||
! end do
|
||
!
|
||
! set up a matrix with the element (i,j) is G_i<5F>G_j<5F>weight(j)
|
||
! to check the correctness of choices on G vectors
|
||
!
|
||
! do i=1, nw
|
||
! do j=1, nw
|
||
! W(i,j)=SUM(gr(i,:)*gr(j,:))*weight(j)
|
||
! write(6, *) i,j,W(i,j)
|
||
! end do
|
||
! end do
|
||
! write(24, *) "wannier function centers: (unit:\AA)"
|
||
! do i=1, m
|
||
! mt=-aimag(log(Oc(:,i,i)))/pi2
|
||
! wfc(1, i)=SUM(mt*weight*gr(:,1))
|
||
! wfc(2, i)=SUM(mt*weight*gr(:,2))
|
||
! wfc(3, i)=SUM(mt*weight*gr(:,3))
|
||
! do inw=1, nw
|
||
! wr(inw)=SUM(wfc(:,i)*gr(inw,:))-mt(inw)
|
||
! end do
|
||
! mt=wr
|
||
! f3=0
|
||
! adjust=0
|
||
!
|
||
! balance the phase factor if necessary
|
||
!
|
||
! do while(SUM((mt-f3)**2).gt.0.01d0)
|
||
! f4=f3
|
||
! f3=nint(mt-mt(1))
|
||
! if (adjust.gt.200) f3=f3-1
|
||
! if (adjust.gt.100.and.adjust.le.200) f3=f3+1
|
||
! mt=wr+matmul(W, f3)
|
||
!! write(6,*) "mt:", mt
|
||
!! write(6,*) "f3:", f3
|
||
! adjust=adjust+1
|
||
! if (adjust.gt.300) stop "unable to balance the phase!"
|
||
! end do
|
||
! wfc(1,i)=(wfc(1,i)+SUM(mt*weight*gr(:,1)))*alat
|
||
! wfc(2,i)=(wfc(2,i)+SUM(mt*weight*gr(:,2)))*alat
|
||
! wfc(3,i)=(wfc(3,i)+SUM(mt*weight*gr(:,3)))*alat
|
||
! end do
|
||
!
|
||
! if (ibrav.eq.1.or.ibrav.eq.6.or.ibrav.eq.8) then
|
||
! do i=1, m
|
||
! if (wfc(1, i).lt.0) wfc(1, i)=wfc(1, i)+a1(1)
|
||
! if (wfc(2, i).lt.0) wfc(2, i)=wfc(2, i)+a2(2)
|
||
! if (wfc(3, i).lt.0) wfc(3, i)=wfc(3, i)+a3(3)
|
||
! end do
|
||
! end if
|
||
!#ifdef __PARA
|
||
! if(me.eq.1) then
|
||
!#endif
|
||
! if(.not.what1) then
|
||
! do i=1, m
|
||
! write(26, '(3f11.6)') wfc(:,i)*autoaf
|
||
! end do
|
||
! end if
|
||
!#ifdef __PARA
|
||
! end if
|
||
!#endif
|
||
! deallocate(wr, W)
|
||
deallocate (mt,X1,Oc)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Leaving DDYN"
|
||
end if
|
||
return
|
||
end subroutine ddyn
|
||
!-----------------------------------------------------------------------
|
||
subroutine wfunc_init(clwf,b1,b2,b3,ibrav)
|
||
!-----------------------------------------------------------------------
|
||
|
||
use gvec, only: gx, mill_l
|
||
use gvecw, only : ngw, ng0
|
||
use elct
|
||
use wfparm
|
||
! use cell_base
|
||
use cvan
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
real(kind=8), intent(in) :: b1(3),b2(3),b3(3)
|
||
#ifdef __PARA
|
||
integer :: ntot, proc, ierr, root, i,j,inw,ngppp(nproc)
|
||
integer :: ii,ig,recvcount(nproc), sendcount(nproc),displs(nproc)
|
||
#else
|
||
integer :: ierr, i,j,inw, ntot
|
||
integer :: ii,ig
|
||
#endif
|
||
real (kind=8), allocatable:: bigg(:,:)
|
||
integer, allocatable :: bign(:,:)
|
||
integer :: igcount,nw1,jj,nw2, in, kk, ibrav
|
||
integer, allocatable :: i_1(:), j_1(:), k_1(:)
|
||
real(kind=8) :: ti, tj, tk, t1, vt, err1, err2, err3
|
||
integer :: ti1,tj1,tk1, clwf
|
||
|
||
# ifdef __PARA
|
||
if(n.lt.nproc) then
|
||
write(6,*) "Number of Processors (",nproc,") is greater than the number of states (",n,")."
|
||
write(6,*) "The Program will Stop."
|
||
|
||
call MPI_FINALIZE(ierr)
|
||
STOP
|
||
end if
|
||
#endif
|
||
allocate(gnx(3,ngw))
|
||
allocate(gnn(3,ngw))
|
||
#ifdef __PARA
|
||
root=0
|
||
#endif
|
||
vt=1.0d-4
|
||
j=0
|
||
do i=1,ngw
|
||
gnx(1,i)=gx(i,1)
|
||
gnx(2,i)=gx(i,2)
|
||
gnx(3,i)=gx(i,3)
|
||
gnn(1,i)=mill_l(1,i)
|
||
gnn(2,i)=mill_l(2,i)
|
||
gnn(3,i)=mill_l(3,i)
|
||
end do
|
||
#ifdef __PARA
|
||
ntot=0
|
||
do i=1,nproc
|
||
ngppp(i)=(dfftp%nwl(i)+1)/2
|
||
end do
|
||
|
||
do proc=1,nproc
|
||
recvcount(proc)=ngppp(proc)*3
|
||
if(proc.eq.1) then
|
||
displs(proc)=0
|
||
else
|
||
displs(proc)=displs(proc-1)+recvcount(proc-1)
|
||
end if
|
||
ntot=ntot+recvcount(proc)/3
|
||
end do
|
||
|
||
if(me.eq.1) then
|
||
allocate(bigg(3,ntot))
|
||
allocate(bign(3,ntot))
|
||
end if
|
||
#else
|
||
ntot=ngw
|
||
allocate(bigg(3,ntot))
|
||
allocate(bign(3,ntot))
|
||
bigg(1:3,1:ntot)=gnx(1:3,1:ntot)
|
||
bign(1:3,1:ntot)=gnn(1:3,1:ntot)
|
||
! do j=1,ntot
|
||
! write(50,'(6(2x,i6))') gnn(:,j), bign(:,j)
|
||
! end do
|
||
#endif
|
||
|
||
select case(ibrav)
|
||
case(0)
|
||
! free cell for cpr
|
||
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(indexminusz(ngw))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=1 ! 1
|
||
k_1(4)=0 ! 0
|
||
|
||
i_1(5)=0 ! 0
|
||
j_1(5)=1 ! 1
|
||
k_1(5)=1 ! 1
|
||
|
||
i_1(6)=1 ! 1
|
||
j_1(6)=0 ! 0
|
||
k_1(6)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(1)
|
||
! cubic P [sc]
|
||
|
||
nw1=3
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(2)
|
||
! cubic F [FCC]
|
||
nw1=4
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=-1 ! -1
|
||
j_1(4)=-1 ! -1
|
||
k_1(4)=-1 ! -1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(3)
|
||
! cubic I [bcc]
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=1 ! 1
|
||
k_1(4)=0 ! 0
|
||
|
||
i_1(5)=1 ! 1
|
||
j_1(5)=1 ! 1
|
||
k_1(5)=1 ! 1
|
||
|
||
i_1(6)=-1 ! -1
|
||
j_1(6)=0 ! 0
|
||
k_1(6)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(4)
|
||
! hexagonal and trigonal P
|
||
|
||
nw1=4
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=-1 ! -1
|
||
k_1(4)=0 ! 0
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(5)
|
||
! trigonal R
|
||
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=0 ! 0
|
||
k_1(4)=1 ! 1
|
||
|
||
i_1(5)=0 ! 0
|
||
j_1(5)=-1 ! -1
|
||
k_1(5)=1 ! 1
|
||
|
||
i_1(6)=1 ! 1
|
||
j_1(6)=-1 ! -1
|
||
k_1(6)=0 ! 0
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(6)
|
||
! tetragonal P [st]
|
||
|
||
nw1=3
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(7)
|
||
! tetragonal I [bct]
|
||
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=0 ! 0
|
||
k_1(4)=1 ! 1
|
||
|
||
i_1(5)=0 ! 0
|
||
j_1(5)=1 ! 1
|
||
k_1(5)=-1 ! -1
|
||
|
||
i_1(6)=1 ! 1
|
||
j_1(6)=1 ! 1
|
||
k_1(6)=0 ! 0
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(8)
|
||
! Orthorhombic P
|
||
nw1=3
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
indexplus=0
|
||
indexminus=0
|
||
tag=0
|
||
tagp=0
|
||
indexplusz=0
|
||
indexminusz=0
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(9)
|
||
! One face centered Orthorhombic C
|
||
if(b1(2).eq.1) then
|
||
|
||
nw1=3
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
else
|
||
if(b1(2).gt.1) then
|
||
write (6,*) "Please make celldm(2) not less than 1"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
STOP
|
||
else
|
||
nw1=4
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(4)=1
|
||
j_1(4)=1
|
||
k_1(4)=0
|
||
end if
|
||
end if
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(10)
|
||
! all face centered orthorhombic F
|
||
|
||
if(b1(2).eq.-1.and.b1(3).eq.1) then
|
||
write(6,*) "Please change ibrav to 2"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
STOP
|
||
end if
|
||
if((b1(1).gt.b1(3)).or.(b1(1)+b1(2).lt.0)) then
|
||
write(6,*) "Please make celldm(2)>=1>=celldm(3)"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
STOP
|
||
end if
|
||
if(b1(3).eq.1) then
|
||
nw1=5
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
else
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(6)=1 ! 1
|
||
j_1(6)=1 ! 1
|
||
k_1(6)=0 ! 0
|
||
|
||
end if
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=1 ! 1
|
||
k_1(4)=1 ! 1
|
||
|
||
i_1(5)=0 ! 0
|
||
j_1(5)=1 ! 1
|
||
k_1(5)=0 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(11)
|
||
! Body centered orthorhombic I
|
||
|
||
if((b1(3).eq.1).and.(b2(2).eq.1)) then
|
||
write(6,*) "Please change ibrav to 3"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
STOP
|
||
end if
|
||
if((b1(3).eq.1).or.(b2(2).eq.1)) then
|
||
write(6,*) "Please change ibrav to 7"
|
||
#ifdef __PARA
|
||
call mpi_finalize(i)
|
||
#endif
|
||
STOP
|
||
end if
|
||
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=1 ! 1
|
||
k_1(4)=0 ! 0
|
||
|
||
i_1(5)=1 ! 1
|
||
j_1(5)=0 ! 0
|
||
k_1(5)=1 ! 1
|
||
|
||
i_1(6)=-1 ! -1
|
||
j_1(6)=0 ! 0
|
||
k_1(6)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(12)
|
||
! monoclinic P
|
||
|
||
nw1=4
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
t1=-b1(2)/b2(2)
|
||
kk=nint(t1)
|
||
if((kk.eq.0).and.(t1.ge.0)) kk=1
|
||
if((kk.eq.0).and.(t1.le.0)) kk=-1
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=kk ! kk
|
||
k_1(4)=0 ! 0
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case(13)
|
||
! one face centered monoclinic C
|
||
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminusz(ngw))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
t1=-b1(2)/b3(2)
|
||
kk=nint(t1)
|
||
if((kk.eq.0).and.(t1.ge.0)) kk=1
|
||
if((kk.eq.0).and.(t1.le.0)) kk=-1
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=-1 ! -1
|
||
k_1(4)=0 ! 0
|
||
|
||
i_1(5)=1 ! 1
|
||
j_1(5)=0 ! 0
|
||
k_1(5)=kk ! kk
|
||
|
||
i_1(6)=0 ! 0
|
||
j_1(6)=1 ! 1
|
||
k_1(6)=kk ! kk
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
|
||
go to 99
|
||
|
||
case default
|
||
! free cell for cpr
|
||
|
||
nw1=6
|
||
write(6,*) "Translations to be done", nw1
|
||
allocate(indexplus(ntot,nw1))
|
||
allocate(indexplusz(ngw))
|
||
allocate(indexminus(ntot,nw1))
|
||
allocate(indexminusz(ngw))
|
||
allocate(tag(ntot,nw1))
|
||
allocate(tagp(ntot,nw1))
|
||
allocate(i_1(nw1))
|
||
allocate(j_1(nw1))
|
||
allocate(k_1(nw1))
|
||
|
||
i_1(1)=1 ! 1
|
||
j_1(1)=0 ! 0
|
||
k_1(1)=0 ! 0
|
||
|
||
i_1(2)=0 ! 0
|
||
j_1(2)=1 ! 1
|
||
k_1(2)=0 ! 0
|
||
|
||
i_1(3)=0 ! 0
|
||
j_1(3)=0 ! 0
|
||
k_1(3)=1 ! 1
|
||
|
||
i_1(4)=1 ! 1
|
||
j_1(4)=1 ! 1
|
||
k_1(4)=0 ! 0
|
||
|
||
i_1(5)=0 ! 0
|
||
j_1(5)=1 ! 1
|
||
k_1(5)=1 ! 1
|
||
|
||
i_1(6)=1 ! 1
|
||
j_1(6)=0 ! 0
|
||
k_1(6)=1 ! 1
|
||
|
||
indexplus(:,3)=0
|
||
indexminus(:,3)=0
|
||
tag(:,3)=0
|
||
tagp(:,3)=0
|
||
go to 99
|
||
|
||
! ibrav 14 : Triclinic P
|
||
! write(6,*) "Hey!! I'm not superman... Implement triclinic yourself"
|
||
!#ifdef __PARA
|
||
! call mpi_finalize(i)
|
||
!#endif
|
||
! STOP
|
||
end select
|
||
|
||
99 write(6,*) "ibrav selected:", ibrav
|
||
if(nvb.gt.0) call small_box_wf(i_1, j_1, k_1, nw1)
|
||
#ifdef __PARA
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_barrier' , ierr)
|
||
call mpi_gatherv(gnx, recvcount(me), MPI_REAL8, &
|
||
bigg, recvcount, displs, MPI_REAL8, &
|
||
root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_gatherv' , ierr)
|
||
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_barrier' , ierr)
|
||
call mpi_gatherv(gnn, recvcount(me), MPI_INTEGER, &
|
||
bign, recvcount, displs, MPI_INTEGER, &
|
||
root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_gatherv' , ierr)
|
||
#endif
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
if(clwf.eq.5) then
|
||
#ifdef __PARA
|
||
do ii=1,ntot
|
||
write(21,*) bigg(:,ii)
|
||
end do
|
||
#else
|
||
do ii=1,ngw
|
||
write(21,*) gx(ii,1), gx(ii,2), gx(ii,3)
|
||
end do
|
||
#endif
|
||
close(21)
|
||
end if
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
|
||
do inw=1,nw1
|
||
if(i_1(inw).eq.0.and.j_1(inw).eq.0) then
|
||
do ig=1,ngw
|
||
if(ng0.eq.2) then
|
||
indexminusz(1)=-1
|
||
end if
|
||
ti=(gnn(1,ig)+i_1(inw))*b1(1)+(gnn(2,ig)+j_1(inw))*b2(1)+(gnn(3,ig)+k_1(inw))*b3(1)
|
||
tj=(gnn(1,ig)+i_1(inw))*b1(2)+(gnn(2,ig)+j_1(inw))*b2(2)+(gnn(3,ig)+k_1(inw))*b3(2)
|
||
tk=(gnn(1,ig)+i_1(inw))*b1(3)+(gnn(2,ig)+j_1(inw))*b2(3)+(gnn(3,ig)+k_1(inw))*b3(3)
|
||
do ii=1,ngw
|
||
err1=ABS(gnx(1,ii)-ti)
|
||
err2=ABS(gnx(2,ii)-tj)
|
||
err3=ABS(gnx(3,ii)-tk)
|
||
! if(gnx(1,ii).eq.ti.and.gnx(2,ii).eq.tj.and.gnx(3,ii).eq.tk) then
|
||
if(err1.lt.vt.and.err2.lt.vt.and.err3.lt.vt) then
|
||
indexplusz(ig)=ii
|
||
! write (6,*) "Found +", ig,ii,inw
|
||
go to 224
|
||
else
|
||
end if
|
||
end do
|
||
indexplusz(ig)=-1
|
||
! write (6,*) "Not Found +", ig,-1,inw
|
||
224 ti=(-gnn(1,ig)+i_1(inw))*b1(1)+(-gnn(2,ig)+j_1(inw))*b2(1)+(-gnn(3,ig)+k_1(inw))*b3(1)
|
||
tj=(-gnn(1,ig)+i_1(inw))*b1(2)+(-gnn(2,ig)+j_1(inw))*b2(2)+(-gnn(3,ig)+k_1(inw))*b3(2)
|
||
tk=(-gnn(1,ig)+i_1(inw))*b1(3)+(-gnn(2,ig)+j_1(inw))*b2(3)+(-gnn(3,ig)+k_1(inw))*b3(3)
|
||
ti1=-gnn(1,ig)+i_1(inw)
|
||
tj1=-gnn(2,ig)+j_1(inw)
|
||
tk1=-gnn(3,ig)+k_1(inw)
|
||
if(ti1.lt.0.or.(ti1.eq.0.and.(tj1.lt.0.or.(tj1.eq.0.and.tk1.lt.0)))) then
|
||
do ii=1,ngw
|
||
err1=ABS(gnx(1,ii)+ti)
|
||
err2=ABS(gnx(2,ii)+tj)
|
||
err3=ABS(gnx(3,ii)+tk)
|
||
! if(gnx(1,ii).eq.-ti.and.gnx(2,ii).eq.-tj.and.gnx(3,ii).eq.-tk) then
|
||
if(err1.lt.vt.and.err2.lt.vt.and.err3.lt.vt) then
|
||
indexminusz(ig)=ii
|
||
! tag(ig,inw)=1
|
||
! write (6,*) "Found -", ig,ii,inw
|
||
go to 223
|
||
else
|
||
end if
|
||
end do
|
||
indexminusz(ig)=-1
|
||
! tag(ig,inw)=1
|
||
! write (6,*) "Not Found -", ig,-1,inw
|
||
else
|
||
do ii=1,ngw
|
||
err1=ABS(gnx(1,ii)-ti)
|
||
err2=ABS(gnx(2,ii)-tj)
|
||
err3=ABS(gnx(3,ii)-tk)
|
||
! if(gnx(1,ii).eq.ti.and.gnx(2,ii).eq.tj.and.gnx(3,ii).eq.tk) then
|
||
if(err1.lt.vt.and.err2.lt.vt.and.err3.lt.vt) then
|
||
indexminusz(ig)=ii
|
||
! tag(ig,inw)=-1
|
||
! write (6,*) "Found -", ig,ii,inw
|
||
go to 223
|
||
else
|
||
end if
|
||
end do
|
||
indexminusz(ig)=-1
|
||
! tag(ig,inw)=-1
|
||
! write (6,*) "Not Found -", ig,-1,inw
|
||
end if
|
||
223 continue
|
||
end do
|
||
write(6,*) "Translation", inw, "for", ngw, "G vectors"
|
||
else
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
do ig=1,ntot
|
||
if(ng0.eq.2) then
|
||
indexminus(1,inw)=-1
|
||
end if
|
||
ti=(bign(1,ig)+i_1(inw))*b1(1)+(bign(2,ig)+j_1(inw))*b2(1)+(bign(3,ig)+k_1(inw))*b3(1)
|
||
tj=(bign(1,ig)+i_1(inw))*b1(2)+(bign(2,ig)+j_1(inw))*b2(2)+(bign(3,ig)+k_1(inw))*b3(2)
|
||
tk=(bign(1,ig)+i_1(inw))*b1(3)+(bign(2,ig)+j_1(inw))*b2(3)+(bign(3,ig)+k_1(inw))*b3(3)
|
||
ti1=bign(1,ig)+i_1(inw)
|
||
tj1=bign(2,ig)+j_1(inw)
|
||
tk1=bign(3,ig)+k_1(inw)
|
||
if(ti1.lt.0.or.(ti1.eq.0.and.(tj1.lt.0.or.(tj1.eq.0.and.tk1.lt.0)))) then
|
||
do ii=1,ntot
|
||
err1=ABS(bigg(1,ii)+ti)
|
||
err2=ABS(bigg(2,ii)+tj)
|
||
err3=ABS(bigg(3,ii)+tk)
|
||
if(err1.lt.vt.and.err2.lt.vt.and.err3.lt.vt) then
|
||
! if(bigg(1,ii).eq.-ti.and.bigg(2,ii).eq.-tj.and.bigg(3,ii).eq.-tk) then
|
||
indexplus(ig,inw)=ii
|
||
tagp(ig,inw)=1
|
||
! write (6,*) "Found +", ig,ii,inw
|
||
go to 214
|
||
else
|
||
end if
|
||
end do
|
||
indexplus(ig,inw)=-1
|
||
tagp(ig,inw)=1
|
||
! write (6,*) "Not Found +", ig,-1,inw
|
||
else
|
||
do ii=1,ntot
|
||
err1=ABS(bigg(1,ii)-ti)
|
||
err2=ABS(bigg(2,ii)-tj)
|
||
err3=ABS(bigg(3,ii)-tk)
|
||
if(err1.lt.vt.and.err2.lt.vt.and.err3.lt.vt) then
|
||
! if(bigg(1,ii).eq.ti.and.bigg(2,ii).eq.tj.and.bigg(3,ii).eq.tk) then
|
||
indexplus(ig,inw)=ii
|
||
tagp(ig,inw)=-1
|
||
! write (6,*) "Found +", ig,ii,inw
|
||
go to 214
|
||
else
|
||
end if
|
||
end do
|
||
indexplus(ig,inw)=-1
|
||
tagp(ig,inw)=-1
|
||
! write (6,*) "Not Found +", ig,-1,inw
|
||
end if
|
||
214 ti=(-bign(1,ig)+i_1(inw))*b1(1)+(-bign(2,ig)+j_1(inw))*b2(1)+(-bign(3,ig)+k_1(inw))*b3(1)
|
||
tj=(-bign(1,ig)+i_1(inw))*b1(2)+(-bign(2,ig)+j_1(inw))*b2(2)+(-bign(3,ig)+k_1(inw))*b3(2)
|
||
tk=(-bign(1,ig)+i_1(inw))*b1(3)+(-bign(2,ig)+j_1(inw))*b2(3)+(-bign(3,ig)+k_1(inw))*b3(3)
|
||
ti1=-bign(1,ig)+i_1(inw)
|
||
tj1=-bign(2,ig)+j_1(inw)
|
||
tk1=-bign(3,ig)+k_1(inw)
|
||
if(ti1.lt.0.or.(ti1.eq.0.and.(tj1.lt.0.or.(tj1.eq.0.and.tk1.lt.0)))) then
|
||
do ii=1,ntot
|
||
err1=ABS(bigg(1,ii)+ti)
|
||
err2=ABS(bigg(2,ii)+tj)
|
||
err3=ABS(bigg(3,ii)+tk)
|
||
if(err1.lt.vt.and.err2.lt.vt.and.err3.lt.vt) then
|
||
! if(bigg(1,ii).eq.-ti.and.bigg(2,ii).eq.-tj.and.bigg(3,ii).eq.-tk) then
|
||
indexminus(ig,inw)=ii
|
||
tag(ig,inw)=1
|
||
! write (6,*) "Found -", ig,ii,inw
|
||
go to 213
|
||
else
|
||
end if
|
||
end do
|
||
indexminus(ig,inw)=-1
|
||
tag(ig,inw)=1
|
||
! write (6,*) "Not Found -", ig,-1,inw
|
||
else
|
||
do ii=1,ntot
|
||
err1=ABS(bigg(1,ii)-ti)
|
||
err2=ABS(bigg(2,ii)-tj)
|
||
err3=ABS(bigg(3,ii)-tk)
|
||
if(err1.lt.vt.and.err2.lt.vt.and.err3.lt.vt) then
|
||
! if(bigg(1,ii).eq.ti.and.bigg(2,ii).eq.tj.and.bigg(3,ii).eq.tk) then
|
||
indexminus(ig,inw)=ii
|
||
tag(ig,inw)=-1
|
||
! write (6,*) "Found -", ig,ii,inw
|
||
go to 213
|
||
else
|
||
end if
|
||
end do
|
||
indexminus(ig,inw)=-1
|
||
tag(ig,inw)=-1
|
||
! write (6,*) "Not Found -", ig,-1,inw
|
||
end if
|
||
213 continue
|
||
end do
|
||
write(6,*) "Translation", inw, "for", ntot, "G vectors"
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
end if
|
||
end do
|
||
|
||
! do inw=1,nw1
|
||
! do i=1,ntot
|
||
! write(36,222) indexplus(i,inw), tagp(i,inw)
|
||
! write(37,222) indexminus(i,inw), tag(i,inw)
|
||
! end do
|
||
! end do
|
||
!222 format (1x,i10,1x,i10)
|
||
|
||
#ifdef __PARA
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_barrier 2' , ierr)
|
||
|
||
call mpi_bcast(indexplus,nw1*ntot , MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_bcast +' , ierr)
|
||
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_barrier 3' , ierr)
|
||
|
||
call mpi_bcast(indexminus,nw1*ntot , MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_bcast -' , ierr)
|
||
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_barrier 4' , ierr)
|
||
|
||
call mpi_bcast(tag,nw1*ntot , MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_bcast -' , ierr)
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_barrier 4' , ierr)
|
||
|
||
call mpi_bcast(tagp,nw1*ntot , MPI_INTEGER, root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('wfunc_init','mpi_bcast -' , ierr)
|
||
|
||
if (me.eq.1) then
|
||
#endif
|
||
deallocate(bigg)
|
||
deallocate(bign)
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
deallocate(i_1,j_1,k_1)
|
||
|
||
return
|
||
end subroutine wfunc_init
|
||
!--------------------------------------------------------------
|
||
subroutine grid_map
|
||
!--------------------------------------------------------------
|
||
use efcalc
|
||
use cell_base
|
||
! use parms
|
||
use smooth_grid_dimensions, nnrs=>nnrsx
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
|
||
integer ir1, ir2, ir3, ibig3
|
||
allocate(xdist(nnrs))
|
||
allocate(ydist(nnrs))
|
||
allocate(zdist(nnrs))
|
||
|
||
do ir3=1,nr3s
|
||
#ifdef __PARA
|
||
ibig3 = ir3 - dffts%ipp( me )
|
||
if(ibig3.gt.0.and.ibig3.le.dffts%npp(me)) then
|
||
#else
|
||
ibig3=ir3
|
||
#endif
|
||
do ir2=1,nr2s
|
||
do ir1=1,nr1s
|
||
xdist(ir1+(ir2-1)*nr1sx+(ibig3-1)*nr1sx*nr2sx) = &
|
||
& ((ir1-1)/dfloat(nr1sx))
|
||
ydist(ir1+(ir2-1)*nr1sx+(ibig3-1)*nr1sx*nr2sx) = &
|
||
& ((ir2-1)/dfloat(nr2sx))
|
||
zdist(ir1+(ir2-1)*nr1sx+(ibig3-1)*nr1sx*nr2sx) = &
|
||
& ((ir3-1)/dfloat(nr3sx))
|
||
!
|
||
end do
|
||
end do
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
end do
|
||
return
|
||
end subroutine grid_map
|
||
|
||
!--------------------------------------------------------------
|
||
subroutine tric_wts(rp1,rp2,rp3,alat,wts)
|
||
!--------------------------------------------------------------
|
||
|
||
!***** This subroutine computes the weights to be used for ****
|
||
!***** R.P. translations in the WF calculation in the case ****
|
||
!***** of ibrav=0 or ibrav=14 *********************************
|
||
|
||
implicit none
|
||
real(kind=8),intent(in) :: rp1(3), rp2(3), rp3(3)
|
||
real(kind=8),intent(in) :: alat
|
||
real(kind=8),intent(out) :: wts(6)
|
||
real(kind=8) :: pi, tpiba, tpiba2
|
||
real(kind=8) :: b1x, b2x, b3x, b1y, b2y, b3y, b1z, b2z, b3z
|
||
integer :: i
|
||
|
||
! WRITE(6,*) 'ENTERED TRIC_WTS !'
|
||
! WRITE(6,*) 'b3(3) :',rp3(3)
|
||
! WRITE(6,*) 'alat :',alat
|
||
pi = 2.0d0*asin(1.0)
|
||
tpiba = 2.0d0*pi/alat
|
||
tpiba2 = tpiba**2
|
||
|
||
b1x = rp1(1)*tpiba
|
||
b2x = rp2(1)*tpiba
|
||
b3x = rp3(1)*tpiba
|
||
b1y = rp1(2)*tpiba
|
||
b2y = rp2(2)*tpiba
|
||
b3y = rp3(2)*tpiba
|
||
b1z = rp1(3)*tpiba
|
||
b2z = rp2(3)*tpiba
|
||
b3z = rp3(3)*tpiba
|
||
! WRITE(6,*) 'COMPUTING WEIGHTS NOW ...'
|
||
|
||
wts(1) = tpiba2*(-b1z*b2x*b2z*b3x + b2y**2*b3x**2 + b1z*b2z*b3x**2 + &
|
||
b2z**2*b3x**2 - b1z*b2y*b2z*b3y - 2.d0*b2x*b2y*b3x*b3y + &
|
||
b2x**2*b3y**2 + b1z*b2z*b3y**2 + b2z**2*b3y**2 + &
|
||
b1z*b2x**2*b3z + b1z*b2y**2*b3z - b1z*b2x*b3x*b3z - &
|
||
2.d0*b2x*b2z*b3x*b3z - b1z*b2y*b3y*b3z - &
|
||
2.d0*b2y*b2z*b3y*b3z + b2x**2*b3z**2 + b2y**2*b3z**2 + &
|
||
b1x*(b2y**2*b3x + b2z**2*b3x - b2y*(b2x + b3x)*b3y - &
|
||
b2z*(b2x + b3x)*b3z + b2x*(b3y**2 + b3z**2)) + &
|
||
b1y*(b2x**2*b3y - b2x*b3x*(b2y + b3y) + &
|
||
b2z*b3y*(b2z - b3z) + b2y*(b3x**2 - b2z*b3z + b3z**2)))/ &
|
||
((b1z*b2y*b3x - b1y*b2z*b3x - b1z*b2x*b3y + b1x*b2z*b3y &
|
||
+ b1y*b2x*b3z - b1x*b2y*b3z)**2)
|
||
|
||
wts(2) = tpiba2*(b1z**2*(b2x*b3x + b3x**2 + b3y*(b2y + b3y)) + &
|
||
b1y**2*(b2x*b3x + b3x**2 + b3z*(b2z + b3z)) - &
|
||
b1z*(-b2z*(b3x**2 + b3y**2) + (b2x*b3x + b2y*b3y)*b3z + &
|
||
b1x*(b2z*b3x + (b2x + 2.d0* b3x)*b3z)) - &
|
||
b1y*(b1x*(b2y*b3x + (b2x + 2.d0*b3x)*b3y) + &
|
||
b3y*(b1z*b2z + b2x*b3x + 2.d0*b1z*b3z + b2z*b3z) - &
|
||
b2y*(b3x**2 - b1z* b3z + b3z**2)) + &
|
||
b1x*(-b2y*b3x*b3y + b2x*b3y**2 - b2z*b3x*b3z + b2x*b3z**2 + &
|
||
b1x*(b2y*b3y + b3y**2 + b3z*(b2z + b3z))))/ &
|
||
((b1z*b2y*b3x - b1y*b2z*b3x - b1z*b2x*b3y + b1x*b2z*b3y + &
|
||
b1y*b2x*b3z - b1x*b2y*b3z)**2)
|
||
|
||
wts(3) = tpiba2*(b1z**2*(b2x**2 + b2x*b3x + b2y*(b2y + b3y)) - &
|
||
b1y*(2.d0*b1z*b2y*b2z + b2x*b2y*b3x - b2x**2*b3y + &
|
||
b1z*b2z*b3y - b2z**2*b3y + b1x*(2.d0*b2x*b2y + b2y*b3x + b2x*b3y) + &
|
||
b1z*b2y*b3z + b2y*b2z*b3z) + b1y**2*(b2x**2 + b2x*b3x + b2z*(b2z + b3z)) - &
|
||
b1z*(b2x*b2z*b3x + b2y*b2z*b3y - b2x**2*b3z - b2y**2*b3z + &
|
||
b1x*(2.d0*b2x*b2z + b2z*b3x + b2x*b3z)) + &
|
||
b1x*(b2y**2*b3x + b2z**2*b3x - b2x*b2y*b3y - b2x*b2z*b3z + &
|
||
b1x*(b2y**2 + b2y*b3y + b2z*(b2z + b3z))))/ &
|
||
((b1z*b2y*b3x - b1y*b2z*b3x - b1z*b2x*b3y + b1x*b2z*b3y + b1y*b2x*b3z - &
|
||
b1x*b2y*b3z)**2)
|
||
|
||
wts(4) = tpiba2*(b1z*(-b2z*(b3x**2 + b3y**2) + (b2x*b3x + b2y*b3y)*b3z) + &
|
||
b1y*(b3y*(b2x*b3x + b2z*b3z) - b2y*(b3x**2 + b3z**2)) + &
|
||
b1x*(b2y*b3x*b3y + b2z*b3x*b3z - b2x*(b3y**2 + b3z**2)))/ &
|
||
((b1z*b2y*b3x - b1y*b2z*b3x - b1z*b2x*b3y + b1x*b2z*b3y + &
|
||
b1y*b2x*b3z - b1x*b2y*b3z)**2)
|
||
|
||
wts(5) = -tpiba2*(b1z**2*(b2x*b3x + b2y*b3y) - b1x*b1z*(b2z*b3x + b2x*b3z) - &
|
||
b1y*(b1x*b2y*b3x + b1x*b2x*b3y + b1z*b2z*b3y + b1z*b2y*b3z) + &
|
||
b1y**2*(b2x*b3x + b2z*b3z) + b1x**2*(b2y*b3y + b2z*b3z))/ &
|
||
((b1z*b2y*b3x - b1y*b2z*b3x - b1z*b2x*b3y + b1x*b2z*b3y + &
|
||
b1y*b2x*b3z - b1x*b2y*b3z)**2)
|
||
|
||
wts(6) = -tpiba2*(b1z*(-b2x*b2z*b3x - b2y*b2z*b3y + b2x**2*b3z + b2y**2*b3z) + &
|
||
b1x*(b2y**2*b3x + b2z**2*b3x - b2x*b2y*b3y - b2x*b2z*b3z) + &
|
||
b1y*(-b2x*b2y*b3x + b2x**2*b3y + b2z*(b2z*b3y - b2y*b3z)))/ &
|
||
((b1z*b2y*b3x - b1y*b2z*b3x - b1z*b2x*b3y + b1x*b2z*b3y + &
|
||
b1y*b2x*b3z - b1x*b2y*b3z)**2)
|
||
|
||
! WRITE(6,*) 'WEIGHTS ARE :'
|
||
! WRITE(6,"(F10.6)") (wts(i),i=1,6)
|
||
|
||
end subroutine tric_wts
|
||
!-----------------------------------------------------------------
|
||
subroutine small_box_wf(i_1,j_1,k_1,nw1)
|
||
!-----------------------------------------------------------------
|
||
use efcalc
|
||
use cell_base
|
||
! use parms
|
||
use smooth_grid_dimensions, nnrs=>nnrsx
|
||
use constants
|
||
use wfparm
|
||
use grid_dimensions, only : nr1, nr2, nr3, nr1x, nr2x, nr3x, nnr => nnrx
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
|
||
integer ir1, ir2, ir3, ibig3 , inw
|
||
real(kind=8) x
|
||
integer , intent(in) :: nw1, i_1(nw1), j_1(nw1), k_1(nw1)
|
||
allocate(expo(nnr,nw1))
|
||
|
||
do inw=1,nw1
|
||
|
||
write(6,*) inw ,":", i_1(inw), j_1(inw), k_1(inw)
|
||
|
||
do ir3=1,nr3
|
||
#ifdef __PARA
|
||
ibig3 = ir3 - dfftp%ipp( me )
|
||
if(ibig3.gt.0.and.ibig3.le.dfftp%npp(me)) then
|
||
#else
|
||
ibig3=ir3
|
||
#endif
|
||
do ir2=1,nr2
|
||
do ir1=1,nr1
|
||
x = (((ir1-1)/dfloat(nr1x))*i_1(inw) + &
|
||
& ((ir2-1)/dfloat(nr2x))*j_1(inw) + &
|
||
& ((ir3-1)/dfloat(nr3x))*k_1(inw))*0.5d0*fpi
|
||
expo(ir1+(ir2-1)*nr1x+(ibig3-1)*nr1x*nr2x,inw) = cmplx(cos(x), -sin(x))
|
||
end do
|
||
end do
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
end do
|
||
end do
|
||
return
|
||
end subroutine small_box_wf
|
||
!-----------------------------------------------------------------------
|
||
complex(kind=8) function boxdotgridcplx(irb,qv,vr)
|
||
!-----------------------------------------------------------------------
|
||
!
|
||
! Calculate \sum_i qv(r_i)*vr(r_i) with r_i on box grid
|
||
! array qv(r) is defined on box grid, array vr(r)on dense grid
|
||
! irb : position of the box in the dense grid
|
||
! Parallel execution: remember to sum the contributions from other nodes
|
||
!
|
||
! use ion_parameters
|
||
use grid_dimensions, nnr => nnrx
|
||
use smallbox_grid_dimensions ,nnrb => nnrbx
|
||
use cell_base
|
||
use small_box
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
integer, intent(in):: irb(3)
|
||
complex(kind=8), intent(in):: qv(nnrb), vr(nnr)
|
||
!
|
||
integer ir1, ir2, ir3, ir, ibig1, ibig2, ibig3, ibig
|
||
!
|
||
! if(nfft.le.0.or.nfft.gt.2) call errore('box2grid','wrong data',nfft)
|
||
|
||
boxdotgridcplx=(0.d0, 0.d0)
|
||
|
||
do ir3=1,nr3b
|
||
ibig3=irb(3)+ir3-1
|
||
ibig3=1+mod(ibig3-1,nr3)
|
||
#ifdef __PARA
|
||
ibig3 = ibig3 - dfftp%ipp( me )
|
||
if (ibig3.gt.0.and.ibig3.le.dfftp%npp(me)) then
|
||
#endif
|
||
do ir2=1,nr2b
|
||
ibig2=irb(2)+ir2-1
|
||
ibig2=1+mod(ibig2-1,nr2)
|
||
do ir1=1,nr1b
|
||
ibig1=irb(1)+ir1-1
|
||
ibig1=1+mod(ibig1-1,nr1)
|
||
ibig=ibig1 + (ibig2-1)*nr1x + (ibig3-1)*nr1x*nr2x
|
||
ir =ir1 + (ir2-1)*nr1bx + (ir3-1)*nr1bx*nr2bx
|
||
boxdotgridcplx = boxdotgridcplx + qv(ir)*vr(ibig)
|
||
end do
|
||
end do
|
||
#ifdef __PARA
|
||
endif
|
||
#endif
|
||
end do
|
||
|
||
return
|
||
end
|
||
|
||
!-----------------------------------------------------------------------
|
||
subroutine write_rho_g(rhog)
|
||
!-----------------------------------------------------------------------
|
||
|
||
use gvecp, only: ng=>ngm
|
||
use gvec, only: gx, mill_l
|
||
use elct
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
|
||
implicit none
|
||
|
||
real(kind=8), allocatable:: gnx(:,:), bigg(:,:)
|
||
complex(kind=8) ,intent(in) :: rhog(ng,nspin)
|
||
complex(kind=8),allocatable :: bigrho(:)
|
||
complex(kind=8) :: rhotmp_g(ng)
|
||
integer ntot, i, j
|
||
#ifdef __PARA
|
||
integer proc, ierr, root, ngdens(nproc),recvcount(nproc), displs(nproc)
|
||
integer recvcount2(nproc), displs2(nproc)
|
||
#endif
|
||
character (len=6) :: name
|
||
character (len=15) :: name2
|
||
|
||
allocate(gnx(3,ng))
|
||
|
||
|
||
#ifdef __PARA
|
||
root=0
|
||
#endif
|
||
|
||
do i=1,ng
|
||
gnx(1,i)=gx(i,1)
|
||
gnx(2,i)=gx(i,2)
|
||
gnx(3,i)=gx(i,3)
|
||
end do
|
||
|
||
#ifdef __PARA
|
||
ntot=0
|
||
do i=1,nproc
|
||
ngdens(i)=(dfftp%ngl(i)+1)/2
|
||
end do
|
||
|
||
do proc=1,nproc
|
||
recvcount(proc)=ngdens(proc)*3
|
||
recvcount2(proc)=ngdens(proc)
|
||
if(proc.eq.1) then
|
||
displs(proc)=0
|
||
displs2(proc)=0
|
||
else
|
||
displs(proc)=displs(proc-1)+recvcount(proc-1)
|
||
displs2(proc)=displs2(proc-1)+recvcount2(proc-1)
|
||
end if
|
||
ntot=ntot+recvcount(proc)/3
|
||
end do
|
||
|
||
if(me.eq.1) then
|
||
allocate(bigg(3,ntot))
|
||
end if
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD,ierr)
|
||
if(ierr.ne.0) call errore('write_rho_g0','mpi_barrier', ierr)
|
||
call mpi_gatherv(gnx,recvcount(me),MPI_REAL8, &
|
||
bigg,recvcount,displs,MPI_REAL8, &
|
||
root,MPI_COMM_WORLD, ierr)
|
||
if(ierr.ne.0) call errore('write_rho_g0','mpi_gatherv', ierr)
|
||
do i=1,nspin
|
||
|
||
rhotmp_g(1:ng)=rhog(1:ng,i)
|
||
|
||
if(me.eq.1) then
|
||
allocate (bigrho(ntot))
|
||
end if
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD,ierr)
|
||
if(ierr.ne.0) call errore('write_rho_g1','mpi_barrier', ierr)
|
||
call mpi_gatherv(rhotmp_g,recvcount2(me),MPI_DOUBLE_COMPLEX, &
|
||
bigrho,recvcount2,displs2,MPI_DOUBLE_COMPLEX, &
|
||
root,MPI_COMM_WORLD, ierr)
|
||
if(ierr.ne.0) call errore('write_rho_g1','mpi_gatherv', ierr)
|
||
|
||
|
||
if(me.eq.1) then
|
||
if(i.eq.1) name2="CH_DEN_G_PARA.1"
|
||
if(i.eq.2) name2="CH_DEN_G_PARA.2"
|
||
OPEN(unit=57, file=name2)
|
||
do j=1,ntot
|
||
write(57,*) bigrho(j)
|
||
end do
|
||
close(57)
|
||
deallocate(bigrho)
|
||
end if
|
||
|
||
write(6,*) "Charge density written to ", name2
|
||
|
||
end do
|
||
|
||
if(me.eq.1) then
|
||
name="G_PARA"
|
||
OPEN(unit=56, file=name)
|
||
do i=1,ntot
|
||
write(56,*) bigg(:,i)
|
||
end do
|
||
close(56)
|
||
deallocate(bigg)
|
||
end if
|
||
write(6,*) "G-vectors written to G_PARA"
|
||
#else
|
||
ntot=ng
|
||
allocate(bigg(3,ntot))
|
||
bigg(1:3,1:ntot)=gnx(1:3,1:ng)
|
||
do i=1,nspin
|
||
allocate(bigrho(ntot))
|
||
bigrho(1:ng)=rhog(1:ng,i)
|
||
|
||
if(i.eq.1) name2="CH_DEN_G_SERL.1"
|
||
if(i.eq.2) name2="CH_DEN_G_SERL.2"
|
||
|
||
OPEN(unit=57, file=name2)
|
||
do j=1,ntot
|
||
write(57,*) bigrho(j)
|
||
end do
|
||
close(57)
|
||
deallocate(bigrho)
|
||
|
||
write(6,*) "Charge density written to", name2
|
||
|
||
end do
|
||
|
||
name="G_SERL"
|
||
OPEN(unit=56, file=name)
|
||
do i=1,ntot
|
||
write(56,*) bigg(:,i)
|
||
end do
|
||
close(56)
|
||
deallocate(bigg)
|
||
write(6,*) "G-vectors written to G_SERL"
|
||
#endif
|
||
deallocate(gnx)
|
||
return
|
||
end subroutine write_rho_g
|
||
|
||
!-----------------------------------------------------------------------
|
||
subroutine macroscopic_average(rhog,tau0,e_tuned)
|
||
!-----------------------------------------------------------------------
|
||
use gvec
|
||
use elct
|
||
use tune
|
||
use cell_base
|
||
! use ion_parameters
|
||
use ions_base
|
||
use constants
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
|
||
real(kind=8), allocatable:: gnx(:,:), bigg(:,:)
|
||
complex(kind=8) ,intent(in) :: rhog(ng,nspin)
|
||
complex(kind=8),allocatable :: bigrho(:)
|
||
complex(kind=8) :: rhotmp_g(ng)
|
||
complex(kind=8),parameter :: zero=(0.d0,0.d0), ci=(0.d0,1.d0)
|
||
integer ntot, i, j, ngz, l, isa
|
||
integer ,allocatable :: g_red(:,:)
|
||
#ifdef __PARA
|
||
integer proc, ierr, root, ngdens(nproc),recvcount(nproc), displs(nproc)
|
||
integer recvcount2(nproc), displs2(nproc)
|
||
#endif
|
||
real(kind=8) zlen,vtot, pos(3,nax,nsx), a_direct(3,3),a_trans(3,3), e_slp, e_int
|
||
real(kind=8), intent(out) :: e_tuned(3)
|
||
real(kind=8), intent(in) :: tau0(3,nax)
|
||
real(kind=8),allocatable :: v_mr(:), dz(:), gz(:), g_1(:,:), vbar(:), cd(:), v_final(:)
|
||
real(kind=8), allocatable:: cdion(:), cdel(:), v_line(:), dist(:)
|
||
complex(kind=8),allocatable :: rho_ion(:),v_1(:),vmac(:),rho_tot(:),rhogz(:), bigrhog(:)
|
||
|
||
allocate(gnx(3,ng))
|
||
|
||
|
||
#ifdef __PARA
|
||
root=0
|
||
#endif
|
||
|
||
do i=1,ng
|
||
gnx(1,i)=gx(i,1)
|
||
gnx(2,i)=gx(i,2)
|
||
gnx(3,i)=gx(i,3)
|
||
end do
|
||
|
||
#ifdef __PARA
|
||
ntot=0
|
||
do i=1,nproc
|
||
ngdens(i)=(dfftp%ngl(i)+1)/2
|
||
end do
|
||
|
||
do proc=1,nproc
|
||
recvcount(proc)=ngdens(proc)*3
|
||
recvcount2(proc)=ngdens(proc)
|
||
if(proc.eq.1) then
|
||
displs(proc)=0
|
||
displs2(proc)=0
|
||
else
|
||
displs(proc)=displs(proc-1)+recvcount(proc-1)
|
||
displs2(proc)=displs2(proc-1)+recvcount2(proc-1)
|
||
end if
|
||
ntot=ntot+recvcount(proc)/3
|
||
end do
|
||
|
||
! if(me.eq.1) then
|
||
allocate(bigg(3,ntot))
|
||
allocate(g_1(3,2*ntot-1))
|
||
allocate(g_red(3,2*ntot-1))
|
||
! end if
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD,ierr)
|
||
if(ierr.ne.0) call errore('macroscopic_average','mpi_barrier', ierr)
|
||
call mpi_gatherv(gnx,recvcount(me),MPI_REAL8, &
|
||
bigg,recvcount,displs,MPI_REAL8, &
|
||
root,MPI_COMM_WORLD, ierr)
|
||
if(ierr.ne.0) call errore('macroscopic_avergae','mpi_gatherv', ierr)
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('macroscopic_average','mpi_barrier 2' , ierr)
|
||
|
||
call mpi_bcast(bigg,3*ntot , MPI_REAL8, root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('macroscopic_average','mpi_bcast_bigg' , ierr)
|
||
|
||
rhotmp_g(1:ng)=rhog(1:ng,1)
|
||
|
||
! if(me.eq.1) then
|
||
allocate (bigrho(ntot))
|
||
allocate (bigrhog(2*ntot-1))
|
||
! end if
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD,ierr)
|
||
if(ierr.ne.0) call errore('macroscopic_average','mpi_barrier', ierr)
|
||
call mpi_gatherv(rhotmp_g,recvcount2(me),MPI_DOUBLE_COMPLEX, &
|
||
bigrho,recvcount2,displs2,MPI_DOUBLE_COMPLEX, &
|
||
root,MPI_COMM_WORLD, ierr)
|
||
if(ierr.ne.0) call errore('macroscopic_avergae','mpi_gatherv', ierr)
|
||
|
||
call mpi_barrier(MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('macroscopic_average','mpi_barrier 3' , ierr)
|
||
|
||
call mpi_bcast(bigrho,ntot , MPI_DOUBLE_COMPLEX, root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('macroscopic_average','mpi_bcast_bigrho' , ierr)
|
||
|
||
|
||
|
||
#else
|
||
ntot=ng
|
||
allocate(bigg(3,ntot))
|
||
allocate(g_1(3,2*ntot-1))
|
||
allocate(g_red(3,2*ntot-1))
|
||
bigg(1:3,1:ntot)=gnx(1:3,1:ng)
|
||
allocate(bigrho(ntot))
|
||
allocate(bigrhog(2*ntot-1))
|
||
bigrho(1:ng)=rhog(1:ng,1)
|
||
#endif
|
||
|
||
! e_tuned=0.d0
|
||
! return
|
||
|
||
allocate(v_mr(npts))
|
||
allocate(v_final(npts))
|
||
allocate(dz(npts))
|
||
allocate(vbar(npts))
|
||
allocate(cd(npts))
|
||
allocate(cdel(npts))
|
||
allocate(cdion(npts))
|
||
|
||
!-- needed for non-orthogonal cells
|
||
|
||
a_direct(1,1:3)=a1(1:3)
|
||
a_direct(2,1:3)=a2(1:3)
|
||
a_direct(3,1:3)=a3(1:3)
|
||
|
||
a_trans=TRANSPOSE(a_direct)
|
||
|
||
!--- end
|
||
|
||
! e_tuned=0.d0
|
||
! return
|
||
|
||
!--- Construct rho(-g) from rho(g). rgo(-g)=rho*(g)
|
||
|
||
bigrhog(1:ntot)=bigrho(1:ntot)
|
||
g_1(:,1:ntot)=bigg(:,1:ntot)
|
||
do i=2,ntot
|
||
bigrhog(ntot+i-1)=conjg(bigrho(i))
|
||
g_1(:,ntot+i-1)=-bigg(:,i)
|
||
end do
|
||
|
||
!--- needed fot non-orthogonal cells
|
||
|
||
do i=1,2*ntot-1
|
||
g_red(:,i)=NINT(MATMUL(a_trans(:,:),g_1(:,i))*tpiba/(2.d0*pi))
|
||
end do
|
||
|
||
!--- end
|
||
! e_tuned=0.d0
|
||
! return
|
||
!--- define the direction of the line
|
||
|
||
xdir=1
|
||
ydir=2
|
||
|
||
if ((zdir).eq.1) xdir=3
|
||
if ((zdir).eq.2) ydir=3
|
||
|
||
if(zdir.eq.1) zlen=DSQRT(a1(1)**2+a1(2)**2+a1(3)**2)
|
||
if(zdir.eq.2) zlen=DSQRT(a2(1)**2+a2(2)**2+a2(3)**2)
|
||
if(zdir.eq.3) zlen=DSQRT(a3(1)**2+a3(2)**2+a3(3)**2)
|
||
|
||
|
||
!--- We need the potentiail only along zdir, so pick the appropriate G-vectors with Gxdir=Gydir=0
|
||
|
||
ngz=0
|
||
do i=1,2*ntot-1
|
||
if((g_red(xdir,i).eq.0).and.(g_red(ydir,i).eq.0)) ngz=ngz+1
|
||
end do
|
||
|
||
! write(6,*) 'ngz=',ngz
|
||
|
||
allocate(gz(ngz))
|
||
allocate(rhogz(ngz))
|
||
allocate(rho_ion(ngz))
|
||
allocate(rho_tot(ngz))
|
||
allocate(vmac(ngz))
|
||
allocate(v_1(ngz))
|
||
|
||
! write(6,*) 'allocated'
|
||
|
||
!--- The G-vectors are output in units of 2*pi/a, so convert them to the correct values
|
||
|
||
j=0
|
||
do i=1,2*ntot-1
|
||
if((g_red(xdir,i).eq.0).and.(g_red(ydir,i).eq.0)) then
|
||
j=j+1
|
||
gz(j)=g_1(zdir,i)*tpiba
|
||
rhogz(j)=bigrhog(i)
|
||
end if
|
||
end do
|
||
|
||
! write(6,*) 'mapped'
|
||
|
||
! e_tuned=0.d0
|
||
! return
|
||
|
||
isa = 0
|
||
do i=1,nsp
|
||
do j=1,na(i)
|
||
isa = isa + 1
|
||
pos(:,j,i)=tau0(:,isa)
|
||
end do
|
||
end do
|
||
|
||
!--- Construct the ionic Charge density in G-space
|
||
|
||
rho_ion=zero
|
||
do j=1,ngz
|
||
do i=1,nsp
|
||
do l=1,na(i)
|
||
rho_ion(j)=rho_ion(j)+zv(i)*exp(-ci*gz(j)*pos(zdir,l,i))*exp(-gz(j)**2/(4.d0*alpha))
|
||
end do
|
||
end do
|
||
end do
|
||
|
||
! write(6,*) 'rho_ion'
|
||
|
||
rho_ion=rho_ion/omega
|
||
|
||
!--- Construct the total Charge density in G-space
|
||
|
||
rho_tot=rho_ion-rhogz
|
||
|
||
!--- Construct the electrostatic potential and macroscopic average in G-space
|
||
|
||
v_1(1)=zero
|
||
vmac(1)=zero
|
||
v_1(2:ngz)=4*pi*rho_tot(2:ngz)/gz(2:ngz)**2
|
||
vmac(2:)=v_1(2:)*sin(gz(2:)*b)/(gz(2:)*b)
|
||
|
||
|
||
!--- Calculate planewise average in R-space and FFT V(Gz) ---> V(z) ... well not really FFT but FT
|
||
|
||
vbar=0.d0
|
||
v_mr=0.d0
|
||
cdel=0.d0
|
||
cdion=0.d0
|
||
cd=0.d0
|
||
do j=1,npts
|
||
dz(j)=(j-1)*zlen/(npts*1.d0)
|
||
do i=1,ngz
|
||
vbar(j)=vbar(j)-Real(exp(ci*gz(i)*dz(j))*v_1(i))
|
||
v_mr(j)=v_mr(j)-Real(exp(ci*gz(i)*dz(j))*vmac(i))
|
||
cdel(j)=cdel(j)-Real(exp(ci*gz(i)*dz(j))*rhogz(i))
|
||
cdion(j)=cdion(j)+Real(exp(ci*gz(i)*dz(j))*rho_ion(i))
|
||
cd(j)=cd(j)+Real(exp(ci*gz(i)*dz(j))*rho_tot(i))
|
||
end do
|
||
! write(6,*) vbar(j), v_mr(j), cdel(j), cdion(j)
|
||
end do
|
||
if (shift) then
|
||
vtot=(v_mr(start)+v_mr(start-1))/2.d0
|
||
v_final(1:npts-start+1)=v_mr(start:npts)-vtot
|
||
v_final(npts-start+2:npts)=v_mr(1:start-1)-vtot
|
||
else
|
||
vtot=(v_mr(1)+v_mr(npts))/2.d0
|
||
v_final(1:npts)=v_mr(1:npts)-vtot
|
||
end if
|
||
! write(6,*) vtot
|
||
e_tuned=0.d0
|
||
|
||
allocate(v_line(1:av1-av0+1))
|
||
allocate(dist(1:av1-av0+1))
|
||
|
||
|
||
v_line(1:av1-av0+1)=v_final(av0:av1)
|
||
dist(1:av1-av0+1) =dz(av0:av1)
|
||
|
||
! call least_square(av1-av0+1, dist, v_line, e_slp, e_int)
|
||
|
||
! e_tuned(zdir)=-e_slp
|
||
|
||
e_tuned(zdir)=-(v_final(av1)-v_final(av0))/((av1-av0)*zlen/(npts*1.d0))
|
||
! write(6,*) 'e_tuned=',e_tuned
|
||
|
||
#ifdef __PARA
|
||
! if(me.eq.1) then
|
||
deallocate(bigg,g_1,bigrho,bigrhog,g_red)
|
||
! end if
|
||
#else
|
||
deallocate(bigg,g_1,bigrho,bigrhog,g_red)
|
||
#endif
|
||
|
||
deallocate(gnx,v_mr,v_final,dz,vbar,cd,cdel,cdion)
|
||
deallocate(v_line, dist)
|
||
deallocate(gz,rhogz,rho_ion,rho_tot,vmac,v_1)
|
||
|
||
! write(6,*) 'deallocated'
|
||
|
||
return
|
||
end subroutine macroscopic_average
|
||
!--------------------------------------------------------------------
|
||
subroutine least_square(npts,x,y,slope,intercept)
|
||
!--------------------------------------------------------------------
|
||
|
||
implicit none
|
||
integer,intent(in):: npts
|
||
integer i
|
||
real(kind=8),intent(in) :: x(npts),y(npts)
|
||
real(kind=8), intent(out):: slope, intercept
|
||
real(kind=8) :: sumx,sumy,sumx2,sumxy,sumsqx
|
||
real(kind=8) :: xav,yav
|
||
|
||
sumxy=0.d0
|
||
sumx =0.d0
|
||
sumy =0.d0
|
||
sumx2=0.d0
|
||
do i=1,npts
|
||
sumxy=sumxy+x(i)*y(i)
|
||
sumx =sumx +x(i)
|
||
sumy =sumy +y(i)
|
||
sumx2=sumx2+x(i)*x(i)
|
||
end do
|
||
sumsqx=sumx**2
|
||
xav=sumx/dfloat(npts)
|
||
yav=sumy/dfloat(npts)
|
||
|
||
slope=(npts*sumxy - sumx*sumy)/(npts*sumx2 - sumsqx)
|
||
|
||
intercept=yav-slope*xav
|
||
|
||
return
|
||
|
||
end subroutine least_square
|
||
!-----------------------------------------------------------------------
|
||
subroutine wfsteep(m, Omat, Umat,b1,b2,b3)
|
||
!-----------------------------------------------------------------------
|
||
use wfparm
|
||
use wfparm2
|
||
use control_flags
|
||
use cell_base
|
||
use parallel_include
|
||
#ifdef __PARA
|
||
use para_mod
|
||
#endif
|
||
implicit none
|
||
|
||
! (m,m) is the size of the matrix Ospin.
|
||
! Ospin is input overlap matrix.
|
||
! Uspin is the output unitary transformation.
|
||
! Rough guess for Uspin can be carried in.
|
||
!
|
||
! conjugated gradient to search maximization
|
||
!
|
||
real(kind=8), parameter :: autoaf=0.529177d0
|
||
integer, intent(in) :: m
|
||
real(kind=8), intent(in) :: b1(3),b2(3),b3(3)
|
||
complex(kind=8), intent(inout) :: Omat(nw, m, m)
|
||
real(kind=8), intent(inout) :: Umat(m,m)
|
||
!
|
||
integer :: i, j, k, l, ig, ierr, ti, tj, tk, inw, ir, adjust
|
||
! integer :: f3(nw), f4(nw),isteep , ierr1
|
||
integer :: f3(nw), f4(nw), ierr1
|
||
real(kind=8) :: slope, slope2, t1, t2, t3, pi2, mt(nw),t21,temp1,maxdt
|
||
real(kind=8) :: U(m,m), wfc(3, m), Wm(m,m), schd(m,m), f2(4*m), gr(nw, 3)
|
||
real(kind=8) :: Uspin2(m,m),temp2,wfdtold,oldt1,t01, d3(m,m), d4(m,m), U1(m,m)
|
||
real(kind=8) :: spread, sp
|
||
real(kind=8), allocatable, dimension(:) :: wr
|
||
real(kind=8), allocatable, dimension(:,:) :: W
|
||
complex(kind=8) :: ci, ct1, ct2, ct3, z(m, m), X(m, m), d(m,m), d2(m,m)
|
||
complex(kind=8) :: f1(2*m-1), wp(m*(m+1)/2), Oc(nw, m, m), alpha, beta1
|
||
complex(kind=8) :: Oc2(nw, m, m),wp1(m*(m+1)/2), X1(m,m), U2(m,m), U3(m,m)
|
||
|
||
!
|
||
ci=(0.d0,1.d0)
|
||
alpha=(1.0d0, 0.0d0)
|
||
beta1=(0.0d0, 0.0d0)
|
||
pi2=2.d0*3.14159265358979d0
|
||
!
|
||
allocate(W(m,m), wr(m))
|
||
|
||
|
||
Umat=0.d0
|
||
do i=1,m
|
||
Umat(i,i)=1.d0
|
||
end do
|
||
Oc=beta1
|
||
Oc2=beta1
|
||
X1=beta1
|
||
U2=Umat*alpha
|
||
|
||
!
|
||
! update Oc using the initial guess of Uspin
|
||
!
|
||
do inw=1, nw
|
||
X1(:, :)=Omat(inw, :, :)
|
||
U3=beta1
|
||
call ZGEMM ('T', 'N', m,m,m,alpha,U2,m,X1,m,beta1,U3,m)
|
||
X1=beta1
|
||
call ZGEMM ('N','N', m,m,m,alpha,U3,m,U2,m,beta1,X1,m)
|
||
Oc(inw, :, :)=X1(:, :)
|
||
end do
|
||
|
||
U2=beta1
|
||
U3=beta1
|
||
|
||
W=0.d0
|
||
schd=0.d0
|
||
oldt1=0.d0
|
||
wfdtold=0.d0
|
||
|
||
do k=1, nit
|
||
t01=0.d0 !use t1 to store the value of omiga
|
||
do inw=1, nw
|
||
do i=1, m
|
||
t01=t01+real(conjg(Oc(inw, i, i))*Oc(inw, i, i))
|
||
end do
|
||
end do
|
||
|
||
! write(6,*) t01
|
||
|
||
if(ABS(oldt1-t01).lt.tolw) then
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(27,*) "MLWF Generated at Step",k
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "MLWF Generated at Step",k
|
||
end if
|
||
go to 40
|
||
end if
|
||
|
||
! oldt1=t01
|
||
|
||
! calculate d(omiga)/dW and store result in W
|
||
! W should be a real symmetric matrix for gamma-point calculation
|
||
!
|
||
Wm=W
|
||
W=0.d0
|
||
do inw=1, nw
|
||
t2=weight(inw)
|
||
do i=1,m
|
||
do j=i+1,m
|
||
W(i,j)=W(i,j)+t2*real(Oc(inw,i,j)*conjg(Oc(inw,i,i) &
|
||
-Oc(inw,j,j))+conjg(Oc(inw,j,i))*(Oc(inw,i,i)-Oc(inw,j,j)))
|
||
end do
|
||
end do
|
||
end do
|
||
W=W-transpose(W)
|
||
|
||
! calculate slope=d(omiga)/d(lamda)
|
||
slope=SUM(W**2)
|
||
|
||
! calculate slope2=d2(omiga)/d(lamda)2
|
||
slope2=0.d0
|
||
do ti=1, m
|
||
do tj=1, m
|
||
do tk=1, m
|
||
t2=0.d0
|
||
do inw=1, nw
|
||
t2=t2+real(Oc(inw,tj,tk)*conjg(Oc(inw,tj,tj)+Oc(inw,tk,tk) &
|
||
-2.d0*Oc(inw,ti,ti))-4.d0*Oc(inw,ti,tk) &
|
||
*conjg(Oc(inw,ti,tj)))*weight(inw)
|
||
end do
|
||
slope2=slope2+W(tk,ti)*W(ti,tj)*2.d0*t2
|
||
end do
|
||
end do
|
||
end do
|
||
slope2=2.d0*slope2
|
||
|
||
! use parabola approximation. Defined by 1 point and 2 slopes
|
||
if (slope2.lt.0) wfdt=-slope/2.d0/slope2
|
||
if (maxwfdt.gt.0.and.wfdt.gt.maxwfdt) wfdt=maxwfdt
|
||
|
||
if (k.lt.nsd) then
|
||
schd=W !use steepest-descent technique
|
||
|
||
! calculate slope=d(omiga)/d(lamda)
|
||
slope=SUM(schd**2)
|
||
|
||
! schd=schd*maxwfdt
|
||
do i=1, m
|
||
do j=i, m
|
||
wp1(i + (j-1)*j/2) = cmplx(0.0, schd(i,j))
|
||
end do
|
||
end do
|
||
|
||
#if ! defined __AIX
|
||
call zhpev('V','U',m,wp1,wr,z,m,f1,f2,ierr)
|
||
#else
|
||
call zhpev(21, wp1, wr, z, m, m, f2, 4*m)
|
||
ierr1 = 0
|
||
#endif
|
||
|
||
if (ierr.ne.0) stop 'failed to diagonalize W!'
|
||
|
||
else
|
||
!
|
||
! construct conjugated gradient
|
||
! d(i)=-g(i)+belta(i)*d(i-1)
|
||
! belta^FR(i)=g(i)t*g(i)/(g(i-1)t*g(i-1))
|
||
! belta^PR(i)=g(i)t*(g(i)-g(i-1))/(g(i-1)t*g(i-1))
|
||
!
|
||
call DGEMM ('T','N', m,m,m,alpha,Wm,m,Wm,m,beta1,d3,m)
|
||
|
||
|
||
t1=0.d0
|
||
do i=1, m
|
||
t1=t1+d3(i, i)
|
||
end do
|
||
if (t1.ne.0) then
|
||
d4=(W-Wm)
|
||
call DGEMM ('T','N', m,m,m,alpha,W,m,d4,m,beta1,d3,m)
|
||
t2=0.d0
|
||
do i=1, m
|
||
t2=t2+d3(i, i)
|
||
end do
|
||
t3=t2/t1
|
||
schd=W+schd*t3
|
||
else
|
||
schd=W
|
||
end if
|
||
!
|
||
! calculate the new d(Lambda) for the new Search Direction
|
||
! added by Manu. September 19, 2001
|
||
!
|
||
! calculate slope=d(omiga)/d(lamda)
|
||
slope=SUM(schd**2)
|
||
!------------------------------------------------------------------------
|
||
! schd=schd*maxwfdt
|
||
do i=1, m
|
||
do j=i, m
|
||
wp1(i + (j-1)*j/2) = cmplx(0.0, schd(i,j))
|
||
end do
|
||
end do
|
||
|
||
#if ! defined __AIX
|
||
call zhpev('V','U',m,wp1,wr,z,m,f1,f2,ierr)
|
||
#else
|
||
call zhpev(21, wp1, wr, z, m, m, f2, 4*m)
|
||
ierr1 = 0
|
||
#endif
|
||
if (ierr.ne.0) stop 'failed to diagonalize W!'
|
||
|
||
maxdt=maxwfdt
|
||
|
||
11 d=0.d0
|
||
do i=1, m
|
||
d(i, i)=exp(ci*(maxwfdt)*wr(i))
|
||
end do !d=exp(d)
|
||
|
||
! U=z*exp(d)*z+
|
||
U3=beta1
|
||
call ZGEMM ('N', 'N', m,m,m,alpha,z,m,d,m,beta1,U3,m)
|
||
U2=beta1
|
||
call ZGEMM ('N','c', m,m,m,alpha,U3,m,z,m,beta1,U2,m)
|
||
U=real(U2)
|
||
U2=beta1
|
||
U3=beta1
|
||
!
|
||
! update Uspin
|
||
U1=beta1
|
||
call DGEMM ('N', 'N', m,m,m,alpha,Umat,m,U,m,beta1,U1,m)
|
||
Umat=U1
|
||
|
||
! Uspin2=matmul(Uspin, U2)
|
||
!
|
||
! update Oc
|
||
!
|
||
U2=Umat*alpha
|
||
U3=beta1
|
||
do inw=1, nw
|
||
X1(:,:)=Omat(inw,:,:)
|
||
call ZGEMM ('T', 'N', m,m,m,alpha,U2,m,X1,m,beta1,U3,m)
|
||
X1=beta1
|
||
call ZGEMM ('N','N',m,m,m,alpha,U3,m,U2,m,beta1,X1,m)
|
||
Oc2(inw, :,:)=X(:,:)
|
||
end do
|
||
U2=beta1
|
||
U3=beta1
|
||
!
|
||
t21=0.d0 !use t21 to store the value of omiga
|
||
do inw=1, nw
|
||
do i=1, m
|
||
t21=t21+real(conjg(Oc2(inw, i, i))*Oc2(inw, i, i))
|
||
end do
|
||
end do
|
||
|
||
temp1=-((t01-t21)+slope*maxwfdt)/(maxwfdt**2)
|
||
temp2=slope
|
||
wfdt=-temp2/(2*temp1)
|
||
|
||
if (wfdt.gt.maxwfdt.or.wfdt.lt.0.d0) then
|
||
maxwfdt=2*maxwfdt
|
||
go to 11
|
||
end if
|
||
|
||
maxwfdt=maxdt
|
||
!
|
||
!
|
||
! use parabola approximation. Defined by 2 point and 1 slopes
|
||
! if (slope2.lt.0) wfdt=-slope/2.d0/slope2
|
||
! if (maxwfdt.gt.0.and.wfdt.gt.maxwfdt) wfdt=maxwfdt
|
||
!
|
||
! write(6, '(e12.5E2,1x,e11.5E2,1x,f6.2)') slope2, slope, wfdt
|
||
!-------------------------------------------------------------------------
|
||
!
|
||
! schd is the new searching direction
|
||
!
|
||
end if
|
||
|
||
d=0.d0
|
||
do i=1, m
|
||
d(i, i)=exp(ci*wfdt*wr(i))
|
||
end do !d=exp(d)
|
||
|
||
|
||
! U=z*exp(d)*z+
|
||
!
|
||
U3=beta1
|
||
call ZGEMM ('N', 'N', m,m,m,alpha,z,m,d,m,beta1,U3,m)
|
||
U2=beta1
|
||
call ZGEMM ('N','c', m,m,m,alpha,U3,m,z,m,beta1,U2,m)
|
||
U=real(U2)
|
||
U2=beta1
|
||
U3=beta1
|
||
|
||
! update Uspin
|
||
!
|
||
U1=beta1
|
||
call DGEMM ('N', 'N', m,m,m,alpha,Umat,m,U,m,beta1,U1,m)
|
||
Umat=U1
|
||
|
||
! update Oc
|
||
!
|
||
U2=Umat*alpha
|
||
U3=beta1
|
||
do inw=1, nw
|
||
X1(:, :)=Omat(inw, :, :)
|
||
call ZGEMM ('T', 'N', m,m,m,alpha,U2,m,X1,m,beta1,U3,m)
|
||
X1=beta1
|
||
call ZGEMM ('N','N',m,m,m,alpha,U3,m,U2,m,beta1,X1,m)
|
||
Oc(inw, :, :)=X1(:, :)
|
||
end do
|
||
U2=beta1
|
||
U3=beta1
|
||
if(ABS(t01-oldt1).ge.tolw.and.k.ge.nit) then
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(27,*) "MLWF Not generated after",k,"Steps."
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "MLWF Not generated after",k,"Steps."
|
||
end if
|
||
go to 40
|
||
end if
|
||
oldt1=t01
|
||
end do
|
||
|
||
40 deallocate(W, wr)
|
||
|
||
!
|
||
! calculate the spread
|
||
!
|
||
! write(24, *) "spread: (unit \AA^2)"
|
||
do i=1, m
|
||
mt=1.d0-real(Oc(:,i,i)*conjg(Oc(:,i,i)))
|
||
sp = (alat*autoaf/pi2)**2*SUM(mt*weight)
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(25, '(f10.7)') sp
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
if(sp.lt.0.d0) then
|
||
write(6,*) "Something wrong WF Spread negative. The Program will Stop."
|
||
#ifdef __PARA
|
||
call MPI_FINALIZE(ierr1)
|
||
#endif
|
||
STOP
|
||
end if
|
||
spread=spread+sp
|
||
end do
|
||
spread=spread/dfloat(m)
|
||
|
||
#ifdef __PARA
|
||
if(me.eq.1) then
|
||
#endif
|
||
write(24, '(f10.7)') spread
|
||
write(27,*) "Average spread = ", spread
|
||
#ifdef __PARA
|
||
end if
|
||
#endif
|
||
|
||
!
|
||
! calculate wannier-function centers
|
||
!
|
||
!allocate(wr(nw), W(nw, nw))
|
||
! do inw=1, nw
|
||
! gr(inw, :)=wfg(inw,1)*b1(:)+wfg(inw,2)*b2(:)+wfg(inw,3)*b3(:)
|
||
! end do
|
||
!
|
||
! set up a matrix with the element (i,j) is G_i<5F>G_j<5F>weight(j)
|
||
! to check the correctness of choices on G vectors
|
||
!
|
||
! do i=1, nw
|
||
! do j=1, nw
|
||
! W(i,j)=SUM(gr(i,:)*gr(j,:))*weight(j)
|
||
! write(6, *) i,j,W(i,j)
|
||
! end do
|
||
! end do
|
||
!! write(24, *) "wannier function centers: (unit:\AA)"
|
||
! do i=1, m
|
||
! mt=-aimag(log(Oc(:,i,i)))/pi2
|
||
! wfc(1, i)=SUM(mt*weight*gr(:,1))
|
||
! wfc(2, i)=SUM(mt*weight*gr(:,2))
|
||
! wfc(3, i)=SUM(mt*weight*gr(:,3))
|
||
! do inw=1, nw
|
||
! wr(inw)=SUM(wfc(:,i)*gr(inw,:))-mt(inw)
|
||
! end do
|
||
! mt=wr
|
||
! wfc(1, i)=(wfc(1,i)+SUM(mt*weight*gr(:,1)))*alat
|
||
! wfc(2, i)=(wfc(2,i)+SUM(mt*weight*gr(:,2)))*alat
|
||
! wfc(3, i)=(wfc(3,i)+SUM(mt*weight*gr(:,3)))*alat
|
||
! end do
|
||
!
|
||
!
|
||
! do i=1, m
|
||
! write(26, '(3f11.6)') wfc(:,i)*autoaf
|
||
! end do
|
||
! deallocate(wr, W)
|
||
! deallocate (mt,X1,Oc)
|
||
if(iprsta.gt.4) then
|
||
write(6,*) "Leaving WFSTEEP"
|
||
end if
|
||
return
|
||
end subroutine wfsteep
|
||
!
|
||
!-------------------------------------------------------------------------
|
||
subroutine dforce_field (bec,deeq,betae,i,c,ca,df,da,v,v1)
|
||
!-----------------------------------------------------------------------
|
||
!computes: the generalized force df=cmplx(dfr,dfi) acting on the i-th
|
||
! electron state at the gamma point of the brillouin zone
|
||
! represented by the vector c=cmplx(cr,ci)
|
||
!
|
||
! d_n(g) = f_n { 0.5 g^2 c_n(g) + [vc_n](g) +
|
||
! sum_i,ij d^q_i,ij (-i)**l beta_i,i(g)
|
||
! e^-ig.r_i < beta_i,j | c_n >}
|
||
use control_flags, only: iprint, tbuff
|
||
use gvec
|
||
use gvecs
|
||
use gvecw, only: ngw
|
||
use cvan
|
||
use smooth_grid_dimensions, only: nr1s, nr2s, nr3s, &
|
||
nr1sx, nr2sx, nr3sx, nnrsx
|
||
use elct
|
||
use constants, only: pi, fpi
|
||
use ions_base, only: nsp, na, nat
|
||
use gvecw, only: ggp, agg => ecutz, sgg => ecsig, e0gg => ecfix
|
||
use uspp_param, only: nh, nhm
|
||
use uspp, only : nhsa=> nkb, dvan
|
||
!
|
||
implicit none
|
||
!
|
||
complex(kind=8) betae(ngw,nhsa), c(ngw), ca(ngw), df(ngw), da(ngw)
|
||
real(kind=8) bec(nhsa,n), deeq(nhm,nhm,nat,nspin), v(nnrsx,nspin), v1(nnrsx,nspin)
|
||
integer i
|
||
! local variables
|
||
integer iv, jv, ia, is, isa, ism, ios, iss1, iss2, ir, ig, inl, jnl
|
||
real(kind=8) fi, fip, dd
|
||
complex(kind=8) fp,fm,ci
|
||
real(kind=8) af(nhsa), aa(nhsa) ! automatic arrays
|
||
complex(kind=8) dtemp(ngw) !
|
||
complex(kind=8), allocatable :: psi(:)
|
||
!
|
||
!
|
||
call start_clock( 'dforce_field' )
|
||
allocate( psi( nnrsx ) )
|
||
!
|
||
! important: if n is odd => c(*,n+1)=0.
|
||
!
|
||
if (mod(n,2).ne.0.and.i.eq.n) then
|
||
do ig=1,ngw
|
||
ca(ig)=(0.,0.)
|
||
end do
|
||
endif
|
||
!
|
||
ci=(0.0,1.0)
|
||
!
|
||
if (.not.tbuff) then
|
||
!
|
||
psi( 1:nnrsx ) = 0.0d0 ! call zero(2*nnrsx,psi)
|
||
do ig=1,ngw
|
||
psi(nms(ig))=conjg(c(ig)-ci*ca(ig))
|
||
psi(nps(ig))=c(ig)+ci*ca(ig)
|
||
end do
|
||
!
|
||
call ivfftw(psi,nr1s,nr2s,nr3s,nr1sx,nr2sx,nr3sx)
|
||
!
|
||
else
|
||
!
|
||
! read psi from buffer 21
|
||
!
|
||
#if defined(__CRAYY)
|
||
buffer in(21,0) (psi(1),psi(nnrsx))
|
||
ios = unit(21)
|
||
#else
|
||
read(21,iostat=ios) psi
|
||
#endif
|
||
if(ios.ne.0) call errore &
|
||
& (' dforce',' error in reading unit 21',ios)
|
||
!
|
||
endif
|
||
!
|
||
iss1=ispin(i)
|
||
!
|
||
! the following avoids a potential out-of-bounds error
|
||
!
|
||
if (i.ne.n) then
|
||
iss2=ispin(i+1)
|
||
else
|
||
iss2=iss1
|
||
end if
|
||
!
|
||
do ir=1,nnrsx
|
||
psi(ir)=cmplx(v(ir,iss1)* real(psi(ir)), &
|
||
& v1(ir,iss2)*aimag(psi(ir)) )
|
||
end do
|
||
!
|
||
call fwfftw(psi,nr1s,nr2s,nr3s,nr1sx,nr2sx,nr3sx)
|
||
!
|
||
! note : the factor 0.5 appears
|
||
! in the kinetic energy because it is defined as 0.5*g**2
|
||
! in the potential part because of the logics
|
||
!
|
||
fi =- f(i)*0.5
|
||
fip=-f(i+1)*0.5
|
||
do ig=1,ngw
|
||
fp= psi(nps(ig)) + psi(nms(ig))
|
||
fm= psi(nps(ig)) - psi(nms(ig))
|
||
df(ig)= fi*(tpiba2*ggp(ig)* c(ig)+cmplx(real(fp), aimag(fm)))
|
||
da(ig)=fip*(tpiba2*ggp(ig)*ca(ig)+cmplx(aimag(fp),-real(fm)))
|
||
end do
|
||
!
|
||
! aa_i,i,n = sum_j d_i,ij <beta_i,j|c_n>
|
||
!
|
||
if(nhsa.gt.0)then
|
||
do inl=1,nhsa
|
||
af(inl)=0.
|
||
aa(inl)=0.
|
||
end do
|
||
!
|
||
do is=1,nsp
|
||
do iv=1,nh(is)
|
||
do jv=1,nh(is)
|
||
isa=0
|
||
do ism=1,is-1
|
||
isa=isa+na(ism)
|
||
end do
|
||
do ia=1,na(is)
|
||
inl=ish(is)+(iv-1)*na(is)+ia
|
||
jnl=ish(is)+(jv-1)*na(is)+ia
|
||
isa=isa+1
|
||
dd = deeq(iv,jv,isa,iss1)+dvan(iv,jv,is)
|
||
af(inl)=af(inl)- f(i)*dd*bec(jnl, i)
|
||
dd = deeq(iv,jv,isa,iss2)+dvan(iv,jv,is)
|
||
if (i.ne.n) aa(inl)=aa(inl)-f(i+1)*dd*bec(jnl,i+1)
|
||
end do
|
||
end do
|
||
end do
|
||
end do
|
||
!
|
||
do ig=1,ngw
|
||
dtemp(ig)=(0.,0.)
|
||
end do
|
||
call MXMA &
|
||
& (betae,1,2*ngw,af,1,nhsa,dtemp,1,2*ngw,2*ngw,nhsa,1)
|
||
do ig=1,ngw
|
||
df(ig)=df(ig)+dtemp(ig)
|
||
end do
|
||
!
|
||
do ig=1,ngw
|
||
dtemp(ig)=(0.,0.)
|
||
end do
|
||
call MXMA &
|
||
& (betae,1,2*ngw,aa,1,nhsa,dtemp,1,2*ngw,2*ngw,nhsa,1)
|
||
do ig=1,ngw
|
||
da(ig)=da(ig)+dtemp(ig)
|
||
end do
|
||
endif
|
||
|
||
deallocate( psi )
|
||
!
|
||
call stop_clock( 'dforce_field' )
|
||
!
|
||
return
|
||
end
|
||
!----------------------------------------------------------------------
|
||
#ifdef __PARA
|
||
!-----------------------------------------------------------------------
|
||
subroutine write_psi(c,jw)
|
||
!----------------------------------------------------------------------
|
||
! for calwf 5 - M.S
|
||
! collect wavefunctions on first node and write to file
|
||
!
|
||
use gvec
|
||
use gvecs
|
||
use elct
|
||
use para_mod
|
||
use smooth_grid_dimensions , nnrs => nnrsx
|
||
use gvecw , only : ngw
|
||
use parallel_include
|
||
!
|
||
implicit none
|
||
|
||
integer unit, jw
|
||
complex*16 c(ngw,nx)
|
||
complex*16, allocatable :: psis(:)
|
||
!
|
||
integer i, ii, ig, proc, ierr, ntot, ncol, mc,ngpwpp(nproc)
|
||
integer nmin(3), nmax(3), n1,n2,nzx,nz,nz_
|
||
integer root, displs(nproc), recvcount(nproc)
|
||
complex*16, allocatable:: psitot(:), psiwr(:,:,:)
|
||
!
|
||
! nmin, nmax are the bounds on (i,j,k) indexes of wavefunction G-vectors
|
||
!
|
||
call nrbounds(ngw,nr1s,nr2s,nr3s,mill_l,nmin,nmax)
|
||
!
|
||
! nzx is the maximum length of a column along z
|
||
!
|
||
nzx=nmax(3)-nmin(3)+1
|
||
!
|
||
root = 0
|
||
! root is the first node
|
||
ntot = 0
|
||
|
||
|
||
do proc=1,nproc
|
||
ngpwpp(proc)=(dfftp%nwl(proc)+1)/2
|
||
ntot=ntot+ngpwpp(proc)
|
||
end do
|
||
|
||
do proc=1,nproc
|
||
|
||
recvcount(proc) = ngpwpp(proc)
|
||
!
|
||
!!
|
||
! recvcount(proc) = size of data received from processor proc
|
||
! (number of columns times length of each column)
|
||
!
|
||
if (proc.eq.1) then
|
||
displs(proc)=0
|
||
else
|
||
displs(proc)=displs(proc-1) + recvcount(proc-1)
|
||
end if
|
||
!
|
||
! displs(proc) is the position of data received from processor proc
|
||
!
|
||
! ntot = ntot + recvcount(proc)
|
||
!
|
||
! ntot = total size of gathered data
|
||
!
|
||
end do
|
||
!
|
||
! allocate the needed work spaces
|
||
!
|
||
allocate( psis( nnrs ) )
|
||
psis( 1:nnrs ) = 0.0d0 ! call zero(2*nnrs,psis)
|
||
if (me.eq.1) then
|
||
allocate(psitot(ntot))
|
||
allocate(psiwr(nmin(3):nmax(3),nmin(1):nmax(1),nmin(2):nmax(2)))
|
||
! write(unit) n, nmin, nmax
|
||
end if
|
||
!
|
||
! fill array psis with c_i(G) (as packed columns along z)
|
||
!
|
||
! do i=1,n
|
||
do ig=1,ngw
|
||
!
|
||
! ncol+1 is the index of the column
|
||
!
|
||
ncol=(nps(ig)-1)/nr3sx
|
||
!
|
||
! nz_ is the z component in FFT style (refolded between 1 and nr3s)
|
||
!
|
||
nz_ =nps(ig)-ncol*nr3sx
|
||
!
|
||
! nz is the z component in "natural" style (between nmin(3) and nmax(3))
|
||
!
|
||
nz =nz_-1
|
||
if (nz.ge.nr3s/2) nz=nz-nr3s
|
||
|
||
! ncpw(me) columns along z are stored in contiguous order on each node
|
||
!
|
||
! psis(nz-nmin(3)+1+ncol*nzx)=c(ig,jw)
|
||
psis(ig)=c(ig,jw)
|
||
end do
|
||
!
|
||
! gather all psis arrays on the first node, in psitot
|
||
!
|
||
call mpi_barrier ( MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('write_wfc','mpi_barrier 2',ierr)
|
||
call mpi_gatherv (psis, recvcount(me), MPI_DOUBLE_COMPLEX, &
|
||
& psitot,recvcount, displs,MPI_DOUBLE_COMPLEX, &
|
||
& root, MPI_COMM_WORLD, ierr)
|
||
if (ierr.ne.0) call errore('write_wfc','mpi_gatherv',ierr)
|
||
!
|
||
! write the node-number-independent array
|
||
!
|
||
if(me.eq.1) then
|
||
do i=1,ntot
|
||
write(22,*) psitot(i)
|
||
end do
|
||
write(6,*) "State Written", jw
|
||
end if
|
||
!
|
||
if (me.eq.1) then
|
||
deallocate(psiwr)
|
||
deallocate(psitot)
|
||
end if
|
||
|
||
deallocate( psis )
|
||
!
|
||
return
|
||
!
|
||
end subroutine write_psi
|
||
!
|
||
#endif
|
||
!-----------------------------------------------------------------------
|
||
subroutine rhoiofr (nfi,c,irb,eigrb,bec,rhovan,rhor,rhog,rhos,enl,ekin,ndwwf)
|
||
!-----------------------------------------------------------------------
|
||
! the normalized electron density rhor in real space
|
||
! the kinetic energy ekin
|
||
! subroutine uses complex fft so it computes two ft's
|
||
! simultaneously
|
||
!
|
||
! rho_i,ij = sum_n < beta_i,i | psi_n >< psi_n | beta_i,j >
|
||
! < psi_n | beta_i,i > = c_n(0) beta_i,i(0) +
|
||
! 2 sum_g> re(c_n*(g) (-i)**l beta_i,i(g) e^-ig.r_i)
|
||
!
|
||
! e_v = sum_i,ij rho_i,ij d^ion_is,ji
|
||
!
|
||
use control_flags, only: iprint, tbuff, iprsta, thdyn, tpre, trhor
|
||
use ions_base , nas => nax
|
||
use parameters, only: natx, nsx
|
||
use gvec
|
||
use gvecs
|
||
use gvecb, only: ngb
|
||
use gvecw, only: ngw
|
||
use reciprocal_vectors, only: ng0 => gstart
|
||
use cvan
|
||
!use parm
|
||
use grid_dimensions, only: nr1, nr2, nr3, &
|
||
nr1x, nr2x, nr3x, nnr => nnrx
|
||
use cell_base, only: omega
|
||
use smooth_grid_dimensions, only: nr1s, nr2s, nr3s, &
|
||
nr1sx, nr2sx, nr3sx, nnrsx
|
||
use elct
|
||
use constants, only: pi, fpi
|
||
use pseu
|
||
use wfparm, only : iwf
|
||
!
|
||
use cdvan
|
||
use dener
|
||
use io_global, only: stdout
|
||
use uspp_param, only: nh, nhm
|
||
use uspp, only : nhsa=> nkb
|
||
!
|
||
implicit none
|
||
real(kind=8) bec(nhsa,n), rhovan(nhm*(nhm+1)/2,nat,nspin)
|
||
real(kind=8) rhovanaux(nhm,nhm,nat,nspin)
|
||
real(kind=8) rhor(nnr,nspin), rhos(nnrsx,nspin)
|
||
real(kind=8) enl, ekin
|
||
complex(kind=8) eigrb(ngb,nas,nsp), c(ngw,nx), rhog(ng,nspin)
|
||
integer irb(3,natx,nsx), nfi, ndwwf
|
||
! local variables
|
||
integer iss, isup, isdw, iss1, iss2, ios, i, ir, ig
|
||
integer is,iv,jv,isa,isn, jnl, j, k, inl, ism, ia
|
||
real(kind=8) rsumr(2), rsumg(2), sa1, sa2, sums(2)
|
||
real(kind=8) rnegsum, rmin, rmax, rsum
|
||
real(kind=8) enkin, ennl
|
||
complex(kind=8) ci,fp,fm
|
||
complex(kind=8), allocatable :: psi(:), psis(:)
|
||
external ennl, enkin
|
||
!
|
||
!
|
||
call start_clock(' rhoiofr ')
|
||
allocate( psi( nnr ) )
|
||
allocate( psis( nnrsx ) )
|
||
ci=(0.0,1.0)
|
||
do iss=1,nspin
|
||
rhor( 1:nnr, iss ) = 0.0d0 ! call zero(nnr,rhor(1,iss))
|
||
rhos( 1:nnrsx, iss ) = 0.0d0 ! call zero(nnrsx,rhos(1,iss))
|
||
rhog( 1:ng, iss ) = 0.0d0 ! call zero(2*ng,rhog(1,iss))
|
||
end do
|
||
!
|
||
! ==================================================================
|
||
! calculation of kinetic energy ekin
|
||
! ==================================================================
|
||
ekin=enkin(c)
|
||
if(tpre) call denkin(c,dekin)
|
||
!
|
||
! ==================================================================
|
||
! calculation of non-local energy
|
||
! ==================================================================
|
||
! enl=ennl(rhovan,bec)
|
||
do is=1,nsp
|
||
do iv=1, nh(is)
|
||
do jv=iv,nh(is)
|
||
isa=0
|
||
do ism=1,is-1
|
||
isa=isa+na(ism)
|
||
end do
|
||
do ia=1,na(is)
|
||
inl=ish(is)+(iv-1)*na(is)+ia
|
||
jnl=ish(is)+(jv-1)*na(is)+ia
|
||
isa=isa+1
|
||
sums(1)=f(iwf)*bec(inl,iwf)*bec(jnl,iwf)
|
||
rhovanaux(iv,jv,isa,1) = sums(1)
|
||
rhovanaux(jv,iv,isa,1) = sums(1)
|
||
end do
|
||
end do
|
||
end do
|
||
end do
|
||
|
||
k=1
|
||
do i=1,nhm
|
||
do j=i,nhm
|
||
rhovan(k,:,:)=rhovanaux(j,i,:,:)
|
||
k=k+1
|
||
end do
|
||
end do
|
||
|
||
if(tpre) call dennl(bec,denl)
|
||
!
|
||
! warning! trhor and thdyn are not compatible yet!
|
||
!
|
||
if(trhor.and.(.not.thdyn))then
|
||
! ==================================================================
|
||
! charge density is read from unit 47
|
||
! ==================================================================
|
||
#ifdef __PARA
|
||
call read_rho(47,nspin,rhor)
|
||
#else
|
||
read(47) ((rhor(ir,iss),ir=1,nnr),iss=1,nspin)
|
||
#endif
|
||
rewind 47
|
||
!
|
||
if(nspin.eq.1)then
|
||
iss=1
|
||
do ir=1,nnr
|
||
psi(ir)=cmplx(rhor(ir,iss),0.)
|
||
end do
|
||
call fwfft(psi,nr1,nr2,nr3,nr1x,nr2x,nr3x)
|
||
do ig=1,ng
|
||
rhog(ig,iss)=psi(np(ig))
|
||
end do
|
||
else
|
||
isup=1
|
||
isdw=2
|
||
do ir=1,nnr
|
||
psi(ir)=cmplx(rhor(ir,isup),rhor(ir,isdw))
|
||
end do
|
||
call fwfft(psi,nr1,nr2,nr3,nr1x,nr2x,nr3x)
|
||
do ig=1,ng
|
||
fp=psi(np(ig))+psi(nm(ig))
|
||
fm=psi(np(ig))-psi(nm(ig))
|
||
rhog(ig,isup)=0.5*cmplx( real(fp),aimag(fm))
|
||
rhog(ig,isdw)=0.5*cmplx(aimag(fp),-real(fm))
|
||
end do
|
||
endif
|
||
!
|
||
else
|
||
! ==================================================================
|
||
! self-consistent charge
|
||
! ==================================================================
|
||
!
|
||
! important: if n is odd then nx must be .ge.n+1 and c(*,n+1)=0.
|
||
!
|
||
! if (mod(n,2).ne.0) then
|
||
! do ig=1,ngw
|
||
! c(ig,n+1)=(0.,0.)
|
||
! end do
|
||
! endif
|
||
!
|
||
! do i=1,n,2
|
||
i=iwf
|
||
psis( 1:nnrsx ) = 0.0d0 ! call zero(2*nnrsx,psis)
|
||
do ig=1,ngw
|
||
! c(ig,i+1)=(0.,0.)
|
||
psis(nms(ig))=conjg(c(ig,i))
|
||
psis(nps(ig))=c(ig,i)
|
||
end do
|
||
!
|
||
call ivfftw(psis,nr1s,nr2s,nr3s,nr1sx,nr2sx,nr3sx)
|
||
!
|
||
! wavefunctions in unit 21
|
||
!
|
||
#if defined(__CRAYY)
|
||
if(tbuff) buffer out(21,0) (psis(1),psis(nnrsx))
|
||
#else
|
||
if(tbuff) write(21,iostat=ios) psis
|
||
#endif
|
||
! iss1=ispin(i)
|
||
iss1=1
|
||
sa1=f(i)/omega
|
||
! if (i.ne.n) then
|
||
! iss2=ispin(i+1)
|
||
! sa2=f(i+1)/omega
|
||
! else
|
||
iss2=iss1 ! carlo
|
||
sa2=0.0
|
||
! end if
|
||
do ir=1,nnrsx
|
||
rhos(ir,iss1)=rhos(ir,iss1) + sa1*( real(psis(ir)))**2
|
||
rhos(ir,iss2)=rhos(ir,iss2) + sa2*(aimag(psis(ir)))**2
|
||
end do
|
||
!
|
||
! buffer 21
|
||
!
|
||
if(tbuff) then
|
||
#if defined(__CRAYY)
|
||
ios=unit(21)
|
||
#endif
|
||
if(ios.ne.0) call errore &
|
||
& (' rhoofr',' error in writing unit 21',ios)
|
||
endif
|
||
!
|
||
! end do
|
||
!
|
||
if(tbuff) rewind 21
|
||
!
|
||
! smooth charge in g-space is put into rhog(ig)
|
||
!
|
||
if(nspin.eq.1)then
|
||
iss=1
|
||
do ir=1,nnrsx
|
||
psis(ir)=cmplx(rhos(ir,iss),0.)
|
||
end do
|
||
call fwffts(psis,nr1s,nr2s,nr3s,nr1sx,nr2sx,nr3sx)
|
||
do ig=1,ngs
|
||
rhog(ig,iss)=psis(nps(ig))
|
||
end do
|
||
else
|
||
isup=1
|
||
isdw=2
|
||
do ir=1,nnrsx
|
||
psis(ir)=cmplx(rhos(ir,isup),rhos(ir,isdw))
|
||
end do
|
||
call fwffts(psis,nr1s,nr2s,nr3s,nr1sx,nr2sx,nr3sx)
|
||
do ig=1,ngs
|
||
fp= psis(nps(ig)) + psis(nms(ig))
|
||
fm= psis(nps(ig)) - psis(nms(ig))
|
||
rhog(ig,isup)=0.5*cmplx( real(fp),aimag(fm))
|
||
rhog(ig,isdw)=0.5*cmplx(aimag(fp),-real(fm))
|
||
end do
|
||
endif
|
||
!
|
||
if(nspin.eq.1) then
|
||
! ==================================================================
|
||
! case nspin=1
|
||
! ------------------------------------------------------------------
|
||
iss=1
|
||
psi( 1:nnr ) = 0.0d0 ! call zero(2*nnr,psi)
|
||
do ig=1,ngs
|
||
psi(nm(ig))=conjg(rhog(ig,iss))
|
||
psi(np(ig))= rhog(ig,iss)
|
||
end do
|
||
call invfft(psi,nr1,nr2,nr3,nr1x,nr2x,nr3x)
|
||
do ir=1,nnr
|
||
rhor(ir,iss)=real(psi(ir))
|
||
end do
|
||
else
|
||
! ==================================================================
|
||
! case nspin=2
|
||
! ------------------------------------------------------------------
|
||
isup=1
|
||
isdw=2
|
||
psi( 1:nnr ) = 0.0d0 ! call zero(2*nnr,psi)
|
||
do ig=1,ngs
|
||
psi(nm(ig))=conjg(rhog(ig,isup))+ci*conjg(rhog(ig,isdw))
|
||
psi(np(ig))=rhog(ig,isup)+ci*rhog(ig,isdw)
|
||
end do
|
||
call invfft(psi,nr1,nr2,nr3,nr1x,nr2x,nr3x)
|
||
do ir=1,nnr
|
||
rhor(ir,isup)= real(psi(ir))
|
||
rhor(ir,isdw)=aimag(psi(ir))
|
||
end do
|
||
endif
|
||
!
|
||
! if(iprsta.ge.3)then
|
||
write( stdout,*) 'Smooth part of charge density :'
|
||
do iss=1,nspin
|
||
rsumg(iss)=omega*real(rhog(1,iss))
|
||
rsumr(iss)=SUM(rhor(1:nnr,iss))*omega/dfloat(nr1*nr2*nr3)
|
||
end do
|
||
#ifdef __PARA
|
||
if (ng0.ne.2) then
|
||
! in the parallel case, only one processor has G=0 !
|
||
do iss=1,nspin
|
||
rsumg(iss)=0.0
|
||
end do
|
||
end if
|
||
call reduce(nspin,rsumg)
|
||
call reduce(nspin,rsumr)
|
||
#endif
|
||
if (nspin.eq.1) then
|
||
WRITE( stdout,1) rsumg(1),rsumr(1)
|
||
else
|
||
WRITE( stdout,2) (rsumg(iss),iss=1,nspin),(rsumr(iss),iss=1,nspin)
|
||
endif
|
||
! endif
|
||
! ==================================================================
|
||
!
|
||
! add vanderbilt contribution to the charge density
|
||
!
|
||
! drhov called before rhov because input rho must be the smooth part
|
||
!
|
||
if (tpre) call drhov(irb,eigrb,rhovan,rhog,rhor)
|
||
!
|
||
call rhov(irb,eigrb,rhovan,rhog,rhor)
|
||
endif
|
||
! ======================================endif for trhor=============
|
||
rewind ndwwf
|
||
#ifdef __PARA
|
||
call write_rho(ndwwf,nspin,rhor)
|
||
#else
|
||
write(ndwwf,'(f12.7)') &
|
||
((rhor(ir,iss),ir=1,nnr),iss=1,nspin)
|
||
#endif
|
||
|
||
|
||
!
|
||
! here to check the integral of the charge density
|
||
!
|
||
!
|
||
if(iprsta.ge.2) then
|
||
call checkrho(nnr,nspin,rhor,rmin,rmax,rsum,rnegsum)
|
||
rnegsum=rnegsum*omega/dfloat(nr1*nr2*nr3)
|
||
rsum=rsum*omega/dfloat(nr1*nr2*nr3)
|
||
WRITE( stdout,'(a,4(1x,f12.6))') &
|
||
& ' rhoofr: rmin rmax rnegsum rsum ',rmin,rmax,rnegsum,rsum
|
||
end if
|
||
!
|
||
if(nfi.eq.0.or.mod(nfi-1,iprint).eq.0) then
|
||
|
||
write( stdout, * )
|
||
write( stdout, * ) 'Smooth part + Augmentatio Part: '
|
||
do iss=1,nspin
|
||
rsumg(iss)=omega*real(rhog(1,iss))
|
||
rsumr(iss)=SUM(rhor(1:nnr,iss))*omega/dfloat(nr1*nr2*nr3)
|
||
end do
|
||
#ifdef __PARA
|
||
if (ng0.ne.2) then
|
||
! in the parallel case, only one processor has G=0 !
|
||
do iss=1,nspin
|
||
rsumg(iss)=0.0
|
||
end do
|
||
end if
|
||
call reduce(nspin,rsumg)
|
||
call reduce(nspin,rsumr)
|
||
#endif
|
||
if (nspin.eq.1) then
|
||
WRITE( stdout,1) rsumg(1),rsumr(1)
|
||
else
|
||
if(iprsta.ge.3) &
|
||
& WRITE( stdout,2) rsumg(1),rsumg(2),rsumr(1),rsumr(2)
|
||
WRITE( stdout,1) rsumg(1)+rsumg(2),rsumr(1)+rsumr(2)
|
||
endif
|
||
endif
|
||
!
|
||
2 format(//' subroutine rhoofr: total integrated electronic', &
|
||
& ' density'/' in g-space =',f10.6,2x,f10.6,4x, &
|
||
& ' in r-space =',f10.6,2x,f10.6)
|
||
1 format(//' subroutine rhoofr: total integrated electronic', &
|
||
& ' density'/' in g-space =',f10.6,4x, &
|
||
& ' in r-space =',f10.6)
|
||
!
|
||
|
||
write( stdout, * )
|
||
write( stdout , * ) 'State Written : ' ,iwf, 'to unit',ndwwf
|
||
write( stdout, * )
|
||
|
||
deallocate( psi )
|
||
deallocate( psis )
|
||
|
||
call stop_clock(' rhoiofr ')
|
||
!
|
||
return
|
||
end
|
||
!
|
||
!-----------------------------------------------------------------------
|