The Elk Code
 
Loading...
Searching...
No Matches
tddftlr.f90
Go to the documentation of this file.
1
2! Copyright (C) 2010 S. Sharma, J. K. Dewhurst and E. K. U. Gross.
3! This file is distributed under the terms of the GNU General Public License.
4! See the file COPYING for license details.
5
6subroutine tddftlr
7use modmain
8use modtddft
9use modtest
10use modmpi
11use modomp
12implicit none
13! local variables
14logical tq0
15integer, parameter :: maxit=500
16integer iq,ik,isym
17integer nm,it,i,j,n
18integer iw,ioc,nthd
19real(8) v(3),t1,t2
20complex(8) vfxcp,z1
21character(256) fname
22! allocatable arrays
23integer(omp_lock_kind), allocatable :: lock(:)
24real(8), allocatable :: vgqc(:,:),gqc(:),gclgq(:),jlgqr(:,:,:)
25complex(8), allocatable :: ylmgq(:,:),sfacgq(:,:)
26complex(8), allocatable :: vchi0(:,:,:),vfxc(:,:,:)
27complex(4), allocatable :: vchi0_sp(:,:,:)
28complex(8), allocatable :: eps0(:,:,:),epsi(:,:,:),epsm(:,:,:)
29complex(8), allocatable :: zw(:),a(:,:)
30! initialise global variables
31call init0
32call init1
33call init2
34call init3
35! check q-vector is commensurate with k-point grid
36v(1:3)=dble(ngridk(1:3))*vecql(1:3)
37v(1:3)=abs(v(1:3)-nint(v(1:3)))
38if ((v(1) > epslat).or.(v(2) > epslat).or.(v(3) > epslat)) then
39 write(*,*)
40 write(*,'("Error(tddftlr): q-vector incommensurate with k-point grid")')
41 write(*,'(" ngridk : ",3I6)') ngridk
42 write(*,'(" vecql : ",3G18.10)') vecql
43 write(*,*)
44 stop
45end if
46! find the equivalent reduced q-point
47call findqpt(vecql,isym,iq)
48! check if q = 0
49tq0=.false.
50if (sum(abs(vecql(:))) < epslat) tq0=.true.
51! read density and potentials from file
52call readstate
53! find the new linearisation energies
54call linengy
55! generate the APW radial functions
56call genapwfr
57! generate the local-orbital radial functions
58call genlofr
59! get the eigenvalues and occupation numbers from file
60do ik=1,nkpt
61 call getevalsv(filext,ik,vkl(:,ik),evalsv(:,ik))
62 call getoccsv(filext,ik,vkl(:,ik),occsv(:,ik))
63end do
64! generate the G+q-vectors and related functions
65allocate(vgqc(3,ngrf),gqc(ngrf),jlgqr(njcmax,nspecies,ngrf))
66allocate(ylmgq(lmmaxo,ngrf),sfacgq(ngrf,natmtot))
67call gengqf(ngrf,vecqc,vgqc,gqc,jlgqr,ylmgq,sfacgq)
68deallocate(vgqc)
69! generate the regularised Coulomb Green's function in G+q-space
70allocate(gclgq(ngrf))
71call gengclgq(.true.,iq,ngrf,gqc,gclgq)
72gclgq(1:ngrf)=sqrt(gclgq(1:ngrf))
73! matrix sizes
74if (tq0) then
75! for q = 0 the head is a 3 x 3 matrix and the wings are 3 x ngrf
76 nm=ngrf+2
77else
78! otherwise the head is just G = G' = 0 and finite q
79 nm=ngrf
80end if
81! initialise the OpenMP locks
82allocate(lock(nwrf))
83do iw=1,nwrf
84 call omp_init_lock(lock(iw))
85end do
86! compute v¹⸍² χ₀ v¹⸍² (the symmetric version of v χ₀) in single-precision
87allocate(vchi0_sp(nm,nm,nwrf))
88vchi0_sp(1:nm,1:nm,1:nwrf)=0.e0
89call holdthd(nkptnr/np_mpi,nthd)
90!$OMP PARALLEL DO DEFAULT(SHARED) &
91!$OMP SCHEDULE(DYNAMIC) &
92!$OMP NUM_THREADS(nthd)
93do ik=1,nkptnr
94! distribute among MPI processes
95 if (mod(ik-1,np_mpi) /= lp_mpi) cycle
96!$OMP CRITICAL(tddftlr_)
97 write(*,'("Info(tddftlr): ",I6," of ",I6," k-points")') ik,nkptnr
98!$OMP END CRITICAL(tddftlr_)
99! add to v¹⸍² χ₀ v¹⸍²
100 call genvchi0(.true.,ik,lock,vecql,gclgq,jlgqr,ylmgq,sfacgq,nm,vchi0_sp)
101end do
102!$OMP END PARALLEL DO
103call freethd(nthd)
104! destroy the OpenMP locks
105do iw=1,nwrf
106 call omp_destroy_lock(lock(iw))
107end do
108deallocate(lock)
109! add vchi0 from each process and redistribute
110if (np_mpi > 1) then
111 n=nm*nm*nwrf
112 call mpi_allreduce(mpi_in_place,vchi0_sp,n,mpi_complex,mpi_sum,mpicom,ierror)
113end if
114! copy to double-precision array
115allocate(vchi0(nm,nm,nwrf))
116vchi0(1:nm,1:nm,1:nwrf)=vchi0_sp(1:nm,1:nm,1:nwrf)
117deallocate(vchi0_sp)
118allocate(vfxc(nm,nm,nwrf),eps0(nm,nm,nwrf),epsi(nm,nm,nwrf))
119! calculate symmetric ϵ_0 = 1 - v¹⸍² χ₀ v¹⸍²
120eps0(1:nm,1:nm,1:nwrf)=-vchi0(1:nm,1:nm,1:nwrf)
121do i=1,nm
122 eps0(i,i,1:nwrf)=eps0(i,i,1:nwrf)+1.d0
123end do
124! initialise ϵ for use with the bootstrap functional
125if (any(fxctype(1) == [210,211])) then
126 epsi(1:nm,1:nm,1:nwrf)=vchi0(1:nm,1:nm,1:nwrf)
127 do i=1,nm
128 epsi(i,i,1:nwrf)=epsi(i,i,1:nwrf)+1.d0
129 end do
130end if
131allocate(a(nm,nm))
132vfxcp=0.d0
133it=0
13410 continue
135! compute v χ₀ v⁻¹⸍² f_xc v⁻¹⸍² v χ₀
136call genvfxc(tq0,.true.,gclgq,nm,vchi0,eps0,epsi,vfxc)
137! begin loop over frequencies
138do iw=1,nwrf
139! compute 1 - v¹⸍² χ₀ v¹⸍² - v⁻¹⸍² f_xc v⁻¹⸍² v χ₀
140 a(1:nm,1:nm)=eps0(1:nm,1:nm,iw)-vfxc(1:nm,1:nm,iw)
141! invert this matrix
142 call zminv(nm,a)
143! left multiply by v¹⸍² χ₀ v¹⸍²
144 call zgemm('N','N',nm,nm,nm,zone,vchi0(:,:,iw),nm,a,nm,zzero,epsi(:,:,iw),nm)
145! compute ϵ⁻¹ = 1 + v¹⸍² χ v¹⸍²
146 do i=1,nm
147 epsi(i,i,iw)=1.d0+epsi(i,i,iw)
148 end do
149end do
150if (fxctype(1) == 210) then
151! self-consistent bootstrap f_xc
152 it=it+1
153 if (it > maxit) then
154 write(*,*)
155 write(*,'("Error(tddftlr): bootstrap kernel failed to converge")')
156 write(*,*)
157 stop
158 end if
159 if (mp_mpi) then
160 if (mod(it,10) == 0) then
161 write(*,'("Info(tddftlr): done ",I4," bootstrap iterations")') it
162 t1=dble(vfxc(1,1,1))
163 write(*,⁻¹⸍²⁻¹⸍²'(" head of matrix v f_xc v : ",G18.10)') t1
164 write(*,πα'(" multiplied by -4 gives : ",G18.10)') -fourpi*t1
165 end if
166 end if
167! check for convergence
168 t1=abs(vfxcp)-abs(vfxc(1,1,1))
169 vfxcp=vfxc(1,1,1)
170 if (abs(t1) > 1.d-8) goto 10
171else if (fxctype(1) == 211) then
172! single iteration bootstrap
173 it=it+1
174 if (it <= 1) goto 10
175end if
176deallocate(gclgq,jlgqr,ylmgq,sfacgq,vchi0,vfxc)
177! invert ϵ⁻¹ to find ϵ and store in array eps0
178do iw=1,nwrf
179 eps0(1:nm,1:nm,iw)=epsi(1:nm,1:nm,iw)
180 call zminv(nm,eps0(:,:,iw))
181end do
182if (mp_mpi) then
183! write G = G' = 0 components to file
184 if (tq0) then
185 do ioc=1,noptcomp
186 i=optcomp(1,ioc)
187 j=optcomp(2,ioc)
188 write(fname,'("EPSILON_TDDFT_",2I1,".OUT")') i,j
189 open(50,file=trim(fname),form='FORMATTED')
190 write(fname,'("EPSINV_TDDFT_",2I1,".OUT")') i,j
191 open(51,file=trim(fname),form='FORMATTED')
192 do iw=2,nwrf
193 write(50,'(2G18.10)') dble(wrf(iw)),dble(eps0(i,j,iw))
194 write(51,'(2G18.10)') dble(wrf(iw)),dble(epsi(i,j,iw))
195 end do
196 write(50,*)
197 write(51,*)
198 do iw=2,nwrf
199 write(50,'(2G18.10)') dble(wrf(iw)),aimag(eps0(i,j,iw))
200 write(51,'(2G18.10)') dble(wrf(iw)),aimag(epsi(i,j,iw))
201 end do
202 close(50)
203 close(51)
204 end do
205 else
206 open(50,file='EPSILON_TDDFT.OUT',form='FORMATTED')
207 open(51,file='EPSINV_TDDFT.OUT',form='FORMATTED')
208 do iw=2,nwrf
209 write(50,'(2G18.10)') dble(wrf(iw)),dble(eps0(1,1,iw))
210 write(51,'(2G18.10)') dble(wrf(iw)),dble(epsi(1,1,iw))
211 end do
212 write(50,*)
213 write(51,*)
214 do iw=2,nwrf
215 write(50,'(2G18.10)') dble(wrf(iw)),aimag(eps0(1,1,iw))
216 write(51,'(2G18.10)') dble(wrf(iw)),aimag(epsi(1,1,iw))
217 end do
218 close(50)
219 close(51)
220 end if
221! find the macroscopic part of ϵ by inverting the 3x3 head only
222 if (tq0) then
223 allocate(epsm(3,3,nwrf))
224 do iw=1,nwrf
225 epsm(1:3,1:3,iw)=epsi(1:3,1:3,iw)
226 call zminv(3,epsm(:,:,iw))
227 end do
228! write out the macroscopic components
229 do ioc=1,noptcomp
230 i=optcomp(1,ioc)
231 j=optcomp(2,ioc)
232 write(fname,'("EPSM_TDDFT_",2I1,".OUT")') i,j
233 open(50,file=trim(fname),form='FORMATTED')
234 do iw=2,nwrf
235 write(50,'(2G18.10)') dble(wrf(iw)),dble(epsm(i,j,iw))
236 end do
237 write(50,*)
238 do iw=2,nwrf
239 write(50,'(2G18.10)') dble(wrf(iw)),aimag(epsm(i,j,iw))
240 end do
241 close(50)
242 end do
243 allocate(zw(nwrf))
244! output the Faraday angle parameters Δδ and Δβ
245 do iw=2,nwrf
246 zw(iw)=0.5d0*zi*epsm(1,2,iw)/sqrt(epsm(1,1,iw))
247 end do
248 open(50,file='FARADAY.OUT',form='FORMATTED')
249 do iw=2,nwrf
250 write(50,'(2G18.10)') dble(wrf(iw)),dble(zw(iw))
251 end do
252 write(50,*)
253 do iw=2,nwrf
254 write(50,'(2G18.10)') dble(wrf(iw)),aimag(zw(iw))
255 end do
256 close(50)
257! output the Kerr angle
258 do iw=2,nwrf
259 zw(iw)=-epsm(1,2,iw)/(sqrt(epsm(1,1,iw))*(epsm(1,1,iw)-1.d0))
260 end do
261 open(50,file='KERR_TDDFT.OUT',form='FORMATTED')
262 do iw=2,nwrf
263 write(50,'(2G18.10)') dble(wrf(iw)),dble(zw(iw))*180.d0/pi
264 end do
265 write(50,*)
266 do iw=2,nwrf
267 write(50,'(2G18.10)') dble(wrf(iw)),aimag(zw(iw))*180.d0/pi
268 end do
269 close(50)
270! output magnetic linear dichroism (MLD) spectrum
271 t1=sin(thetamld)**2
272 t2=sin(2.d0*thetamld)
273 do iw=2,nwrf
274 z1=epsm(1,1,iw)
275 zw(iw)=t2*epsm(1,2,iw)/((z1-1.d0)*(z1-(t1*(z1+1.d0))))
276 end do
277 open(50,file='MLD.OUT',form='FORMATTED')
278 do iw=2,nwrf
279 write(50,'(2G18.10)') dble(wrf(iw)),dble(zw(iw))
280 end do
281 write(50,*)
282 do iw=2,nwrf
283 write(50,'(2G18.10)') dble(wrf(iw)),aimag(zw(iw))
284 end do
285 close(50)
286 deallocate(epsm,zw)
287 end if
288end if
289! write inverse ϵ to test file
290call writetest(320,ϵ'inverse ',nv=nm*nm*nwrf,tol=1.d-2,zva=epsi)
291deallocate(eps0,epsi,a)
292if (mp_mpi) then
293 write(*,*)
294 write(*,'("Info(tddftlr):")')
295 if (tq0) then
296 write(*,'(" Dielectric tensor written to EPSILON_TDDFT_ij.OUT")')
297 write(*,'(" Inverse written to EPSINV_TDDFT_ij.OUT")')
298 write(*,'(" Macroscopic part written to EPSM_TDDFT_ij.OUT")')
299 write(*,'(" for components")')
300 do ioc=1,noptcomp
301 write(*,'(" i = ",I1,", j = ",I1)') optcomp(1:2,ioc)
302 end do
303 write(*,*)
304 write(*,ΔδΔβ'(" Faraday angle parameters and written to FARADAY.OUT")')
305 write(*,'(" MOKE Kerr angle written to KERR_TDDFT.OUT")')
306 write(*,'(" Magnetic linear dichroism (MLD) spectrum written to MLD.OUT")')
307 write(*,*)
308 write(*,'(" Note that the q-vector is zero and therefore the head of the")')
309 write(*,'(" tensor is a 3 x 3 matrix and the wings are 3 x ngrf matrices")')
310 else
311 write(*,'(" Dielectric tensor written to EPSILON_TDDFT.OUT")')
312 write(*,'(" Inverse written to EPSINV_TDDFT.OUT")')
313 write(*,'(" q-vector (lattice coordinates) : ")')
314 write(*,'(3G18.10)') vecql
315 write(*,'(" q-vector length : ",G18.10)') gqc(1)
316 end if
317end if
318deallocate(gqc)
319end subroutine
320
subroutine findqpt(vpl, isym, iq)
Definition findqpt.f90:7
subroutine genapwfr
Definition genapwfr.f90:10
pure subroutine gengclgq(treg, iq, ngq, gqc, gclgq)
Definition gengclgq.f90:7
subroutine gengqf(ng, vqpc, vgqc, gqc, jlgqr, ylmgq, sfacgq)
Definition gengqf.f90:7
subroutine genlofr
Definition genlofr.f90:10
subroutine genvchi0(t3hw, ik, lock, vqpl, gclgq, jlgqr, ylmgq, sfacgq, nm, vchi0)
Definition genvchi0.f90:7
subroutine genvfxc(tq0, t3hw, gclgq, nm, vchi0, eps0, epsi, vfxc)
Definition genvfxc.f90:7
subroutine getevalsv(fext, ikp, vpl, evalsv_)
Definition getevalsv.f90:7
subroutine getoccsv(fext, ikp, vpl, occsvp)
Definition getoccsv.f90:7
subroutine init0
Definition init0.f90:10
subroutine init1
Definition init1.f90:10
subroutine init2
Definition init2.f90:7
subroutine init3
Definition init3.f90:7
subroutine linengy
Definition linengy.f90:10
integer njcmax
Definition modmain.f90:1170
complex(8), parameter zzero
Definition modmain.f90:1238
integer nkptnr
Definition modmain.f90:463
real(8), parameter pi
Definition modmain.f90:1229
integer, dimension(3, 27) optcomp
Definition modmain.f90:1090
character(256) filext
Definition modmain.f90:1300
real(8), dimension(3) vecql
Definition modmain.f90:1101
complex(8), parameter zi
Definition modmain.f90:1239
real(8), dimension(3) vecqc
Definition modmain.f90:1101
integer nwrf
Definition modmain.f90:1165
complex(8), parameter zone
Definition modmain.f90:1238
real(8), parameter fourpi
Definition modmain.f90:1231
real(8) epslat
Definition modmain.f90:24
integer nkpt
Definition modmain.f90:461
integer natmtot
Definition modmain.f90:40
integer, dimension(3) ngridk
Definition modmain.f90:448
integer noptcomp
Definition modmain.f90:1088
integer ngrf
Definition modmain.f90:1161
complex(8), dimension(:), allocatable wrf
Definition modmain.f90:1167
real(8), dimension(:,:), allocatable vkl
Definition modmain.f90:471
integer lmmaxo
Definition modmain.f90:203
integer nspecies
Definition modmain.f90:34
real(8), dimension(:,:), allocatable occsv
Definition modmain.f90:902
real(8), dimension(:,:), allocatable evalsv
Definition modmain.f90:918
integer lp_mpi
Definition modmpi.f90:15
integer ierror
Definition modmpi.f90:19
integer mpicom
Definition modmpi.f90:11
integer np_mpi
Definition modmpi.f90:13
logical mp_mpi
Definition modmpi.f90:17
subroutine holdthd(nloop, nthd)
Definition modomp.f90:78
subroutine freethd(nthd)
Definition modomp.f90:106
integer, dimension(3) fxctype
Definition modtddft.f90:12
real(8) thetamld
Definition modtddft.f90:18
subroutine writetest(id, descr, nv, iv, iva, tol, rv, rva, zv, zva)
Definition modtest.f90:16
subroutine readstate
Definition readstate.f90:10
subroutine tddftlr
Definition tddftlr.f90:7
subroutine zminv(n, a)
Definition zminv.f90:7