The Elk Code
eveqnit.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2002-2005 J. K. Dewhurst, S. Sharma and C. Ambrosch-Draxl.
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 eveqnit(nmatp,ngp,igpig,vpl,vgpl,vgpc,apwalm,evalfv,evecfv)
7 use modmain
8 use modomp
9 implicit none
10 ! arguments
11 integer, intent(in) :: nmatp,ngp,igpig(ngkmax)
12 real(8), intent(in) :: vpl(3),vgpl(3,ngkmax),vgpc(3,ngkmax)
13 complex(8), intent(in) :: apwalm(ngkmax,apwordmax,lmmaxapw,natmtot)
14 real(8), intent(out) :: evalfv(nstfv)
15 complex(8), intent(out) :: evecfv(nmatmax,nstfv)
16 ! local variables
17 integer ns,ist,it,i,j
18 integer is,ias,nthd
19 integer lwork,info
20 real(8) t1
21 real(8) ts1,ts0
22 ! allocatable arrays
23 integer, allocatable :: idx(:)
24 real(8), allocatable :: w(:),rwork(:)
25 complex(8), allocatable :: h(:,:),o(:,:),hv(:,:),ov(:,:)
26 complex(8), allocatable :: u(:,:),hu(:,:),ou(:,:)
27 complex(8), allocatable :: hs(:,:),os(:,:),work(:)
28 ! external functions
29 real(8), external :: ddot
30 ! compute Hamiltonian and overlap matrices
31 call timesec(ts0)
32 allocate(h(nmatp,nmatp),o(nmatp,nmatp))
33 call holdthd(2,nthd)
34 !$OMP PARALLEL SECTIONS DEFAULT(SHARED) &
35 !$OMP PRIVATE(j,ias,is) &
36 !$OMP NUM_THREADS(nthd)
37 !$OMP SECTION
38 ! Hamiltonian
39 call hmlistl(ngp,igpig,vgpc,nmatp,h)
40 do j=ngp+1,nmatp
41  h(1:j,j)=0.d0
42 end do
43 do ias=1,natmtot
44  is=idxis(ias)
45  call hmlaa(tefvr,is,ias,ngp,apwalm(:,:,:,ias),nmatp,h)
46  call hmlalo(is,ias,ngp,apwalm(:,:,:,ias),nmatp,h)
47  call hmllolo(is,ias,ngp,nmatp,h)
48 end do
49 !$OMP SECTION
50 ! overlap
51 call olpistl(ngp,igpig,nmatp,o)
52 do j=ngp+1,nmatp
53  o(1:j,j)=0.d0
54 end do
55 do ias=1,natmtot
56  is=idxis(ias)
57  call olpaa(tefvr,is,ngp,apwalm(:,:,:,ias),nmatp,o)
58  call olpalo(is,ias,ngp,apwalm(:,:,:,ias),nmatp,o)
59  call olplolo(is,ias,ngp,nmatp,o)
60 end do
61 !$OMP END PARALLEL SECTIONS
62 call freethd(nthd)
63 call timesec(ts1)
64 !$OMP ATOMIC
65 timemat=timemat+ts1-ts0
66 if (trdstate.or.(iscl >= 2)) then
67 ! read in the eigenvalues/vectors from file if available
68  call getevalfv(filext,0,vpl,evalfv)
69  call getevecfv(filext,0,vpl,vgpl,evecfv)
70 else
71 ! initialise the eigenvalues/vectors using the diagonal elements of H
72  allocate(idx(nmatp),w(nmatp))
73  do i=1,nmatp
74  w(i)=h(i,i)
75  end do
76  call sortidx(nmatp,w,idx)
77  do ist=1,nstfv
78  evalfv(ist)=w(idx(ist))
79  end do
80  evecfv(1:nmatp,1:nstfv)=0.d0
81  do ist=1,nstfv
82  evecfv(idx(ist),ist)=1.d0
83  end do
84  deallocate(idx,w)
85 end if
86 call timesec(ts0)
87 ns=2*nstfv
88 allocate(w(ns),rwork(3*ns))
89 allocate(hv(nmatp,nstfv),ov(nmatp,nstfv))
90 allocate(u(nmatp,nstfv),hu(nmatp,nstfv),ou(nmatp,nstfv))
91 allocate(hs(ns,ns),os(ns,ns))
92 lwork=2*ns
93 allocate(work(lwork))
94 call holdthd(nstfv,nthd)
95 ! iteration loop
96 !$OMP PARALLEL DEFAULT(SHARED) &
97 !$OMP PRIVATE(it,ist,t1) &
98 !$OMP NUM_THREADS(nthd)
99 do it=1,nefvit
100 !$OMP DO SCHEDULE(DYNAMIC)
101  do ist=1,nstfv
102 ! operate with O on the current eigenvector
103  call zhemv('U',nmatp,zone,o,nmatp,evecfv(:,ist),1,zzero,ov(:,ist),1)
104 ! normalise the eigenvector
105  t1=ddot(2*nmatp,evecfv(:,ist),1,ov(:,ist),1)
106  if (t1 > 0.d0) then
107  t1=1.d0/sqrt(t1)
108  call zdscal(nmatp,t1,evecfv(:,ist),1)
109  call zdscal(nmatp,t1,ov(:,ist),1)
110  end if
111 ! operate with H on the current eigenvector
112  call zhemv('U',nmatp,zone,h,nmatp,evecfv(:,ist),1,zzero,hv(:,ist),1)
113 ! estimate the eigenvalue
114  t1=ddot(2*nmatp,evecfv(:,ist),1,hv(:,ist),1)
115 ! mix with old eigenvalue
116  evalfv(ist)=(1.d0-befvit)*evalfv(ist)+befvit*t1
117 ! compute the residual |u⟩ = (H - eO)|v⟩
118  call zcopy(nmatp,hv(:,ist),1,u(:,ist),1)
119  t1=-evalfv(ist)
120  u(1:nmatp,ist)=u(1:nmatp,ist)+t1*ov(1:nmatp,ist)
121 ! apply the overlap matrix to the residual
122  call zhemv('U',nmatp,zone,o,nmatp,u(:,ist),1,zzero,ou(:,ist),1)
123 ! apply the Hamiltonian matrix to the residual
124  call zhemv('U',nmatp,zone,h,nmatp,u(:,ist),1,zzero,hu(:,ist),1)
125  end do
126 !$OMP END DO
127 ! compute the Hamiltonian and overlap matrices in the subspace formed by the
128 ! eigenvectors and their residuals
129 !$OMP DO SCHEDULE(DYNAMIC)
130  do ist=1,nstfv
131  call zgemv('C',nmatp,nstfv,zone,evecfv,nmatmax,hv(:,ist),1,zzero, &
132  hs(1,ist),1)
133  call zgemv('C',nmatp,nstfv,zone,evecfv,nmatmax,hu(:,ist),1,zzero, &
134  hs(1,nstfv+ist),1)
135  call zgemv('C',nmatp,nstfv,zone,u,nmatp,hu(:,ist),1,zzero, &
136  hs(nstfv+1,nstfv+ist),1)
137  end do
138 !$OMP END DO NOWAIT
139 !$OMP DO SCHEDULE(DYNAMIC)
140  do ist=1,nstfv
141  call zgemv('C',nmatp,nstfv,zone,evecfv,nmatmax,ov(:,ist),1,zzero, &
142  os(1,ist),1)
143  call zgemv('C',nmatp,nstfv,zone,evecfv,nmatmax,ou(:,ist),1,zzero, &
144  os(1,nstfv+ist),1)
145  call zgemv('C',nmatp,nstfv,zone,u,nmatp,ou(:,ist),1,zzero, &
146  os(nstfv+1,nstfv+ist),1)
147  end do
148 !$OMP END DO
149 ! solve the generalised eigenvalue problem in the subspace (one thread only)
150 !$OMP SINGLE
151  call zhegv(1,'V','U',ns,hs,ns,os,ns,w,work,lwork,rwork,info)
152 !$OMP END SINGLE
153  if (info /= 0) exit
154 ! construct the new eigenvectors
155 !$OMP DO SCHEDULE(DYNAMIC)
156  do ist=1,nstfv
157  call zgemv('N',nmatp,nstfv,zone,evecfv,nmatmax,hs(1,ist),1,zzero, &
158  ov(:,ist),1)
159  call zgemv('N',nmatp,nstfv,zone,u,nmatp,hs(nstfv+1,ist),1,zone,ov(:,ist),1)
160  end do
161 !$OMP END DO
162 !$OMP DO SCHEDULE(DYNAMIC)
163  do ist=1,nstfv
164  call zcopy(nmatp,ov(:,ist),1,evecfv(:,ist),1)
165  end do
166 !$OMP END DO
167 ! end iteration loop
168 end do
169 !$OMP END PARALLEL
170 call freethd(nthd)
171 deallocate(w,rwork,h,o,hv,ov)
172 deallocate(u,hu,ou,hs,os,work)
173 call timesec(ts1)
174 !$OMP ATOMIC
175 timefv=timefv+ts1-ts0
176 end subroutine
177 
pure subroutine hmlistl(ngp, igpig, vgpc, ld, h)
Definition: hmlistl.f90:10
character(256) filext
Definition: modmain.f90:1301
subroutine getevecfv(fext, ikp, vpl, vgpl, evecfv)
Definition: getevecfv.f90:10
integer iscl
Definition: modmain.f90:1051
Definition: modomp.f90:6
subroutine hmlaa(thr, is, ias, ngp, apwalm, ld, h)
Definition: hmlaa.f90:10
complex(8), parameter zone
Definition: modmain.f90:1240
real(8) timemat
Definition: modmain.f90:1217
logical tefvr
Definition: modmain.f90:870
subroutine olpaa(tor, is, ngp, apwalm, ld, o)
Definition: olpaa.f90:7
pure subroutine olpalo(is, ias, ngp, apwalm, ld, o)
Definition: olpalo.f90:7
subroutine getevalfv(fext, ikp, vpl, evalfv)
Definition: getevalfv.f90:7
pure subroutine sortidx(n, x, idx)
Definition: sortidx.f90:10
complex(8), parameter zzero
Definition: modmain.f90:1240
integer, dimension(maxatoms *maxspecies) idxis
Definition: modmain.f90:44
subroutine timesec(ts)
Definition: timesec.f90:10
pure subroutine olpistl(ngp, igpig, ld, o)
Definition: olpistl.f90:10
integer nefvit
Definition: modmain.f90:875
real(8) timefv
Definition: modmain.f90:1219
subroutine eveqnit(nmatp, ngp, igpig, vpl, vgpl, vgpc, apwalm, evalfv, evecfv)
Definition: eveqnit.f90:7
subroutine freethd(nthd)
Definition: modomp.f90:106
subroutine holdthd(nloop, nthd)
Definition: modomp.f90:78
logical trdstate
Definition: modmain.f90:682
real(8) befvit
Definition: modmain.f90:877
pure subroutine olplolo(is, ias, ngp, ld, o)
Definition: olplolo.f90:7
pure subroutine hmllolo(is, ias, ngp, ld, h)
Definition: hmllolo.f90:7
pure subroutine hmlalo(is, ias, ngp, apwalm, ld, h)
Definition: hmlalo.f90:7