TABLE OF CONTENTS


ABINIT/dfpt_rhotov [ Functions ]

[ Top ] [ Functions ]

NAME

 dfpt_rhotov

FUNCTION

 This routine is called to compute, from a given 1st-order total density
   - the trial (local) 1st-order potential and/or the residual potential,
   - some contributions to the 2nd-order energy

COPYRIGHT

 Copyright (C) 1999-2018 ABINIT group (XG, DRH, MT, 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 .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt .

INPUTS

  cplex: if 1, real space 1-order WF on FFT grid are REAL; if 2, COMPLEX
  gsqcut=cutoff on (k+G)^2 (bohr^-2)
  idir=direction of atomic displacement (=1,2 or 3 : displacement of atom ipert along the 1st, 2nd or 3rd axis).
  ipert=type of the perturbation
  ixc= choice of exchange-correlation scheme
  kxc(nfft,nkxc)=exchange-correlation kernel
  mpi_enreg=information about MPI parallelization
  natom=number of atoms in cell.
  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- compensation density
  nhat1(cplex*nfft,2nspden*usepaw)= -PAW only- 1st-order compensation density
  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 array kxc, see rhotoxc.f for a description
  nspden=number of spin-density components
  n3xccc=dimension of xccc3d1 ; 0 if no XC core correction is used
  optene=0: the contributions to the 2nd order energy are not computed
         1: the contributions to the 2nd order energy are computed
  optres=0: the trial potential residual is computed ; the input potential value is kept
         1: the new value of the trial potential is computed in place of the input value
  paral_kgb=flag controlling (k,g,bands) parallelization
  qphon(3)=reduced coordinates for the phonon wavelength
  rhog(2,nfft)=array for Fourier transform of GS electron density
  rhog1(2,nfft)=RF electron density in reciprocal space
  rhor(nfft,nspden)=array for GS electron density in electrons/bohr**3.
  rhor1(cplex*nfft,nspden)=RF electron density in real space (electrons/bohr**3).
  rprimd(3,3)=dimensional primitive translations in real space (bohr)
  ucvol=unit cell volume in ($\textrm{bohr}^{3}$)
  usepaw= 0 for non paw calculation; =1 for paw calculation
  usexcnhat= -PAW only- flag controling use of compensation density in Vxc
  vpsp1(cplex*nfft)=first-order derivative of the ionic potential
  xccc3d1(cplex*n3xccc)=3D change in core charge density, see n3xccc

OUTPUT

  vhartr1(cplex*nfft)=1-order Hartree potential (not output if size=0)
  vxc1(cplex*nfft,nspden)= 1st-order XC potential (not output if size=0)
  ==== if optene==1
    ehart01=inhomogeneous 1st-order Hartree part of 2nd-order total energy
    ehart1=1st-order Hartree part of 2nd-order total energy
    exc1=1st-order exchange-correlation part of 2nd-order total energy
    elpsp1=1st-order local pseudopot. part of 2nd-order total energy.
  ==== if optres==0
    vresid1(cplex*nfft,nspden)=potential residual
    vres2=square of the norm of the residual

SIDE EFFECTS

  ==== if optres==1
    vtrial1(cplex*nfft,nspden)= new value of 1st-order trial potential

PARENTS

      dfpt_scfcv

CHILDREN

      dfpt_mkvxc,dfpt_mkvxc_noncoll,dfpt_mkvxcstr,dfpt_v1zeeman,dotprod_vn
      hartre,hartrestr,sqnorm_v,timab

SOURCE

 79 #if defined HAVE_CONFIG_H
 80 #include "config.h"
 81 #endif
 82 
 83 #include "abi_common.h"
 84 
 85 
 86  subroutine dfpt_rhotov(cplex,ehart01,ehart1,elpsp1,exc1,elmag1,gsqcut,idir,ipert,&
 87 &           ixc,kxc,mpi_enreg,natom,nfft,ngfft,nhat,nhat1,nhat1gr,nhat1grdim,nkxc,nspden,n3xccc,&
 88 &           optene,optres,paral_kgb,qphon,rhog,rhog1,rhor,rhor1,rprimd,ucvol,&
 89 &           usepaw,usexcnhat,vhartr1,vpsp1,vresid1,vres2,vtrial1,vxc,vxc1,xccc3d1,ixcrot)
 90 
 91  use defs_basis
 92  use defs_abitypes
 93  use m_profiling_abi
 94  use m_errors
 95  use m_cgtools
 96 
 97 !This section has been created automatically by the script Abilint (TD).
 98 !Do not modify the following lines by hand.
 99 #undef ABI_FUNC
100 #define ABI_FUNC 'dfpt_rhotov'
101  use interfaces_18_timing
102  use interfaces_56_xc
103  use interfaces_72_response, except_this_one => dfpt_rhotov
104 !End of the abilint section
105 
106  implicit none
107 
108 !Arguments ------------------------------------
109 !scalars
110  integer,intent(in) :: cplex,idir,ipert,ixc,n3xccc,natom,nfft,nhat1grdim,nkxc,nspden
111  integer,intent(in) :: optene,optres,paral_kgb,usepaw,usexcnhat,ixcrot
112  real(dp),intent(in) :: gsqcut,ucvol
113  real(dp),intent(inout) :: ehart01 !vz_i
114  real(dp),intent(out) :: vres2
115  type(MPI_type),intent(in) :: mpi_enreg
116 !arrays
117  real(dp),intent(in) :: kxc(nfft,nkxc)
118  real(dp),intent(in) :: vxc(nfft,nspden)
119  real(dp),intent(in) :: nhat(nfft,nspden)
120  real(dp),intent(in) :: nhat1(cplex*nfft,nspden)  !vz_d
121  real(dp),intent(in) :: nhat1gr(cplex*nfft,nspden,3*nhat1grdim)
122  real(dp),intent(in) :: qphon(3),rhog(2,nfft)
123  real(dp),intent(in) :: rhog1(2,nfft)
124  real(dp),target,intent(in) :: rhor(nfft,nspden),rhor1(cplex*nfft,nspden)
125  real(dp),intent(in) :: rprimd(3,3),vpsp1(cplex*nfft)
126  real(dp),intent(in) :: xccc3d1(cplex*n3xccc)
127  real(dp),intent(inout) :: vtrial1(cplex*nfft,nspden),elpsp1,ehart1,exc1,elmag1
128  real(dp),intent(out) :: vresid1(cplex*nfft,nspden)
129  real(dp),target,intent(out) :: vhartr1(:),vxc1(:,:)
130 
131 !Local variables-------------------------------
132 !scalars
133  integer :: ifft,ispden,nfftot,option
134  integer :: optnc,nkxc_cur
135  logical :: vhartr1_allocated,vxc1_allocated
136  real(dp) :: doti,elpsp10
137 !arrays
138  integer,intent(in)   :: ngfft(18)
139  real(dp)             :: tsec(20)
140  real(dp),allocatable :: rhor1_nohat(:,:),vhartr01(:),vxc1val(:,:)
141  real(dp),pointer     :: rhor1_(:,:),vhartr1_(:),vxc1_(:,:),v1zeeman(:,:)
142 
143 ! *********************************************************************
144 
145  call timab(157,1,tsec)
146 
147  !FR EB SPr
148  if (nspden==4) then
149    if(usepaw==1) then
150      MSG_ERROR('DFPT with nspden=4 works only for norm-conserving psp!')
151    end if
152  end if
153 
154 !Get size of FFT grid
155  nfftot=ngfft(1)*ngfft(2)*ngfft(3)
156 
157 !Eventually allocate temporary memory space
158  vhartr1_allocated=(size(vhartr1)>0)
159  if (vhartr1_allocated) then
160    vhartr1_ => vhartr1
161  else
162    ABI_ALLOCATE(vhartr1_,(cplex*nfft))
163  end if
164  vxc1_allocated=(size(vxc1)>0)
165  if (vxc1_allocated) then
166    vxc1_ => vxc1
167  else
168    ABI_ALLOCATE(vxc1_,(cplex*nfft,nspden))
169  end if
170 
171 !If needed, store pseudo density without charge compensation
172  if (usepaw==1.and.usexcnhat==0) then
173    ABI_ALLOCATE(rhor1_,(cplex*nfft,nspden))
174    rhor1_(:,:)=rhor1(:,:)-nhat1(:,:)
175  else
176    rhor1_ => rhor1
177  end if
178 
179 
180  if(ipert==natom+5)then
181    ABI_ALLOCATE(v1zeeman,(cplex*nfft,nspden))
182    call dfpt_v1zeeman(nspden,nfft,cplex,idir,v1zeeman)
183  end if
184 
185 !------ Compute 1st-order Hartree potential (and energy) ----------------------
186 
187  call hartre(cplex,gsqcut,0,mpi_enreg,nfft,ngfft,paral_kgb,rhog1,rprimd,vhartr1_,qpt=qphon)
188 
189  if (optene>0) then
190    call dotprod_vn(cplex,rhor1,ehart1,doti,nfft,nfftot,1,1,vhartr1_,ucvol)
191  end if
192 
193  if (optene>0) ehart01=zero
194  if(ipert==natom+3 .or. ipert==natom+4) then
195    ABI_ALLOCATE(vhartr01,(cplex*nfft))
196    call hartrestr(gsqcut,idir,ipert,mpi_enreg,natom,nfft,ngfft,paral_kgb,rhog,rprimd,vhartr01)
197    if (optene>0) then
198      call dotprod_vn(cplex,rhor1,ehart01,doti,nfft,nfftot,1,1,vhartr01,ucvol)
199      ehart01=two*ehart01
200      ehart1=ehart1+ehart01
201    end if
202 !  Note that there is a factor 2.0_dp difference with the similar GS formula
203    vhartr1_(:)=vhartr1_(:)+vhartr01(:)
204 
205    ABI_DEALLOCATE(vhartr01)
206  end if
207 
208 !------ Compute 1st-order XC potential (and energy) ----------------------
209 !(including the XC core correction)
210 
211 !Compute Vxc^(1) (with or without valence contribution according to options)
212  option=0;if (optene==0) option=1
213  if(ipert==natom+3.or.ipert==natom+4) then
214    call dfpt_mkvxcstr(cplex,idir,ipert,kxc,mpi_enreg,natom,nfft,ngfft,nhat,&
215 &   nhat1,nkxc,nspden,n3xccc,option,paral_kgb,qphon,rhor,rhor1,rprimd,&
216 &   usepaw,usexcnhat,vxc1_,xccc3d1)
217  else
218 ! FR EB non-collinear magnetism
219 ! the second nkxc should be nkxc_cur (see 67_common/nres2vres.F90)
220    if (nspden==4) then
221      optnc=1
222      nkxc_cur=nkxc ! TODO: remove nkxc_cur?
223 
224      call dfpt_mkvxc_noncoll(cplex,ixc,kxc,mpi_enreg,nfft,ngfft,nhat,usepaw,nhat1,usepaw,nhat1gr,nhat1grdim,nkxc,&
225 &     nspden,n3xccc,optnc,option,paral_kgb,qphon,rhor,rhor1,rprimd,usexcnhat,vxc,vxc1_,xccc3d1,ixcrot=ixcrot)
226 
227    else
228      call dfpt_mkvxc(cplex,ixc,kxc,mpi_enreg,nfft,ngfft,nhat1,usepaw,nhat1gr,nhat1grdim,nkxc,&
229 &     nspden,n3xccc,option,paral_kgb,qphon,rhor1,rprimd,usexcnhat,vxc1_,xccc3d1)
230    end if !nspden==4
231  end if
232 
233 !Compute local contribution to 2nd-order energy (includes Vxc and Vpsp and Vmag)
234  if (optene>0) then
235    if (usepaw==0) then
236      call dotprod_vn(cplex,rhor1,elpsp10,doti,nfft,nfftot,nspden,1,vxc1_,ucvol)
237      call dotprod_vn(cplex,rhor1,elpsp1 ,doti,nfft,nfftot,1     ,1,vpsp1,ucvol)
238      if (ipert==natom+5) then
239        call dotprod_vn(cplex,rhor1,elmag1 ,doti,nfft,nfftot,nspden,1,v1zeeman,ucvol)
240      end if
241    else
242      if (usexcnhat/=0) then
243        ABI_ALLOCATE(rhor1_nohat,(cplex*nfft,1))
244        rhor1_nohat(:,1)=rhor1(:,1)-nhat1(:,1)
245        call dotprod_vn(cplex,rhor1      ,elpsp10,doti,nfft,nfftot,nspden,1,vxc1_,ucvol)
246        call dotprod_vn(cplex,rhor1_nohat,elpsp1 ,doti,nfft,nfftot,1     ,1,vpsp1,ucvol)
247        ABI_DEALLOCATE(rhor1_nohat)
248      else
249        call dotprod_vn(cplex,rhor1_,elpsp10,doti,nfft,nfftot,nspden,1,vxc1_,ucvol)
250        call dotprod_vn(cplex,rhor1_,elpsp1 ,doti,nfft,nfftot,1     ,1,vpsp1,ucvol)
251      end if
252    end if
253 
254 !  Note that there is a factor 2 difference with the similar GS formula
255    elpsp1=two*(elpsp1+elpsp10)
256  end if
257 
258 
259 !Compute XC valence contribution exc1 and complete eventually Vxc^(1)
260  if (optene>0) then
261    ABI_ALLOCATE(vxc1val,(cplex*nfft,nspden))
262    vxc1val=zero
263    option=2
264 !FR SPr EB non-collinear magnetism
265    if (nspden==4) then
266      optnc=1
267      nkxc_cur=nkxc
268      call dfpt_mkvxc_noncoll(cplex,ixc,kxc,mpi_enreg,nfft,ngfft,nhat,usepaw,nhat1,usepaw,nhat1gr,nhat1grdim,nkxc,&
269 &     nspden,n3xccc,optnc,option,paral_kgb,qphon,rhor,rhor1,rprimd,usexcnhat,vxc,vxc1val,xccc3d1,ixcrot=ixcrot)
270    else
271      call dfpt_mkvxc(cplex,ixc,kxc,mpi_enreg,nfft,ngfft,nhat1,usepaw,nhat1gr,nhat1grdim,nkxc,&
272 &     nspden,n3xccc,option,paral_kgb,qphon,rhor1,rprimd,usexcnhat,vxc1val,xccc3d1)
273    end if !nspden==4
274    vxc1_(:,:)=vxc1_(:,:)+vxc1val(:,:)
275    call dotprod_vn(cplex,rhor1_,exc1,doti,nfft,nfftot,nspden,1,vxc1val,ucvol)
276    ABI_DEALLOCATE(vxc1val)
277  end if
278 
279  if (usepaw==1.and.usexcnhat==0) then
280    ABI_DEALLOCATE(rhor1_)
281  end if
282 
283 !DEBUG (do not take away)
284 !Compute NSC energy ensc1 associated with rhor1 in vtrial1, for debugging purposes
285 !call dotprod_vn(cplex,rhor1,ensc1,doti,nfft,nfftot,nspden,1,vtrial1,ucvol)
286 !write(std_out,*)' ek0+eeig0+eloc0=',ek0+eeig0+eloc0
287 !write(std_out,*)' ensc1=',ensc1
288 !Compute NSC energy associated with vtrial1, for debugging purposes
289 !call dotprod_vn(cplex,rhor1,ensc1,doti,mpi_enreg,nfft,nfftot,nspden,1,vtrial1,ucvol)
290 !ensc1=ensc1+half*enl1
291 !write(std_out,*)' dfpt_rhotov : check NSC energy, diff=',&
292 !&  ek0+edocc+eeig0+eloc0+enl0+ensc1
293 !write(std_out,*)' evarNSC=',ek0+edocc+eeig0+eloc0+enl0
294 !write(std_out,*)' ensc1,exc1=',ensc1,exc1
295 !ENDDEBUG
296 
297 !Here, vhartr1 contains Hartree potential, vpsp1 contains local psp,
298 !while vxc1 contain xc potential
299 
300 !------ Produce residual vector and square of norm of it -------------
301 !(only if requested ; if optres==0)
302  if (optres==0) then
303 !$OMP PARALLEL DO COLLAPSE(2)
304    do ispden=1,min(nspden,2)
305      do ifft=1,cplex*nfft
306        vresid1(ifft,ispden)=vhartr1_(ifft)+vxc1_(ifft,ispden)+vpsp1(ifft)-vtrial1(ifft,ispden)
307      end do
308    end do
309    if(nspden==4)then
310 !$OMP PARALLEL DO COLLAPSE(2)
311      do ispden=3,4
312        do ifft=1,cplex*nfft
313          vresid1(ifft,ispden)=vxc1_(ifft,ispden)-vtrial1(ifft,ispden)
314        end do
315      end do
316    end if
317 
318    if (ipert==natom+5) then
319      vresid1 = vresid1 + v1zeeman
320    end if
321 !  Compute square norm vres2 of potential residual vresid
322    call sqnorm_v(cplex,nfft,vres2,nspden,optres,vresid1)
323 
324  else
325 
326 !  ------ Produce new value of trial potential-------------
327 !  (only if requested ; if optres==1)
328 
329 !$OMP PARALLEL DO COLLAPSE(2)
330    do ispden=1,min(nspden,2)
331      do ifft=1,cplex*nfft
332        vtrial1(ifft,ispden)=vhartr1_(ifft)+vxc1_(ifft,ispden)+vpsp1(ifft)
333      end do
334    end do
335    if(nspden==4)then
336 !$OMP PARALLEL DO COLLAPSE(2)
337      do ispden=3,4
338        do ifft=1,cplex*nfft
339          vtrial1(ifft,ispden)=vxc1_(ifft,ispden)
340        end do
341      end do
342    end if
343 
344    if (ipert==natom+5) then
345      vtrial1 = vtrial1 + v1zeeman
346    end if
347 
348  end if
349 
350 !Release temporary memory space
351  if (.not.vhartr1_allocated) then
352    ABI_DEALLOCATE(vhartr1_)
353  end if
354  if (.not.vxc1_allocated) then
355    ABI_DEALLOCATE(vxc1_)
356  end if
357 
358  if (ipert==natom+5) then
359    ABI_DEALLOCATE(v1zeeman)
360  end if
361 
362  call timab(157,2,tsec)
363 
364 end subroutine dfpt_rhotov