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

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

SOURCE

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

ABINIT/dfpt_v1zeeman [ Functions ]

[ Top ] [ Functions ]

NAME

  dfpt_v1zeeman

FUNCTION

  Calculate 1st order Zeeman potential = -vec{\sigma}.\vec{b}, where
  sigma is the vector of Pauli matrices and \vec{b} is the unit
  vector indicating the perturbing field direction.

INPUTS

  nspden = number of density matrix components
  nfft   = numbder of fft grid points
  cplex  = complex or real density matrix
  idir   = direction of the perturbing field in Cartesian frame
           1: along x
           2: along y
           3: along z
           4: identity matrix at each fft point is returned (for density-density response)

OUTPUT

  v1zeeman(nfft*cplex,nspden)= 1st order Zeeman potential, or Identity matrix (electrostatic potential) for idir=4

SIDE EFFECTS

NOTES

  The definition of components of the potential matrix differ depending on cplex
  for nspden=4:
  For cplex=1, the potential is defined as (V_upup,V_dndn,Re[V_updn],Im[V_updn])
  For cplex=2, the definition is (V_upup,V_dndn,V_updn,i.V_updn)

SOURCE

406 subroutine dfpt_v1zeeman(nspden,nfft,cplex,idir,v1zeeman)
407 
408 !Arguments ------------------------------------
409  integer , intent(in)    :: idir,nfft,cplex,nspden
410  real(dp), intent(inout) :: v1zeeman(cplex*nfft,nspden)
411 
412 !Local variables-------------------------------
413  integer :: ifft
414 !character(len=500) :: msg
415 
416 ! *************************************************************************
417 
418  DBG_ENTER("COLL")
419 
420 ! if (option/=1 .and. option/=2 ) then
421 !   write(msg,'(3a,i0)')&
422 !&   'The argument option should be 1 or 2,',ch10,&
423 !&   'however, option=',option
424 !   ABI_BUG(msg)
425 ! end if
426 !
427 ! if (sizein<1) then
428 !   write(msg,'(3a,i0)')&
429 !&   'The argument sizein should be a positive number,',ch10,&
430 !&   'however, sizein=',sizein
431 !   ABI_ERROR(msg)
432 ! end if
433 
434  DBG_EXIT("COLL")
435 
436  select case(cplex)
437  case(1)
438    if (nspden==4) then
439      if(idir==3)then       ! Zeeman field along the 3rd axis (z)
440        v1zeeman(:,1)=-0.5d0
441        v1zeeman(:,2)=+0.5d0
442        v1zeeman(:,3)= 0.0d0
443        v1zeeman(:,4)= 0.0d0
444      else if(idir==2)then  ! Zeeman field along the 2nd axis (y)
445        v1zeeman(:,1)= 0.0d0
446        v1zeeman(:,2)= 0.0d0
447        v1zeeman(:,3)= 0.0d0
448        v1zeeman(:,4)=+0.5d0
449      else                  ! Zeeman field along the 1st axis (x)
450        v1zeeman(:,1)= 0.0d0
451        v1zeeman(:,2)= 0.0d0
452        v1zeeman(:,3)=-0.5d0
453        v1zeeman(:,4)= 0.0d0
454      end if
455    else if (nspden==2) then
456      v1zeeman(:,1)=-0.5e0
457      v1zeeman(:,2)= 0.5e0
458    else
459      v1zeeman(:,1)= 0.0e0
460    end if
461  case(2)
462    if (nspden==2) then
463      do ifft=1,nfft
464        v1zeeman(2*ifft-1,1)  =-0.5e0
465        v1zeeman(2*ifft  ,1)  = 0.0e0
466        v1zeeman(2*ifft-1,2)  = 0.5e0
467        v1zeeman(2*ifft  ,2)  = 0.0e0
468      end do
469    else if (nspden==4) then
470      select case(idir)
471      case(1) !along x, v1=-sigma_x
472        do ifft=1,nfft
473          v1zeeman(2*ifft-1,1)= 0.0e0 !Re[V^11]
474          v1zeeman(2*ifft  ,1)= 0.0e0 !Im[V^11]
475          v1zeeman(2*ifft-1,2)= 0.0e0 !Re[V^22]
476          v1zeeman(2*ifft  ,2)= 0.0e0 !Im[V^22]
477          v1zeeman(2*ifft-1,3)=-0.5e0 !Re[V^12]
478          v1zeeman(2*ifft  ,3)= 0.0e0 !Im[V^12]
479          v1zeeman(2*ifft-1,4)= 0.0e0 !Re[i.V^21]=Im[V^12]
480          v1zeeman(2*ifft  ,4)=-0.5e0 !Im[i.V^21]=Re[V^12]
481        end do
482      case(2) !along y, v1 = -sigma_y
483        do ifft=1,nfft
484          v1zeeman(2*ifft-1,1)= 0.0e0 !Re[V^11]
485          v1zeeman(2*ifft  ,1)= 0.0e0 !Im[V^11]
486          v1zeeman(2*ifft-1,2)= 0.0e0 !Re[V^22]
487          v1zeeman(2*ifft  ,2)= 0.0e0 !Im[V^22]
488          v1zeeman(2*ifft-1,3)= 0.0e0 !Re[V^12]
489          v1zeeman(2*ifft  ,3)=+0.5e0 !Im[V^12]
490          v1zeeman(2*ifft-1,4)=+0.5e0 !Re[i.V^21]=Im[V^12]
491          v1zeeman(2*ifft  ,4)= 0.0e0 !Im[i.V^21]=Re[V^12]
492        end do
493      case(3)
494        do ifft=1,nfft
495          v1zeeman(2*ifft-1,1)=-0.5e0 !Re[V^11]
496          v1zeeman(2*ifft  ,1)= 0.0e0 !Im[V^11]
497          v1zeeman(2*ifft-1,2)= 0.5e0 !Re[V^22]
498          v1zeeman(2*ifft  ,2)= 0.0e0 !Im[V^22]
499          v1zeeman(2*ifft-1,3)= 0.0e0 !Re[V^12]
500          v1zeeman(2*ifft  ,3)= 0.0e0 !Im[V^12]
501          v1zeeman(2*ifft-1,4)= 0.0e0 !Re[i.V^21]
502          v1zeeman(2*ifft  ,4)= 0.0e0 !Im[i.V^21]
503        end do
504      end select
505    end if
506  end select !cplex
507 
508 end subroutine dfpt_v1zeeman

ABINIT/m_dfpt_rhotov [ Modules ]

[ Top ] [ Modules ]

NAME

  m_dfpt_rhotov

FUNCTION

COPYRIGHT

  Copyright (C) 1999-2024 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 .

SOURCE

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 module m_dfpt_rhotov
23 
24  use defs_basis
25  use m_abicore
26  use m_errors
27  use m_cgtools
28 
29  use defs_abitypes, only : MPI_type
30  use m_time,        only : timab
31  use m_spacepar,    only : hartrestr, hartre
32  use m_dfpt_mkvxc,    only : dfpt_mkvxc, dfpt_mkvxc_noncoll
33  use m_dfpt_mkvxcstr, only : dfpt_mkvxcstr
34 
35  implicit none
36 
37  private