Line data Source code
1 : !!****m* ABINIT/m_kxc
2 : !! NAME
3 : !! m_kxc
4 : !!
5 : !! FUNCTION
6 : !! Helper functions to compute the XC kernel in reciprocal space.
7 : !! WARNING: At present (10/01/14) these routines are not tested
8 : !! since the ACFD code has been disabled.
9 : !!
10 : !! COPYRIGHT
11 : !! Copyright (C) 1998-2026 ABINIT group (DCA, MF, XG, GMR, LSI, YMN, Rhaltaf, MS)
12 : !! This file is distributed under the terms of the
13 : !! GNU General Public License, see ~abinit/COPYING
14 : !! or http://www.gnu.org/copyleft/gpl.txt .
15 : !!
16 : !! NOTES:
17 : !! libxc_functionals.F90 uses a global structure (funcs) to store the XC parameters.
18 : !! This structure is initialized in driver with the value of ixc specified by the user in the input file.
19 : !! In order to change the value of ixc at run-time, we have to reinitialize the global structure
20 : !! with the new value of ixc before computing XC quantities.
21 : !! Moreover one has to reinstate the old functional before returning so that the other routines
22 : !! will continue to used the previous ixc. This task can be accomplished with the following pseudocode
23 : !!
24 : !! ! Reinitialize the libxc module with the overridden values
25 : !! if (old_ixc<0) call libxc_functionals_end()
26 : !! if (new_ixc<0) call libxc_functionals_init(new_ixc,nspden)
27 : !! ! Compute XC stuff here.
28 : !! ! Revert libxc module to the original settings
29 : !! if (new_ixc<0) call libxc_functionals_end()
30 : !! if (old_ixc<0) call libxc_functionals_init(old_ixc,nspden)
31 : !!
32 : !! SOURCE
33 :
34 : #if defined HAVE_CONFIG_H
35 : #include "config.h"
36 : #endif
37 :
38 : #include "abi_common.h"
39 :
40 : MODULE m_kxc
41 :
42 : use defs_basis
43 : use m_abicore
44 : use m_errors
45 : use m_xmpi
46 : use m_crystal
47 : use m_distribfft
48 : use m_xcdata
49 : use libxc_functionals
50 : use m_dtset
51 :
52 : use defs_abitypes, only : MPI_type
53 : use m_fstrings, only : sjoin, itoa
54 : use m_numeric_tools, only : hermitianize
55 : use m_fft_mesh, only : g2ifft
56 : use m_fft, only : fourdp_6d, fourdp
57 : use m_mpinfo, only : initmpi_seq, destroy_mpi_enreg
58 : use m_spacepar, only : hartre
59 : use m_rhotoxc, only : rhotoxc
60 : use m_dfpt_mkvxc, only : dfpt_mkvxc
61 :
62 : implicit none
63 :
64 : private
65 : !!***
66 :
67 : public :: kxc_rpa ! Hartree kernel
68 : public :: kxc_local ! Compute local xc kernel in G space.
69 : public :: kxc_alda ! AL(S)DA kernel in reciprocal space, on the FFT grid.
70 : public :: kxc_pgg ! Compute the PGG-exchange kernel in reciprocal space (Phys. Rev. Lett. 76, 1212 (1996) [[cite:Petersilka1996]]).
71 : public :: kxc_eok ! linear or non-linear (ixceok = 2) energy optimized kernel of Dobson and Wang.
72 : public :: kxc_driver ! Driver routine (TODO)
73 : public :: kxc_ADA ! Adiabatic density approximation
74 :
75 :
76 : CONTAINS !=========================================================================================================================
77 : !!***
78 :
79 : !!****f* m_kxc/kxc_rpa
80 : !! NAME
81 : !! kxc_rpa
82 : !!
83 : !! FUNCTION
84 : !! Return the Hartree kernel:
85 : !! If option = 0, the bare Hartree kernel:
86 : !! krpa(ipw) = 4.0*pi/gsq(ipw) if gsq(ipw) /= 0.,
87 : !! krpa(ipw) = 0.0 if gsq(ipw) == 0. (1 <= ipw <= npw).
88 : !! If option /= 0, the Hartree kernel with a cut-off in real space beyond rcut_coulomb:
89 : !! krpa(ipw) = (4.0*pi/gsq(ipw))*(1.0-cos(sqrt(gsq(ipw))*rcut_coulomb)) if gsq(ipw) /= 0.,
90 : !! krpa(ipw) = 2.0*pi*rcut_coulomb**2 if gsq(ipw) == 0.
91 : !!
92 : !! INPUTS
93 : !! gsq(npw) = the squared norm of the planewaves.
94 : !! npw = number of planewaves in the gsq array.
95 : !! option = 0 for the bare Hartree kernel, /=0 for the cut-off Hartree kernel.
96 : !! rcut_coulomb = real space cut-off radius for the Coulomb interaction in Bohr.
97 : !!
98 : !! OUTPUT
99 : !! krpa(npw) = the Hartree kernel.
100 : !!
101 : !! SOURCE
102 :
103 0 : subroutine kxc_rpa(gsq,krpa,npw,option,rcut_coulomb)
104 :
105 : !Arguments -------------------------------------------------------------
106 : !scalars
107 : integer,intent(in) :: npw,option
108 : real(dp),intent(in) :: rcut_coulomb
109 : !arrays
110 : real(dp),intent(in) :: gsq(npw)
111 : real(dp),intent(out) :: krpa(npw)
112 :
113 : !Local variables -------------------------------------------------------
114 : !scalars
115 : integer :: ipw
116 : !***********************************************************************
117 :
118 0 : if (option == 0) then
119 : ! Compute the bare Hartree kernel.
120 0 : do ipw = 1,npw
121 0 : if (gsq(ipw) > tol12) then
122 0 : krpa(ipw) = four_pi/gsq(ipw)
123 : else
124 0 : krpa(ipw) = zero
125 : end if
126 : end do
127 :
128 : else
129 :
130 : ! Compute the Hartree kernel with a cut-off in real space beyond rcut_coulomb:
131 0 : do ipw = 1,npw
132 0 : if (gsq(ipw) > tol12) then
133 0 : krpa(ipw) = (four_pi/gsq(ipw))*(1._dp-cos(sqrt(gsq(ipw))*rcut_coulomb))
134 : else
135 0 : krpa(ipw) = two_pi*rcut_coulomb**2
136 : end if
137 : end do
138 :
139 : end if
140 :
141 0 : end subroutine kxc_rpa
142 : !!***
143 :
144 : !----------------------------------------------------------------------
145 :
146 : !!****f* m_kxc/kxc_local
147 : !! NAME
148 : !! kxc_local
149 : !!
150 : !! FUNCTION
151 : !! In a planewave basis set, the matrix of a local xc kernel:
152 : !!
153 : !! $f_{\rm xc}(\vec{r},\vec{r}') = f(\vec{r})\delta(\vec{r}-\vec{r}')$
154 : !!
155 : !! is just:
156 : !!
157 : !! $f_{\rm xc}(\vec{G},\vec{G}') = f(\vec{G}-\vec{G}')$.
158 : !!
159 : !! This subroutine calculates the matrix of such a local xc kernel given $f(\vec{G})$ on the FFT grid.
160 : !!
161 : !! INPUTS
162 : !! ispxc = 1 for the up-up spin channel.
163 : !! = 2 for the up-down (and down-up) spin channels.
164 : !! = 3 for the down-down spin channel.
165 : !! ispxc must be 1 if nspden = 1.
166 : !! kg_diel(3,npwdiel) = reduced planewave coordinates for the kxc matrix.
167 : !! kxcg(2,nfft) = $f(\vec{G})$ on the FFT grid.
168 : !! nfft = number of fft grid points.
169 : !! ngfft(1:3) = integer fft box dimensions, see getng for ngfft(4:8).
170 : !! npwdiel = number of planewaves for the susceptibility matrix.
171 : !! nspden = number of spin-density components.
172 : !! option = 0 do not compute the first row and column of the matrix of the
173 : !! xc kernel (which we assume to the G = 0 row and column).
174 : !! /= 0 compute the full matrix of the xc kernel.
175 : !!
176 : !! OUTPUT
177 : !! kxc(2,npwdiel,nspden,npwdiel,nspden) = the matrix of the xc kernel.
178 : !!
179 : !! SOURCE
180 :
181 0 : subroutine kxc_local(ispxc,kg_diel,kxc,kxcg,nfft,ngfft,npwdiel,nspden,option)
182 :
183 : !Arguments -------------------------------------------------------------
184 : !scalars
185 : integer,intent(in) :: ispxc,nfft,npwdiel,nspden,option
186 : !arrays
187 : integer,intent(in) :: kg_diel(3,npwdiel),ngfft(18)
188 : real(dp),intent(in) :: kxcg(2,nfft)
189 : real(dp),intent(out) :: kxc(2,npwdiel,nspden,npwdiel,nspden)
190 :
191 : !Local variables -------------------------------------------------------
192 : !For debugging purposes:
193 : !real(dp) :: c1,c2,c3
194 : !scalars
195 : integer :: i1,i2,i3,ifft,ipw1,ipw2,ipwstart,isp1,isp2,j1,j2,j3,k1,k2,k3,n1,n2
196 : integer :: n3
197 : logical :: ok
198 : character(len=500) :: msg
199 : !***********************************************************************
200 :
201 : !Check input parameters.
202 0 : if (nspden > 2) then
203 0 : ABI_ERROR('kxc_local does not work yet for nspden > 2.')
204 : end if
205 :
206 0 : isp1 = 1
207 0 : isp2 = 1
208 0 : ok = .true.
209 0 : if (nspden == 1) then
210 0 : select case (ispxc)
211 : case (1)
212 : isp1 = 1
213 : isp2 = 1
214 : case default
215 0 : ok = .false.
216 : end select
217 : else
218 0 : select case (ispxc)
219 : case (1)
220 : isp1 = 1
221 : isp2 = 1
222 : case (2)
223 : isp1 = 1
224 : isp2 = 2
225 : case (3)
226 : isp1 = 2
227 : isp2 = 2
228 : case default
229 0 : ok = .false.
230 : end select
231 : end if
232 :
233 : if (.not.ok) then
234 0 : write (msg,'(2(a,i0))')' The input ispxc = ',ispxc,' is not compatible with nspden = ',nspden
235 0 : ABI_BUG(msg)
236 : end if
237 :
238 0 : if (option == 0) then
239 0 : ipwstart = 2
240 0 : kxc(:,1,isp1,:,isp2) = 0._dp
241 0 : kxc(:,:,isp1,1,isp2) = 0._dp
242 : else
243 : ipwstart = 1
244 : end if
245 :
246 : ! Calculate the xc matrix.
247 0 : n1 = ngfft(1) ; n2 = ngfft(2) ; n3 = ngfft(3)
248 :
249 0 : do ipw2 = ipwstart,npwdiel
250 0 : j1 = kg_diel(1,ipw2) ; j2 = kg_diel(2,ipw2) ; j3 = kg_diel(3,ipw2)
251 :
252 : !Fill the diagonal.
253 :
254 0 : kxc(:,ipw2,isp1,ipw2,isp2) = kxcg(:,1)
255 :
256 : !Fill the off-diagonal elements.
257 :
258 0 : do ipw1 = ipw2+1,npwdiel
259 :
260 0 : i1 = kg_diel(1,ipw1) ; i2 = kg_diel(2,ipw1) ; i3 = kg_diel(3,ipw1)
261 :
262 : ! Compute the difference between G vectors.
263 : ! The use of two mod calls handles both i1-j1 >= n1 AND i1-j1 < 0.
264 :
265 0 : k1 = mod(n1+mod(i1-j1,n1),n1)
266 0 : k2 = mod(n2+mod(i2-j2,n2),n2)
267 0 : k3 = mod(n3+mod(i3-j3,n3),n3)
268 :
269 0 : ifft = k1+n1*(k2+n2*k3)+1
270 :
271 0 : kxc(1,ipw1,isp1,ipw2,isp2) = kxcg(1,ifft)
272 0 : kxc(2,ipw1,isp1,ipw2,isp2) = kxcg(2,ifft)
273 :
274 0 : kxc(1,ipw2,isp1,ipw1,isp2) = kxcg(1,ifft)
275 0 : kxc(2,ipw2,isp1,ipw1,isp2) = -kxcg(2,ifft)
276 : end do
277 : end do
278 :
279 : ! If needed, copy the up-down to the down-up spin channel.
280 0 : if (ispxc == 2) then
281 0 : do ipw2 = 1,npwdiel
282 0 : do ipw1 = 1,npwdiel
283 0 : kxc(1,ipw2,isp2,ipw1,isp1) = kxc(1,ipw1,isp1,ipw2,isp2)
284 0 : kxc(2,ipw2,isp2,ipw1,isp1) = -kxc(2,ipw1,isp1,ipw2,isp2)
285 : end do
286 : end do
287 : end if
288 :
289 : !DEBUG
290 : !See kxc_alda.f, "test kernel" DEBUG section.
291 : !do ipw2 = 1,npwdiel
292 : !j1 = kg_diel(1,ipw2) ; j2 = kg_diel(2,ipw2) ; j3 = kg_diel(3,ipw2)
293 : !do ipw1 = ipw2+1,npwdiel
294 : !i1 = kg_diel(1,ipw1) ; i2 = kg_diel(2,ipw1) ; i3 = kg_diel(3,ipw1)
295 : !k1 = mod(n1+mod(i1-j1,n1),n1)
296 : !k2 = mod(n2+mod(i2-j2,n2),n2)
297 : !k3 = mod(n3+mod(i3-j3,n3),n3)
298 : !ifft = k1+n1*(k2+n2*k3)+1
299 : !c1 = 0._dp ; c2 = 0._dp ; c3 = 0._dp
300 : !if (i1-j1 == 0) c1 = c1+0.0_dp
301 : !if (i2-j2 == 0) c2 = c2+0.0_dp
302 : !if (i3-j3 == 0) c3 = c3+0.0_dp
303 : !if (i1-j1 == 1) c1 = c1+0.5_dp
304 : !if (i2-j2 == 2) c2 = c2+0.5_dp
305 : !if (i3-j3 == 3) c3 = c3+0.5_dp
306 : !if (i1-j1 == -1) c1 = c1+0.5_dp
307 : !if (i2-j2 == -2) c2 = c2+0.5_dp
308 : !if (i3-j3 == -3) c3 = c3+0.5_dp
309 : !if ((abs(kxcg(1,ifft)-c1*c2*c3) > tol10).or.(abs(kxcg(2,ifft)) > tol10)) then
310 : !write (std_out,*) ' i1 i2 i3 ifft: ',i1,i2,i3,ifft
311 : !write (std_out,*) ' exp.: ',c1*c2*c3,' got: ',kxcg(:,ifft)
312 : !end if
313 : !end do
314 : !end do
315 : !ENDDEBUG
316 :
317 0 : end subroutine kxc_local
318 : !!***
319 :
320 : !----------------------------------------------------------------------
321 :
322 : !!****f* m_kxc/kxc_alda
323 : !! NAME
324 : !! kxc_alda
325 : !!
326 : !! FUNCTION
327 : !! If option = 1:
328 : !! Compute the AL(S)DA kernel in reciprocal space, on the FFT grid.
329 : !! If option = 2:
330 : !! Only computes the up-down channel of the AL(S)DA kernel, on the
331 : !! FFT grid, for use in the BPG kernel.
332 : !!
333 : !! INPUTS
334 : !! dtset <type(dataset_type)>=all input variables in this dataset
335 : !! ixc = choice of exchange-correlation functional.
336 : !! mpi_enreg=information about MPI parallelization
337 : !! nfft = number of fft grid points.
338 : !! ngfft(1:3) = integer fft box dimensions, see getng for ngfft(4:8).
339 : !! nspden = number of spin-density components.
340 : !! option = 1 compute the AL(S)DA kernel in reciprocal space.
341 : !! = 2 only computes the up-down channel of the AL(S)DA kernel,
342 : !! for use in the BPG kernel.
343 : !! rhor(nfft,nspden) = electron density in real space in electrons/bohr**3
344 : !! (total in first half and spin-up in second half if nspden = 2).
345 : !! rhocut = cut-off density for the local kernels (ALDA, EOK),
346 : !! relative to max(rhor(:,:)).
347 : !! rprimd(3,3) = dimensional primitive translations for real space in Bohr.
348 : !!
349 : !! OUTPUT
350 : !! kxcg(2,nfft,*) = the AL(S)DA kernel in reciprocal space, on the FFT grid
351 : !! (the third dimension is 2*nspden-1 if option = 1, and 1 if option = 2).
352 : !!
353 : !! WARNINGS
354 : !! Spin-polarized case not tested.
355 : !!
356 : !! SOURCE
357 :
358 0 : subroutine kxc_alda(dtset,ixc,kxcg,mpi_enreg,nfft,ngfft,nspden,option,rhor,rhocut,rprimd)
359 :
360 : !Arguments -------------------------------------------------------------
361 : !scalars
362 : integer,intent(in) :: ixc,nfft,nspden,option
363 : real(dp),intent(in) :: rhocut
364 : type(MPI_type),intent(in) :: mpi_enreg
365 : type(dataset_type),intent(in) :: dtset
366 : !arrays
367 : integer,intent(in) :: ngfft(18)
368 : real(dp),intent(in) :: rhor(nfft,2*nspden-1),rprimd(3,3)
369 : real(dp),intent(out) :: kxcg(2,nfft,*)
370 :
371 : !Local variables -------------------------------------------------------
372 : !No improved xc quadrature.
373 : !No core correction.
374 : !Dummy here.
375 : !For debugging purposes (see tests below):
376 : !integer :: i1,i2,i3,k1,n1,n2,n3
377 : !real(dp) :: kx,rho,rhomax,ftest
378 : !scalars
379 : integer :: ifft,ikxc,isp,n3xccc,ncut,nk3xc,nkxc,optionrhoxc,tim_fourdp
380 : logical :: non_magnetic_xc
381 : real(dp),parameter :: gsqcut=1._dp
382 : real(dp) :: el_temp,bigexc,bigsxc,rhocuttot,rhomin,vxcavg
383 : character(len=500) :: msg
384 : type(xcdata_type) :: xcdata
385 : !arrays
386 : real(dp) :: dum(0)
387 : real(dp),parameter :: dummyvgeo(3)=zero
388 0 : real(dp),allocatable :: kxcr(:,:),rhog(:,:),rhorcut(:,:),vhartree(:)
389 0 : real(dp),allocatable :: vxc(:,:),xccc3d(:)
390 : !***********************************************************************
391 :
392 : !For debugging purposes (see tests below):
393 : !ftest(i1,n1,k1) = 0._dp+1._dp*cos(k1*two_pi*float(i1)/float(n1))
394 :
395 : ! Check input parameters.
396 0 : if (nspden > 2) then
397 0 : ABI_ERROR('kxc_alda does not work yet for nspden > 2.')
398 : end if
399 :
400 : ! Allocate memory.
401 0 : ABI_MALLOC(rhorcut, (nfft,nspden))
402 0 : ABI_MALLOC(rhog, (2,nfft))
403 0 : ABI_MALLOC(vhartree, (nfft))
404 0 : ABI_MALLOC(vxc, (nfft,nspden))
405 :
406 0 : call xcdata_init(xcdata,dtset=dtset,intxc=0,ixc=ixc,nspden=nspden)
407 :
408 0 : non_magnetic_xc=(dtset%usepaw==1.and.mod(abs(dtset%usepawu),10)==4)
409 :
410 : ! Reinitialize the libxc module with the overridden values
411 0 : if (dtset%ixc<0) then
412 0 : call libxc_functionals_end()
413 : end if
414 :
415 0 : if (ixc<0) then
416 0 : el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
417 0 : call libxc_functionals_init(ixc,dtset%nspden,el_temp=el_temp,xc_tb09_c=dtset%xc_tb09_c)
418 : end if
419 :
420 : !to be adjusted for the call to rhotoxc
421 0 : nk3xc=1
422 :
423 : ! Cut-off the density.
424 0 : rhorcut(:,:) = rhor(:,:)
425 :
426 0 : do isp = 1,nspden
427 0 : rhomin = maxval(rhorcut(:,isp))*rhocut
428 :
429 0 : ncut = 0
430 0 : rhocuttot = 0._dp
431 :
432 0 : do ifft = 1,nfft
433 0 : if (rhorcut(ifft,isp) < rhomin) then
434 0 : ncut = ncut+1
435 0 : rhocuttot = rhocuttot+rhorcut(ifft,isp)
436 0 : rhorcut(ifft,isp) = rhomin
437 : end if
438 : end do
439 :
440 0 : if (ncut > 0) then
441 : write (msg,'(a,es10.3,3a,i1,a,i6,a,f6.3,3a,f6.3,a)') &
442 0 : 'rhocut = ',rhocut,'.',ch10,&
443 0 : 'For isp = ',isp,' the density was cut-off at ',ncut,' (',100._dp*float(ncut)/float(ifft),'%) grid points.',ch10,&
444 0 : 'These points account for ',100._dp*rhocuttot/sum(rhor(:,isp)),'% of the total density.'
445 0 : ABI_WARNING(msg)
446 : end if
447 :
448 : end do
449 :
450 : ! Calculate the AL(S)DA kernel in real space.
451 0 : rhog(:,:) = zero !We do not need the Hartree potential.
452 0 : tim_fourdp=0
453 :
454 0 : if ((option == 1).or.((option == 2).and.(nspden == 2))) then
455 :
456 0 : nkxc = 2*nspden-1
457 0 : n3xccc=0
458 0 : ABI_MALLOC(kxcr,(nfft,nkxc))
459 0 : ABI_MALLOC(xccc3d,(n3xccc))
460 :
461 0 : optionrhoxc = 2 !See rhotoxc.f
462 :
463 0 : call hartre(1,gsqcut,3,0,mpi_enreg,nfft,ngfft,1,zero,rhog,rprimd,dummyvgeo,vhartree)
464 : call rhotoxc(bigexc,bigsxc,kxcr,mpi_enreg,nfft,ngfft,dum,0,dum,0,nkxc,nk3xc,non_magnetic_xc,n3xccc,&
465 0 : optionrhoxc,rhorcut,rprimd,1,vxc,vxcavg,xccc3d,xcdata,vhartr=vhartree)
466 :
467 : ! DEBUG
468 : ! fx for tests.
469 : ! write (std_out,'(a)') ' kxc_alda: Using exchange-only kernel for tests.'
470 : ! rhomin = minval(rhor(:,1))
471 : ! rhomax = maxval(rhor(:,1))
472 : ! write (std_out,'(a,es12.5,a,es12.5)') ' kxc_alda: rhomin = ',rhomin,' rhomax = ',rhomax
473 : ! write (std_out,'(a)') ' kxc_alda: loping below 0.2*rhomax.'
474 : ! kx = (3._dp/4._dp)*((3._dp/pi)**(1._dp/3._dp))
475 : ! do ifft = 1,nfft
476 : ! rho = rhor(ifft,1)
477 : ! rho = max(rho,0.2_dp*rhomax)
478 : ! kxcr(ifft,1) = -(4._dp/9._dp)*kx*(rho**(-2._dp/3._dp))
479 : ! write (std_out,'(i4,a,es12.5)') ifft,': ',kxcr(ifft,1)
480 : ! end do
481 : ! write (std_out,'(a,es12.5)') 'kxcrmin: ',minval(kxcr(:,1))
482 : ! write (std_out,'(a,es12.5)') 'kxcrmax: ',maxval(kxcr(:,1))
483 : ! ENDDEBUG
484 :
485 : ! DEBUG
486 : ! test kernel.
487 : ! write(std_out,'(a)') ' kxc_alda: Using test kernel for tests.'
488 : ! n1 = ngfft(1) ; n2 = ngfft(2) ; n3 = ngfft(3)
489 : ! do i3 = 0,n3-1
490 : ! do i2 = 0,n2-1
491 : ! do i1 = 0,n1-1
492 : ! ifft = i1+n1*(i2+n2*i3)+1
493 : ! kxcr(ifft,1) = ftest(i1,n1,1)*ftest(i2,n2,2)*ftest(i3,n3,3)
494 : ! end do
495 : ! end do
496 : ! end do
497 : ! ENDDEBUG
498 :
499 : ! Calculate the Fourier transform of the AL(S)DA kernel.
500 :
501 0 : if (option == 1) then
502 0 : do ikxc = 1,nkxc
503 0 : call fourdp(1,kxcg(:,:,ikxc),kxcr(:,ikxc),-1,mpi_enreg,nfft,1,ngfft,tim_fourdp)
504 : end do
505 : else
506 0 : call fourdp(1,kxcg(:,:,1),kxcr(:,2),-1,mpi_enreg,nfft,1,ngfft,tim_fourdp)
507 : end if
508 :
509 0 : else if ((option == 2).and.(nspden == 1)) then
510 :
511 0 : nkxc = 2
512 0 : n3xccc=0
513 0 : ABI_MALLOC(kxcr,(nfft,nkxc))
514 0 : ABI_MALLOC(xccc3d,(n3xccc))
515 :
516 0 : optionrhoxc = -2 !See rhotoxc.f
517 :
518 0 : call hartre(1,gsqcut,3,0,mpi_enreg,nfft,ngfft,1,zero,rhog,rprimd,dummyvgeo,vhartree)
519 : call rhotoxc(bigexc,bigsxc,kxcr,mpi_enreg,nfft,ngfft,dum,0,dum,0,nkxc,nk3xc,non_magnetic_xc,n3xccc,&
520 0 : & optionrhoxc,rhorcut,rprimd,1,vxc,vxcavg,xccc3d,xcdata,vhartr=vhartree)
521 :
522 0 : kxcr(:,2) = 0.5_dp*kxcr(:,2)
523 :
524 : ! Calculate the Fourier transform of the up-down channel of the AL(S)DA kernel.
525 0 : call fourdp(1,kxcg(:,:,1),kxcr(:,2),-1,mpi_enreg,nfft,1,ngfft,tim_fourdp)
526 :
527 : else
528 0 : ABI_ERROR(sjoin("Invalid option:", itoa(option)))
529 : end if
530 :
531 : !write(std_out,*)' kxc_alda: Exc = ',bigexc
532 : !write(std_out,*)' kxc_alda: Sxc = ',bigsxc
533 : !write(std_out,*)' kxc_alda: <Vxc> = ',vxcavg
534 :
535 : ! Revert libxc module to the original settings
536 0 : if (ixc<0) then
537 0 : call libxc_functionals_end()
538 : end if
539 0 : if (dtset%ixc<0) then
540 0 : el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
541 0 : call libxc_functionals_init(dtset%ixc,dtset%nspden,el_temp=el_temp,xc_tb09_c=dtset%xc_tb09_c)
542 : end if
543 :
544 : ! Free memory.
545 0 : ABI_FREE(rhorcut)
546 0 : ABI_FREE(rhog)
547 0 : ABI_FREE(vhartree)
548 0 : ABI_FREE(vxc)
549 0 : ABI_FREE(kxcr)
550 0 : ABI_FREE(xccc3d)
551 :
552 0 : end subroutine kxc_alda
553 : !!***
554 :
555 : !----------------------------------------------------------------------
556 :
557 : !!****f* m_kxc/kxc_pgg
558 : !! NAME
559 : !! kxc_pgg
560 : !!
561 : !! FUNCTION
562 : !! Compute the PGG-exchange kernel in reciprocal space
563 : !! (Phys. Rev. Lett. 76, 1212 (1996) [[cite:Petersilka1996]]).
564 : !!
565 : !! INPUTS
566 : !! gmet=reciprocal space metric (bohr**-2)
567 : !! npw=number of plane waves
568 : !! rcut_coulomb=real space cutoff radius for Coulomb interaction (bohr)
569 : !! susmat(2,npw,npw)=density weighted squared density matrix in reciprocal space
570 : !! ucvol=unit cell volume (bohr**3)
571 : !!
572 : !! OUTPUT
573 : !! khxcg(2,npwdiel,nspden,npwdiel,nspden)=PGG-exhange kernel in G space, at
574 : !! full interaction strength
575 : !!
576 : !! NOTES
577 : !! The density weighted squared density matrix (actually the reduced=summed-over-spin
578 : !! density matrix) is convolved with the spherically cutoff Coulomb interaction.
579 : !!
580 : !! WARNINGS
581 : !! a - 'rcut_coulomb' should be chosen consistently with cutoffs elsewhere,
582 : !! for instance dieltcel8.f
583 : !! b - applicable for spin-polarized case as well, through input 'susmat',
584 : !! but this has not been checked
585 : !!
586 : !! TODO
587 : !! If simply the squared density matrix is input through 'susmat' the
588 : !! exchange energy is recovered as the zero-G component of the resulting 'khxcg'
589 : !! (then not the kernel of course). This could help to check convergence
590 : !! with respect to 'npw'. See +ex_pgg comment.
591 : !!
592 : !! SOURCE
593 :
594 0 : subroutine kxc_pgg(gmet,kg,khxcg,npw,rcut_coulomb,susmat,ucvol)
595 :
596 : !Arguments ------------------------------------
597 : !scalars
598 : integer,intent(in) :: npw
599 : real(dp),intent(in) :: rcut_coulomb,ucvol
600 : !arrays
601 : integer,intent(in) :: kg(3,npw)
602 : real(dp),intent(in) :: gmet(3,3),susmat(2,npw,npw)
603 : real(dp),intent(out) :: khxcg(2,npw,npw)
604 :
605 : !Local variables-------------------------------
606 : !scalars
607 : integer :: i1,i2,i3,ig,ii,ikg11,ikg12,ikg13,ikg21,ikg22,ikg23,ipw1,ipw2
608 : integer :: j1,j2,j3,jg,jj
609 : real(dp),parameter :: diffgsq=1.d-2
610 : real(dp) :: kg_red1,kg_red2,kg_red3,gsquar,tpisq
611 : !arrays
612 : integer :: kgmax(3)
613 0 : integer,allocatable :: index_g_inv(:,:,:),jgarr(:)
614 0 : real(dp),allocatable :: gsq(:),sumg(:),vcoul(:)
615 : ! *************************************************************************
616 :
617 : !write(std_out,*) '%kxc_pgg: enter', 'npw=',npw
618 :
619 : !tpisq is (2 Pi) **2:
620 0 : tpisq=(two_pi)**2
621 :
622 0 : kgmax(:)=0
623 0 : do ipw1=1,npw
624 0 : do jj=1,3
625 0 : kgmax(jj)=max( kg(jj,ipw1), kgmax(jj) )
626 : end do
627 : end do
628 : !write(std_out,*) 'kgmax:',kgmax(1:3)
629 :
630 : ! Perform allocations
631 0 : ABI_MALLOC(index_g_inv,(-2*kgmax(1):2*kgmax(1),-2*kgmax(2):2*kgmax(2),-2*kgmax(3):2*kgmax(3)))
632 0 : ABI_MALLOC(jgarr,(npw))
633 0 : ABI_MALLOC(gsq,(npw))
634 0 : ABI_MALLOC(sumg,(2))
635 0 : ABI_MALLOC(vcoul,(npw))
636 :
637 : !write(std_out,*) '%kxc_pg: creating plane wave index and coulomb potential'
638 0 : index_g_inv(:,:,:)=0
639 0 : do ipw1=1,npw
640 0 : index_g_inv(kg(1,ipw1),kg(2,ipw1),kg(3,ipw1))=ipw1
641 :
642 : !write(std_out,'(i5,2x,3i3,2x,i4)') ipw1,kg(1,ipw1),kg(2,ipw1),kg(3,ipw1)
643 :
644 0 : kg_red1=dble(kg(1,ipw1))
645 0 : kg_red2=dble(kg(2,ipw1))
646 0 : kg_red3=dble(kg(3,ipw1))
647 : gsquar=tpisq*(gmet(1,1)*kg_red1**2+gmet(2,2)*kg_red2**2+gmet(3,3)*kg_red3**2 &
648 : & +2.0_dp*( (gmet(1,2)*kg_red2+gmet(1,3)*kg_red3)* kg_red1 + &
649 0 : & gmet(2,3)*kg_red2*kg_red3) )
650 : ! Distinguish G=0 from other elements
651 0 : if(gsquar > 1.0d-12)then
652 0 : vcoul(ipw1)=four_pi/gsquar*(1._dp-cos(sqrt(gsquar)*rcut_coulomb))
653 : else
654 0 : vcoul(ipw1)=four_pi*0.5_dp*rcut_coulomb**2
655 : end if
656 :
657 : end do
658 :
659 : !write(std_out,*) '%kxc_pg: starting convolution integral'
660 : !loop over G1,G2 components of the density matrix
661 0 : do ipw2=1,npw
662 0 : ikg21=kg(1,ipw2)
663 0 : ikg22=kg(2,ipw2)
664 0 : ikg23=kg(3,ipw2)
665 :
666 0 : do ii=1,npw
667 0 : j1=ikg21-kg(1,ii)
668 0 : j2=ikg22-kg(2,ii)
669 0 : j3=ikg23-kg(3,ii)
670 0 : jgarr(ii)=index_g_inv(j1,j2,j3)
671 : end do
672 :
673 0 : do ipw1=1,ipw2
674 0 : ikg11=kg(1,ipw1)
675 0 : ikg12=kg(2,ipw1)
676 0 : ikg13=kg(3,ipw1)
677 :
678 : ! do the convolution integral
679 0 : sumg(:)=0._dp
680 0 : do ii=1,npw
681 :
682 0 : if( jgarr(ii) /= 0 ) then
683 0 : i1=ikg11-kg(1,ii)
684 0 : i2=ikg12-kg(2,ii)
685 0 : i3=ikg13-kg(3,ii)
686 :
687 : ! j1=ikg21-kg(1,ii)
688 : ! j2=ikg22-kg(2,ii)
689 : ! j3=ikg23-kg(3,ii)
690 :
691 0 : ig=index_g_inv(i1,i2,i3)
692 : ! jg=index_g_inv(j1,j2,j3)
693 :
694 0 : if( ig /= 0 ) then
695 0 : jg=jgarr(ii)
696 :
697 : ! write(std_out,'(i5,2x,3i3,1x,3i3,2x,2i4)') ii,i1,i2,i3,&
698 : ! & kg(1,jg),kg(2,jg),kg(3,jg),&
699 : ! & ig,jg
700 :
701 0 : sumg(1)=sumg(1)+susmat(1,ig,jg)*vcoul(ii)
702 0 : sumg(2)=sumg(2)+susmat(2,ig,jg)*vcoul(ii)
703 :
704 : end if
705 : end if
706 :
707 : end do
708 0 : khxcg(:,ipw1,ipw2)=-sumg(:)*ucvol
709 :
710 : ! if(ipw1==ipw2) write(std_out,'(2i4,2(1x,es14.6))') ipw1,ipw2,khxcg(1,ipw1,ipw1),vcoul(ipw1)
711 : ! write(std_out,'(2i4,3(1x,es14.6))') ipw1,ipw2,khxcg(1:2,ipw1,ipw2),vcoul(ipw1)
712 :
713 : end do
714 : end do
715 :
716 : !verify hermiticity, note: ipw1 loop above must end at npw
717 : !write(std_out,*) '%kxc_pgg: check hermiticity of pgg kernel'
718 : !do ipw2=1,npw,max(2,npw/10)
719 : !do ipw1=ipw2,npw,max(2,npw/10)
720 : !write(std_out,'(2i4,2(1x,es14.6))') ipw1,ipw2,&
721 : !& khxcg(1,ipw1,ipw2)-khxcg(1,ipw2,ipw1),&
722 : !& khxcg(2,ipw1,ipw2)+khxcg(2,ipw2,ipw1)
723 : !end do
724 : !end do
725 :
726 : ! Impose hermiticity
727 0 : write(std_out,*) '%kxc_pg: imposing hermiticity'
728 0 : do ipw2=1,npw
729 0 : do ipw1=ipw2+1,npw
730 0 : khxcg(1,ipw1,ipw2)= khxcg(1,ipw2,ipw1)
731 0 : khxcg(2,ipw1,ipw2)=-khxcg(2,ipw2,ipw1)
732 : end do
733 : end do
734 :
735 : !write(std_out,'(a10,2(1x,es20.12))') '+ex_pgg? ', 0.5_dp*khxcg(1,1,1)/ucvol
736 :
737 0 : ABI_FREE(index_g_inv)
738 0 : ABI_FREE(jgarr)
739 0 : ABI_FREE(gsq)
740 0 : ABI_FREE(sumg)
741 0 : ABI_FREE(vcoul)
742 :
743 : !write(std_out,*) '%kxc_pgg: done'
744 :
745 0 : end subroutine kxc_pgg
746 : !!***
747 :
748 : !----------------------------------------------------------------------
749 :
750 : !!****f* m_kxc/kxc_eok
751 : !! NAME
752 : !! kxc_eok
753 : !!
754 : !! FUNCTION
755 : !! Compute the linear (ixceok = 1) or non-linear (ixceok = 2)
756 : !! energy optimized kernel of Dobson and Wang, in reciprocal space, on the FFT grid.
757 : !! See J. Dobson and J. Wang, Phys. Rev. B 62, 10038 (2000) [[cite:Dobson2000]].
758 : !!
759 : !! INPUTS
760 : !! ixceok = 1 linear energy optimized kernel.
761 : !! = 2 non-linear energy optimized kernel.
762 : !! mpi_enreg=information about MPI parallelization
763 : !! nfft = number of fft grid points.
764 : !! ngfft(1:3) = integer fft box dimensions, see getng for ngfft(4:8).
765 : !! nspden = number of spin-density components.
766 : !! rhor(nfft,nspden) = electron density in real space in electrons/bohr**3
767 : !! (total in first half and spin-up in second half if nspden = 2).
768 : !! rhocut = cut-off density for the local kernels (ALDA, EOK),
769 : !! relative to max(rhor(:,:)).
770 : !! OUTPUT
771 : !! kxcg(2,nfft,2*nspden-1) = the EOK kernel in reciprocal space, on the FFT grid.
772 : !!
773 : !! SOURCE
774 :
775 0 : subroutine kxc_eok(ixceok,kxcg,mpi_enreg,nfft,ngfft,nspden,rhor,rhocut)
776 :
777 : !Arguments -------------------------------------------------------------
778 : !scalars
779 : integer,intent(in) :: ixceok,nfft,nspden
780 : real(dp),intent(in) :: rhocut
781 : type(MPI_type),intent(in) :: mpi_enreg
782 : !arrays
783 : integer,intent(in) :: ngfft(18)
784 : real(dp),intent(in) :: rhor(nfft,2*nspden-1)
785 : real(dp),intent(out) :: kxcg(2,nfft,2*nspden-1)
786 :
787 : !Local variables -------------------------------------------------------
788 : !Maximum value allowed for rs.
789 : !scalars
790 : integer :: ifft,ikxc,ncut,nkxc,nlop,tim_fourdp
791 : real(dp),parameter :: rslim=50._dp,dummyvgeo(3)=zero
792 : real(dp) :: a2,a3,a4,rho,rhocuttot,rhomin,rs
793 : character(len=500) :: msg
794 : !arrays
795 0 : real(dp),allocatable :: kxcr(:,:)
796 : !***********************************************************************
797 :
798 : ! Check input parameters.
799 0 : if (nspden > 1) then
800 0 : ABI_ERROR('kxc_eok does not work yet for nspden > 1.')
801 : end if
802 :
803 : ! Values of a2, a3 and a4 for case 1
804 0 : a2 = 0.0_dp
805 0 : a3 = 0.0_dp
806 0 : a4 = 0.0_dp
807 :
808 0 : select case (ixceok)
809 : case (1)
810 : a2 = -0.51887_dp
811 : a3 = 4.9359d-03
812 0 : a4 = -5.9603d-05
813 : case (2)
814 0 : a2 = -0.50044_dp
815 0 : a3 = 4.9653d-03
816 0 : a4 = -3.3660d-05
817 : case default
818 0 : ABI_ERROR(' kxc_eok: ixceok /= 1 (linear EOK) or 2 (non-linear EOK).')
819 : end select
820 :
821 : !Allocate memory.
822 0 : nkxc = 2*nspden-1
823 :
824 0 : ABI_MALLOC(kxcr,(nfft,nkxc))
825 :
826 : ! Calculate the energy optimized kernel in real space.
827 0 : nlop = 0
828 :
829 0 : rhomin = rhocut*maxval(rhor(:,:))
830 :
831 0 : ncut = 0
832 0 : rhocuttot = 0._dp
833 :
834 0 : do ifft = 1,nfft
835 0 : rho = rhor(ifft,1)
836 :
837 0 : if (rho < rhomin) then
838 0 : ncut = ncut+1
839 0 : rhocuttot = rhocuttot+rho
840 0 : rho = rhomin
841 : end if
842 :
843 0 : rs = (3._dp/(4._dp*pi*rho))**(1._dp/3._dp)
844 :
845 0 : if (rs > rslim) then
846 0 : rs = rslim
847 0 : nlop = nlop+1
848 : end if
849 :
850 0 : kxcr(ifft,1) = a2*rs**2+a3*rs**3+a4*rs**4
851 : end do
852 :
853 0 : if (ncut > 0) then
854 : write (msg,'(a,es10.3,3a,i1,a,i6,a,f6.3,3a,f6.3,a)') &
855 0 : 'rhocut = ',rhocut,'.',ch10,&
856 0 : 'For isp = ',1,' the density was cut-off at ',ncut,' (',100._dp*float(ncut)/float(ifft),'%) grid points.',ch10,&
857 0 : 'These points account for ',100._dp*rhocuttot/sum(rhor(:,1)),'% of the total density.'
858 0 : ABI_WARNING(msg)
859 : end if
860 :
861 0 : if (nlop > 0) then
862 : write (msg,'(a,f6.2,a,i6,a,f6.3,a)') &
863 0 : 'rs still exceeds ',rslim,' Bohr at ',nlop,' (',100._dp*float(nlop)/float(ifft),'%) grid points (after cut-off).'
864 0 : ABI_WARNING(msg)
865 : end if
866 :
867 : ! Calculate the Fourier transform of the energy optimized kernel.
868 0 : tim_fourdp=0
869 0 : do ikxc = 1,nkxc
870 0 : call fourdp(1,kxcg(:,:,ikxc),kxcr(:,ikxc),-1,mpi_enreg,nfft,1,ngfft,tim_fourdp)
871 : end do
872 :
873 0 : ABI_FREE(kxcr)
874 :
875 0 : end subroutine kxc_eok
876 : !!***
877 :
878 : !----------------------------------------------------------------------
879 :
880 : !!****f* m_kxc/kxc_driver
881 : !! NAME
882 : !! kxc_driver
883 : !!
884 : !! FUNCTION
885 : !! Calculate the exchange-correlation kernel in reciprocal space.
886 : !! Require density in real space on the FFT mesh. MPI-FFT is not supported.
887 : !!
888 : !! INPUTS
889 : !! Dtset<dataset_type>=all input variables in this dataset
890 : !! Cryst<crystal_t>=Info on the crystal structure.
891 : !! ixc = choice for the exchange-correlation potential.
892 : !! ngfft(18)=contain all needed information about 3D FFT,
893 : !! see ~abinit/doc/variables/vargs.htm#ngfft
894 : !! nfft_tot = Total number of points on the FFT grid.
895 : !! nspden=Number of independent spin densities.
896 : !! rhor(nfft_tot,nspden) = the charge density on the full FFT grid.
897 : !! (total in first half and spin-up in second half if nspden=2)
898 : !! npw: the size of kernel matrix
899 : !! dim_kxcg=dimension of the kernel.
900 : !! comm=MPI communicator.
901 : !! [dbg_mode]=Optional flag used to switch on the debug mode.
902 : !!
903 : !! OUTPUT
904 : !! FIXME: Why are we using nfft_tot instead of the G-sphere
905 : !! kxcg(nfft_tot,dim_kxcg) = the exchange-correlation potential on the FFT grid.
906 : !! warning: the kernel is not divided by the unit cell volume
907 : !!
908 : !! NOTES
909 : !! No xc quadrature
910 : !! No nl core correction
911 : !!
912 : !! SOURCE
913 :
914 11 : subroutine kxc_driver(Dtset,Cryst,ixc,ngfft,nfft_tot,nspden,rhor,npw,dim_kxcg,kxcg,gvec,comm,dbg_mode)
915 :
916 : !Arguments ------------------------------------
917 : !scalars
918 : integer,intent(in) :: ixc,npw,nfft_tot,nspden,dim_kxcg,comm
919 : logical,optional,intent(in) :: dbg_mode
920 : type(crystal_t),intent(in) :: Cryst
921 : type(dataset_type),intent(in) :: Dtset
922 : !arrays
923 : integer,intent(in) :: gvec(3,npw),ngfft(18)
924 : real(dp),intent(in) :: rhor(nfft_tot,nspden)
925 : complex(gwp),intent(out) :: kxcg(nfft_tot,dim_kxcg)
926 :
927 : !Local variables ------------------------------
928 : !scalars
929 : integer :: cplex,i1,i2,i3,ig,igp,iq,ir,n3xccc,ngfft1,ngfft2,izero
930 : integer :: ngfft3,nkxc,option,ikxc,nk3xc,my_rank,master
931 : logical :: non_magnetic_xc
932 : real(dp) :: el_temp,bigexc,bigsxc,expo,gpqx,gpqy,gpqz,gsqcut,vxcavg
933 : character(len=500) :: fname ! msg,
934 : type(xcdata_type) :: xcdata
935 11 : type(MPI_type) :: MPI_enreg_seq
936 : !arrays
937 : real(dp) :: qphon(3),dum(0)
938 : real(dp),parameter :: dummyvgeo(3)=zero
939 11 : real(dp),allocatable :: kxcpw_g(:,:),kxcr(:,:),phas(:,:,:)
940 11 : real(dp),allocatable :: rhog(:,:),vhartr(:),kxcpw_r(:,:),vxclda(:,:)
941 11 : real(dp),allocatable :: xccc3d(:),xx(:,:), my_kxcg(:,:)
942 : !************************************************************************
943 :
944 11 : ABI_CHECK_IEQ(Dtset%nsppol, 1, 'nsppol/=1 not coded')
945 11 : ABI_CHECK_IEQ(Dtset%nspden, 1, 'nspden /= 1 not coded')
946 44 : ABI_CHECK_IEQ(nfft_tot, PRODUCT(ngfft(1:3)), "mismatch in nfftot")
947 :
948 : ! Fake MPI_type for the sequential part.
949 11 : call initmpi_seq(MPI_enreg_seq)
950 11 : call MPI_enreg_seq%distribfft%init_seq('c',ngfft(2),ngfft(3),'all')
951 11 : my_rank = xmpi_comm_rank(comm)
952 11 : master =0
953 :
954 11 : call wrtout(std_out,sjoin(' kxc_driver: calculating exchange-correlation kernel using ixc: ', itoa(ixc)))
955 11 : call xcdata_init(xcdata,dtset=Dtset,intxc=0,ixc=ixc,nspden=nspden)
956 :
957 11 : if (all(xcdata%xclevel /= [1,2])) then
958 0 : ABI_ERROR(sjoin("Unsupported xclevel: ", itoa(xcdata%xclevel)))
959 : end if
960 :
961 11 : ngfft1=ngfft(1)
962 11 : ngfft2=ngfft(2)
963 11 : ngfft3=ngfft(3)
964 :
965 11 : non_magnetic_xc=(dtset%usepaw==1.and.mod(abs(dtset%usepawu),10)==4)
966 :
967 11 : if (ixc>=1.and.ixc<11) then ! LDA case
968 11 : nkxc= 2*min(nspden,2)-1 ! 1 or 3
969 0 : elseif (ixc==51) then ! TLDA case, same as LDA above
970 0 : nkxc= 2*min(nspden,2)-1
971 : else ! GGA case
972 0 : nkxc=12*min(nspden,2)-5 ! 7 or 19
973 0 : ABI_CHECK_IEQ(dtset%xclevel, 2,"Functional should be GGA")
974 0 : ABI_ERROR("GGA functional not tested")
975 : end if
976 :
977 44 : ABI_MALLOC(kxcr, (nfft_tot,nkxc))
978 :
979 : ! gsqcut and rhog are zeroed because they are not used by rhotoxc if 1<=ixc<=16 and option=0
980 11 : gsqcut=zero
981 :
982 33 : ABI_MALLOC(rhog,(2,nfft_tot))
983 33 : ABI_MALLOC(vhartr,(nfft_tot))
984 236774 : rhog(:,:)=zero
985 : !MG FIXME this is the 3D core electron density for XC core correction (bohr^-3)
986 : !should implement the non linear core correction
987 11 : n3xccc=0
988 11 : ABI_MALLOC(xccc3d,(n3xccc))
989 44 : ABI_MALLOC(vxclda,(nfft_tot,nspden))
990 :
991 11 : option=2 ! 2 for Hxc and kxcr (no paramagnetic part if nspden=1)
992 11 : qphon =zero
993 :
994 : ! to be adjusted for the call to rhotoxc
995 11 : nk3xc=1
996 11 : izero=0
997 :
998 : ! Reinitialize the libxc module with the overridden values
999 11 : if (dtset%ixc<0) then
1000 0 : call libxc_functionals_end()
1001 : end if
1002 11 : if (ixc<0) then
1003 0 : el_temp=merge(Dtset%tphysel,Dtset%tsmear,Dtset%tphysel>tol8.and.Dtset%occopt/=3.and.Dtset%occopt/=9)
1004 0 : call libxc_functionals_init(ixc,Dtset%nspden,el_temp=el_temp,xc_tb09_c=Dtset%xc_tb09_c)
1005 : end if
1006 :
1007 11 : call hartre(1,gsqcut,3,izero,MPI_enreg_seq,nfft_tot,ngfft,1,zero,rhog,Cryst%rprimd,dummyvgeo,vhartr)
1008 :
1009 : ! Compute the XC kernel.
1010 : call rhotoxc(bigexc,bigsxc,kxcr,MPI_enreg_seq,nfft_tot,ngfft,&
1011 : dum,0,dum,0,nkxc,nk3xc,non_magnetic_xc,&
1012 : n3xccc,option,rhor,Cryst%rprimd,&
1013 11 : 1,vxclda,vxcavg,xccc3d,xcdata,vhartr=vhartr)
1014 :
1015 11 : ABI_FREE(rhog)
1016 11 : ABI_FREE(vhartr)
1017 :
1018 : ! print Kxc
1019 11 : if (present(dbg_mode)) then
1020 1 : if (dbg_mode .and. my_rank==master) then
1021 0 : fname = 'xc_Kxc.xsf'
1022 0 : call cryst%write_xsf_data(fname, ngfft1, ngfft2, ngfft3, kxcr(:,1))
1023 : end if
1024 :
1025 : end if
1026 :
1027 11 : ABI_FREE(xccc3d)
1028 11 : ABI_FREE(vxclda)
1029 :
1030 22 : ABI_MALLOC(my_kxcg,(2,nfft_tot))
1031 22 : do ikxc=1,nkxc
1032 11 : call fourdp(1,my_kxcg,kxcr(:,ikxc),-1,MPI_enreg_seq,nfft_tot,1,ngfft,0)
1033 78943 : kxcg(:,ikxc)=CMPLX(my_kxcg(1,:),my_kxcg(2,:))
1034 : end do
1035 :
1036 : !write(std_out,*)"kxcr(r=0)",kxcr(1,1)
1037 : !write(std_out,*)"my_kxg(G=0)",my_kxcg(:,1)
1038 : !write(std_out,*)"SUM kxcr/nfft_tot ",SUM(kxcr(:,1))/nfft_tot
1039 : !write(std_out,*)"SUM my_kxg ",SUM(kxcg(:,1))
1040 :
1041 11 : ABI_FREE(my_kxcg)
1042 :
1043 : !MG this part is never executed, but one should use dfpt_mkvxc for the GGA kernel.
1044 11 : if (xcdata%xclevel==2) then
1045 0 : ABI_ERROR("check GGA implementation")
1046 0 : cplex=2
1047 0 : ABI_MALLOC(phas,(cplex*nfft_tot,npw,nspden))
1048 0 : ABI_MALLOC(kxcpw_r,(cplex*nfft_tot,nspden))
1049 0 : ABI_MALLOC(xx,(3,nfft_tot))
1050 0 : ABI_MALLOC(kxcpw_g,(2,nfft_tot))
1051 :
1052 0 : kxcg = czero
1053 :
1054 : ! find the coordinates for all r in the FFT grid
1055 : ir=0
1056 0 : do i3=1,ngfft3
1057 0 : do i2=1,ngfft2
1058 0 : do i1=1,ngfft1
1059 0 : ir=ir+1
1060 0 : xx(1,ir)=dble((i1-1))/ngfft1
1061 0 : xx(2,ir)=dble((i2-1))/ngfft2
1062 0 : xx(3,ir)=dble((i3-1))/ngfft3
1063 : end do
1064 : end do
1065 : end do
1066 :
1067 0 : do iq=1,1
1068 :
1069 : ! Calculate at once exp(i(G+q).r), for all possible q,G,r
1070 0 : do ig=1,npw
1071 0 : gpqx=dble(gvec(1,ig))
1072 0 : gpqy=dble(gvec(2,ig))
1073 0 : gpqz=dble(gvec(3,ig))
1074 0 : do ir=1,nfft_tot
1075 0 : expo=gpqx*xx(1,ir)+gpqy*xx(2,ir)+gpqz*xx(3,ir)
1076 0 : phas(2*ir-1,ig,1)= cos(two_pi*expo)
1077 0 : phas(2*ir,ig,1) = sin(two_pi*expo)
1078 : end do
1079 : end do
1080 :
1081 : ! Calculate $K(G,G'',q)=\frac{1}{nfft_tot}\sum_{r} exp(-i(q+G_{2}).r_{2} kxcr(r_{1}r_{2}) exp(i(q+G_{1}).r_{1} $
1082 0 : do igp=1,npw
1083 0 : kxcpw_r(:,:)=zero
1084 :
1085 : call dfpt_mkvxc(cplex,ixc,kxcr,MPI_enreg_seq,nfft_tot,ngfft,dum,0,dum,0,nkxc,non_magnetic_xc,&
1086 0 : nspden,n3xccc,option,qphon(:),phas(:,igp,:),Cryst%rprimd,1,kxcpw_r,xccc3d)
1087 :
1088 : ! FFT the first index to --> to G space
1089 0 : call fourdp(cplex,kxcpw_g(:,:),kxcpw_r(:,1),-1,MPI_enreg_seq,nfft_tot,1,ngfft,0)
1090 :
1091 : !kxcg(:,igp,iq)=CMPLX(kxcpw_g(1,igfft(:)),kxcpw_g(2,igfft(:)))
1092 : !kxcg(:,igp)=CMPLX(kxcpw_g(1,igfft(:)),kxcpw_g(2,igfft(:)))
1093 : end do ! igp
1094 : end do ! iq
1095 :
1096 0 : ABI_FREE(phas)
1097 0 : ABI_FREE(kxcpw_r)
1098 0 : ABI_FREE(xx)
1099 0 : ABI_FREE(kxcpw_g)
1100 : end if !xclevel==2
1101 :
1102 : ! Revert libxc module to the original settings
1103 11 : if (ixc<0) then
1104 0 : call libxc_functionals_end()
1105 : end if
1106 11 : if (dtset%ixc<0) then
1107 0 : el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
1108 0 : call libxc_functionals_init(dtset%ixc,dtset%nspden,el_temp=el_temp,xc_tb09_c=dtset%xc_tb09_c)
1109 : end if
1110 :
1111 11 : call destroy_mpi_enreg(MPI_enreg_seq)
1112 11 : ABI_FREE(kxcr)
1113 :
1114 11 : end subroutine kxc_driver
1115 : !!***
1116 :
1117 : !----------------------------------------------------------------------
1118 :
1119 : !!****f* m_kxc/kxc_ADA
1120 : !! NAME
1121 : !! kxc_ADA
1122 : !!
1123 : !! FUNCTION
1124 : !! Calculate exchange-correlation kernel in reciprocal space
1125 : !!
1126 : !! INPUTS
1127 : !! Dtset <type(dataset_type)>=all input variables in this dataset
1128 : !! Cryst<crystal_t>=Info on the unit cell.
1129 : !! ixc = choice for the exchange-correlation potential.
1130 : !! ngfft(18)=contain all needed information about 3D FFT,
1131 : !! see ~abinit/doc/variables/vargs.htm#ngfft
1132 : !! nfft = total number of points on the FFT grid.
1133 : !! rhor(nfft,nspden) = the charge density on the FFT grid.
1134 : !! (total in first half and spin-up in second half if nsppol=2)
1135 : !! npw: the size of kernel matrix
1136 : !! dim_kxcg=dimension of the kernel.
1137 : !! comm=MPI communicator.
1138 : !! [dbg_mode]=Set it to .TRUE. to switch on the debug mode.
1139 : !!
1140 : !! OUTPUT
1141 : !! kxcg(nfft,dim_kxcg) = the exchange-correlation potential on the FFT grid.
1142 : !! warning: the kernel is not divided by unit cell volume
1143 : !!
1144 : !! NOTES
1145 : !! No xc quadrature
1146 : !! No nl core correction
1147 : !!
1148 : !! SOURCE
1149 :
1150 0 : subroutine kxc_ADA(Dtset,Cryst,ixc,ngfft,nfft,nspden,rhor,&
1151 0 : npw,nqibz,qibz,fxc_ADA,gvec,comm,kappa_init,dbg_mode)
1152 :
1153 : !Arguments ------------------------------------
1154 : !scalars
1155 : integer,intent(in) :: ixc,nfft,nspden,npw,comm
1156 : real(dp),intent(in),optional :: kappa_init
1157 : logical,optional,intent(in) :: dbg_mode
1158 : type(crystal_t),intent(in) :: Cryst
1159 : type(dataset_type),intent(in) :: Dtset
1160 : !arrays
1161 : integer,intent(in) :: gvec(3,npw),ngfft(18)
1162 : integer,intent(in) :: nqibz
1163 : real(dp),intent(in) :: rhor(nfft,nspden)
1164 : real(dp),intent(in) :: qibz(3,nqibz)
1165 : complex(gwp),intent(out) :: fxc_ADA(npw,npw,nqibz)
1166 :
1167 : !Local variables ------------------------------
1168 : !scalars
1169 : integer :: i1,i2,i3,ig,igp,ir,irp,n3xccc,ngfft1,ngfft2,izero !,isp
1170 : integer :: ngfft3,nkxc,option,ikxc,ierr,nproc
1171 : integer :: nk3xc,igrid,iqbz,my_rank,master,gmgp_idx
1172 : logical :: non_magnetic_xc
1173 : real(dp) :: el_temp,bigexc,bigsxc,gsqcut,ucvol !,rs,Kx,Kc
1174 : real(dp) :: vxcavg,kappa,abs_qpg_sq,abs_qpgp_sq
1175 : real(dp) :: difx,dify,difz,inv_kappa_sq
1176 : character(len=500) :: msg,fname
1177 0 : type(MPI_type) :: MPI_enreg_seq
1178 : type(xcdata_type) :: xcdata
1179 : !arrays
1180 : real(dp) :: qpg(3),qpgp(3),qphon(3),q_point(3),dum(0)
1181 : real(dp),parameter :: dummyvgeo(3)=zero
1182 0 : real(dp),allocatable :: kxcr(:,:)
1183 0 : real(dp),allocatable :: rhog(:,:),vhartr(:),vxclda(:,:)
1184 0 : real(dp),allocatable :: xccc3d(:),my_rhor(:,:)
1185 0 : real(dp),allocatable :: my_kxcg(:,:)
1186 0 : real(dp),allocatable :: rhotilder(:,:)
1187 0 : complex(gwp),allocatable :: my_fxc_ADA_ggpq(:,:,:)
1188 0 : complex(gwp),allocatable :: FT_fxc_ADA_ggpq(:,:,:),dummy(:,:)
1189 0 : real(dp),allocatable :: rvec(:,:),my_fxc_ADA_rrp(:,:)
1190 : real(dp) :: rmrp(3),abs_rmrp
1191 0 : integer :: n1,n2,n3,ig_idx_fft(npw)
1192 : ! ************************************************************************
1193 :
1194 0 : ABI_CHECK_IEQ(Dtset%nsppol, 1,'nsppol/=1 not coded')
1195 0 : ABI_CHECK_IEQ(nspden, 1, 'nspden /=1 not coded')
1196 0 : ABI_CHECK_IEQ(nfft, PRODUCT(ngfft(1:3)), "mismatch in nfftot")
1197 :
1198 : ! Fake MPI_type for the sequential part.
1199 0 : call initmpi_seq(MPI_enreg_seq)
1200 :
1201 0 : my_rank = xmpi_comm_rank(comm)
1202 0 : nproc = xmpi_comm_size(comm)
1203 0 : master=0
1204 :
1205 0 : write(msg,'(a,i3)') ' kxc_ADA: calculating exchange-correlation kernel using ixc = ',ixc
1206 0 : call wrtout(std_out,msg)
1207 0 : call wrtout(std_out,' kxc_ADA: using smeared density')
1208 :
1209 0 : if (.not.present(kappa_init)) then
1210 0 : kappa = 2.1_dp
1211 : else
1212 0 : kappa = kappa_init
1213 : end if
1214 :
1215 0 : write(msg,'(a,F10.3)') ' kxc_ADA: inverse smearing length, kappa = ',kappa
1216 0 : call wrtout(std_out,msg)
1217 0 : inv_kappa_sq = one/(kappa*kappa)
1218 :
1219 0 : call xcdata_init(xcdata,dtset=dtset,intxc=0,ixc=ixc,nspden=nspden)
1220 :
1221 0 : if (ALL(xcdata%xclevel/=(/1,2/))) then
1222 0 : ABI_ERROR(sjoin("Unsupported xclevel: ", itoa(xcdata%xclevel)))
1223 : end if
1224 :
1225 0 : ngfft1=ngfft(1)
1226 0 : ngfft2=ngfft(2)
1227 0 : ngfft3=ngfft(3)
1228 :
1229 0 : non_magnetic_xc=(abs(dtset%usepawu)==4.or.dtset%usepawu==14)
1230 :
1231 0 : if (ixc>=1.and.ixc<11) then ! LDA case
1232 0 : nkxc= 2*min(Dtset%nspden,2)-1 ! 1 or 3
1233 0 : elseif (ixc==51) then ! TLDA case, same as LDA above
1234 0 : nkxc= 2*min(Dtset%nspden,2)-1
1235 : else ! GGA case
1236 0 : nkxc=12*min(Dtset%nspden,2)-5 ! 7 or 19
1237 0 : ABI_CHECK_IEQ(dtset%xclevel, 2,"Functional should be GGA")
1238 0 : ABI_ERROR("GGA functional not implemented for ADA vertex")
1239 : end if
1240 :
1241 0 : ABI_MALLOC(kxcr,(nfft,nkxc))
1242 :
1243 : !gsqcut and rhog are zeroed because they are not used by rhotoxc if 1<=ixc<=16 and option=0
1244 0 : gsqcut=zero
1245 :
1246 0 : ABI_MALLOC(rhog,(2,nfft))
1247 0 : ABI_MALLOC(vhartr,(nfft))
1248 0 : rhog(:,:)=zero
1249 : !MG FIXME this is the 3D core electron density for XC core correction (bohr^-3)
1250 : !should implement the non linear core correction
1251 0 : n3xccc=0
1252 0 : ABI_MALLOC(xccc3d,(n3xccc))
1253 0 : ABI_MALLOC(vxclda,(nfft,nspden))
1254 :
1255 0 : option=2 ! 2 for Hxc and kxcr (no paramagnetic part if nspden=1)
1256 : qphon(:)=zero
1257 :
1258 : !to be adjusted for the call to rhotoxc
1259 0 : nk3xc=1
1260 :
1261 : !Compute the kernel.
1262 0 : izero=0
1263 :
1264 : ! print density
1265 0 : if (present(dbg_mode)) then
1266 0 : if (dbg_mode.and.my_rank==master) then
1267 0 : fname = 'xc_ADA_den.xsf'
1268 0 : call cryst%write_xsf_data(fname, ngfft1, ngfft2, ngfft3, rhor(:,1))
1269 : end if
1270 : end if
1271 :
1272 : !Calculate the smeared density
1273 0 : ABI_MALLOC(my_rhor,(nfft,nspden))
1274 0 : ABI_MALLOC(rhotilder,(nfft,nspden))
1275 0 : ucvol = Cryst%ucvol
1276 0 : my_rhor = rhor
1277 : !do isp = 1,nsppol
1278 : !call calc_smeared_density(my_rhor(:,isp),1,rhotilder(:,isp),nfft,ngfft,npw,&
1279 : !& gvec,Cryst%gprimd,Cryst%ucvol,MPI_enreg_seq,paral_kgb0,kappa_in=kappa)
1280 : !my_rhor(:,isp) = rhotilder(:,isp)
1281 : !end do
1282 :
1283 : ! print smeared density
1284 0 : if (present(dbg_mode)) then
1285 0 : if (dbg_mode.and.my_rank==master) then
1286 0 : fname = 'xc_ADA_smeared_den.xsf'
1287 0 : call cryst%write_xsf_data(fname, ngfft1, ngfft2, ngfft3, my_rhor(:,1))
1288 : end if
1289 : end if
1290 :
1291 : ! Reinitialize the libxc module with the overridden values
1292 0 : if (dtset%ixc<0) then
1293 0 : call libxc_functionals_end()
1294 : end if
1295 0 : if (ixc<0) then
1296 0 : el_temp=merge(Dtset%tphysel,Dtset%tsmear,Dtset%tphysel>tol8.and.Dtset%occopt/=3.and.Dtset%occopt/=9)
1297 0 : call libxc_functionals_init(ixc,Dtset%nspden,el_temp=el_temp,xc_tb09_c=Dtset%xc_tb09_c)
1298 : end if
1299 :
1300 0 : call hartre(1,gsqcut,3,izero,MPI_enreg_seq,nfft,ngfft,1,zero,rhog,Cryst%rprimd,dummyvgeo,vhartr)
1301 : call rhotoxc(bigexc,bigsxc,kxcr,MPI_enreg_seq,nfft,ngfft,&
1302 : & dum,0,dum,0,nkxc,nk3xc,non_magnetic_xc,&
1303 : & n3xccc,option,my_rhor,Cryst%rprimd,&
1304 0 : & 1,vxclda,vxcavg,xccc3d,xcdata,vhartr=vhartr)
1305 :
1306 : !Check for extreme (NaN) values
1307 : !do ir=1,nfft
1308 : !if (isnan(kxcr(ir,1))) kxcr(ir,1) = HUGE(kxcr(ir,1))
1309 : !end do
1310 :
1311 : !DEBUG test with direct way of calculating Kxc
1312 : !do i1=1,nfft
1313 : !rs = (three/(four_pi*my_rhor(i1,1)))**third
1314 : !Kx = 16._dp/27._dp*0.3141592653589793e1_dp*(rs**2)*(-0.4581652_dp)
1315 : !
1316 : !Kc = -0.4e1_dp / 0.9e1_dp * 0.3141592654e1_dp * rs ** 4 &
1317 : !* (0.207271333333333333333333333333e-1_dp * &
1318 : !(-0.177442658629204480000000e3_dp * rs - 0.17565190511219200000000e2_dp &
1319 : !* sqrt(rs) - 0.1332650665120000e2_dp * rs ** 2 &
1320 : !- 0.51031691247948928000000e2_dp * rs ** (0.3e1_dp / 0.2e1_dp)) &
1321 : !* rs ** (-0.3e1_dp / 0.2e1_dp) / (rs + 0.37274400e1_dp * sqrt(rs) &
1322 : !+ 0.129352000e2_dp) ** 2 / (-sqrt(rs) - 0.1049800_dp) &
1323 : !+ 0.518178333333333333333333333333e-2_dp * rs ** (-0.3e1_dp / 0.2e1_dp) &
1324 : !* (0.617071835390850041282140897280e3_dp * sqrt(rs) &
1325 : !+ 0.659369347307557491857191871552e5_dp * rs ** 2 + &
1326 : !0.700403648491298930017835369562e5_dp * rs ** (0.3e1_dp / 0.2e1_dp) &
1327 : !+ 0.398437532951539263722720308167e5_dp * rs ** (0.5e1_dp / 0.2e1_dp) &
1328 : !+ 0.368852071032531998953472000000e4_dp * rs ** (0.7e1_dp / 0.2e1_dp) &
1329 : !+ 0.5330602660480000e2_dp * rs ** (0.9e1_dp / 0.2e1_dp) &
1330 : !+ 0.143783940386264738593799346176e5_dp * rs ** 3 &
1331 : !+ 0.124672564145568409213848436081e5_dp * rs &
1332 : !+ 0.557398029956167136000000e3_dp * rs ** 4) &
1333 : !/ (rs + 0.37274400e1_dp * sqrt(rs) + 0.129352000e2_dp) ** 4 &
1334 : !/ (-sqrt(rs) - 0.1049800_dp) ** 2)
1335 : !kxcr(i1,1) = Kx + Kc
1336 : !end do
1337 : !END DEBUG
1338 :
1339 : ! print Kxc
1340 0 : if (present(dbg_mode)) then
1341 0 : if (dbg_mode.and.my_rank==master) then
1342 0 : fname = 'xc_ADA_Kxc.xsf'
1343 0 : call cryst%write_xsf_data(fname, ngfft1, ngfft2, ngfft3, kxcr(:,1))
1344 : end if
1345 : end if
1346 :
1347 0 : ABI_FREE(xccc3d)
1348 0 : ABI_FREE(vxclda)
1349 0 : ABI_FREE(vhartr)
1350 :
1351 0 : ABI_MALLOC(my_kxcg,(2,nfft))
1352 :
1353 0 : do ikxc=1,nkxc
1354 0 : call fourdp(1,my_kxcg,kxcr(:,ikxc),-1,MPI_enreg_seq,nfft,1,ngfft,0)
1355 : !kxcg(:,ikxc)=CMPLX(my_kxcg(1,:),my_kxcg(2,:))
1356 : end do
1357 : !TODO Check symmetry of kxcg
1358 :
1359 : !set up ADA vertex
1360 0 : ABI_MALLOC(my_fxc_ADA_ggpq,(npw,npw,nqibz))
1361 0 : my_fxc_ADA_ggpq = czero
1362 :
1363 : !Calculate f_xc(R,R')=(kappa^2/2)K_xc[\tilde{n}](G-G')
1364 : !x(1/(kappa^2+|q+G|^2) + 1/(kappa^2+|q+G'|^2
1365 : !First get G vectors and indices
1366 :
1367 0 : ierr=0
1368 0 : do iqbz=1,nqibz
1369 0 : q_point(:) = qibz(:,iqbz)
1370 0 : do ig=1,npw
1371 0 : do igp=1,npw
1372 : ! Calculate |q+G| and |q+G'|
1373 0 : qpg(:) = two_pi*MATMUL(Cryst%gprimd,q_point(:)+gvec(:,ig))
1374 0 : qpgp(:) = two_pi*MATMUL(Cryst%gprimd,q_point(:)+gvec(:,igp))
1375 0 : abs_qpg_sq = 1.0_dp/(1.0_dp+dot_product(qpg,qpg)*inv_kappa_sq)
1376 0 : abs_qpgp_sq = 1.0_dp/(1.0_dp+dot_product(qpgp,qpgp)*inv_kappa_sq)
1377 :
1378 0 : gmgp_idx = g2ifft(gvec(:,ig)-gvec(:,igp),ngfft)
1379 0 : if (gmgp_idx>0) then
1380 0 : my_fxc_ADA_ggpq(ig,igp,iqbz) = half*CMPLX(my_kxcg(1,gmgp_idx), my_kxcg(2,gmgp_idx))*(abs_qpg_sq+abs_qpgp_sq)
1381 : else
1382 0 : ierr=ierr+1
1383 0 : my_fxc_ADA_ggpq(ig,igp,iqbz) = czero
1384 : end if
1385 : end do
1386 : end do
1387 0 : if (ierr/=0) then
1388 : write(msg,'(a,i4,3a)')&
1389 0 : ' Found ',ierr,' G1-G2 vectors falling outside the FFT box. ',ch10,&
1390 0 : ' Enlarge the FFT mesh to get rid of this problem. '
1391 0 : ABI_WARNING(msg)
1392 : end if
1393 : end do
1394 :
1395 0 : fxc_ADA = my_fxc_ADA_ggpq
1396 :
1397 : !do iqbz=1,nqibz
1398 : !call hermitianize(my_fxc_ADA_ggpq(:,:,iqbz),"All")
1399 : !end do
1400 :
1401 : !DEBUG check symmetry
1402 : if (.FALSE.) then
1403 : ! do iqbz=1,nkptgw
1404 : ! do ig=1,npw
1405 : ! do igp=ig,npw
1406 : ! if (ABS(REAL(fxc_ADA(ig,igp,iqbz))-REAL(fxc_ADA(igp,ig,iqbz)))>tol15.OR.&
1407 : ! ABS(AIMAG(fxc_ADA(ig,igp,iqbz))-AIMAG(-fxc_ADA(igp,ig,iqbz)))>tol15) then
1408 : ! write(std_out,*) 'Elements:'
1409 : ! write(std_out,*) 'fxc_ADA(ig,igp,iqbz):',ig,igp,iqbz,fxc_ADA(ig,igp,iqbz)
1410 : ! write(std_out,*) 'fxc_ADA(igp,ig,iqbz):',igp,ig,iqbz,fxc_ADA(igp,ig,iqbz)
1411 : ! ABI_ERROR('fxc_ADA not symmetric')
1412 : ! end if
1413 : ! end do
1414 : ! end do
1415 : ! end do
1416 :
1417 : ! write(std_out,*)"kxcr(r=0)",kxcr(1,1)
1418 : ! write(std_out,*)"my_kxg(G=0)",my_kxcg(:,1)
1419 : ! write(std_out,*)"SUM kxcr/nfft ",SUM(kxcr(:,1))/nfft
1420 : ! write(std_out,*)"SUM my_kxg ",SUM(kxcg(:,1))
1421 :
1422 : ! DEBUG Check FT to real space
1423 : ! The real-space expression is:
1424 : ! f_xc(R,R')=(1/2)(kappa^2/(4*Pi))
1425 : ! \{K_xc[\tilde{n(R)}]+K_xc[\tilde{n(R')}]\}
1426 : ! x exp(-kappa|R-R'|)/|R-R'|
1427 : ABI_MALLOC(my_fxc_ADA_rrp,(nfft,nfft))
1428 : ABI_MALLOC(FT_fxc_ADA_ggpq,(npw,npw,nqibz))
1429 : ABI_MALLOC(rvec,(3,nfft))
1430 : ABI_MALLOC(dummy,(nfft,nfft))
1431 : my_fxc_ADA_rrp=zero; FT_fxc_ADA_ggpq=czero; dummy=czero; rvec=zero
1432 :
1433 : ! First find coordinates of real-space fft points
1434 : igrid = 0
1435 : ngfft1 = ngfft(1)
1436 : ngfft2 = ngfft(2)
1437 : ngfft3 = ngfft(3)
1438 : do i3=0,ngfft3-1
1439 : difz=dble(i3)/dble(ngfft3)
1440 : do i2=0,ngfft2-1
1441 : dify=dble(i2)/dble(ngfft2)
1442 : do i1=0,ngfft1-1
1443 : difx=dble(i1)/dble(ngfft1)
1444 : igrid = igrid + 1
1445 : rvec(1,igrid)=difx*Cryst%rprimd(1,1)+dify*Cryst%rprimd(1,2)+difz*Cryst%rprimd(1,3)
1446 : rvec(2,igrid)=difx*Cryst%rprimd(2,1)+dify*Cryst%rprimd(2,2)+difz*Cryst%rprimd(2,3)
1447 : rvec(3,igrid)=difx*Cryst%rprimd(3,1)+dify*Cryst%rprimd(3,2)+difz*Cryst%rprimd(3,3)
1448 : end do
1449 : end do
1450 : end do
1451 : if (igrid/=nfft) then
1452 : ABI_ERROR('kxc_ADA: igrid not equal to nfft')
1453 : end if
1454 :
1455 : ! Construct kernel in real space
1456 : do ir=1,nfft
1457 : do irp=ir,nfft
1458 : rmrp(:) = rvec(:,ir)-rvec(:,irp)
1459 : abs_rmrp = sqrt(dot_product(rmrp,rmrp))
1460 : my_fxc_ADA_rrp(ir,irp) = eighth*kappa*kappa*piinv* &
1461 : (kxcr(ir,1)+kxcr(irp,1))* &
1462 : EXP(-kappa*abs_rmrp)/(abs_rmrp+1.e-3_dp)
1463 : ! (a small convergence factor is introduced
1464 : ! to avoid a singularity)
1465 : my_fxc_ADA_rrp(irp,ir) = my_fxc_ADA_rrp(ir,irp)
1466 : end do
1467 : end do
1468 :
1469 : ! Find FFT index for all G
1470 : n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
1471 : ! Use the following indexing (N means ngfft of the adequate direction)
1472 : ! 0 1 2 3 ... N/2 -(N-1)/2 ... -1 <= kg
1473 : ! 1 2 3 4 ....N/2+1 N/2+2 ... N <= index
1474 : do ig=1,npw
1475 : i1=modulo(gvec(1,ig),n1)
1476 : i2=modulo(gvec(2,ig),n2)
1477 : i3=modulo(gvec(3,ig),n3)
1478 : ig_idx_fft(ig)=i1+1+n1*(i2+n2*i3)
1479 : end do
1480 : ! FT kernel to reciprocal space for each q
1481 : do iqbz=1,nqibz
1482 : dummy = CMPLX(my_fxc_ADA_rrp,0.0_dp)
1483 : ! Multiply with q-point phase factors exp(-iq.r)*f_xc(r,r')*exp(iq.r')
1484 : do ir=1,nfft
1485 : do irp=1,nfft
1486 : ! Calculate q (variables defined for other purposes
1487 : ! are being reused as dummy variables)
1488 : q_point(:) = qibz(:,iqbz)
1489 : qpg(:) = two_pi*MATMUL(Cryst%gprimd,q_point(:))
1490 : abs_qpg_sq = dot_product(qpg(:),rvec(:,ir))
1491 : abs_qpgp_sq = dot_product(qpg(:),rvec(:,irp))
1492 : dummy(ir,irp) = EXP(-j_dpc*abs_qpg_sq) * dummy(ir,irp)* EXP(j_dpc*abs_qpgp_sq)
1493 : end do
1494 : end do
1495 :
1496 : call fourdp_6d(2,dummy,-1,MPI_enreg_seq,nfft,ngfft, 0)
1497 :
1498 : do ig=1,npw
1499 : do igp=1,npw
1500 : FT_fxc_ADA_ggpq(ig,igp,iqbz) = dummy(ig_idx_fft(ig),ig_idx_fft(igp))
1501 : end do
1502 : end do
1503 :
1504 : ! Output
1505 : msg=''
1506 : if (iqbz<10) write(msg,'(a,i1,a)') './debug_fxc_ADA_q',iqbz,'.dat'
1507 : if ((iqbz>9).and.(iqbz<100)) write(msg,'(a,i2,a)') './debug_fxc_ADA_q',iqbz,'.dat'
1508 : if ((iqbz>99).and.(iqbz<1000)) write(msg,'(a,i3,a)') './debug_fxc_ADA_q',iqbz,'.dat'
1509 :
1510 : !open(777,file=TRIM(msg),STATUS='REPLACE')
1511 : !do igp=1,npw
1512 : ! do ig=1,npw
1513 : ! write(777,*) ig,igp,REAL(my_fxc_ADA_ggpq(ig,igp,iqbz)),AIMAG(my_fxc_ADA_ggpq(ig,igp,iqbz)), &
1514 : ! REAL(FT_fxc_ADA_ggpq(ig,igp,iqbz)),AIMAG(FT_fxc_ADA_ggpq(ig,igp,iqbz)), &
1515 : ! ABS(ABS(my_fxc_ADA_ggpq(ig,igp,iqbz))-ABS(FT_fxc_ADA_ggpq(ig,igp,iqbz)))
1516 : ! end do
1517 : ! write(777,*) ''
1518 : !end do
1519 : !close(777)
1520 :
1521 : end do ! iqbz
1522 :
1523 : ABI_ERROR('Stopping in kxc_ADA for debugging')
1524 :
1525 : ABI_FREE(rvec)
1526 : ABI_FREE(my_fxc_ADA_rrp)
1527 : ABI_FREE(FT_fxc_ADA_ggpq)
1528 :
1529 : if (xcdata%xclevel==2) then
1530 : ABI_ERROR(" GGA not implemented for kxc_ADA")
1531 : end if !xclevel==2
1532 :
1533 : end if ! Debugging section
1534 :
1535 : ! Revert libxc module to the original settings
1536 0 : if (ixc<0) then
1537 0 : call libxc_functionals_end()
1538 : end if
1539 0 : if (dtset%ixc<0) then
1540 0 : el_temp=merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
1541 0 : call libxc_functionals_init(dtset%ixc,dtset%nspden,el_temp=el_temp,xc_tb09_c=dtset%xc_tb09_c)
1542 : end if
1543 :
1544 0 : ABI_FREE(my_kxcg)
1545 0 : ABI_FREE(my_rhor)
1546 0 : ABI_FREE(rhotilder)
1547 0 : ABI_FREE(rhog)
1548 0 : ABI_FREE(kxcr)
1549 :
1550 0 : call destroy_mpi_enreg(MPI_enreg_seq)
1551 :
1552 0 : end subroutine kxc_ADA
1553 : !!***
1554 :
1555 : !----------------------------------------------------------------------
1556 :
1557 : end MODULE m_kxc
|