The Elk Code
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 
6 subroutine tddftlr
7 use modmain
8 use modtddft
9 use modtest
10 use modmpi
11 use modomp
12 implicit none
13 ! local variables
14 logical tq0
15 integer, parameter :: maxit=500
16 integer iq,ik,isym
17 integer nm,it,i,j,n
18 integer iw,ioc,nthd
19 real(8) v(3),t1,t2
20 complex(8) vfxcp,z1
21 character(256) fname
22 ! allocatable arrays
23 integer(omp_lock_kind), allocatable :: lock(:)
24 real(8), allocatable :: vgqc(:,:),gqc(:),gclgq(:),jlgqr(:,:,:)
25 complex(8), allocatable :: ylmgq(:,:),sfacgq(:,:)
26 complex(8), allocatable :: vchi0(:,:,:),vfxc(:,:,:)
27 complex(4), allocatable :: vchi0_sp(:,:,:)
28 complex(8), allocatable :: eps0(:,:,:),epsi(:,:,:),epsm(:,:,:)
29 complex(8), allocatable :: zw(:),a(:,:)
30 ! initialise global variables
31 call init0
32 call init1
33 call init2
34 call init3
35 ! check q-vector is commensurate with k-point grid
36 v(1:3)=dble(ngridk(1:3))*vecql(1:3)
37 v(1:3)=abs(v(1:3)-nint(v(1:3)))
38 if ((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
45 end if
46 ! find the equivalent reduced q-point
47 call findqpt(vecql,isym,iq)
48 ! check if q = 0
49 tq0=.false.
50 if (sum(abs(vecql(:))) < epslat) tq0=.true.
51 ! read density and potentials from file
52 call readstate
53 ! find the new linearisation energies
54 call linengy
55 ! generate the APW radial functions
56 call genapwfr
57 ! generate the local-orbital radial functions
58 call genlofr
59 ! get the eigenvalues and occupation numbers from file
60 do ik=1,nkpt
61  call getevalsv(filext,ik,vkl(:,ik),evalsv(:,ik))
62  call getoccsv(filext,ik,vkl(:,ik),occsv(:,ik))
63 end do
64 ! generate the G+q-vectors and related functions
65 allocate(vgqc(3,ngrf),gqc(ngrf),jlgqr(njcmax,nspecies,ngrf))
66 allocate(ylmgq(lmmaxo,ngrf),sfacgq(ngrf,natmtot))
67 call gengqf(ngrf,vecqc,vgqc,gqc,jlgqr,ylmgq,sfacgq)
68 deallocate(vgqc)
69 ! generate the regularised Coulomb Green's function in G+q-space
70 allocate(gclgq(ngrf))
71 call gengclgq(.true.,iq,ngrf,gqc,gclgq)
72 gclgq(1:ngrf)=sqrt(gclgq(1:ngrf))
73 ! matrix sizes
74 if (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
77 else
78 ! otherwise the head is just G = G' = 0 and finite q
79  nm=ngrf
80 end if
81 ! initialise the OpenMP locks
82 allocate(lock(nwrf))
83 do iw=1,nwrf
84  call omp_init_lock(lock(iw))
85 end do
86 ! compute v¹⸍² χ₀ v¹⸍² (the symmetric version of v χ₀) in single-precision
87 allocate(vchi0_sp(nm,nm,nwrf))
88 vchi0_sp(1:nm,1:nm,1:nwrf)=0.e0
89 call holdthd(nkptnr/np_mpi,nthd)
90 !$OMP PARALLEL DO DEFAULT(SHARED) &
91 !$OMP SCHEDULE(DYNAMIC) &
92 !$OMP NUM_THREADS(nthd)
93 do 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)
101 end do
102 !$OMP END PARALLEL DO
103 call freethd(nthd)
104 ! destroy the OpenMP locks
105 do iw=1,nwrf
106  call omp_destroy_lock(lock(iw))
107 end do
108 deallocate(lock)
109 ! add vchi0 from each process and redistribute
110 if (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)
113 end if
114 ! copy to double-precision array
115 allocate(vchi0(nm,nm,nwrf))
116 vchi0(1:nm,1:nm,1:nwrf)=vchi0_sp(1:nm,1:nm,1:nwrf)
117 deallocate(vchi0_sp)
118 allocate(vfxc(nm,nm,nwrf),eps0(nm,nm,nwrf),epsi(nm,nm,nwrf))
119 ! calculate symmetric ϵ_0 = 1 - v¹⸍² χ₀ v¹⸍²
120 eps0(1:nm,1:nm,1:nwrf)=-vchi0(1:nm,1:nm,1:nwrf)
121 do i=1,nm
122  eps0(i,i,1:nwrf)=eps0(i,i,1:nwrf)+1.d0
123 end do
124 ! initialise ϵ for use with the bootstrap functional
125 if (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
130 end if
131 allocate(a(nm,nm))
132 vfxcp=0.d0
133 it=0
134 10 continue
135 ! compute v χ₀ v⁻¹⸍² f_xc v⁻¹⸍² v χ₀
136 call genvfxc(tq0,.true.,gclgq,nm,vchi0,eps0,epsi,vfxc)
137 ! begin loop over frequencies
138 do 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
149 end do
150 if (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
171 else if (fxctype(1) == 211) then
172 ! single iteration bootstrap
173  it=it+1
174  if (it <= 1) goto 10
175 end if
176 deallocate(gclgq,jlgqr,ylmgq,sfacgq,vchi0,vfxc)
177 ! invert ϵ⁻¹ to find ϵ and store in array eps0
178 do iw=1,nwrf
179  eps0(1:nm,1:nm,iw)=epsi(1:nm,1:nm,iw)
180  call zminv(nm,eps0(:,:,iw))
181 end do
182 if (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
288 end if
289 ! write inverse ϵ to test file
290 call writetest(320,'inverse ϵ',nv=nm*nm*nwrf,tol=1.d-2,zva=epsi)
291 deallocate(eps0,epsi,a)
292 if (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
317 end if
318 deallocate(gqc)
319 end subroutine
320 
subroutine writetest(id, descr, nv, iv, iva, tol, rv, rva, zv, zva)
Definition: modtest.f90:16
integer nwrf
Definition: modmain.f90:1168
character(256) filext
Definition: modmain.f90:1301
real(8), dimension(:,:), allocatable evalsv
Definition: modmain.f90:921
logical mp_mpi
Definition: modmpi.f90:17
integer lmmaxo
Definition: modmain.f90:203
integer nkpt
Definition: modmain.f90:461
subroutine genlofr
Definition: genlofr.f90:10
subroutine gengqf(ng, vqpc, vgqc, gqc, jlgqr, ylmgq, sfacgq)
Definition: gengqf.f90:7
subroutine getevalsv(fext, ikp, vpl, evalsv_)
Definition: getevalsv.f90:7
Definition: modomp.f90:6
complex(8), dimension(:), allocatable wrf
Definition: modmain.f90:1170
integer ngrf
Definition: modmain.f90:1164
complex(8), parameter zone
Definition: modmain.f90:1240
integer nkptnr
Definition: modmain.f90:463
real(8), parameter pi
Definition: modmain.f90:1232
real(8), dimension(3) vecql
Definition: modmain.f90:1104
subroutine tddftlr
Definition: tddftlr.f90:7
integer np_mpi
Definition: modmpi.f90:13
subroutine linengy
Definition: linengy.f90:10
pure subroutine gengclgq(treg, iq, ngq, gqc, gclgq)
Definition: gengclgq.f90:7
subroutine findqpt(vpl, isym, iq)
Definition: findqpt.f90:7
subroutine genvchi0(t3hw, ik, lock, vqpl, gclgq, jlgqr, ylmgq, sfacgq, nm, vchi0)
Definition: genvchi0.f90:7
subroutine init3
Definition: init3.f90:7
integer, dimension(3, 27) optcomp
Definition: modmain.f90:1093
subroutine init2
Definition: init2.f90:7
integer, dimension(3) ngridk
Definition: modmain.f90:448
real(8), dimension(:,:), allocatable occsv
Definition: modmain.f90:905
subroutine init1
Definition: init1.f90:10
complex(8), parameter zzero
Definition: modmain.f90:1240
real(8), dimension(:,:), allocatable vkl
Definition: modmain.f90:471
integer noptcomp
Definition: modmain.f90:1091
subroutine genapwfr
Definition: genapwfr.f90:10
real(8) epslat
Definition: modmain.f90:24
Definition: modmpi.f90:6
subroutine getoccsv(fext, ikp, vpl, occsvp)
Definition: getoccsv.f90:7
subroutine readstate
Definition: readstate.f90:10
integer lp_mpi
Definition: modmpi.f90:15
integer nspecies
Definition: modmain.f90:34
subroutine freethd(nthd)
Definition: modomp.f90:106
subroutine holdthd(nloop, nthd)
Definition: modomp.f90:78
integer njcmax
Definition: modmain.f90:1173
subroutine zminv(n, a)
Definition: zminv.f90:7
complex(8), parameter zi
Definition: modmain.f90:1240
subroutine init0
Definition: init0.f90:10
real(8), parameter fourpi
Definition: modmain.f90:1234
integer natmtot
Definition: modmain.f90:40
subroutine genvfxc(tq0, t3hw, gclgq, nm, vchi0, eps0, epsi, vfxc)
Definition: genvfxc.f90:7
integer, dimension(3) fxctype
Definition: modtddft.f90:12
real(8) thetamld
Definition: modtddft.f90:18
integer mpicom
Definition: modmpi.f90:11
real(8), dimension(3) vecqc
Definition: modmain.f90:1104
integer ierror
Definition: modmpi.f90:19