LCOV - code coverage report
Current view: top level - src/56_xc - m_kxc.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 12.5 % 433 54
Test Date: 2026-09-21 22:40:37 Functions: 14.3 % 7 1

            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
        

Generated by: LCOV version 2.3-1