The Elk Code
tddftsplr.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2013 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 tddftsplr
7 use modmain
8 use modtest
9 use modmpi
10 use modomp
11 implicit none
12 ! local variables
13 integer ik,isym,iq,iw
14 integer ig,jg,i,j,n
15 integer nthd
16 real(8) v(3)
17 complex(8) a(4,4),b(4,4),z1
18 character(256) fname
19 ! allocatable arrays
20 integer(omp_lock_kind), allocatable :: lock(:)
21 real(8), allocatable :: vgqc(:,:),gqc(:),gclgq(:),jlgqr(:,:,:)
22 complex(8), allocatable :: ylmgq(:,:),sfacgq(:,:)
23 complex(8), allocatable :: chi(:,:,:,:,:),chit(:),fxc(:,:,:,:)
24 complex(8), allocatable :: c(:,:),d(:,:,:,:)
25 if (.not.spinpol) then
26  write(*,*)
27  write(*,'("Error(tddftsplr): spin-unpolarised calculation")')
28  write(*,*)
29  stop
30 end if
31 ! initialise global variables
32 call init0
33 call init1
34 call init2
35 call init3
36 ! check q-vector is commensurate with k-point grid
37 v(1:3)=dble(ngridk(1:3))*vecql(1:3)
38 v(1:3)=abs(v(1:3)-nint(v(1:3)))
39 if ((v(1) > epslat).or.(v(2) > epslat).or.(v(3) > epslat)) then
40  write(*,*)
41  write(*,'("Error(tddftsplr): q-vector incommensurate with k-point grid")')
42  write(*,'(" ngridk : ",3I6)') ngridk
43  write(*,'(" vecql : ",3G18.10)') vecql
44  write(*,*)
45  stop
46 end if
47 ! find the equivalent reduced q-point
48 call findqpt(vecql,isym,iq)
49 ! read density and potentials from file
50 call readstate
51 ! find the new linearisation energies
52 call linengy
53 ! generate the APW radial functions
54 call genapwfr
55 ! generate the local-orbital radial functions
56 call genlofr
57 ! get the eigenvalues and occupation numbers from file
58 do ik=1,nkpt
59  call getevalsv(filext,ik,vkl(:,ik),evalsv(:,ik))
60  call getoccsv(filext,ik,vkl(:,ik),occsv(:,ik))
61 end do
62 ! generate the G+q-vectors and related functions
63 allocate(vgqc(3,ngrf),gqc(ngrf),jlgqr(njcmax,nspecies,ngrf))
64 allocate(ylmgq(lmmaxo,ngrf),sfacgq(ngrf,natmtot))
65 call gengqf(ngrf,vecqc,vgqc,gqc,jlgqr,ylmgq,sfacgq)
66 deallocate(vgqc)
67 ! initialise the OpenMP locks
68 allocate(lock(nwrf))
69 do iw=1,nwrf
70  call omp_init_lock(lock(iw))
71 end do
72 ! compute χ₀
73 allocate(chi(ngrf,4,ngrf,4,nwrf))
74 chi(:,:,:,:,:)=0.d0
75 call holdthd(nkptnr/np_mpi,nthd)
76 !$OMP PARALLEL DO DEFAULT(SHARED) &
77 !$OMP SCHEDULE(DYNAMIC) &
78 !$OMP NUM_THREADS(nthd)
79 do ik=1,nkptnr
80 ! distribute among MPI processes
81  if (mod(ik-1,np_mpi) /= lp_mpi) cycle
82 !$OMP CRITICAL(tddftsplr_)
83  write(*,'("Info(tddftsplr): ",I6," of ",I6," k-points")') ik,nkptnr
84 !$OMP END CRITICAL(tddftsplr_)
85  call genspchi0(ik,lock,vecql,jlgqr,ylmgq,sfacgq,chi)
86 end do
87 !$OMP END PARALLEL DO
88 call freethd(nthd)
89 ! destroy the OpenMP locks
90 do iw=1,nwrf
91  call omp_destroy_lock(lock(iw))
92 end do
93 deallocate(lock)
94 ! add χ₀ from each process and redistribute
95 if (np_mpi > 1) then
96  n=ngrf*4*ngrf*4*nwrf
97  call mpi_allreduce(mpi_in_place,chi,n,mpi_double_complex,mpi_sum,mpicom, &
98  ierror)
99 end if
100 ! transform χ₀ from 2x2 to 1x3 basis
101 do iw=1,nwrf
102  do ig=1,ngrf
103  do jg=1,ngrf
104  a(1:4,1:4)=chi(ig,1:4,jg,1:4,iw)
105  call tfm2213(a,b)
106  chi(ig,1:4,jg,1:4,iw)=b(1:4,1:4)
107  end do
108  end do
109 end do
110 ! generate transverse χ₀ for the collinear case
111 if (.not.ncmag) then
112  allocate(chit(nwrf))
113  do iw=1,nwrf
114  a(1:4,1:4)=chi(1,1:4,1,1:4,iw)
115  call tfm13t(a,b)
116  chit(iw)=b(2,2)
117  end do
118 end if
119 ! write χ₀ to file
120 if (mp_mpi) then
121 ! write χ₀ to file in 1x3 basis
122  do i=1,4
123  do j=1,4
124  write(fname,'("CHI0_",2I1,".OUT")') i-1,j-1
125  open(50,file=trim(fname),form='FORMATTED',action='WRITE')
126  do iw=1,nwrf
127  write(50,'(2G18.10)') dble(wrf(iw)),dble(chi(1,i,1,j,iw))
128  end do
129  write(50,*)
130  do iw=1,nwrf
131  write(50,'(2G18.10)') dble(wrf(iw)),aimag(chi(1,i,1,j,iw))
132  end do
133  close(50)
134  end do
135  end do
136 ! write transverse χ₀ for collinear case
137  if (.not.ncmag) then
138  open(50,file='CHI0_T.OUT',form='FORMATTED',action='WRITE')
139  do iw=1,nwrf
140  write(50,'(2G18.10)') dble(wrf(iw)),dble(chit(iw))
141  end do
142  write(50,*)
143  do iw=1,nwrf
144  write(50,'(2G18.10)') dble(wrf(iw)),aimag(chit(iw))
145  end do
146  close(50)
147  end if
148 end if
149 ! compute f_xc in G-space
150 allocate(fxc(ngrf,4,ngrf,4))
151 call genspfxcg(fxc)
152 ! generate the Coulomb Green's function in G+q-space regularised for q = 0
153 allocate(gclgq(ngrf))
154 call gengclgq(.true.,iq,ngrf,gqc,gclgq)
155 ! add the regularised Coulomb interaction to f_xc to give f_Hxc
156 do ig=1,ngrf
157  fxc(ig,1,ig,1)=fxc(ig,1,ig,1)+gclgq(ig)
158 end do
159 deallocate(gclgq)
160 ! matrix size
161 n=4*ngrf
162 allocate(c(n,n),d(ngrf,4,ngrf,4))
163 ! loop over frequencies
164 do iw=1,nwrf
165 ! multiply f_Hxc by -χ₀ from the left
166  z1=-1.d0
167  call zgemm('N','N',n,n,n,z1,chi(:,:,:,:,iw),n,fxc,n,zzero,c,n)
168 ! add the identity
169  do i=1,n
170  c(i,i)=c(i,i)+1.d0
171  end do
172 ! invert the matrix
173  call zminv(n,c)
174 ! multiply by χ₀ on the right and store in χ
175  call zgemm('N','N',n,n,n,zone,c,n,chi(:,:,:,:,iw),n,zzero,d,n)
176  chi(:,:,:,:,iw)=d(:,:,:,:)
177 end do
178 deallocate(c,d)
179 ! generate transverse χ for the collinear case
180 if (.not.ncmag) then
181  do iw=1,nwrf
182  a(1:4,1:4)=chi(1,1:4,1,1:4,iw)
183  call tfm13t(a,b)
184  chit(iw)=b(2,2)
185  end do
186 end if
187 if (mp_mpi) then
188 ! write the complete χ matrix if required
189  if (task == 331) then
190  open(120,file='CHI.OUT',form='UNFORMATTED',action='WRITE')
191  write(120) chi
192  close(120)
193  end if
194 ! write χ for G = G' = 0 in the 1x3 basis
195  do i=1,4
196  do j=1,4
197  write(fname,'("CHI_",2I1,".OUT")') i-1,j-1
198  open(50,file=trim(fname),form='FORMATTED',action='WRITE')
199  do iw=1,nwrf
200  write(50,'(2G18.10)') dble(wrf(iw)),dble(chi(1,i,1,j,iw))
201  end do
202  write(50,*)
203  do iw=1,nwrf
204  write(50,'(2G18.10)') dble(wrf(iw)),aimag(chi(1,i,1,j,iw))
205  end do
206  close(50)
207  end do
208  end do
209 ! write transverse χ for collinear case
210  if (.not.ncmag) then
211  open(50,file='CHI_T.OUT',form='FORMATTED',action='WRITE')
212  do iw=1,nwrf
213  write(50,'(2G18.10)') dble(wrf(iw)),dble(chit(iw))
214  end do
215  write(50,*)
216  do iw=1,nwrf
217  write(50,'(2G18.10)') dble(wrf(iw)),aimag(chit(iw))
218  end do
219  close(50)
220  end if
221  write(*,*)
222  write(*,'("Info(tddftsplr):")')
223  write(*,'(" Spin-dependent response function χ_ij(G,G'',q,w) written to &
224  &CHI_ij.OUT")')
225  write(*,'(" for i,j = 0-3; G = G'' = 0; and all wplot frequencies")')
226  write(*,'(" q-vector (lattice coordinates) : ")')
227  write(*,'(3G18.10)') vecql
228  write(*,'(" q-vector length : ",G18.10)') gqc(1)
229  write(*,*)
230  write(*,'(" The elements of χ labeled by (i,j) form the 4x4 matrix :")')
231  write(*,*)
232  write(*,'(" ⎛_|_ _ _⎞")')
233  write(*,'(" χ(G,G'',q,w) = ⎜ | ⎟")')
234  write(*,'(" ⎜ | ⎟")')
235  write(*,'(" ⎝ | ⎠")')
236  write(*,*)
237  write(*,'(" (0,0) is the charge-charge response dρ/dv")')
238  write(*,'(" (0,1-3) is the charge-magnetisation response dρ/dB")')
239  write(*,'(" (1-3,0) is the magnetisation-charge response dm/v")')
240  write(*,'(" (1-3,1-3) is the magnetisation-magnetisation response dm/dB")')
241  write(*,*)
242  write(*,'(" Non-interacting Kohn-Sham response function written to &
243  &CHI0_ij.OUT")')
244  if (.not.ncmag) then
245  write(*,*)
246  write(*,'(" Transverse components corresponding to m_± = m_x ± im_y")')
247  write(*,'(" written to CHI_T.OUT and CHI0_T.OUT")')
248  end if
249  if (task == 331) then
250  write(*,*)
251  write(*,'(" Complete response function for all G, G'' written to binary &
252  &file CHI.OUT")')
253  write(*,'(" (array index ordering changed from version 4.5.16 onwards)")')
254  end if
255 end if
256 ! write transverse response to test file
257 call writetest(330,'transverse response function',nv=nwrf,tol=1.d-2,zva=chit)
258 deallocate(gqc,ylmgq,sfacgq,chi,fxc)
259 if (.not.ncmag) deallocate(chit)
260 
261 contains
262 
263 pure subroutine tfm2213(a,b)
264 implicit none
265 ! arguments
266 complex(8), intent(in) :: a(4,4)
267 complex(8), intent(out) :: b(4,4)
268 ! local variables
269 integer i,j
270 complex(8) c(4,4),z1
271 do i=1,4
272  c(i,1)=a(i,1)+a(i,4)
273  c(i,2)=a(i,2)+a(i,3)
274  z1=a(i,2)-a(i,3)
275  c(i,3)=cmplx(z1%im,-z1%re,8)
276  c(i,4)=a(i,1)-a(i,4)
277 end do
278 do j=1,4
279  b(1,j)=c(1,j)+c(4,j)
280  b(2,j)=c(2,j)+c(3,j)
281  z1=c(2,j)-c(3,j)
282  b(3,j)=cmplx(-z1%im,z1%re,8)
283  b(4,j)=c(1,j)-c(4,j)
284 end do
285 end subroutine
286 
287 pure subroutine tfm13t(a,b)
288 implicit none
289 ! arguments
290 complex(8), intent(in) :: a(4,4)
291 complex(8), intent(out) :: b(4,4)
292 ! local variables
293 integer i,j
294 complex(8) c(4,4),z1
295 do i=1,4
296  c(i,1)=a(i,1)
297  z1=a(i,3)
298  z1=cmplx(-z1%im,z1%re,8)
299  c(i,2)=a(i,2)-z1
300  c(i,3)=a(i,2)+z1
301  c(i,4)=a(i,4)
302 end do
303 do j=1,4
304  b(1,j)=c(1,j)
305  z1=c(3,j)
306  z1=cmplx(-z1%im,z1%re,8)
307  b(2,j)=c(2,j)+z1
308  b(3,j)=c(2,j)-z1
309  b(4,j)=c(4,j)
310 end do
311 end subroutine
312 
313 end subroutine
314 
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
integer task
Definition: modmain.f90:1299
logical mp_mpi
Definition: modmpi.f90:17
integer lmmaxo
Definition: modmain.f90:203
logical spinpol
Definition: modmain.f90:228
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
subroutine genspchi0(ik, lock, vqpl, jlgqr, ylmgq, sfacgq, chi0)
Definition: genspchi0.f90:10
integer nkptnr
Definition: modmain.f90:463
real(8), dimension(3) vecql
Definition: modmain.f90:1104
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 init3
Definition: init3.f90:7
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
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
subroutine init0
Definition: init0.f90:10
integer natmtot
Definition: modmain.f90:40
logical ncmag
Definition: modmain.f90:240
subroutine tddftsplr
Definition: tddftsplr.f90:7
pure subroutine tfm13t(a, b)
Definition: tddftsplr.f90:288
integer mpicom
Definition: modmpi.f90:11
real(8), dimension(3) vecqc
Definition: modmain.f90:1104
pure subroutine tfm2213(n, fxcuu, fxcud, fxcdd, magu, magm, bxcp, ld, fxc)
Definition: genspfxcr.f90:154
subroutine genspfxcg(fxc)
Definition: genspfxcg.f90:7
integer ierror
Definition: modmpi.f90:19