The Elk Code
dielectric_tdrt.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2017 J. K. Dewhurst, S. Sharma 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 dielectric_tdrt
7 use modmain
8 use modtddft
9 implicit none
10 ! local variables
11 integer iw,i,j
12 real(8) w1,w2,t0,t1
13 complex(8) eta,z1,z2
14 character(256) fname
15 ! allocatable arrays
16 real(8), allocatable :: w(:),wt(:),jt(:,:)
17 complex(8), allocatable :: ew(:,:),jw(:,:),eps(:)
18 ! initialise global variables
19 call init0
20 call init1
21 ! generate energy grid (always non-negative)
22 allocate(w(nwplot))
23 w1=max(wplot(1),0.d0)
24 w2=max(wplot(2),w1)
25 t1=(w2-w1)/dble(nwplot)
26 do iw=1,nwplot
27  w(iw)=w1+t1*dble(iw-1)
28 end do
29 ! i divided by the complex relaxation time
30 eta=cmplx(0.d0,swidth,8)
31 ! determine the weights for the spline integration
32 allocate(wt(ntimes))
33 call wsplint(ntimes,times,wt)
34 ! compute the electric field from E = -1/c dA/dt and Fourier transform
35 allocate(ew(nwplot,3))
36 t0=-1.d0/solsc
37 do i=1,3
38  if (task == 480) then
39 ! Fourier transform A(t) numerically to obtain A(ω)
40  call zftft(w,wt,3,afieldt(i,1),ew(:,i))
41 ! take the time derivative E(t)=-1/c dA(t)/dt analytically to get E(ω)
42  do iw=1,nwplot
43  z1=ew(iw,i)
44  ew(iw,i)=t0*w(iw)*cmplx(z1%im,-z1%re,8)
45  end do
46 ! filter the high-frequency components from E(ω) with a Lorentzian convolution
47  call zlrzncnv(nwplot,swidth,w,ew(:,i))
48  else
49 ! analytic Fourier transform of E(t) assumed to be a delta function at t=0
50  t1=t0*afieldt(i,1)
51  ew(:,i)=t1
52  end if
53 end do
54 ! read in the total current from file
55 allocate(jt(3,ntimes))
56 call readjtot(jt)
57 ! divide by the unit cell volume
58 jt(:,:)=jt(:,:)/omega
59 ! set the constant part of J(t) to zero if required; this effectively removes
60 ! the Drude term
61 if (jtconst0) then
62  do i=1,3
63  t1=dot_product(wt(:),jt(i,:))
64  t1=t1/times(ntimes)
65  jt(i,1:ntimes)=jt(i,1:ntimes)-t1
66  end do
67 end if
68 ! Fourier transform the current
69 allocate(jw(nwplot,3))
70 do i=1,3
71  call zftft(w,wt,3,jt(i,1),jw(:,i))
72 ! filter the high-frequency components from J(ω) with a Lorentzian convolution
73  call zlrzncnv(nwplot,swidth,w,jw(:,i))
74 end do
75 deallocate(wt,jt)
76 ! compute the dielectric function and write to file
77 allocate(eps(nwplot))
78 do i=1,3
79  do j=1,3
80  do iw=1,nwplot
81  z1=jw(iw,i)
82  z2=ew(iw,j)
83  t1=abs(z2%re)+abs(z2%im)
84  if (t1 > 1.d-8) then
85  z1=z1/z2
86  else
87  z1=0.d0
88  end if
89  z1=fourpi*cmplx(-z1%im,z1%re,8)/(w(iw)+eta)
90  if (i == j) z1=z1+1.d0
91  eps(iw)=z1
92  end do
93 ! filter the high-frequency components of ϵ
94  call zlrzncnv(nwplot,2.d0*swidth,w,eps)
95  write(fname,'("EPSILON_TDRT_",2I1,".OUT")') i,j
96  open(50,file=trim(fname),form='FORMATTED')
97  do iw=1,nwplot
98  write(50,'(2G18.10)') w(iw),dble(eps(iw))
99  end do
100  write(50,*)
101  do iw=1,nwplot
102  write(50,'(2G18.10)') w(iw),aimag(eps(iw))
103  end do
104  close(50)
105  end do
106 end do
107 ! write Fourier transform of total current to file
108 open(50,file='JTOTW.OUT',form='FORMATTED')
109 do i=1,3
110  do iw=1,nwplot
111  write(50,'(3G18.10)') w(iw),jw(iw,i)
112  end do
113  write(50,*)
114 end do
115 close(50)
116 write(*,*)
117 write(*,'("Info(dielectric_tdrt):")')
118 write(*,'(" dielectric tensor determined from real-time evolution")')
119 write(*,'(" written to EPSILON_TDRT_ij.OUT for components i,j = 1,2,3")')
120 write(*,*)
121 write(*,'(" (Note that only those components which are not orthogonal to the")')
122 write(*,'(" applied A-field will be calculated correctly)")')
123 write(*,*)
124 write(*,'(" Fourier transform of total current J(ω) written to JTOTW.OUT")')
125 deallocate(w,ew,jw,eps)
126 end subroutine
127 
subroutine zftft(w, wt, ld, ft, fw)
Definition: zftft.f90:7
subroutine dielectric_tdrt
integer task
Definition: modmain.f90:1299
integer ntimes
Definition: modtddft.f90:42
real(8) omega
Definition: modmain.f90:20
real(8) swidth
Definition: modmain.f90:895
real(8), dimension(2) wplot
Definition: modmain.f90:1079
subroutine readjtot(jt)
Definition: readjtot.f90:7
real(8) solsc
Definition: modmain.f90:1253
logical jtconst0
Definition: modtddft.f90:108
subroutine init1
Definition: init1.f90:10
real(8), dimension(:,:), allocatable afieldt
Definition: modtddft.f90:58
subroutine zlrzncnv(n, s, w, zf)
Definition: zlrzncnv.f90:7
real(8), dimension(:), allocatable times
Definition: modtddft.f90:48
subroutine init0
Definition: init0.f90:10
subroutine wsplint(n, x, w)
Definition: wsplint.f90:7
real(8), parameter fourpi
Definition: modmain.f90:1234
integer nwplot
Definition: modmain.f90:1073