The Elk Code
eveqnss.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2006 F. Bultmark, F. Cricchio, L. Nordstrom and J. K. Dewhurst.
3 ! This file is distributed under the terms of the GNU General Public License.
4 ! See the file COPYING for license details.
5 
6 subroutine eveqnss(ngp,igpig,apwalm,evalfv,evecfv,evalsv_,evecsv)
7 use modmain
8 use moddftu
9 use modomp
10 implicit none
11 ! arguments
12 integer, intent(in) :: ngp(nspnfv),igpig(ngkmax,nspnfv)
13 complex(8), intent(in) :: apwalm(ngkmax,apwordmax,lmmaxapw,natmtot,nspnfv)
14 real(8), intent(in) :: evalfv(nstfv,nspnfv)
15 complex(8), intent(in) :: evecfv(nmatmax,nstfv,nspnfv)
16 real(8), intent(out) :: evalsv_(nstsv)
17 complex(8), intent(out) :: evecsv(nstsv,nstsv)
18 ! local variables
19 integer ld,ist,jst,ispn,is,ias
20 integer nrc,nrci,nrco,nj,i,j
21 integer l,lm,nm,npc,npc2,npci
22 integer n1,n12,n2,n22,igp,nthd
23 real(8) ts0,ts1
24 complex(8) zq
25 ! automatic arrays
26 complex(8) wfmt2(npcmtmax,nspnfv),wfmt4(npcmtmax)
27 complex(8) wfmt31(npcmtmax),wfmt32(npcmtmax),wfmt33(npcmtmax)
28 complex(4) wfmt5(npcmtmax),wfgp1(ngkmax),wfgp2(ngkmax),wfgp3(ngkmax)
29 complex(4) wfir1(ngtc,nspnfv),wfir2(ngtc),y(nstfv)
30 ! allocatable arrays
31 complex(4), allocatable :: wfmt0(:,:,:),wfgp0(:,:,:)
32 complex(8), allocatable :: wfmt1(:,:,:)
33 ! external functions
34 real(4), external :: sdot
35 if (.not.spinpol) then
36  write(*,*)
37  write(*,'("Error(eveqnss): spin-unpolarised calculation")')
38  write(*,*)
39  stop
40 end if
41 call timesec(ts0)
43 ! zero the second-variational Hamiltonian (stored in the eigenvector array)
44 evecsv(1:nstsv,1:nstsv)=0.d0
45 ! set the diagonal elements equal to the first-variational eigenvalues
46 do ispn=1,nspinor
47  do ist=1,nstfv
48  i=nstfv*(ispn-1)+ist
49  evecsv(i,i)=evalfv(ist,ispn)
50  end do
51 end do
52 call holdthd(nstfv,nthd)
53 !$OMP PARALLEL DEFAULT(SHARED) &
54 !$OMP PRIVATE(wfmt2,wfmt31,wfmt32,wfmt33,wfmt4,wfmt5) &
55 !$OMP PRIVATE(wfir1,wfir2,wfgp1,wfgp2,wfgp3,y) &
56 !$OMP PRIVATE(ias,is,nrc,nrci,nrco,npc,npc2,npci) &
57 !$OMP PRIVATE(zq,ispn,ist,jst,l,nm,lm,i,j,nj,igp) &
58 !$OMP NUM_THREADS(nthd)
59 !-------------------------!
60 ! muffin-tin part !
61 !-------------------------!
62 !$OMP SINGLE
63 allocate(wfmt0(npcmtmax,nstfv,nspnfv),wfmt1(npcmtmax,nstfv,nspnfv))
64 !$OMP END SINGLE
65 do ias=1,natmtot
66  is=idxis(ias)
67  nrc=nrcmt(is)
68  nrci=nrcmti(is)
69  nrco=nrc-nrci
70  npc=npcmt(is)
71  npc2=npc*2
72  npci=npcmti(is)
73 ! de-phasing factor (FC, FB & LN)
74  if (ssdph) zq=zqss(ias)
75 ! compute the first-variational wavefunctions
76  do ispn=1,nspnfv
77  if (ssdph.and.(ispn == 2)) zq=conjg(zq)
78 !$OMP DO SCHEDULE(DYNAMIC)
79  do ist=1,nstfv
80  call wfmtfv(ias,ngp(ispn),apwalm(:,:,:,ias,ispn),evecfv(:,ist,ispn), &
81  wfmt1(:,ist,ispn))
82 ! de-phase if required
83  if (ssdph) wfmt1(1:npc,ist,ispn)=zq*wfmt1(1:npc,ist,ispn)
84 ! multiply wavefunction by integration weights and store as single-precision
85  call zcfmtwr(nrc,nrci,wr2cmt(:,is),wfmt1(:,ist,ispn),wfmt0(:,ist,ispn))
86  end do
87 !$OMP END DO
88  end do
89 !$OMP DO SCHEDULE(DYNAMIC)
90  do jst=1,nstfv
91 ! convert wavefunction to spherical coordinates
92  do ispn=1,nspnfv
93  call zbsht(nrc,nrci,wfmt1(:,jst,ispn),wfmt2(:,ispn))
94  end do
95 ! apply effective magnetic field and convert to spherical harmonics
96  wfmt4(1:npc)=bsmt(1:npc,ias,3)*wfmt2(1:npc,1)
97  call zfsht(nrc,nrci,wfmt4,wfmt31)
98  wfmt4(1:npc)=-bsmt(1:npc,ias,3)*wfmt2(1:npc,2)
99  call zfsht(nrc,nrci,wfmt4,wfmt32)
100  wfmt4(1:npc)=cmplx(bsmt(1:npc,ias,1),-bsmt(1:npc,ias,2),8)*wfmt2(1:npc,2)
101  call zfsht(nrc,nrci,wfmt4,wfmt33)
102 ! apply muffin-tin DFT+U potential matrix if required
103  if (tvmatmt) then
104  do l=0,lmaxdm
105  if (tvmmt(l,ias)) then
106  nm=2*l+1
107  lm=l**2+1
108  i=npci+lm
109  if (l <= lmaxi) then
110  call zgemm('N','N',nm,nrci,nm,zone,vmatmt(lm,1,lm,1,ias),ld, &
111  wfmt1(lm,jst,1),lmmaxi,zone,wfmt31(lm),lmmaxi)
112  end if
113  call zgemm('N','N',nm,nrco,nm,zone,vmatmt(lm,1,lm,1,ias),ld, &
114  wfmt1(i,jst,1),lmmaxo,zone,wfmt31(i),lmmaxo)
115  if (l <= lmaxi) then
116  call zgemm('N','N',nm,nrci,nm,zone,vmatmt(lm,2,lm,2,ias),ld, &
117  wfmt1(lm,jst,2),lmmaxi,zone,wfmt32(lm),lmmaxi)
118  end if
119  call zgemm('N','N',nm,nrco,nm,zone,vmatmt(lm,2,lm,2,ias),ld, &
120  wfmt1(i,jst,2),lmmaxo,zone,wfmt32(i),lmmaxo)
121  if (l <= lmaxi) then
122  call zgemm('N','N',nm,nrci,nm,zone,vmatmt(lm,1,lm,2,ias),ld, &
123  wfmt1(lm,jst,2),lmmaxi,zone,wfmt33(lm),lmmaxi)
124  end if
125  call zgemm('N','N',nm,nrco,nm,zone,vmatmt(lm,1,lm,2,ias),ld, &
126  wfmt1(i,jst,2),lmmaxo,zone,wfmt33(i),lmmaxo)
127  end if
128  end do
129  end if
130 ! add to second-variational Hamiltonian matrix
131  nj=jst-1
132 ! upper diagonal block
133  wfmt5(1:npc)=wfmt31(1:npc)
134  call cgemv('C',npc,nj,cone,wfmt0,npcmtmax,wfmt5,1,czero,y,1)
135  evecsv(1:nj,jst)=evecsv(1:nj,jst)+y(1:nj)
136  evecsv(jst,jst)=evecsv(jst,jst)+sdot(npc2,wfmt0(:,jst,1),1,wfmt5,1)
137  j=jst+nstfv
138 ! lower diagonal block
139  wfmt5(1:npc)=wfmt32(1:npc)
140  call cgemv('C',npc,nj,cone,wfmt0(:,:,2),npcmtmax,wfmt5,1,czero,y,1)
141  evecsv(nstfv+1:nstfv+nj,j)=evecsv(nstfv+1:nstfv+nj,j)+y(1:nj)
142  evecsv(j,j)=evecsv(j,j)+sdot(npc2,wfmt0(:,jst,2),1,wfmt5,1)
143 ! off-diagonal block
144  wfmt5(1:npc)=wfmt33(1:npc)
145  call cgemv('C',npc,nstfv,cone,wfmt0,npcmtmax,wfmt5,1,czero,y,1)
146  evecsv(1:nstfv,j)=evecsv(1:nstfv,j)+y(1:nstfv)
147  end do
148 !$OMP END DO
149 ! end loop over atoms
150 end do
151 !$OMP SINGLE
152 deallocate(wfmt0,wfmt1)
153 !$OMP END SINGLE
154 !---------------------------!
155 ! interstitial part !
156 !---------------------------!
157 !$OMP SINGLE
158 n1=ngp(1); n12=n1*2
159 n2=ngp(2); n22=n2*2
160 allocate(wfgp0(ngkmax,nstfv,nspnfv))
161 !$OMP END SINGLE
162 ! make single-precision copy of wavefunction
163 !$OMP DO SCHEDULE(DYNAMIC)
164  do ist=1,nstfv
165  do ispn=1,nspnfv
166  wfgp0(1:ngp(ispn),ist,ispn)=evecfv(1:ngp(ispn),ist,ispn)
167  end do
168  end do
169 !$OMP END DO
170 ! begin loop over states
171 !$OMP DO SCHEDULE(DYNAMIC)
172 do jst=1,nstfv
173  do ispn=1,nspnfv
174  wfir1(:,ispn)=0.e0
175  do igp=1,ngp(ispn)
176  wfir1(igfc(igpig(igp,ispn)),ispn)=wfgp0(igp,jst,ispn)
177  end do
178 ! Fourier transform wavefunction to real-space
179  call cfftifc(3,ngdgc,1,wfir1(:,ispn))
180  end do
181 ! multiply with magnetic field and transform to G-space
182  wfir2(1:ngtc)=bsirc(1:ngtc,3)*wfir1(1:ngtc,1)
183  call cfftifc(3,ngdgc,-1,wfir2)
184  do igp=1,n1
185  wfgp1(igp)=wfir2(igfc(igpig(igp,1)))
186  end do
187  wfir2(1:ngtc)=-bsirc(1:ngtc,3)*wfir1(1:ngtc,2)
188  call cfftifc(3,ngdgc,-1,wfir2)
189  do igp=1,n2
190  wfgp2(igp)=wfir2(igfc(igpig(igp,2)))
191  end do
192  wfir2(1:ngtc)=cmplx(bsirc(1:ngtc,1),-bsirc(1:ngtc,2),8)*wfir1(1:ngtc,2)
193  call cfftifc(3,ngdgc,-1,wfir2)
194  do igp=1,n1
195  wfgp3(igp)=wfir2(igfc(igpig(igp,1)))
196  end do
197 ! add to second-variational Hamiltonian matrix
198  nj=jst-1
199 ! upper diagonal block
200  call cgemv('C',n1,nj,cone,wfgp0,ngkmax,wfgp1,1,czero,y,1)
201  evecsv(1:nj,jst)=evecsv(1:nj,jst)+y(1:nj)
202  evecsv(jst,jst)=evecsv(jst,jst)+sdot(n12,wfgp0(:,jst,1),1,wfgp1,1)
203 ! lower diagonal block
204  j=jst+nstfv
205  call cgemv('C',n2,nj,cone,wfgp0(:,:,2),ngkmax,wfgp2,1,czero,y,1)
206  evecsv(nstfv+1:nstfv+nj,j)=evecsv(nstfv+1:nstfv+nj,j)+y(1:nj)
207  evecsv(j,j)=evecsv(j,j)+sdot(n22,wfgp0(:,jst,2),1,wfgp2,1)
208 ! off-diagonal block
209  call cgemv('C',n1,nstfv,cone,wfgp0,ngkmax,wfgp3,1,czero,y,1)
210  evecsv(1:nstfv,j)=evecsv(1:nstfv,j)+y(1:nstfv)
211 end do
212 !$OMP END DO
213 !$OMP SINGLE
214 deallocate(wfgp0)
215 !$OMP END SINGLE
216 !$OMP END PARALLEL
217 call freethd(nthd)
218 ! diagonalise the second-variational Hamiltonian
219 call eveqnzh(nstsv,nstsv,evecsv,evalsv_)
220 call timesec(ts1)
221 !$OMP ATOMIC
222 timesv=timesv+ts1-ts0
223 end subroutine
224 
integer, dimension(maxspecies) npcmt
Definition: modmain.f90:214
subroutine eveqnss(ngp, igpig, apwalm, evalfv, evecfv, evalsv_, evecsv)
Definition: eveqnss.f90:7
integer lmmaxo
Definition: modmain.f90:203
logical spinpol
Definition: modmain.f90:228
integer, parameter lmmaxdm
Definition: moddftu.f90:14
complex(4), parameter czero
Definition: modmain.f90:1239
Definition: modomp.f90:6
complex(4), parameter cone
Definition: modmain.f90:1239
complex(8), parameter zone
Definition: modmain.f90:1240
subroutine zfsht(nr, nri, zfmt1, zfmt2)
Definition: zfsht.f90:10
subroutine eveqnzh(n, ld, a, w)
Definition: eveqnzh.f90:7
subroutine cfftifc(nd, n, sgn, c)
Definition: cfftifc_fftw.f90:7
complex(8), dimension(:), allocatable zqss
Definition: modmain.f90:287
integer, dimension(:), allocatable igfc
Definition: modmain.f90:410
logical tvmatmt
Definition: moddftu.f90:24
integer nspinor
Definition: modmain.f90:267
complex(8), dimension(:,:,:,:,:), allocatable vmatmt
Definition: moddftu.f90:20
logical, dimension(:,:), allocatable tvmmt
Definition: moddftu.f90:26
subroutine wfmtfv(ias, ngp, apwalm, evecfv, wfmt)
Definition: wfmtfv.f90:10
logical ssdph
Definition: modmain.f90:285
real(8), dimension(:,:), allocatable wr2cmt
Definition: modmain.f90:189
integer, dimension(maxspecies) npcmti
Definition: modmain.f90:214
integer, dimension(maxatoms *maxspecies) idxis
Definition: modmain.f90:44
integer lmmaxi
Definition: modmain.f90:207
subroutine timesec(ts)
Definition: timesec.f90:10
subroutine zbsht(nr, nri, zfmt1, zfmt2)
Definition: zbsht.f90:10
integer, dimension(3) ngdgc
Definition: modmain.f90:388
pure subroutine zcfmtwr(nr, nri, wr, zfmt, cfmt)
Definition: zcfmtwr.f90:7
subroutine freethd(nthd)
Definition: modomp.f90:106
subroutine holdthd(nloop, nthd)
Definition: modomp.f90:78
real(8) timesv
Definition: modmain.f90:1221
integer, dimension(maxspecies) nrcmt
Definition: modmain.f90:173
integer, dimension(maxspecies) nrcmti
Definition: modmain.f90:211
integer, parameter lmaxdm
Definition: moddftu.f90:13
real(8), dimension(:,:), pointer, contiguous bsirc
Definition: modmain.f90:660
real(8), dimension(:,:,:), pointer, contiguous bsmt
Definition: modmain.f90:656
integer lmaxi
Definition: modmain.f90:205