TABLE OF CONTENTS


ABINIT/dfpt_mkvxc [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_mkvxc

FUNCTION

 Compute the first-order change of exchange-correlation potential
 due to atomic displacement: assemble the first-order
 density change with the frozen-core density change, then use
 the exchange-correlation kernel.

INPUTS

  cplex= if 1, real space 1-order functions on FFT grid are REAL,
         if 2, COMPLEX
  ixc= choice of exchange-correlation scheme
  kxc(nfft,nkxc)=exchange and correlation kernel (see below)
  mpi_enreg=information about MPI parallelization
  nfft=(effective) number of FFT grid points (for this processor)
  ngfft(18)=contain all needed information about 3D FFT,
     see ~abinit/doc/variables/vargs.htm#ngfft
  nhat1(cplex*nfft,2nspden*nhat1dim)= -PAW only- 1st-order compensation density
  nhat1dim= -PAW only- 1 if nhat1 array is used ; 0 otherwise
  nhat1gr(cplex*nfft,nspden,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
  non_magnetic_xc= if true, handle density/potential as non-magnetic (even if it is)
  nspden=number of spin-density components
  n3xccc=dimension of xccc3d1 ; 0 if no XC core correction is used, otherwise, nfft
  option=if 0, work only with the XC core-correction,
         if 1, treat both density change and XC core correction
         if 2, treat only density change
  qphon(3)=reduced coordinates for the phonon wavelength (needed if cplex==2).
  rhor1(cplex*nfft,nspden)=array for electron density in electrons/bohr**3.
  rprimd(3,3)=dimensional primitive translations in real space (bohr)
  usexcnhat= -PAW only- 1 if nhat density has to be taken into account in Vxc
  xccc3d1(cplex*n3xccc)=3D change in core charge density, see n3xccc

OUTPUT

  vxc1(cplex*nfft,nspden)=change in exchange-correlation potential (including
   core-correction, if applicable)

NOTES

  Content of Kxc array:
   ===== if LDA
    if nspden==1: kxc(:,1)= d2Exc/drho2
                 (kxc(:,2)= d2Exc/drho_up drho_dn)
    if nspden>=2: kxc(:,1)= d2Exc/drho_up drho_up
                  kxc(:,2)= d2Exc/drho_up drho_dn
                  kxc(:,3)= d2Exc/drho_dn drho_dn
   ===== if GGA (or mGGA)
    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)
    Note about mGGA: 2nd derivatives involving Tau or Laplacian are not taken into account (yet)

SOURCE

129 subroutine dfpt_mkvxc(cplex,ixc,kxc,mpi_enreg,nfft,ngfft,nhat1,nhat1dim,nhat1gr,nhat1grdim,&
130 &          nkxc,non_magnetic_xc,nspden,n3xccc,option,qphon,rhor1,rprimd,usexcnhat,vxc1,xccc3d1)
131 
132 !Arguments ------------------------------------
133 !scalars
134  integer,intent(in) :: cplex,ixc,n3xccc,nfft,nhat1dim,nhat1grdim
135  integer,intent(in) :: nkxc,nspden,option,usexcnhat
136  logical,intent(in) :: non_magnetic_xc
137  type(MPI_type),intent(in) :: mpi_enreg
138 !arrays
139  integer,intent(in) :: ngfft(18)
140  real(dp),intent(in),target :: nhat1(cplex*nfft,nspden*nhat1dim)
141  real(dp),intent(in),target :: nhat1gr(cplex*nfft,nspden,3*nhat1grdim)
142  real(dp),intent(in) :: kxc(nfft,nkxc),qphon(3)
143  real(dp),intent(in),target :: rhor1(cplex*nfft,nspden)
144  real(dp),intent(in) :: rprimd(3,3),xccc3d1(cplex*n3xccc)
145  real(dp),intent(out) :: vxc1(cplex*nfft,nspden)
146 
147 !Local variables-------------------------------
148 !scalars
149  integer :: ii,ir,ispden,nhat1dim_,nhat1rgdim_
150  real(dp) :: rho1_dn,rho1_up,rho1im_dn,rho1im_up,rho1re_dn,rho1re_up
151  real(dp) :: spin_scale
152 !arrays
153  real(dp) :: gprimd(3,3),tsec(2)
154  real(dp), ABI_CONTIGUOUS pointer :: nhat1_(:,:),nhat1gr_(:,:,:),rhor1_(:,:)
155 
156 ! *************************************************************************
157 
158  DBG_ENTER("COLL")
159 
160  call timab(181,1,tsec)
161 
162  if(nspden/=1 .and. nspden/=2) then
163    ABI_BUG('For nspden==4 please use dfpt_mkvxc_noncoll!')
164  end if
165 
166 !Special case: no XC applied
167  if (ixc==0.or.nkxc==0) then
168    ABI_WARNING('Note that no xc is applied (ixc=0)')
169    vxc1=zero
170    return
171  end if
172 
173 !Treat first LDA
174  if(nkxc==1.or.nkxc==3)then
175 
176 !  PAW: eventually substract compensation density
177    if (option/=0) then
178      if ((usexcnhat==0.and.nhat1dim==1).or.(non_magnetic_xc)) then
179        ABI_MALLOC(rhor1_,(cplex*nfft,nspden))
180        if (usexcnhat==0.and.nhat1dim==1) then
181          rhor1_(:,:)=rhor1(:,:)-nhat1(:,:)
182        else
183          rhor1_(:,:)=rhor1(:,:)
184        end if
185        if (non_magnetic_xc) then
186          if(nspden==2) rhor1_(:,2)=rhor1_(:,1)*half
187          if(nspden==4) rhor1_(:,2:4)=zero
188        end if
189      else
190        rhor1_ => rhor1
191      end if
192    end if
193 
194 !  Case without non-linear core correction
195    if(n3xccc==0 .or. option==2)then
196 
197      if(option==0)then  ! No straight XC to compute
198 
199        vxc1(:,:)=zero
200 
201      else               ! XC, without non-linear XC correction
202 
203 !      Non-spin-polarized
204        if(nspden==1)then
205          if(cplex==1)then
206            do ir=1,nfft
207              vxc1(ir,1)=kxc(ir,1)*rhor1_(ir,1)
208            end do
209          else
210            do ir=1,nfft
211              vxc1(2*ir-1,1)=kxc(ir,1)*rhor1_(2*ir-1,1)
212              vxc1(2*ir  ,1)=kxc(ir,1)*rhor1_(2*ir  ,1)
213            end do
214          end if ! cplex==1
215 
216 !        Spin-polarized
217        else
218          if(cplex==1)then
219            do ir=1,nfft
220              rho1_dn=rhor1_(ir,1)-rhor1_(ir,2)
221              vxc1(ir,1)=kxc(ir,1)*rhor1_(ir,2)+kxc(ir,2)*rho1_dn
222              vxc1(ir,2)=kxc(ir,2)*rhor1_(ir,2)+kxc(ir,3)*rho1_dn
223            end do
224          else
225            do ir=1,nfft
226              rho1re_dn=rhor1_(2*ir-1,1)-rhor1_(2*ir-1,2)
227              rho1im_dn=rhor1_(2*ir  ,1)-rhor1_(2*ir  ,2)
228              vxc1(2*ir-1,1)=kxc(ir,1)*rhor1_(2*ir-1,2)+kxc(ir,2)*rho1re_dn
229              vxc1(2*ir  ,1)=kxc(ir,1)*rhor1_(2*ir  ,2)+kxc(ir,2)*rho1im_dn
230              vxc1(2*ir-1,2)=kxc(ir,2)*rhor1_(2*ir-1,2)+kxc(ir,3)*rho1re_dn
231              vxc1(2*ir  ,2)=kxc(ir,2)*rhor1_(2*ir  ,2)+kxc(ir,3)*rho1im_dn
232            end do
233          end if ! cplex==1
234        end if ! nspden==1
235 
236      end if ! option==0
237 
238 !    Treat case with non-linear core correction
239    else
240 
241      if(option==0)then
242 
243        if(nspden==1)then
244          if(cplex==1)then
245            do ir=1,nfft
246              vxc1(ir,1)=kxc(ir,1)*xccc3d1(ir)
247            end do
248          else
249            do ir=1,nfft
250              vxc1(2*ir-1,1)=kxc(ir,1)*xccc3d1(2*ir-1)
251              vxc1(2*ir  ,1)=kxc(ir,1)*xccc3d1(2*ir  )
252            end do
253          end if ! cplex==1
254        else
255          if(cplex==1)then
256            do ir=1,nfft
257              vxc1(ir,1)=(kxc(ir,1)+kxc(ir,2))*xccc3d1(ir)*half
258              vxc1(ir,2)=(kxc(ir,2)+kxc(ir,3))*xccc3d1(ir)*half
259            end do
260          else
261            do ir=1,nfft
262              vxc1(2*ir-1,1)=(kxc(ir,1)+kxc(ir,2))*xccc3d1(2*ir-1)*half
263              vxc1(2*ir  ,1)=(kxc(ir,1)+kxc(ir,2))*xccc3d1(2*ir  )*half
264              vxc1(2*ir-1,2)=(kxc(ir,2)+kxc(ir,3))*xccc3d1(2*ir-1)*half
265              vxc1(2*ir  ,2)=(kxc(ir,2)+kxc(ir,3))*xccc3d1(2*ir  )*half
266            end do
267          end if ! cplex==1
268        end if ! nspden==1
269 
270      else ! option/=0
271 
272        if(nspden==1)then
273          if(cplex==1)then
274            do ir=1,nfft
275              vxc1(ir,1)=kxc(ir,1)*(rhor1_(ir,1)+xccc3d1(ir))
276            end do
277          else
278            do ir=1,nfft
279              vxc1(2*ir-1,1)=kxc(ir,1)*(rhor1_(2*ir-1,1)+xccc3d1(2*ir-1))
280              vxc1(2*ir  ,1)=kxc(ir,1)*(rhor1_(2*ir  ,1)+xccc3d1(2*ir  ))
281            end do
282          end if ! cplex==1
283        else
284          if(cplex==1)then
285            do ir=1,nfft
286              rho1_dn=rhor1_(ir,1)-rhor1_(ir,2) + xccc3d1(ir)*half
287              rho1_up=rhor1_(ir,2)             + xccc3d1(ir)*half
288              vxc1(ir,1)=kxc(ir,1)*rho1_up+kxc(ir,2)*rho1_dn
289              vxc1(ir,2)=kxc(ir,2)*rho1_up+kxc(ir,3)*rho1_dn
290            end do
291          else
292            do ir=1,nfft
293              rho1re_dn=rhor1_(2*ir-1,1)-rhor1_(2*ir-1,2) + xccc3d1(2*ir-1)*half
294              rho1im_dn=rhor1_(2*ir  ,1)-rhor1_(2*ir  ,2) + xccc3d1(2*ir  )*half
295              rho1re_up=rhor1_(2*ir-1,2)                 + xccc3d1(2*ir-1)*half
296              rho1im_up=rhor1_(2*ir  ,2)                 + xccc3d1(2*ir  )*half
297              vxc1(2*ir-1,1)=kxc(ir,1)*rho1re_up+kxc(ir,2)*rho1re_dn
298              vxc1(2*ir  ,1)=kxc(ir,1)*rho1im_up+kxc(ir,2)*rho1im_dn
299              vxc1(2*ir-1,2)=kxc(ir,2)*rho1re_up+kxc(ir,3)*rho1re_dn
300              vxc1(2*ir  ,2)=kxc(ir,2)*rho1im_up+kxc(ir,3)*rho1im_dn
301            end do
302          end if ! cplex==1
303        end if ! nspden==1
304 
305      end if ! option==0
306 
307    end if ! n3xccc==0
308 
309    if (option/=0.and.((usexcnhat==0.and.nhat1dim==1).or.(non_magnetic_xc))) then
310      ABI_FREE(rhor1_)
311    end if
312 
313 !  Treat GGA
314  else if (nkxc==7.or.nkxc==19) then
315 
316 !  Transfer the data to spin-polarized storage
317 
318 !  Treat the density change
319    ABI_MALLOC(rhor1_,(cplex*nfft,nspden))
320    if (option==1 .or. option==2) then
321      if (nspden==1) then
322        do ir=1,cplex*nfft
323          rhor1_(ir,1)=rhor1(ir,1)
324        end do
325      else
326        if(non_magnetic_xc) then
327          do ir=1,cplex*nfft
328            rho1_dn=rhor1(ir,1)*half
329            rhor1_(ir,1)=rho1_dn
330            rhor1_(ir,2)=rho1_dn
331          end do
332        else
333          do ir=1,cplex*nfft
334            rho1_dn=rhor1(ir,1)-rhor1(ir,2)
335            rhor1_(ir,1)=rhor1(ir,2)
336            rhor1_(ir,2)=rho1_dn
337          end do
338        end if
339      end if
340    else
341      do ispden=1,nspden
342        do ir=1,cplex*nfft
343          rhor1_(ir,ispden)=zero
344        end do
345      end do
346    end if
347 
348    if( (option==0 .or. option==1) .and. n3xccc/=0)then
349      spin_scale=one;if (nspden==2) spin_scale=half
350      do ispden=1,nspden
351        do ir=1,cplex*nfft
352          rhor1_(ir,ispden)=rhor1_(ir,ispden)+xccc3d1(ir)*spin_scale
353        end do
354      end do
355    end if
356 
357 !  PAW: treat also compensation density (and gradients)
358    nhat1dim_=nhat1dim ; nhat1rgdim_=nhat1grdim
359    if (option/=0.and.nhat1dim==1.and.nspden==2) then
360      ABI_MALLOC(nhat1_,(cplex*nfft,nspden))
361      if (non_magnetic_xc) then
362        do ir=1,cplex*nfft
363          rho1_dn=nhat1(ir,1)*half
364          nhat1_(ir,1:2)=rho1_dn
365        end do
366      else
367        do ir=1,cplex*nfft
368          rho1_dn=nhat1(ir,1)-nhat1(ir,2)
369          nhat1_(ir,1)=nhat1(ir,2)
370          nhat1_(ir,2)=rho1_dn
371        end do
372      end if
373    else if (option==0) then
374      ABI_MALLOC(nhat1_,(0,0))
375      nhat1dim_=0
376    else
377      nhat1_ => nhat1
378    end if
379    if (option/=0.and.nhat1grdim==1.and.nspden==2) then
380      ABI_MALLOC(nhat1gr_,(cplex*nfft,nspden,3))
381      if (non_magnetic_xc) then
382        do ii=1,3
383          do ir=1,cplex*nfft
384            rho1_dn=nhat1(ir,1)*half
385            nhat1gr_(ir,1:2,ii)=rho1_dn
386          end do
387        end do
388      else
389        do ii=1,3
390          do ir=1,cplex*nfft
391            rho1_dn=nhat1gr(ir,1,ii)-nhat1gr(ir,2,ii)
392            nhat1gr_(ir,1,ii)=nhat1gr(ir,2,ii)
393            nhat1gr_(ir,2,ii)=rho1_dn
394          end do
395        end do
396      end if
397    else if (option==0) then
398      ABI_MALLOC(nhat1gr_,(0,0,0))
399      nhat1rgdim_=0
400    else
401      nhat1gr_ => nhat1gr
402    end if
403 
404    call matr3inv(rprimd,gprimd)
405 
406    call dfpt_mkvxcgga(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,nhat1_,nhat1dim_,&
407 &   nhat1gr_,nhat1rgdim_,nkxc,nspden,qphon,rhor1_,usexcnhat,vxc1)
408 
409    ABI_FREE(rhor1_)
410    if ((option==0).or.(nhat1dim==1.and.nspden==2)) then
411      ABI_FREE(nhat1_)
412    end if
413    if ((option==0).or.(nhat1grdim==1.and.nspden==2)) then
414      ABI_FREE(nhat1gr_)
415    end if
416 
417  else
418    ABI_BUG('Invalid nkxc!')
419 
420  end if ! LDA or GGA
421 
422  call timab(181,2,tsec)
423 
424  DBG_EXIT("COLL")
425 
426 end subroutine dfpt_mkvxc

ABINIT/dfpt_mkvxc_noncoll [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_mkvxc_noncoll

FUNCTION

 Compute the first-order change of exchange-correlation potential
 due to atomic displacement for non-collinear spins: assemble the first-order
 density change with the frozen-core density change, then use
 the exchange-correlation kernel.

INPUTS

  cplex= if 1, real space 1-order functions on FFT grid are REAL,
         if 2, COMPLEX
  ixc= choice of exchange-correlation scheme
  ixcrot= option for rotation of collinear spin potential to non collinear full matrix
  kxc(nfft,nkxc)=exchange and correlation kernel (see rhotoxc.F90)
  mpi_enreg=information about MPI parallelization
  nfft=(effective) number of FFT grid points (for this processor)
  ngfft(18)=contain all needed information about 3D FFT,
     see ~abinit/doc/variables/vargs.htm#ngfft
  nhat(nfft,nspden*nhatdim)= -PAW only- GS compensation density
  nhatdim= -PAW only- 1 if nhat array is used ; 0 otherwise
  nhat1(cplex*nfft,nspden*nhat1dim)= -PAW only- 1st-order compensation density
  nhat1dim= -PAW only- 1 if nhat1 array is used ; 0 otherwise
  nhat1gr(cplex*nfft,nspden,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
  non_magnetic_xc= if true, handle density/potential as non-magnetic (even if it is)
  nspden=number of spin-density components
  n3xccc=dimension of xccc3d1 ; 0 if no XC core correction is used, otherwise, nfft
  optnc=option for non-collinear magnetism (nspden=4):
       1: the whole 2x2 Vres matrix is computed
       2: only Vres^{11} and Vres^{22} are computed
  option=if 0, work only with the XC core-correction,
         if 1, treat both density change and XC core correction
         if 2, treat only density change
  qphon(3)=reduced coordinates for the phonon wavelength (needed if cplex==2).
  rhor(nfft,nspden)=GS electron density in real space
  rhor1(cplex*nfft,nspden)=1st-order electron density in real space
  rprimd(3,3)=dimensional primitive translations in real space (bohr)
  usexcnhat= -PAW only- 1 if nhat density has to be taken into account in Vxc
  vxc(nfft,nspden)=GS XC potential

OUTPUT

  vxc1(cplex*nfft,nspden)=change in exchange-correlation potential (including
   core-correction, if applicable)

SOURCE

770 subroutine dfpt_mkvxc_noncoll(cplex,ixc,kxc,mpi_enreg,nfft,ngfft,nhat,nhatdim,nhat1,nhat1dim,&
771 &          nhat1gr,nhat1grdim,nkxc,non_magnetic_xc,nspden,n3xccc,optnc,option,qphon,&
772 &          rhor,rhor1,rprimd,usexcnhat,vxc,vxc1,xccc3d1,ixcrot)
773 
774 !Arguments ------------------------------------
775 !scalars
776  integer,intent(in) :: cplex,ixc,n3xccc,nfft,nhatdim,nhat1dim,nhat1grdim,optnc
777  integer,intent(in) :: nkxc,nspden,option,usexcnhat
778  logical,intent(in) :: non_magnetic_xc
779  type(MPI_type),intent(in) :: mpi_enreg
780 !arrays
781  integer,intent(in) :: ngfft(18)
782  real(dp),intent(in) :: nhat1gr(cplex*nfft,nspden,3*nhat1grdim)
783  real(dp),intent(in) :: kxc(nfft,nkxc)
784  real(dp),intent(in) :: vxc(nfft,nspden)
785  real(dp),intent(in) :: nhat(nfft,nspden*nhatdim),nhat1(cplex*nfft,nspden*nhat1dim)
786  real(dp),intent(in),target :: rhor(nfft,nspden),rhor1(cplex*nfft,nspden)
787  real(dp),intent(in) :: qphon(3),rprimd(3,3),xccc3d1(cplex*n3xccc)
788  real(dp),intent(out) :: vxc1(cplex*nfft,nspden)
789  integer,optional,intent(in) :: ixcrot
790 !Local variables-------------------------------
791 !scalars
792 !arrays
793  real(dp) :: nhat1_zero(0,0),nhat1gr_zero(0,0,0),tsec(2)
794  real(dp),allocatable :: m_norm(:),rhor1_diag(:,:),vxc1_diag(:,:)
795  real(dp), ABI_CONTIGUOUS pointer :: mag(:,:),rhor_(:,:),rhor1_(:,:)
796 ! *************************************************************************
797 
798 !  Non-collinear magnetism
799 !  Has to locally "rotate" rho(r)^(1) (according to magnetization),
800 !  Compute Vxc(r)^(1) in the spin frame aligned with \vec{m} and rotate it back
801 
802  DBG_ENTER("COLL")
803  ABI_UNUSED(nhat1gr)
804 
805  call timab(181,1,tsec)
806 
807  if(nspden/=4) then
808    ABI_BUG('only for nspden=4!')
809  end if
810 
811  if(nkxc/=2*min(nspden,2)-1) then
812    ABI_BUG('nspden=4 works only with LSDA.')
813  end if
814 
815 !Special case: no XC applied
816  if (ixc==0.or.nkxc==0) then
817    ABI_WARNING('Note that no xc is applied (ixc=0)')
818    vxc1(:,:)=zero
819    return
820  end if
821 
822 
823 
824 !Treat first LDA
825  if(nkxc==1.or.nkxc==3)then
826 
827    vxc1(:,:)=zero
828 
829 !  PAW: possibly substract compensation density
830    if ((usexcnhat==0.and.nhatdim==1).or.(non_magnetic_xc)) then
831      ABI_MALLOC(rhor_,(nfft,nspden))
832      if (usexcnhat==0.and.nhatdim==1) then
833        rhor_(:,:) =rhor(:,:)-nhat(:,:)
834      else
835        rhor_(:,:) =rhor(:,:)
836      end if
837      if (non_magnetic_xc) then
838        if(nspden==2) rhor_(:,2)=rhor_(:,1)*half
839        if(nspden==4) rhor_(:,2:4)=zero
840      end if
841    else
842      rhor_ => rhor
843    end if
844    if ((usexcnhat==0.and.nhat1dim==1).or.(non_magnetic_xc)) then
845      ABI_MALLOC(rhor1_,(cplex*nfft,nspden))
846      if (usexcnhat==0.and.nhatdim==1) then
847        rhor1_(:,:)=rhor1(:,:)-nhat1(:,:)
848      else
849        rhor1_(:,:)=rhor1(:,:)
850      end if
851      if (non_magnetic_xc) then
852        if(nspden==2) rhor1_(:,2)=rhor1_(:,1)*half
853        if(nspden==4) rhor1_(:,2:4)=zero
854      end if
855    else
856      rhor1_ => rhor1
857    end if
858 
859 !  Magnetization
860    mag => rhor_(:,2:4)
861    ABI_MALLOC(rhor1_diag,(cplex*nfft,2))
862    ABI_MALLOC(vxc1_diag,(cplex*nfft,2))
863    ABI_MALLOC(m_norm,(nfft))
864 
865 !  -- Rotate rho(r)^(1)
866 !  SPr: for option=0 the rhor is not used, only core density xccc3d1
867 !       rotate_mag is only to compute the m_norm
868    call rotate_mag(rhor1_,rhor1_diag,mag,nfft,cplex,mag_norm_out=m_norm,&
869 &   rho_out_format=2)
870 
871 !  -- Compute Vxc(r)^(1)=Kxc(r).rho(r)^(1)_rotated
872 !  Note for PAW: nhat has already been substracted; don't use it in dfpt_mkvxc
873 !                 (put all nhat options to zero).
874 !  The collinear routine dfpt_mkvxc wants a general density built as (tr[rho],rho_upup)
875    call dfpt_mkvxc(cplex,ixc,kxc,mpi_enreg,nfft,ngfft,nhat1_zero,0,nhat1gr_zero,0,&
876 &   nkxc,non_magnetic_xc,2,n3xccc,option,qphon,rhor1_diag,rprimd,0,vxc1_diag,xccc3d1)
877 
878    !call test_rotations(0,1)
879 
880 !  -- Rotate back Vxc(r)^(1)
881    if (optnc==1) then
882      if(present(ixcrot)) then
883        call rotate_back_mag_dfpt(option,vxc1_diag,vxc1,vxc,kxc,rhor1_,mag,nfft,cplex,&
884 &       mag_norm_in=m_norm,rot_method=ixcrot)
885      else
886        call rotate_back_mag_dfpt(option,vxc1_diag,vxc1,vxc,kxc,rhor1_,mag,nfft,cplex,&
887 &       mag_norm_in=m_norm)
888      end if
889    else
890      call rotate_back_mag(vxc1_diag,vxc1,mag,nfft,mag_norm_in=m_norm)
891      vxc1(:,3:4)=zero
892    end if
893 
894    ABI_FREE(rhor1_diag)
895    ABI_FREE(vxc1_diag)
896    ABI_FREE(m_norm)
897    if ((usexcnhat==0.and.nhatdim==1).or.(non_magnetic_xc)) then
898      ABI_FREE(rhor_)
899    end if
900    if ((usexcnhat==0.and.nhat1dim==1).or.(non_magnetic_xc)) then
901      ABI_FREE(rhor1_)
902    end if
903 
904  end if ! nkxc=1 or nkxc=3
905 
906  call timab(181,2,tsec)
907 
908  DBG_EXIT("COLL")
909 
910 end subroutine dfpt_mkvxc_noncoll

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.

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=information 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

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)

SOURCE

497 subroutine dfpt_mkvxcgga(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,&
498 &                    nhat1,nhat1dim,nhat1gr,nhat1grdim,nkxc,&
499 &                    nspden,qphon,rhor1,usexcnhat,vxc1)
500 
501 !Arguments ------------------------------------
502 !scalars
503  integer,intent(in) :: cplex,nfft,nhat1dim,nhat1grdim,nkxc,nspden,usexcnhat
504  type(MPI_type),intent(in) :: mpi_enreg
505 !arrays
506  integer,intent(in) :: ngfft(18)
507  real(dp),intent(in) :: gprimd(3,3)
508  real(dp),intent(in) :: kxc(nfft,nkxc)
509  real(dp),intent(in) :: nhat1(cplex*nfft,nspden*nhat1dim)
510  real(dp),intent(in) :: nhat1gr(cplex*nfft,nspden,3*nhat1grdim)
511  real(dp),intent(in) :: qphon(3)
512  real(dp),intent(in),target :: rhor1(cplex*nfft,nspden)
513  real(dp),intent(out) :: vxc1(cplex*nfft,nspden)
514 
515 !Local variables-------------------------------
516 !scalars
517  integer :: ii,ir,ishift,ngrad,nspgrad,use_laplacian
518  logical :: test_nhat
519  real(dp) :: coeff_grho,coeff_grho_corr,coeff_grho_dn,coeff_grho_up
520  real(dp) :: coeffim_grho,coeffim_grho_corr,coeffim_grho_dn,coeffim_grho_up
521  real(dp) :: gradrho_gradrho1,gradrho_gradrho1_dn,gradrho_gradrho1_up
522  real(dp) :: gradrho_gradrho1im,gradrho_gradrho1im_dn,gradrho_gradrho1im_up
523  character(len=500) :: msg
524 !arrays
525  real(dp) :: r0(3),r0_dn(3),r0_up(3),r1(3),r1_dn(3),r1_up(3)
526  real(dp) :: r1im(3),r1im_dn(3),r1im_up(3)
527  real(dp),allocatable :: dnexcdn(:,:),rho1now(:,:,:)
528  real(dp),ABI_CONTIGUOUS pointer :: rhor1_ptr(:,:)
529 
530 ! *************************************************************************
531 
532  DBG_ENTER("COLL")
533 
534  if (nkxc/=12*min(nspden,2)-5) then
535    msg='Wrong nkxc value for GGA!'
536    ABI_BUG(msg)
537  end if
538 
539 !metaGGA contributions are not taken into account here
540  use_laplacian=0
541 
542 !PAW: substract 1st-order compensation density from 1st-order density
543  test_nhat=((nhat1dim==1).and.(usexcnhat==0.or.nhat1grdim==1))
544  if (test_nhat) then
545    ABI_MALLOC(rhor1_ptr,(cplex*nfft,nspden))
546    rhor1_ptr(:,:)=rhor1(:,:)-nhat1(:,:)
547  else
548    rhor1_ptr => rhor1
549  end if
550 
551 !call filterpot(paral_kgb,cplex,gmet,gsqcut,nfft,ngfft,2,qphon,rhor1_ptr)
552 
553 !Compute the gradients of the first-order density
554 !rho1now(:,:,1) contains the first-order density, and
555 !rho1now(:,:,2:4) contains the gradients of the first-order density
556  ishift=0 ; ngrad=2
557  ABI_MALLOC(rho1now,(cplex*nfft,nspden,ngrad*ngrad))
558  call xcden(cplex,gprimd,ishift,mpi_enreg,nfft,ngfft,ngrad,nspden,qphon,rhor1_ptr,rho1now)
559 
560 !PAW: add "exact" gradients of compensation density
561  if (test_nhat.and.usexcnhat==1) then
562    rho1now(:,1:nspden,1)=rho1now(:,1:nspden,1)+nhat1(:,1:nspden)
563  end if
564  if (nhat1grdim==1) then
565    do ii=1,3
566      rho1now(:,1:nspden,ii+1)=rho1now(:,1:nspden,ii+1)+nhat1gr(:,1:nspden,ii)
567    end do
568  end if
569  if (test_nhat) then
570    ABI_FREE(rhor1_ptr)
571  end if
572 
573 !Apply the XC kernel
574  nspgrad=2; if (nspden==2) nspgrad=5
575  ABI_MALLOC(dnexcdn,(cplex*nfft,nspgrad))
576 
577  if (cplex==1) then  ! Treat real case first
578    if (nspden==1) then
579      do ir=1,nfft
580        r0(:)=kxc(ir,5:7) ; r1(:)=rho1now(ir,1,2:4)
581        gradrho_gradrho1=dot_product(r0,r1)
582        dnexcdn(ir,1)=kxc(ir,1)*rho1now(ir,1,1) + kxc(ir,3)*gradrho_gradrho1
583        coeff_grho=kxc(ir,3)*rho1now(ir,1,1) + kxc(ir,4)*gradrho_gradrho1
584   !    Reuse the storage in rho1now
585        rho1now(ir,1,2:4)=r1(:)*kxc(ir,2)+r0(:)*coeff_grho
586      end do
587    else
588      do ir=1,nfft
589        do ii=1,3  ! grad of spin-up ans spin_dn GS rho
590          r0_up(ii)=kxc(ir,13+2*ii);r0_dn(ii)=kxc(ir,12+2*ii)-kxc(ir,13+2*ii)
591        end do
592        r0(:)=r0_up(:)+r0_dn(:)      ! grad of GS rho
593        r1_up(:)=rho1now(ir,1,2:4)   ! grad of spin-up rho1
594        r1_dn(:)=rho1now(ir,2,2:4)   ! grad of spin-down rho1
595        r1(:)=r1_up(:)+r1_dn(:)      ! grad of GS rho1
596        gradrho_gradrho1_up=dot_product(r0_up,r1_up)
597        gradrho_gradrho1_dn=dot_product(r0_dn,r1_dn)
598        gradrho_gradrho1   =dot_product(r0,r1)
599        dnexcdn(ir,1)=kxc(ir, 1)*rho1now(ir,1,1)     &
600 &       +kxc(ir, 2)*rho1now(ir,2,1)     &
601 &       +kxc(ir, 6)*gradrho_gradrho1_up &
602 &       +kxc(ir,11)*gradrho_gradrho1
603        dnexcdn(ir,2)=kxc(ir, 3)*rho1now(ir,2,1)     &
604 &       +kxc(ir, 2)*rho1now(ir,1,1)     &
605 &       +kxc(ir, 7)*gradrho_gradrho1_dn &
606 &       +kxc(ir,12)*gradrho_gradrho1
607        coeff_grho_corr=kxc(ir,11)*rho1now(ir,1,1) &
608 &       +kxc(ir,12)*rho1now(ir,2,1) &
609 &       +kxc(ir,13)*gradrho_gradrho1
610        coeff_grho_up=kxc(ir,6)*rho1now(ir,1,1)+kxc(ir,8)*gradrho_gradrho1_up
611        coeff_grho_dn=kxc(ir,7)*rho1now(ir,2,1)+kxc(ir,9)*gradrho_gradrho1_dn
612   !    Reuse the storage in rho1now
613        rho1now(ir,1,2:4)=(kxc(ir,4)+kxc(ir,10))*r1_up(:) &
614 &       +kxc(ir,10)            *r1_dn(:) &
615 &       +coeff_grho_up         *r0_up(:) &
616 &       +coeff_grho_corr       *r0(:)
617        rho1now(ir,2,2:4)=(kxc(ir,5)+kxc(ir,10))*r1_dn(:) &
618 &       +kxc(ir,10)            *r1_up(:) &
619 &       +coeff_grho_dn         *r0_dn(:) &
620 &       +coeff_grho_corr       *r0(:)
621      end do
622    end if ! nspden
623 
624  else ! if cplex==2
625    if (nspden==1) then
626      do ir=1,nfft
627        r0(:)=kxc(ir,5:7)
628        r1(:)  =rho1now(2*ir-1,1,2:4)
629        r1im(:)=rho1now(2*ir  ,1,2:4)
630        gradrho_gradrho1  =dot_product(r0,r1)
631        gradrho_gradrho1im=dot_product(r0,r1im)
632        dnexcdn(2*ir-1,1)=kxc(ir,1)*rho1now(2*ir-1,1,1) + kxc(ir,3)*gradrho_gradrho1
633        dnexcdn(2*ir  ,1)=kxc(ir,1)*rho1now(2*ir  ,1,1) + kxc(ir,3)*gradrho_gradrho1im
634        coeff_grho  =kxc(ir,3)*rho1now(2*ir-1,1,1) + kxc(ir,4)*gradrho_gradrho1
635        coeffim_grho=kxc(ir,3)*rho1now(2*ir  ,1,1) + kxc(ir,4)*gradrho_gradrho1im
636   !    Reuse the storage in rho1now
637        rho1now(2*ir-1,1,2:4)=r1(:)  *kxc(ir,2)+r0(:)*coeff_grho
638        rho1now(2*ir  ,1,2:4)=r1im(:)*kxc(ir,2)+r0(:)*coeffim_grho
639      end do
640    else
641      do ir=1,nfft
642        do ii=1,3  ! grad of spin-up ans spin_dn GS rho
643          r0_up(ii)=kxc(ir,13+2*ii);r0_dn(ii)=kxc(ir,12+2*ii)-kxc(ir,13+2*ii)
644        end do
645        r0(:)=r0_up(:)+r0_dn(:)          ! grad of GS rho
646        r1_up(:)=rho1now(2*ir-1,1,2:4)   ! grad of spin-up rho1
647        r1im_up(:)=rho1now(2*ir,1,2:4)   ! grad of spin-up rho1 , im part
648        r1_dn(:)=rho1now(2*ir-1,2,2:4)   ! grad of spin-down rho1
649        r1im_dn(:)=rho1now(2*ir,2,2:4)   ! grad of spin-down rho1 , im part
650        r1(:)=r1_up(:)+r1_dn(:)      ! grad of GS rho1
651        r1im(:)=r1im_up(:)+r1im_dn(:)      ! grad of GS rho1, im part
652        gradrho_gradrho1_up  =dot_product(r0_up,r1_up)
653        gradrho_gradrho1_dn  =dot_product(r0_dn,r1_dn)
654        gradrho_gradrho1     =dot_product(r0,r1)
655        gradrho_gradrho1im_up=dot_product(r0_up,r1im_up)
656        gradrho_gradrho1im_dn=dot_product(r0_dn,r1im_dn)
657        gradrho_gradrho1im   =dot_product(r0,r1im)
658        dnexcdn(2*ir-1,1)=kxc(ir, 1)*rho1now(2*ir-1,1,1) &
659 &       +kxc(ir, 2)*rho1now(2*ir-1,2,1) &
660 &       +kxc(ir, 6)*gradrho_gradrho1_up &
661 &       +kxc(ir,11)*gradrho_gradrho1
662        dnexcdn(2*ir-1,2)=kxc(ir, 3)*rho1now(2*ir-1,2,1) &
663 &       +kxc(ir, 2)*rho1now(2*ir-1,1,1) &
664 &       +kxc(ir, 7)*gradrho_gradrho1_dn &
665 &       +kxc(ir,12)*gradrho_gradrho1
666        dnexcdn(2*ir  ,1)=kxc(ir, 1)*rho1now(2*ir  ,1,1) &
667 &       +kxc(ir, 2)*rho1now(2*ir  ,2,1) &
668 &       +kxc(ir, 6)*gradrho_gradrho1im_up &
669 &       +kxc(ir,11)*gradrho_gradrho1im
670        dnexcdn(2*ir  ,2)=kxc(ir, 3)*rho1now(2*ir  ,2,1) &
671 &       +kxc(ir, 2)*rho1now(2*ir  ,1,1) &
672 &       +kxc(ir, 7)*gradrho_gradrho1im_dn &
673 &       +kxc(ir,12)*gradrho_gradrho1im
674        coeff_grho_corr  =kxc(ir,11)*rho1now(2*ir-1,1,1) &
675 &       +kxc(ir,12)*rho1now(2*ir-1,2,1) &
676 &       +kxc(ir,13)*gradrho_gradrho1
677        coeffim_grho_corr=kxc(ir,11)*rho1now(2*ir  ,1,1) &
678 &       +kxc(ir,12)*rho1now(2*ir  ,2,1) &
679 &       +kxc(ir,13)*gradrho_gradrho1im
680        coeff_grho_up  =kxc(ir,6)*rho1now(2*ir-1,1,1)+kxc(ir,8)*gradrho_gradrho1_up
681        coeff_grho_dn  =kxc(ir,7)*rho1now(2*ir-1,2,1)+kxc(ir,9)*gradrho_gradrho1_dn
682        coeffim_grho_up=kxc(ir,6)*rho1now(2*ir  ,1,1)+kxc(ir,8)*gradrho_gradrho1im_up
683        coeffim_grho_dn=kxc(ir,7)*rho1now(2*ir  ,2,1)+kxc(ir,9)*gradrho_gradrho1im_dn
684 !      Reuse the storage in rho1now
685        rho1now(2*ir-1,1,2:4)=(kxc(ir,4)+kxc(ir,10))*r1_up(:) &
686 &       +kxc(ir,10)            *r1_dn(:) &
687 &       +coeff_grho_up         *r0_up(:) &
688 &       +coeff_grho_corr*r0(:)
689        rho1now(2*ir-1,2,2:4)=(kxc(ir,5)+kxc(ir,10))*r1_dn(:) &
690 &       +kxc(ir,10)            *r1_up(:) &
691 &       +coeff_grho_dn         *r0_dn(:) &
692 &       +coeff_grho_corr*r0(:)
693        rho1now(2*ir  ,1,2:4)=(kxc(ir,4)+kxc(ir,10))*r1im_up(:) &
694 &       +kxc(ir,10)            *r1im_dn(:) &
695 &       +coeffim_grho_up       *r0_up(:)   &
696 &       +coeffim_grho_corr     *r0(:)
697        rho1now(2*ir  ,2,2:4)=(kxc(ir,5)+kxc(ir,10))*r1im_dn(:) &
698 &       +kxc(ir,10)            *r1im_up(:) &
699 &       +coeffim_grho_dn       *r0_dn(:)   &
700 &       +coeffim_grho_corr     *r0(:)
701      end do
702    end if ! nspden
703 
704  end if
705 
706  vxc1(:,:)=zero
707  call xcpot(cplex,gprimd,ishift,use_laplacian,mpi_enreg,nfft,ngfft,ngrad,nspden,&
708 & nspgrad,qphon,depsxc=dnexcdn,rhonow=rho1now,vxc=vxc1)
709 
710 !call filterpot(paral_kgb,cplex,gmet,gsqcut,nfft,ngfft,nspden,qphon,vxc1)
711 
712  ABI_FREE(dnexcdn)
713  ABI_FREE(rho1now)
714 
715  DBG_EXIT("COLL")
716 
717 end subroutine dfpt_mkvxcgga

ABINIT/dfpt_mkvxcgga_n0met [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_mkvxcgga_n0met

FUNCTION

 Compute the contribution to the second q-gradient of the metric 
 perturbation that comes from gga XC potentials and depends only
 on ground state rho

INPUTS

  beta= indicates the Cartesian direction of the metric perturbation
  cplex= if 1, real space 1-order functions on FFT grid are REAL,
    if 2, COMPLEX
  delta= indicates the Cartesian direction of the first q-gradient 
  gamma= indicates the Cartesian direction of the second q-gradient
  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=information about MPI parallelization
  nfft=(effective) number of FFT grid points (for this processor)
  ngfft(18)=contain all needed information about 3D FFT
  nkxc=second dimension of the kxc array
  nspden=number of spin-density components
  rho(cplex*nfft,2)=array for ground-state electron spin-density
   in electrons/bohr**3 (second index corresponds to spin-up and spin-down)

OUTPUT

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

NOTES

  For the time being, a rather crude coding, to be optimized ...
  Content of Kxc array:
  Only works with nspden=1
   ===== 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)

SOURCE

1088 subroutine dfpt_mkvxcgga_n0met(beta,cplex,delta,gamma,gprimd,kxc,mpi_enreg,nfft,ngfft,&
1089 &                    nkxc,nspden,rhor,vxc1)
1090 
1091 !Arguments ------------------------------------
1092 !scalars
1093  integer,intent(in) :: beta,cplex,delta,gamma,nfft,nkxc,nspden
1094  type(MPI_type),intent(in) :: mpi_enreg
1095 !arrays
1096  integer,intent(in) :: ngfft(18)
1097  real(dp),intent(in) :: gprimd(3,3)
1098  real(dp),intent(in) :: kxc(nfft,nkxc)
1099  real(dp),intent(in),target :: rhor(cplex*nfft,nspden)
1100  real(dp),intent(out) :: vxc1(2*nfft,nspden)
1101 
1102 !Local variables-------------------------------
1103 !scalars
1104  integer :: alpha,ii,ir,ishift,ngrad,nspgrad
1105  real(dp) :: delag,delad,delbd,delbg,deldg
1106  real(dp) :: gmodsq
1107  character(len=500) :: msg
1108 !arrays
1109  real(dp) :: r0(3)
1110  real(dp),allocatable :: dadgg(:,:),dadgtgn(:,:),gna(:,:),dadgngn_1(:,:),dadgngn_2(:,:)
1111  real(dp),allocatable :: dadgngn(:,:,:),kro_an(:,:,:),sumgrad(:,:,:)
1112 
1113 ! *************************************************************************
1114 
1115  DBG_EXIT("COLL")
1116 
1117  if (nkxc/=7) then
1118    msg='Wrong nkxc value for GGA in the longwave driver (optdriver=10)!'
1119    ABI_BUG(msg)
1120  end if
1121 
1122 !Kronecker deltas
1123  delbd=0.0_dp; delbg=0.0_dp; deldg=0.0_dp
1124  if (beta==delta) delbd=1.0_dp
1125  if (beta==gamma) delbg=1.0_dp
1126  if (delta==gamma) deldg=1.0_dp
1127 
1128 !Apply the XC kernel
1129  nspgrad=1
1130  ABI_MALLOC(dadgg,(cplex*nfft,nspgrad))
1131  ABI_MALLOC(dadgtgn,(cplex*nfft,nspgrad))
1132  ABI_MALLOC(gna,(cplex*nfft,nspgrad))
1133  ABI_MALLOC(dadgngn_1,(cplex*nfft,nspgrad))
1134  ABI_MALLOC(dadgngn_2,(cplex*nfft,nspgrad))
1135  do ir=1,nfft
1136    r0(:)=kxc(ir,5:7)
1137    gmodsq=r0(1)**2+r0(2)**2+r0(3)**2
1138    dadgg(ir,1)=kxc(ir,4)*gmodsq*(delbd*r0(gamma)+delbg*r0(delta))
1139    dadgtgn(ir,1)=two*kxc(ir,4)*r0(beta)*r0(delta)*r0(gamma)
1140    gna(ir,1)=(delbg*r0(delta)+delbd*r0(gamma)+two*deldg*r0(beta))*kxc(ir,2)
1141    dadgngn_1(ir,1)=delbd*kxc(ir,4)*rhor(ir,1)*r0(gamma)
1142    dadgngn_2(ir,1)=delbg*kxc(ir,4)*rhor(ir,1)*r0(delta)
1143  end do
1144 
1145 !Incorporate the terms that do not need further treatment 
1146  do ir=1,nfft
1147    ii=2*ir
1148    vxc1(ii-1,1)= -dadgg(ir,1)-dadgtgn(ir,1)-gna(ir,1)
1149    vxc1(ii,1)= zero
1150  end do
1151  ABI_FREE(dadgg)
1152  ABI_FREE(dadgtgn)
1153  ABI_FREE(gna)
1154 
1155 !Build the last term whose gradient needs to be computed
1156  ABI_MALLOC(dadgngn,(cplex*nfft,nspgrad,3))
1157  ABI_MALLOC(kro_an,(cplex*nfft,nspgrad,3))
1158  ABI_MALLOC(sumgrad,(cplex*nfft,nspgrad,3))
1159  do alpha=1,3
1160    delad=0.0_dp; delag=0.0_dp
1161    if (alpha==delta) delad=1.0_dp
1162    if (alpha==gamma) delag=1.0_dp
1163    do ir=1,nfft
1164      r0(:)=kxc(ir,5:7)
1165      dadgngn(ir,1,alpha)=(dadgngn_1(ir,1)+dadgngn_2(ir,1))*r0(alpha)
1166      kro_an(ir,1,alpha)=(delbd*delag+delbg*delad)*rhor(ir,1)*kxc(ir,2)
1167      sumgrad(ir,1,alpha)=dadgngn(ir,1,alpha)+kro_an(ir,1,alpha)
1168    end do
1169  end do
1170 
1171  ABI_FREE(dadgngn_1)
1172  ABI_FREE(dadgngn_2)
1173  ABI_FREE(dadgngn)
1174  ABI_FREE(kro_an)
1175 
1176 !Now the term whose sum over real-space derivatives has to be computed.
1177 !(Use the same routine as in the q-gradient of the XC kernel. It saves
1178 ! the gradient sum in the imaginary part of vxc1 and includes an additional
1179 ! two_pi factor. Need to fix this after the call.) 
1180  ishift=0 ; ngrad=2
1181  call xcpotdq(sumgrad,cplex,gprimd,ishift,mpi_enreg,nfft, &
1182 & ngfft,ngrad,nspden,nspgrad,vxc1)
1183 
1184  do ir=1,nfft
1185    ii=2*ir
1186    vxc1(ii-1,1)=vxc1(ii-1,1)+vxc1(ii,1)/two_pi
1187    vxc1(ii,1)=zero
1188  end do 
1189 
1190  
1191  ABI_FREE(sumgrad)
1192 
1193 end subroutine dfpt_mkvxcgga_n0met

ABINIT/dfpt_mkvxcggadq [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_mkvxcggadq

FUNCTION

 Compute the first-order change of exchange-correlation potential
 in case of GGA functionals
 Use the q-gradient (Cartesian) of the exchange-correlation kernel.

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=information about MPI parallelization
  nfft=(effective) number of FFT grid points (for this processor)
  ngfft(18)=contain all needed information about 3D FFT
  nkxc=second dimension of the kxc array
  nspden=number of spin-density components
  qdirc= indicates the Cartesian direction of the q-gradient (1,2 or 3)
  rhor1tmp(cplex*nfft,2)=array for first-order electron spin-density
   in electrons/bohr**3 (second index corresponds to spin-up and spin-down)

OUTPUT

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

NOTES

  For the time being, a rather crude coding, to be optimized ...
  Content of Kxc array:
  Only works with nspden=1
   ===== 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)

SOURCE

 957 subroutine dfpt_mkvxcggadq(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,&
 958 &                    nkxc,nspden,qdirc,rhor1,vxc1)
 959 
 960 !Arguments ------------------------------------
 961 !scalars
 962  integer,intent(in) :: cplex,nfft,nkxc,nspden,qdirc
 963  type(MPI_type),intent(in) :: mpi_enreg
 964 !arrays
 965  integer,intent(in) :: ngfft(18)
 966  real(dp),intent(in) :: gprimd(3,3)
 967  real(dp),intent(in) :: kxc(nfft,nkxc)
 968  real(dp),intent(in),target :: rhor1(cplex*nfft,nspden)
 969  real(dp),intent(out) :: vxc1(2*nfft,nspden)
 970 
 971 !Local variables-------------------------------
 972 !scalars
 973  integer :: ii,ir,ishift,ngrad,nspgrad
 974  real(dp) :: gradrho_gradrho1
 975  character(len=500) :: msg
 976 !arrays
 977  real(dp) :: qphon(3)
 978  real(dp) :: r0(3),r1(3)
 979  real(dp),allocatable :: ar1(:,:)
 980  real(dp),allocatable :: a_gradi_r1(:,:)
 981  real(dp),allocatable :: dadgradn_t1(:,:,:),dadgradn_t2(:,:)
 982  real(dp),allocatable :: rho1now(:,:,:)
 983  real(dp),ABI_CONTIGUOUS pointer :: rhor1_ptr(:,:)
 984 
 985 ! *************************************************************************
 986 
 987  DBG_EXIT("COLL")
 988 
 989  if (nkxc/=7) then
 990    msg='Wrong nkxc value for GGA in the longwave driver (optdriver=10)!'
 991    ABI_BUG(msg)
 992  end if
 993 
 994 !Compute the gradients of the first-order density
 995 !rho1now(:,:,1) contains the first-order density, and
 996 !rho1now(:,:,2:4) contains the gradients of the first-order density
 997  ishift=0 ; ngrad=2
 998  qphon(:)=zero 
 999  rhor1_ptr => rhor1
1000  ABI_MALLOC(rho1now,(cplex*nfft,nspden,ngrad*ngrad))
1001  call xcden(cplex,gprimd,ishift,mpi_enreg,nfft,ngfft,ngrad,nspden,qphon,rhor1_ptr,rho1now)
1002 
1003 !Apply the XC kernel
1004  nspgrad=1
1005  ABI_MALLOC(ar1,(cplex*nfft,nspgrad))
1006  ABI_MALLOC(a_gradi_r1,(cplex*nfft,nspgrad))
1007  ABI_MALLOC(dadgradn_t1,(cplex*nfft,nspgrad,3))
1008  ABI_MALLOC(dadgradn_t2,(cplex*nfft,nspgrad))
1009  do ir=1,nfft
1010    r0(:)=kxc(ir,5:7); r1(:)=rho1now(ir,1,2:4)
1011    gradrho_gradrho1=dot_product(r0,r1)
1012    ar1(ir,1)=kxc(ir,2)*rho1now(ir,1,1)
1013    a_gradi_r1(ir,1)=kxc(ir,2)*r1(qdirc)
1014    dadgradn_t2(ir,1)=kxc(ir,4)*gradrho_gradrho1*r0(qdirc)
1015    dadgradn_t1(ir,1,:)=kxc(ir,4)*r0(:)*r0(qdirc)*rho1now(ir,1,1)
1016  end do
1017  do ii=1,3
1018    if (ii==qdirc) dadgradn_t1(:,1,ii)=dadgradn_t1(:,1,ii)+ar1(:,1)
1019  end do
1020 
1021 !Incorporate the terms that do not need further treatment 
1022 !(a -i factor is applied here)
1023  do ir=1,nfft
1024    ii=2*ir
1025    vxc1(ii-1,1)=zero
1026    vxc1(ii,1)= -a_gradi_r1(ir,1) -dadgradn_t2(ir,1)
1027  end do
1028  ABI_FREE(rho1now)
1029  ABI_FREE(a_gradi_r1)
1030  ABI_FREE(dadgradn_t2)
1031  ABI_FREE(ar1)
1032 
1033 !Now the term whose sum over real-space derivatives has to be computed
1034  call xcpotdq(dadgradn_t1,cplex,gprimd,ishift,mpi_enreg,nfft, &
1035 & ngfft,ngrad,nspden,nspgrad,vxc1)
1036 
1037  ABI_FREE(dadgradn_t1)
1038 
1039 end subroutine dfpt_mkvxcggadq

ABINIT/m_dfpt_mkvxc [ Modules ]

[ Top ] [ Modules ]

NAME

  m_dfpt_mkvxc

FUNCTION

COPYRIGHT

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

SOURCE

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 module m_dfpt_mkvxc
23 
24  use defs_basis
25  use m_errors
26  use m_abicore
27  use m_xc_noncoll
28 
29  use defs_abitypes,     only : MPI_type
30  use m_time,     only : timab
31  use m_symtk,    only : matr3inv
32  use m_xctk,     only : xcden, xcpot, xcpotdq
33 
34  implicit none
35 
36  private