TABLE OF CONTENTS


ABINIT/dfpt_mkvxcgga [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_mkvxcgga

FUNCTION

 Compute the first-order change of exchange-correlation potential
 in case of GGA functionals
 Use the exchange-correlation kernel.

COPYRIGHT

 Copyright (C) 2001-2018 ABINIT group (XG, DRH)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .

INPUTS

  cplex= if 1, real space 1-order functions on FFT grid are REAL,
    if 2, COMPLEX
  gmet(3,3)=metrix tensor in G space in Bohr**-2.
  gprimd(3,3)=dimensional primitive translations in reciprocal space (bohr^-1)
  gsqcut=cutoff value on G**2 for sphere inside fft box.
  kxc(nfft,nkxc)=exchange and correlation kernel (see below)
  mpi_enreg=informations about MPI parallelization
  nfft=(effective) number of FFT grid points (for this processor)
  ngfft(18)=contain all needed information about 3D FFT
  nhat1(cplex*nfft,2*nhat1dim)= -PAW only- 1st-order compensation density
  nhat1dim= -PAW only- 1 if nhat1 array is used ; 0 otherwise
  nhat1gr(cplex*nfft,2,3*nhat1grdim)= -PAW only- gradients of 1st-order compensation density
  nhat1grdim= -PAW only- 1 if nhat1gr array is used ; 0 otherwise
  nkxc=second dimension of the kxc array
  nspden=number of spin-density components
  qphon(3)=reduced coordinates for the phonon wavelength (needed if cplex==2).
  rhor1tmp(cplex*nfft,2)=array for first-order electron spin-density
   in electrons/bohr**3 (second index corresponds to spin-up and spin-down)
  usexcnhat= -PAW only- 1 if nhat density has to be taken into account in Vxc

OUTPUT

  vxc1(cplex*nfft,nspden)=change in exchange-correlation potential

SIDE EFFECTS

NOTES

  For the time being, a rather crude coding, to be optimized ...
  Content of Kxc array:
   ===== if GGA
    if nspden==1:
       kxc(:,1)= d2Exc/drho2
       kxc(:,2)= 1/|grad(rho)| dExc/d|grad(rho)|
       kxc(:,3)= 1/|grad(rho)| d2Exc/d|grad(rho)| drho
       kxc(:,4)= 1/|grad(rho)| * d/d|grad(rho)| ( 1/|grad(rho)| dExc/d|grad(rho)| )
       kxc(:,5)= gradx(rho)
       kxc(:,6)= grady(rho)
       kxc(:,7)= gradz(rho)
    if nspden>=2:
       kxc(:,1)= d2Exc/drho_up drho_up
       kxc(:,2)= d2Exc/drho_up drho_dn
       kxc(:,3)= d2Exc/drho_dn drho_dn
       kxc(:,4)= 1/|grad(rho_up)| dEx/d|grad(rho_up)|
       kxc(:,5)= 1/|grad(rho_dn)| dEx/d|grad(rho_dn)|
       kxc(:,6)= 1/|grad(rho_up)| d2Ex/d|grad(rho_up)| drho_up
       kxc(:,7)= 1/|grad(rho_dn)| d2Ex/d|grad(rho_dn)| drho_dn
       kxc(:,8)= 1/|grad(rho_up)| * d/d|grad(rho_up)| ( 1/|grad(rho_up)| dEx/d|grad(rho_up)| )
       kxc(:,9)= 1/|grad(rho_dn)| * d/d|grad(rho_dn)| ( 1/|grad(rho_dn)| dEx/d|grad(rho_dn)| )
       kxc(:,10)=1/|grad(rho)| dEc/d|grad(rho)|
       kxc(:,11)=1/|grad(rho)| d2Ec/d|grad(rho)| drho_up
       kxc(:,12)=1/|grad(rho)| d2Ec/d|grad(rho)| drho_dn
       kxc(:,13)=1/|grad(rho)| * d/d|grad(rho)| ( 1/|grad(rho)| dEc/d|grad(rho)| )
       kxc(:,14)=gradx(rho_up)
       kxc(:,15)=gradx(rho_dn)
       kxc(:,16)=grady(rho_up)
       kxc(:,17)=grady(rho_dn)
       kxc(:,18)=gradz(rho_up)
       kxc(:,19)=gradz(rho_dn)

PARENTS

      dfpt_mkvxc

CHILDREN

      xcden,xcpot

SOURCE

 84 #if defined HAVE_CONFIG_H
 85 #include "config.h"
 86 #endif
 87 
 88 #include "abi_common.h"
 89 
 90 subroutine dfpt_mkvxcgga(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,&
 91 &                    nhat1,nhat1dim,nhat1gr,nhat1grdim,nkxc,&
 92 &                    nspden,paral_kgb,qphon,rhor1,usexcnhat,vxc1)
 93 
 94  use defs_basis
 95  use defs_abitypes
 96  use m_profiling_abi
 97  use m_errors
 98 
 99 !This section has been created automatically by the script Abilint (TD).
100 !Do not modify the following lines by hand.
101 #undef ABI_FUNC
102 #define ABI_FUNC 'dfpt_mkvxcgga'
103  use interfaces_56_xc, except_this_one => dfpt_mkvxcgga
104 !End of the abilint section
105 
106  implicit none
107 
108 !Arguments ------------------------------------
109 !scalars
110  integer,intent(in) :: cplex,nfft,nhat1dim,nhat1grdim,nkxc,nspden,paral_kgb,usexcnhat
111  type(MPI_type),intent(in) :: mpi_enreg
112 !arrays
113  integer,intent(in) :: ngfft(18)
114  real(dp),intent(in) :: gprimd(3,3)
115  real(dp),intent(in) :: kxc(nfft,nkxc)
116  real(dp),intent(in) :: nhat1(cplex*nfft,nspden*nhat1dim)
117  real(dp),intent(in) :: nhat1gr(cplex*nfft,nspden,3*nhat1grdim)
118  real(dp),intent(in) :: qphon(3)
119  real(dp),intent(in),target :: rhor1(cplex*nfft,nspden)
120  real(dp),intent(out) :: vxc1(cplex*nfft,nspden)
121 
122 !Local variables-------------------------------
123 !scalars
124  integer :: ii,ir,ishift,mgga,ngrad,nspgrad
125  logical :: test_nhat
126  real(dp) :: coeff_grho,coeff_grho_corr,coeff_grho_dn,coeff_grho_up
127  real(dp) :: coeffim_grho,coeffim_grho_corr,coeffim_grho_dn,coeffim_grho_up
128  real(dp) :: gradrho_gradrho1,gradrho_gradrho1_dn,gradrho_gradrho1_up
129  real(dp) :: gradrho_gradrho1im,gradrho_gradrho1im_dn,gradrho_gradrho1im_up
130  character(len=500) :: msg
131 !arrays
132  real(dp) :: r0(3),r0_dn(3),r0_up(3),r1(3),r1_dn(3),r1_up(3)
133  real(dp) :: r1im(3),r1im_dn(3),r1im_up(3)
134  real(dp),allocatable :: dnexcdn(:,:),rho1now(:,:,:)
135  real(dp),ABI_CONTIGUOUS pointer :: rhor1_ptr(:,:)
136 
137 ! *************************************************************************
138 
139  DBG_ENTER("COLL")
140 
141  if (nkxc/=12*min(nspden,2)-5) then
142    msg='Wrong nkxc value for GGA!'
143    MSG_BUG(msg)
144  end if
145 
146 !metaGGA contributions are not taken into account here
147  mgga=0
148 
149 !PAW: substract 1st-order compensation density from 1st-order density
150  test_nhat=((nhat1dim==1).and.(usexcnhat==0.or.nhat1grdim==1))
151  if (test_nhat) then
152    ABI_ALLOCATE(rhor1_ptr,(cplex*nfft,nspden))
153    rhor1_ptr(:,:)=rhor1(:,:)-nhat1(:,:)
154  else
155    rhor1_ptr => rhor1
156  end if
157 
158 !call filterpot(paral_kgb,cplex,gmet,gsqcut,nfft,ngfft,2,qphon,rhor1_ptr)
159 
160 !Compute the gradients of the first-order density
161 !rho1now(:,:,1) contains the first-order density, and
162 !rho1now(:,:,2:4) contains the gradients of the first-order density
163  ishift=0 ; ngrad=2
164  ABI_ALLOCATE(rho1now,(cplex*nfft,nspden,ngrad*ngrad))
165  call xcden(cplex,gprimd,ishift,mpi_enreg,nfft,ngfft,ngrad,nspden,paral_kgb,qphon,rhor1_ptr,rho1now)
166 
167 !PAW: add "exact" gradients of compensation density
168  if (test_nhat.and.usexcnhat==1) then
169    rho1now(:,1:nspden,1)=rho1now(:,1:nspden,1)+nhat1(:,1:nspden)
170  end if
171  if (nhat1grdim==1) then
172    do ii=1,3
173      rho1now(:,1:nspden,ii+1)=rho1now(:,1:nspden,ii+1)+nhat1gr(:,1:nspden,ii)
174    end do
175  end if
176  if (test_nhat) then
177    ABI_DEALLOCATE(rhor1_ptr)
178  end if
179 
180 !Apply the XC kernel
181  nspgrad=2; if (nspden==2) nspgrad=5
182  ABI_ALLOCATE(dnexcdn,(cplex*nfft,nspgrad))
183 
184  if (cplex==1) then  ! Treat real case first
185    if (nspden==1) then
186      do ir=1,nfft
187        r0(:)=kxc(ir,5:7) ; r1(:)=rho1now(ir,1,2:4)
188        gradrho_gradrho1=dot_product(r0,r1)
189        dnexcdn(ir,1)=kxc(ir,1)*rho1now(ir,1,1) + kxc(ir,3)*gradrho_gradrho1
190        coeff_grho=kxc(ir,3)*rho1now(ir,1,1) + kxc(ir,4)*gradrho_gradrho1
191   !    Reuse the storage in rho1now
192        rho1now(ir,1,2:4)=r1(:)*kxc(ir,2)+r0(:)*coeff_grho
193      end do
194    else
195      do ir=1,nfft
196        do ii=1,3  ! grad of spin-up ans spin_dn GS rho
197          r0_up(ii)=kxc(ir,13+2*ii);r0_dn(ii)=kxc(ir,12+2*ii)-kxc(ir,13+2*ii)
198        end do
199        r0(:)=r0_up(:)+r0_dn(:)      ! grad of GS rho
200        r1_up(:)=rho1now(ir,1,2:4)   ! grad of spin-up rho1
201        r1_dn(:)=rho1now(ir,2,2:4)   ! grad of spin-down rho1
202        r1(:)=r1_up(:)+r1_dn(:)      ! grad of GS rho1
203        gradrho_gradrho1_up=dot_product(r0_up,r1_up)
204        gradrho_gradrho1_dn=dot_product(r0_dn,r1_dn)
205        gradrho_gradrho1   =dot_product(r0,r1)
206        dnexcdn(ir,1)=kxc(ir, 1)*rho1now(ir,1,1)     &
207 &       +kxc(ir, 2)*rho1now(ir,2,1)     &
208 &       +kxc(ir, 6)*gradrho_gradrho1_up &
209 &       +kxc(ir,11)*gradrho_gradrho1
210        dnexcdn(ir,2)=kxc(ir, 3)*rho1now(ir,2,1)     &
211 &       +kxc(ir, 2)*rho1now(ir,1,1)     &
212 &       +kxc(ir, 7)*gradrho_gradrho1_dn &
213 &       +kxc(ir,12)*gradrho_gradrho1
214        coeff_grho_corr=kxc(ir,11)*rho1now(ir,1,1) &
215 &       +kxc(ir,12)*rho1now(ir,2,1) &
216 &       +kxc(ir,13)*gradrho_gradrho1
217        coeff_grho_up=kxc(ir,6)*rho1now(ir,1,1)+kxc(ir,8)*gradrho_gradrho1_up
218        coeff_grho_dn=kxc(ir,7)*rho1now(ir,2,1)+kxc(ir,9)*gradrho_gradrho1_dn
219   !    Reuse the storage in rho1now
220        rho1now(ir,1,2:4)=(kxc(ir,4)+kxc(ir,10))*r1_up(:) &
221 &       +kxc(ir,10)            *r1_dn(:) &
222 &       +coeff_grho_up         *r0_up(:) &
223 &       +coeff_grho_corr       *r0(:)
224        rho1now(ir,2,2:4)=(kxc(ir,5)+kxc(ir,10))*r1_dn(:) &
225 &       +kxc(ir,10)            *r1_up(:) &
226 &       +coeff_grho_dn         *r0_dn(:) &
227 &       +coeff_grho_corr       *r0(:)
228      end do
229    end if ! nspden
230 
231  else ! if cplex==2
232    if (nspden==1) then
233      do ir=1,nfft
234        r0(:)=kxc(ir,5:7)
235        r1(:)  =rho1now(2*ir-1,1,2:4)
236        r1im(:)=rho1now(2*ir  ,1,2:4)
237        gradrho_gradrho1  =dot_product(r0,r1)
238        gradrho_gradrho1im=dot_product(r0,r1im)
239        dnexcdn(2*ir-1,1)=kxc(ir,1)*rho1now(2*ir-1,1,1) + kxc(ir,3)*gradrho_gradrho1
240        dnexcdn(2*ir  ,1)=kxc(ir,1)*rho1now(2*ir  ,1,1) + kxc(ir,3)*gradrho_gradrho1im
241        coeff_grho  =kxc(ir,3)*rho1now(2*ir-1,1,1) + kxc(ir,4)*gradrho_gradrho1
242        coeffim_grho=kxc(ir,3)*rho1now(2*ir  ,1,1) + kxc(ir,4)*gradrho_gradrho1im
243   !    Reuse the storage in rho1now
244        rho1now(2*ir-1,1,2:4)=r1(:)  *kxc(ir,2)+r0(:)*coeff_grho
245        rho1now(2*ir  ,1,2:4)=r1im(:)*kxc(ir,2)+r0(:)*coeffim_grho
246      end do
247    else
248      do ir=1,nfft
249        do ii=1,3  ! grad of spin-up ans spin_dn GS rho
250          r0_up(ii)=kxc(ir,13+2*ii);r0_dn(ii)=kxc(ir,12+2*ii)-kxc(ir,13+2*ii)
251        end do
252        r0(:)=r0_up(:)+r0_dn(:)          ! grad of GS rho
253        r1_up(:)=rho1now(2*ir-1,1,2:4)   ! grad of spin-up rho1
254        r1im_up(:)=rho1now(2*ir,1,2:4)   ! grad of spin-up rho1 , im part
255        r1_dn(:)=rho1now(2*ir-1,2,2:4)   ! grad of spin-down rho1
256        r1im_dn(:)=rho1now(2*ir,2,2:4)   ! grad of spin-down rho1 , im part
257        r1(:)=r1_up(:)+r1_dn(:)      ! grad of GS rho1
258        r1im(:)=r1im_up(:)+r1im_dn(:)      ! grad of GS rho1, im part
259        gradrho_gradrho1_up  =dot_product(r0_up,r1_up)
260        gradrho_gradrho1_dn  =dot_product(r0_dn,r1_dn)
261        gradrho_gradrho1     =dot_product(r0,r1)
262        gradrho_gradrho1im_up=dot_product(r0_up,r1im_up)
263        gradrho_gradrho1im_dn=dot_product(r0_dn,r1im_dn)
264        gradrho_gradrho1im   =dot_product(r0,r1im)
265        dnexcdn(2*ir-1,1)=kxc(ir, 1)*rho1now(2*ir-1,1,1) &
266 &       +kxc(ir, 2)*rho1now(2*ir-1,2,1) &
267 &       +kxc(ir, 6)*gradrho_gradrho1_up &
268 &       +kxc(ir,11)*gradrho_gradrho1
269        dnexcdn(2*ir-1,2)=kxc(ir, 3)*rho1now(2*ir-1,2,1) &
270 &       +kxc(ir, 2)*rho1now(2*ir-1,1,1) &
271 &       +kxc(ir, 7)*gradrho_gradrho1_dn &
272 &       +kxc(ir,12)*gradrho_gradrho1
273        dnexcdn(2*ir  ,1)=kxc(ir, 1)*rho1now(2*ir  ,1,1) &
274 &       +kxc(ir, 2)*rho1now(2*ir  ,2,1) &
275 &       +kxc(ir, 6)*gradrho_gradrho1im_up &
276 &       +kxc(ir,11)*gradrho_gradrho1im
277        dnexcdn(2*ir  ,2)=kxc(ir, 3)*rho1now(2*ir  ,2,1) &
278 &       +kxc(ir, 2)*rho1now(2*ir  ,1,1) &
279 &       +kxc(ir, 7)*gradrho_gradrho1im_dn &
280 &       +kxc(ir,12)*gradrho_gradrho1im
281        coeff_grho_corr  =kxc(ir,11)*rho1now(2*ir-1,1,1) &
282 &       +kxc(ir,12)*rho1now(2*ir-1,2,1) &
283 &       +kxc(ir,13)*gradrho_gradrho1
284        coeffim_grho_corr=kxc(ir,11)*rho1now(2*ir  ,1,1) &
285 &       +kxc(ir,12)*rho1now(2*ir  ,2,1) &
286 &       +kxc(ir,13)*gradrho_gradrho1im
287        coeff_grho_up  =kxc(ir,6)*rho1now(2*ir-1,1,1)+kxc(ir,8)*gradrho_gradrho1_up
288        coeff_grho_dn  =kxc(ir,7)*rho1now(2*ir-1,2,1)+kxc(ir,9)*gradrho_gradrho1_dn
289        coeffim_grho_up=kxc(ir,6)*rho1now(2*ir  ,1,1)+kxc(ir,8)*gradrho_gradrho1im_up
290        coeffim_grho_dn=kxc(ir,7)*rho1now(2*ir  ,2,1)+kxc(ir,9)*gradrho_gradrho1im_dn
291 !      Reuse the storage in rho1now
292        rho1now(2*ir-1,1,2:4)=(kxc(ir,4)+kxc(ir,10))*r1_up(:) &
293 &       +kxc(ir,10)            *r1_dn(:) &
294 &       +coeff_grho_up         *r0_up(:) &
295 &       +coeff_grho_corr*r0(:)
296        rho1now(2*ir-1,2,2:4)=(kxc(ir,5)+kxc(ir,10))*r1_dn(:) &
297 &       +kxc(ir,10)            *r1_up(:) &
298 &       +coeff_grho_dn         *r0_dn(:) &
299 &       +coeff_grho_corr*r0(:)
300        rho1now(2*ir  ,1,2:4)=(kxc(ir,4)+kxc(ir,10))*r1im_up(:) &
301 &       +kxc(ir,10)            *r1im_dn(:) &
302 &       +coeffim_grho_up       *r0_up(:)   &
303 &       +coeffim_grho_corr     *r0(:)
304        rho1now(2*ir  ,2,2:4)=(kxc(ir,5)+kxc(ir,10))*r1im_dn(:) &
305 &       +kxc(ir,10)            *r1im_up(:) &
306 &       +coeffim_grho_dn       *r0_dn(:)   &
307 &       +coeffim_grho_corr     *r0(:)
308      end do
309    end if ! nspden
310 
311  end if
312 
313  vxc1(:,:)=zero
314  call xcpot(cplex,dnexcdn,gprimd,ishift,mgga,mpi_enreg,nfft,ngfft,ngrad,nspden,&
315 & nspgrad,paral_kgb,qphon,rho1now,vxc1)
316 
317 !call filterpot(paral_kgb,cplex,gmet,gsqcut,nfft,ngfft,nspden,qphon,vxc1)
318 
319  ABI_DEALLOCATE(dnexcdn)
320  ABI_DEALLOCATE(rho1now)
321 
322  DBG_EXIT("COLL")
323 
324 end subroutine dfpt_mkvxcgga