LCOV - code coverage report
Current view: top level - src/72_response - m_dfpt_mkvxcstr.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.9 % 158 142
Test Date: 2026-09-21 22:40:37 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !!****m* ABINIT/m_dfpt_mkvxcstr
       2              : !! NAME
       3              : !!  m_dfpt_mkvxcstr
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2001-2026 ABINIT group (DRH,XG)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_dfpt_mkvxcstr
      23              : 
      24              :  use defs_basis
      25              :  use m_errors
      26              :  use m_abicore
      27              : 
      28              :  use defs_abitypes, only : MPI_type
      29              :  use m_time,      only : timab
      30              :  use m_matrix,    only : matr3inv
      31              :  use m_xctk,      only : xcden, xcpot
      32              : 
      33              :  implicit none
      34              : 
      35              :  private
      36              : !!***
      37              : 
      38              :  public :: dfpt_mkvxcstr
      39              : !!***
      40              : 
      41              : contains
      42              : !!***
      43              : 
      44              : !!****f* ABINIT/dfpt_mkvxcstr
      45              : !! NAME
      46              : !! dfpt_mkvxcstr
      47              : !!
      48              : !! FUNCTION
      49              : !! Compute the first-order change of exchange-correlation potential
      50              : !! due to strain: assemble the first-order density change with the
      51              : !! frozen-core density change, then use the exchange-correlation kernel.
      52              : !!
      53              : !! INPUTS
      54              : !!  cplex= if 1, real space 1-order functions on FFT grid are REAL, if 2, COMPLEX
      55              : !!  idir=direction of the current perturbation
      56              : !!  ipert=type of the perturbation
      57              : !!  kxc(nfft,nkxc)=exchange and correlation kernel (see rhotoxc.f)
      58              : !!  mpi_enreg=information about MPI parallelization
      59              : !!  natom=number of atoms in cell.
      60              : !!  nfft=(effective) number of FFT grid points (for this processor)
      61              : !!  ngfft(18)=contain all needed information about 3D FFT,
      62              : !!     see ~abinit/doc/variables/vargs.htm#ngfft
      63              : !!  nhat(nfft,nspden*nhatdim)= -PAW only- compensation density
      64              : !!  nhat1(cplex*nfft,2nspden*usepaw)= -PAW only- 1st-order compensation density
      65              : !!  nkxc=second dimension of the kxc array
      66              : !!  non_magnetic_xc= if true, handle density/potential as non-magnetic (even if it is)
      67              : !!  nspden=number of spin-density components
      68              : !!  n3xccc=dimension of xccc3d1 ; 0 if no XC core correction is used, otherwise, nfft
      69              : !!  option=if 0, work only with strain-derivative frozen-wavefunction
      70              : !!    charge and the XC core-correction,
      71              : !!   if 1, treat both density change and XC core correction
      72              : !!   if 2, like 0 but multiply gradient strain derivative term by 2.0 for GGA.
      73              : !!  qphon(3)=reduced coordinates for the phonon wavelength (needed if cplex==2).
      74              : !!  rhor(nfft,nspden)=array for GS electron density in electrons/bohr**3.
      75              : !!  rhor1(cplex*nfft,nspden)=array for electron density in electrons/bohr**3.
      76              : !!  rprimd(3,3)=dimensional primitive translations in real space (bohr)
      77              : !!  usepaw= 0 for non paw calculation; =1 for paw calculation
      78              : !!  usexcnhat= -PAW only- flag controling use of compensation density in Vxc
      79              : !!  xccc3d1(cplex*n3xccc)=3D change in core charge density, see n3xccc
      80              : !!
      81              : !! OUTPUT
      82              : !!  vxc1(cplex*nfft,nspden)=change in exchange-correlation potential (including
      83              : !!   core-correction, if applicable)
      84              : !!
      85              : !! SOURCE
      86              : 
      87         3109 : subroutine dfpt_mkvxcstr(cplex,idir,ipert,kxc,mpi_enreg,natom,nfft,ngfft,nhat,nhat1,&
      88              : &                        nkxc,non_magnetic_xc,nspden,n3xccc,option,qphon,&
      89         3109 : &                        rhor,rhor1,rprimd,usepaw,usexcnhat,vxc1,xccc3d1)
      90              : 
      91              : !Arguments ------------------------------------
      92              : !scalars
      93              :  integer,intent(in) :: cplex,idir,ipert,n3xccc,natom,nfft,nkxc,nspden,option
      94              :  integer,intent(in) :: usepaw,usexcnhat
      95              :  logical,intent(in) :: non_magnetic_xc
      96              :  type(MPI_type),intent(in) :: mpi_enreg
      97              : !arrays
      98              :  integer,intent(in) :: ngfft(18)
      99              :  real(dp),target,intent(in) :: nhat(nfft,nspden)
     100              :  real(dp),target,intent(in) :: nhat1(cplex*nfft,nspden)
     101              :  real(dp),intent(in) :: kxc(nfft,nkxc),qphon(3)
     102              :  real(dp),target,intent(in) :: rhor(nfft,nspden),rhor1(cplex*nfft,nspden)
     103              :  real(dp),intent(in) :: rprimd(3,3)
     104              :  real(dp),intent(in) :: xccc3d1(cplex*n3xccc)
     105              :  real(dp),intent(out) :: vxc1(cplex*nfft,nspden)
     106              : 
     107              : !Local variables-------------------------------
     108              : !scalars
     109              :  integer :: ii,ir,istr
     110              :  real(dp) :: rho1_dn,rho1_up,spin_scale,str_scale
     111              :  character(len=500) :: message
     112              : !arrays
     113              :  real(dp) :: gprimd(3,3),tsec(2)
     114         3109 :  real(dp),allocatable :: rhor1tmp(:,:),rhowk1(:,:)
     115         3109 :  real(dp),pointer :: rhor_(:,:),rhor1_(:,:)
     116              : 
     117              : ! *************************************************************************
     118              : 
     119         3109 :  call timab(181,1,tsec)
     120              : 
     121         3109 :  if(nspden/=1 .and. nspden/=2) then
     122            0 :    message = ' dfpt_mkvxc, Only for nspden==1 and 2.'
     123            0 :    ABI_BUG(message)
     124              :  end if
     125              : 
     126         3109 :  if (usepaw==1.and.usexcnhat==0) then
     127         1032 :    ABI_MALLOC(rhor_,(nfft,nspden))
     128      5064048 :    rhor_(:,:)=rhor(:,:)-nhat(:,:)
     129              :  else
     130         2851 :    rhor_ => rhor
     131              :  end if
     132              : 
     133         3109 :  if (usepaw==1.and.usexcnhat==0.and.option==1) then
     134           48 :    ABI_MALLOC(rhor1_,(nfft,nspden))
     135       186672 :    rhor1_(:,:)=rhor1(:,:)-nhat1(:,:)
     136              :  else
     137         3097 :    rhor1_ => rhor1
     138              :  end if
     139              : 
     140              : !Inhomogeneous term for diagonal strain
     141        12436 :  ABI_MALLOC(rhowk1,(nfft,nspden))
     142         3109 :  if(option==0 .or. option==2) then
     143         2941 :    if(ipert==natom+3) then
     144     10661975 :      rhowk1(:,:)=-rhor_(:,:)
     145              :    else
     146      9771286 :      rhowk1(:,:)=zero
     147              :    end if
     148          168 :  else if(option==1) then
     149          168 :    if(ipert==natom+3) then
     150       535475 :      rhowk1(:,:)=rhor1_(:,:)-rhor_(:,:)
     151              :    else
     152       520016 :      rhowk1(:,:)=rhor1_(:,:)
     153              :    end if
     154              :  end if
     155              : 
     156         3109 :  if (non_magnetic_xc) then
     157            0 :    if(nspden==2) rhowk1(:,2)=rhowk1(:,1)*half
     158            0 :    if(nspden==4) rhowk1(:,2:4)=zero
     159              :  end if
     160              : 
     161              : !Treat first LDA
     162         3109 :  if(nkxc==1.or.nkxc==3)then
     163              : 
     164              : !  Case without non-linear core correction
     165         2829 :    if(n3xccc==0)then
     166              : 
     167              : !    Non-spin-polarized
     168          417 :      if(nspden==1)then
     169      2094701 :        do ir=1,nfft
     170      2094701 :          vxc1(ir,1)=kxc(ir,1)*rhowk1(ir,1)
     171              :        end do
     172              : 
     173              : !      Spin-polarized
     174              :      else
     175            0 :        do ir=1,nfft
     176            0 :          rho1_dn=rhowk1(ir,1)-rhowk1(ir,2)
     177            0 :          vxc1(ir,1)=kxc(ir,1)*rhowk1(ir,2)+kxc(ir,2)*rho1_dn
     178            0 :          vxc1(ir,2)=kxc(ir,2)*rhowk1(ir,2)+kxc(ir,3)*rho1_dn
     179              :        end do
     180              :      end if ! nspden==1
     181              : 
     182              : !    Treat case with non-linear core correction
     183              :    else
     184         2412 :      if(nspden==1)then
     185     17308565 :        do ir=1,nfft
     186     17308565 :          vxc1(ir,1)=kxc(ir,1)*(rhowk1(ir,1)+xccc3d1(ir))
     187              :        end do
     188              :      else
     189       425809 :        do ir=1,nfft
     190       425736 :          rho1_dn=rhowk1(ir,1)-rhowk1(ir,2) + xccc3d1(ir)*half
     191       425736 :          rho1_up=rhowk1(ir,2)              + xccc3d1(ir)*half
     192       425736 :          vxc1(ir,1)=kxc(ir,1)*rho1_up+kxc(ir,2)*rho1_dn
     193       425809 :          vxc1(ir,2)=kxc(ir,2)*rho1_up+kxc(ir,3)*rho1_dn
     194              :        end do
     195              :      end if ! nspden==1
     196              : 
     197              :    end if ! n3xccc==0
     198              : 
     199              : !  Treat GGA
     200          280 :  else if (nkxc==7.or.nkxc==19) then
     201              : 
     202              : !  Generates gprimd and its strain derivative
     203              : !  Note that unlike the implicitly symmetric metric tensor strain
     204              : !  derivatives, we must explicltly symmetrize the strain derivative
     205              : !  here.
     206          280 :    call matr3inv(rprimd,gprimd)
     207          280 :    istr=idir + 3*(ipert-natom-3)
     208          280 :    if(istr<1 .or. istr>6)then
     209              :      write(message, '(a,i10,a,a,a)' )&
     210            0 : &     'Input dir gives istr=',istr,' not allowed.',ch10,&
     211            0 : &     'Possible values are 1,2,3,4,5,6 only.'
     212            0 :      ABI_BUG(message)
     213              :    end if
     214              : 
     215              : !  Rescalling needed for use in dfpt_eltfrxc for elastic tensor (not internal strain tensor).
     216          280 :    str_scale=one;if(option==2) str_scale=two
     217              : 
     218              : !  Transfer the data to spin-polarized storage
     219         1120 :    ABI_MALLOC(rhor1tmp,(cplex*nfft,nspden))
     220          280 :    if(nspden==1)then
     221       892445 :      do ir=1,cplex*nfft
     222       892445 :        rhor1tmp(ir,1)=rhowk1(ir,1)
     223              :      end do
     224              :    else
     225       169157 :      do ir=1,cplex*nfft
     226       169128 :        rho1_dn=rhowk1(ir,1)-rhowk1(ir,2)
     227       169128 :        rhor1tmp(ir,1)=rhowk1(ir,2)
     228       169157 :        rhor1tmp(ir,2)=rho1_dn
     229              :      end do
     230              :    end if ! nspden==1
     231          280 :    if(n3xccc/=0)then
     232           77 :      spin_scale=one;if (nspden==2) spin_scale=half
     233          183 :      do ii=1,nspden
     234       757383 :        do ir=1,cplex*nfft
     235       757306 :          rhor1tmp(ir,ii)=rhor1tmp(ir,ii)+xccc3d1(ir)*spin_scale
     236              :        end do
     237              :      end do
     238              :    end if
     239              : 
     240              :    call dfpt_mkvxcstrgga(cplex,gprimd,istr,kxc,mpi_enreg,nfft,ngfft,nkxc,&
     241          280 : &   nspden,qphon,rhor1tmp,str_scale,vxc1)
     242          280 :    ABI_FREE(rhor1tmp)
     243              : 
     244              :  else
     245            0 :    ABI_BUG('Invalid nkxc!')
     246              : 
     247              :  end if ! LDA or GGA
     248              : 
     249         3109 :  if (usepaw==1.and.usexcnhat==0) then
     250          258 :    ABI_FREE(rhor_)
     251              :  end if
     252         3109 :  if (usepaw==1.and.usexcnhat==0.and.option==1) then
     253           12 :    ABI_FREE(rhor1_)
     254              :  end if
     255              : 
     256         3109 :  ABI_FREE(rhowk1)
     257              : 
     258         3109 :  call timab(181,2,tsec)
     259              : 
     260         3109 : end subroutine dfpt_mkvxcstr
     261              : !!***
     262              : 
     263              : !!****f* ABINIT/dfpt_mkvxcstrgga
     264              : !! NAME
     265              : !! dfpt_mkvxcstrgga
     266              : !!
     267              : !! FUNCTION
     268              : !! Compute the first-order change of exchange-correlation potential
     269              : !! for the strain perturbation in case of GGA functionals
     270              : !! Use the exchange-correlation kernel.
     271              : !!
     272              : !! INPUTS
     273              : !!  cplex= if 1, real space 1-order functions on FFT grid are REAL,
     274              : !!    if 2, COMPLEX
     275              : !!  gprimd(3,3)=dimensional primitive translations in reciprocal space (bohr^-1)
     276              : !!  istr=index of the strain perturbation (1..6)
     277              : !!  kxc(nfft,nkxc)=exchange and correlation kernel (see rhotoxc.f)
     278              : !!  mpi_enreg=information about MPI parallelization
     279              : !!  nfft=(effective) number of FFT grid points (for this processor)
     280              : !!  ngfft(18)=contain all needed information about 3D FFT,
     281              : !!    see ~abinit/doc/variables/vargs.htm#ngfft
     282              : !!  nkxc=second dimension of the kxc array
     283              : !!  nspden=number of spin-density components
     284              : !!  qphon(3)=reduced coordinates for the phonon wavelength (needed if cplex==2).
     285              : !!  rhor1tmp(cplex*nfft,2)=array for first-order electron spin-density
     286              : !!   in electrons/bohr**3 (second index corresponds to spin-up and spin-down)
     287              : !!  str_scale=scaling factor for gradient operator strain-derivative (1. or 2.)
     288              : !!
     289              : !! OUTPUT
     290              : !!  vxc1(cplex*nfft,nspden)=change in exchange-correlation potential
     291              : !!
     292              : !! NOTES
     293              : !!  Closely related to dfpt_mkvxcgga.
     294              : !!  Content of Kxc array:
     295              : !!   ===== if GGA
     296              : !!    if nspden==1:
     297              : !!       kxc(:,1)= d2Exc/drho2
     298              : !!       kxc(:,2)= 1/|grad(rho)| dExc/d|grad(rho)|
     299              : !!       kxc(:,3)= 1/|grad(rho)| d2Exc/d|grad(rho)| drho
     300              : !!       kxc(:,4)= 1/|grad(rho)| * d/d|grad(rho)| ( 1/|grad(rho)| dExc/d|grad(rho)| )
     301              : !!       kxc(:,5)= gradx(rho)
     302              : !!       kxc(:,6)= grady(rho)
     303              : !!       kxc(:,7)= gradz(rho)
     304              : !!    if nspden>=2:
     305              : !!       kxc(:,1)= d2Exc/drho_up drho_up
     306              : !!       kxc(:,2)= d2Exc/drho_up drho_dn
     307              : !!       kxc(:,3)= d2Exc/drho_dn drho_dn
     308              : !!       kxc(:,4)= 1/|grad(rho_up)| dEx/d|grad(rho_up)|
     309              : !!       kxc(:,5)= 1/|grad(rho_dn)| dEx/d|grad(rho_dn)|
     310              : !!       kxc(:,6)= 1/|grad(rho_up)| d2Ex/d|grad(rho_up)| drho_up
     311              : !!       kxc(:,7)= 1/|grad(rho_dn)| d2Ex/d|grad(rho_dn)| drho_dn
     312              : !!       kxc(:,8)= 1/|grad(rho_up)| * d/d|grad(rho_up)| ( 1/|grad(rho_up)| dEx/d|grad(rho_up)| )
     313              : !!       kxc(:,9)= 1/|grad(rho_dn)| * d/d|grad(rho_dn)| ( 1/|grad(rho_dn)| dEx/d|grad(rho_dn)| )
     314              : !!       kxc(:,10)=1/|grad(rho)| dEc/d|grad(rho)|
     315              : !!       kxc(:,11)=1/|grad(rho)| d2Ec/d|grad(rho)| drho_up
     316              : !!       kxc(:,12)=1/|grad(rho)| d2Ec/d|grad(rho)| drho_dn
     317              : !!       kxc(:,13)=1/|grad(rho)| * d/d|grad(rho)| ( 1/|grad(rho)| dEc/d|grad(rho)| )
     318              : !!       kxc(:,14)=gradx(rho_up)
     319              : !!       kxc(:,15)=gradx(rho_dn)
     320              : !!       kxc(:,16)=grady(rho_up)
     321              : !!       kxc(:,17)=grady(rho_dn)
     322              : !!       kxc(:,18)=gradz(rho_up)
     323              : !!       kxc(:,19)=gradz(rho_dn)
     324              : !!
     325              : !! SOURCE
     326              : 
     327          280 : subroutine dfpt_mkvxcstrgga(cplex,gprimd,istr,kxc,mpi_enreg,nfft,ngfft,&
     328          280 : & nkxc,nspden,qphon,rhor1tmp,str_scale,vxc1)
     329              : 
     330              : !Arguments ------------------------------------
     331              : !scalars
     332              :  integer,intent(in) :: cplex,istr,nfft,nkxc,nspden
     333              :  real(dp) :: str_scale
     334              :  type(MPI_type),intent(in) :: mpi_enreg
     335              : !arrays
     336              :  integer,intent(in) :: ngfft(18)
     337              :  real(dp),intent(in) :: gprimd(3,3),kxc(nfft,nkxc)
     338              :  real(dp),intent(in) :: qphon(3),rhor1tmp(cplex*nfft,2)
     339              :  real(dp),intent(out) :: vxc1(cplex*nfft,nspden)
     340              : !Local variables-------------------------------
     341              : !scalars
     342              :  integer :: ii,ir,ishift,ispden,mgga,ngrad,nspgrad
     343              :  real(dp) :: coeff_grho,coeff_grho_corr,coeff_grho_dn,coeff_grho_up
     344              :  real(dp) :: gradrho_gradrho1,gradrho_gradrho1_dn,gradrho_gradrho1_up
     345              :  character(len=500) :: msg
     346              : !arrays
     347              :  real(dp) :: r0(3),r0_dn(3),r0_up(3),r1(3),r1_dn(3),r1_up(3)
     348          280 :  real(dp),allocatable :: dnexcdn(:,:),rho1now(:,:,:),rhodgnow(:,:,:)
     349              : 
     350              : ! *************************************************************************
     351              : 
     352              :  DBG_ENTER("COLL")
     353              : 
     354          280 :  if (nkxc/=12*min(nspden,2)-5) then
     355            0 :    msg='Wrong nkxc value for GGA!'
     356            0 :    ABI_BUG(msg)
     357              :  end if
     358          280 :  if (nspden>2) then
     359            0 :    msg='Not compatible with non-collinear magnetism!'
     360            0 :    ABI_ERROR(msg)
     361              :  end if
     362              : 
     363              : !metaGGA contributions are not taken into account here
     364          280 :  mgga=0
     365              : 
     366              : !if you uncomment the following line, you will have to modify
     367              : !the original function call to pass in gmet and gsqcut
     368              : !call filterpot(cplex,gmet,gsqcut,nfft,ngfft,2,qphon,rhor1tmp)
     369              : 
     370              : !Compute the gradients of the first-order density
     371              : !rho1now(:,:,1) contains the first-order density, and
     372              : !rho1now(:,:,2:4) contains the gradients of the first-order density
     373          280 :  ishift=0 ; ngrad=2
     374         1400 :  ABI_MALLOC(rho1now,(cplex*nfft,nspden,ngrad*ngrad))
     375          280 :  call xcden(cplex,gprimd,ishift,mpi_enreg,nfft,ngfft,ngrad,nspden,qphon,rhor1tmp,rho1now)
     376              : 
     377              : !Calculate the 1st-order contribution to grad(n) from the strain derivative
     378              : !  acting on the gradient operator acting on the GS charge density,
     379              : !Simply use the following formula:
     380              : !   (dGprim/ds_alpha_beta)(i,j) = -half.( delta_alpha,i Gprim(beta,j) + delta_beta,i Gprim(alpha,j) )
     381              : !To finally get:
     382              : !   (nabla)^(alpha,beta)_i[n] = -half ( delta_alpha,i nabla_beta[n] + delta_beta,i nabla_alpha[n] )
     383         1400 :  ABI_MALLOC(rhodgnow,(cplex*nfft,nspden,3))
     384      3693397 :  rhodgnow(1:nfft,1:nspden,1:3)=zero
     385          280 :  if (nspden==1) then
     386       197200 :    if (istr==1) rhodgnow(1:nfft,1,1)=-     kxc(1:nfft,5)
     387       126700 :    if (istr==2) rhodgnow(1:nfft,1,2)=-     kxc(1:nfft,6)
     388       125200 :    if (istr==3) rhodgnow(1:nfft,1,3)=-     kxc(1:nfft,7)
     389       197200 :    if (istr==4) rhodgnow(1:nfft,1,2)=-half*kxc(1:nfft,7)
     390       197200 :    if (istr==4) rhodgnow(1:nfft,1,3)=-half*kxc(1:nfft,6)
     391       123700 :    if (istr==5) rhodgnow(1:nfft,1,1)=-half*kxc(1:nfft,7)
     392       123700 :    if (istr==5) rhodgnow(1:nfft,1,3)=-half*kxc(1:nfft,5)
     393       123700 :    if (istr==6) rhodgnow(1:nfft,1,1)=-half*kxc(1:nfft,6)
     394       123700 :    if (istr==6) rhodgnow(1:nfft,1,2)=-half*kxc(1:nfft,5)
     395              :  else
     396        17525 :    if (istr==1) rhodgnow(1:nfft,1,1)=-     kxc(1:nfft,15)
     397        17525 :    if (istr==2) rhodgnow(1:nfft,1,2)=-     kxc(1:nfft,17)
     398        17525 :    if (istr==3) rhodgnow(1:nfft,1,3)=-     kxc(1:nfft,19)
     399        81677 :    if (istr==4) rhodgnow(1:nfft,1,2)=-half*kxc(1:nfft,19)
     400        81677 :    if (istr==4) rhodgnow(1:nfft,1,3)=-half*kxc(1:nfft,17)
     401        17525 :    if (istr==5) rhodgnow(1:nfft,1,1)=-half*kxc(1:nfft,19)
     402        17525 :    if (istr==5) rhodgnow(1:nfft,1,3)=-half*kxc(1:nfft,15)
     403        17525 :    if (istr==6) rhodgnow(1:nfft,1,1)=-half*kxc(1:nfft,17)
     404        17525 :    if (istr==6) rhodgnow(1:nfft,1,2)=-half*kxc(1:nfft,15)
     405        17525 :    if (istr==1) rhodgnow(1:nfft,2,1)=-     (kxc(1:nfft,14)-kxc(1:nfft,15))
     406        17525 :    if (istr==2) rhodgnow(1:nfft,2,2)=-     (kxc(1:nfft,16)-kxc(1:nfft,17))
     407        17525 :    if (istr==3) rhodgnow(1:nfft,2,3)=-     (kxc(1:nfft,18)-kxc(1:nfft,19))
     408        81677 :    if (istr==4) rhodgnow(1:nfft,2,2)=-half*(kxc(1:nfft,18)-kxc(1:nfft,19))
     409        81677 :    if (istr==4) rhodgnow(1:nfft,2,3)=-half*(kxc(1:nfft,16)-kxc(1:nfft,17))
     410        17525 :    if (istr==5) rhodgnow(1:nfft,2,1)=-half*(kxc(1:nfft,18)-kxc(1:nfft,19))
     411        17525 :    if (istr==5) rhodgnow(1:nfft,2,3)=-half*(kxc(1:nfft,14)-kxc(1:nfft,15))
     412        17525 :    if (istr==6) rhodgnow(1:nfft,2,1)=-half*(kxc(1:nfft,16)-kxc(1:nfft,17))
     413        17525 :    if (istr==6) rhodgnow(1:nfft,2,2)=-half*(kxc(1:nfft,14)-kxc(1:nfft,15))
     414              :  end if
     415              : 
     416              : !Add to the gradients of the first-order density
     417         1120 :  do ii=1,3
     418         2047 :    do ispden=1,nspden
     419      3692277 :      rhodgnow(1:nfft,ispden,ii)=str_scale*rhodgnow(1:nfft,ispden,ii)
     420      3693117 :      rho1now(1:nfft,ispden,1+ii)=rho1now(1:nfft,ispden,1+ii)+rhodgnow(1:nfft,ispden,ii)
     421              :    end do
     422              :  end do
     423              : 
     424              : !rho1now(:,:,1) contains the 1st-order density, and rho1now(:,:,2:4) contains the grads of the 1st-order density
     425              : 
     426              : !Apply the XC kernel
     427          280 :  nspgrad=2; if (nspden==2) nspgrad=5
     428         1120 :  ABI_MALLOC(dnexcdn,(cplex*nfft,nspgrad))
     429              : 
     430              : !== Non polarized
     431          280 :  if (nspden==1) then
     432       892445 :    do ir=1,nfft
     433      6245358 :      r0(:)=kxc(ir,5:7) ; r1(:)=rho1now(ir,1,2:4)
     434      3568776 :      gradrho_gradrho1=dot_product(r0,r1)
     435       892194 :      dnexcdn(ir,1)=kxc(ir,1)*rho1now(ir,1,1) + kxc(ir,3)*gradrho_gradrho1
     436       892194 :      coeff_grho=kxc(ir,3)*rho1now(ir,1,1) + kxc(ir,4)*gradrho_gradrho1
     437              : !    Grad strain derivative contribution enters the following term with a
     438              : !    factor of two compared to above terms, so add it again.
     439      3568776 :      r1(:)=r1(:)+rhodgnow(ir,1,1:3)
     440              : !    Reuse the storage in rho1now
     441      3569027 :      rho1now(ir,1,2:4)=r1(:)*kxc(ir,2)+r0(:)*coeff_grho
     442              :    end do
     443              : 
     444              : !== Spin-polarized
     445              :  else ! nspden==2
     446       169157 :    do ir=1,nfft
     447       676512 :      do ii=1,3  ! grad of spin-up ans spin_dn GS rho
     448       676512 :        r0_up(ii)=kxc(ir,13+2*ii);r0_dn(ii)=kxc(ir,12+2*ii)-kxc(ir,13+2*ii)
     449              :      end do
     450       676512 :      r0(:)=r0_up(:)+r0_dn(:)      ! grad of GS rho
     451       676512 :      r1_up(:)=rho1now(ir,1,2:4)   ! grad of spin-up rho1
     452       676512 :      r1_dn(:)=rho1now(ir,2,2:4)   ! grad of spin-down rho1
     453       676512 :      r1(:)=r1_up(:)+r1_dn(:)      ! grad of GS rho1
     454       676512 :      gradrho_gradrho1_up=dot_product(r0_up,r1_up)
     455       676512 :      gradrho_gradrho1_dn=dot_product(r0_dn,r1_dn)
     456       676512 :      gradrho_gradrho1   =dot_product(r0,r1)
     457              : 
     458              :      dnexcdn(ir,1)=kxc(ir, 1)*rho1now(ir,1,1)     &
     459              : &     +kxc(ir, 2)*rho1now(ir,2,1)     &
     460              : &     +kxc(ir, 6)*gradrho_gradrho1_up &
     461       169128 : &     +kxc(ir,11)*gradrho_gradrho1
     462              :      dnexcdn(ir,2)=kxc(ir, 3)*rho1now(ir,2,1)     &
     463              : &     +kxc(ir, 2)*rho1now(ir,1,1)     &
     464              : &     +kxc(ir, 7)*gradrho_gradrho1_dn &
     465       169128 : &     +kxc(ir,12)*gradrho_gradrho1
     466              :      coeff_grho_corr=kxc(ir,11)*rho1now(ir,1,1) &
     467              : &     +kxc(ir,12)*rho1now(ir,2,1) &
     468       169128 : &     +kxc(ir,13)*gradrho_gradrho1
     469       169128 :      coeff_grho_up=kxc(ir,6)*rho1now(ir,1,1)+kxc(ir,8)*gradrho_gradrho1_up
     470       169128 :      coeff_grho_dn=kxc(ir,7)*rho1now(ir,2,1)+kxc(ir,9)*gradrho_gradrho1_dn
     471              : 
     472              : !    Grad strain derivative contribution enters the following term with a
     473              : !    factor of two compared to above terms, so add it again.
     474       676512 :      r1_up(:)=r1_up(:)+rhodgnow(ir,1,1:3)
     475       676512 :      r1_dn(:)=r1_dn(:)+rhodgnow(ir,2,1:3)
     476              : 
     477              : !    Reuse the storage in rho1now
     478              :      rho1now(ir,1,2:4)=(kxc(ir,4)+kxc(ir,10))*r1_up(:) &
     479              : &     +kxc(ir,10)            *r1_dn(:) &
     480              : &     +coeff_grho_up         *r0_up(:) &
     481       676512 : &     +coeff_grho_corr       *r0(:)
     482              :      rho1now(ir,2,2:4)=(kxc(ir,5)+kxc(ir,10))*r1_dn(:) &
     483              : &     +kxc(ir,10)            *r1_up(:) &
     484              : &     +coeff_grho_dn         *r0_dn(:) &
     485       676541 : &     +coeff_grho_corr       *r0(:)
     486              :    end do
     487              : 
     488              :  end if ! nspden
     489          280 :  ABI_FREE(rhodgnow)
     490              : 
     491      1231039 :  vxc1(:,:)=zero
     492              :  call xcpot(cplex,gprimd,ishift,mgga,mpi_enreg,nfft,ngfft,ngrad,nspden,&
     493          280 : & nspgrad,qphon,depsxc=dnexcdn,rhonow=rho1now,vxc=vxc1)
     494              : 
     495              : !if you uncomment the following line, you will have to modify
     496              : !the original function call to pass in gmet and gsqcut
     497              : !call filterpot(cplex,gmet,gsqcut,nfft,ngfft,nspden,qphon,vxc1)
     498              : 
     499          280 :  ABI_FREE(dnexcdn)
     500          280 :  ABI_FREE(rho1now)
     501              : 
     502          280 : end subroutine dfpt_mkvxcstrgga
     503              : !!***
     504              : 
     505              : end module m_dfpt_mkvxcstr
     506              : !!***
        

Generated by: LCOV version 2.3-1