TABLE OF CONTENTS


ABINIT/calc_vhxc_me [ Functions ]

[ Top ] [ Functions ]

NAME

  calc_vhxc_me

FUNCTION

  Evaluate the matrix elements of $v_H$ and $v_{xc}$ and $v_U$
  both in case of NC pseudopotentials and PAW (DFT+U, presently, is only available in PAW)
  The matrix elements of $v_{xc}$ are calculated with and without the core contribution.
  The later quantity is required in case of GW calculations.

INPUTS

  Wfd <type (wfdgw_t)>=Structure gathering information on the wavefunctions.
  Mflags: Flags specifying the quantities to be computed.
  Dtset <type(dataset_type)>=all input variables in this dataset
  ngfftf(18)contain all needed information about 3D fine FFT, see ~abinit/doc/variables/vargs.htm#ngfft
  nfftf=number of points in the fine FFT mesh (for this processor)
  Pawtab(Dtset%ntypat*Dtset%usepaw) <type(pawtab_type)>=paw tabulated starting data
  Paw_an(natom) <type(paw_an_type)>=paw arrays given on angular mesh
  Pawang <type(pawang_type)>=paw angular mesh and related data
  Paw_ij(natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels
  Pawfgrtab(natom) <type(pawfgrtab_type)>=atomic data given on fine rectangular grid
  Cryst<crystal_t>=unit cell and symmetries
  vhartr(nfftf)= Hartree potential in real space on the fine FFT mesh
  vxc(nfftf,nspden)= xc potential in real space on the fine FFT grid
  rhor(nfftf,nspden)=density in real space (smooth part if PAW).
  nhatgrdim= -PAW only- 0 if nhatgr array is not used ; 1 otherwise
  usexcnhat= -PAW only- 1 if nhat density has to be taken into account in Vxc
  kstab(2,Wfd%nkibz,Wfd%nsppol)=Table temporary used to be compatible with the old implementation.

OUTPUT

  Mels
   %kinetic=matrix elements of $t$.
   %vxc    =matrix elements of $v_{xc}[nv+nc]$.
   %vxcval =matrix elements of $v_{xc}[nv]$.
   %vxcval_hybrid=matrix elements of $v_{xc}[nv]^{hybrid functional}$.
   %vhartr =matrix elements of $v_H$.
   %vu     =matrix elements of $v_U$.

SIDE EFFECTS

  Paw_ij= In case of self-Consistency it is changed. It will contain the new H0
  Hamiltonian calculated using the QP densities. The valence contribution to XC
  is removed.

NOTES

  All the quantities ($v_H$, $v_{xc}$ and $\psi$ are evaluated on the "fine" FFT mesh.
  In case of calculations with NC pseudopotentials the usual mesh is defined by ecut.
  For PAW calculations the dense FFT grid defined by pawecutdg is used
  Besides, in case of PAW, the matrix elements of V_hartree do not contain the onsite
  contributions due to the Coulomb potential generated by ncore and tncore.
  These quantities, as well as the onsite kinetic terms, are stored in Paw_ij%dij0.

SOURCE

113 subroutine calc_vhxc_me(Wfd, Mflags, Mels, Cryst, Dtset, nfftf, ngfftf, &
114                         vtrial, vhartr, vxc, Psps, Pawtab, Paw_an, Pawang, Pawfgrtab, Paw_ij, dijexc_core, &
115                         rhor, usexcnhat, nhat, nhatgr, nhatgrdim, kstab, &
116                         taur) ! optional arguments
117 
118 !Arguments ------------------------------------
119 !scalars
120  integer,intent(in) :: nhatgrdim,usexcnhat,nfftf
121  type(Dataset_type),intent(in) :: Dtset
122  type(Pseudopotential_type),intent(in) :: Psps
123  type(wfdgw_t),target,intent(inout) :: Wfd
124  type(Pawang_type),intent(in) :: Pawang
125  type(crystal_t),intent(in) :: Cryst
126  type(melflags_t),intent(in) :: Mflags
127  type(melements_t),intent(out) :: Mels
128 !arrays
129  integer,intent(in) :: ngfftf(18)
130  integer,intent(in) :: kstab(2, Wfd%nkibz, Wfd%nsppol)
131  real(dp),intent(in) :: vhartr(nfftf), vxc(nfftf, Wfd%nspden), vtrial(nfftf, Wfd%nspden)
132  real(dp),intent(in) :: rhor(nfftf, Wfd%nspden)
133  real(dp),intent(in) :: nhat(nfftf, Wfd%nspden * Wfd%usepaw)
134  real(dp),intent(in) :: nhatgr(nfftf, Wfd%nspden, 3 * nhatgrdim)
135  real(dp),intent(in),optional :: taur(nfftf, Wfd%nspden * Dtset%usekden)
136  real(dp),intent(in) :: dijexc_core(:,:,:) ! (cplex_dij*lmn2_size_max,ndij,Cryst%ntypat)
137  type(Pawtab_type),intent(in) :: Pawtab(Cryst%ntypat * Wfd%usepaw)
138  type(Paw_an_type),intent(in) :: Paw_an(Cryst%natom)
139  type(Paw_ij_type),intent(inout) :: Paw_ij(Cryst%natom)
140  type(Pawfgrtab_type),intent(inout) :: Pawfgrtab(Cryst%natom)
141 
142 !Local variables-------------------------------
143 !scalars
144  integer :: auxc_ixc,iat,ikc,ik_ibz,ib,jb,is,b_start,b_stop,istwf_k
145  integer :: itypat,lmn_size,j0lmn,jlmn,ilmn,klmn,klmn1,lmn2_size_max
146  integer :: isppol,cplex_dij,npw_k,nspinor,nsppol,nspden,nk_calc,rank
147  integer :: iab,isp1,isp2,ixc_sigma,nsploop,nkxc,option,n3xccc_,nk3xc,my_nbbp,my_nmels
148  real(dp) :: nfftfm1,fact,DijH,enxc_val,enxc_hybrid_val,vxcval_avg,vxcval_hybrid_avg,h0dij,vxc1,vxc1_val,re_p,im_p,dijsigcx
149  complex(dpc) :: cdot
150  logical :: ltest,nmxc
151  character(len=500) :: msg
152  type(MPI_type) :: MPI_enreg_seq
153  type(xcdata_type) :: xcdata,xcdata_hybrid
154  type(wave_t),pointer :: wave_jb, wave_ib
155 !arrays
156  integer,parameter :: spinor_idxs(2,4)=RESHAPE([1,1,2,2,1,2,2,1], [2,4])
157  integer :: got(Wfd%nproc)
158  integer,allocatable :: kcalc2ibz(:),dimlmn(:),bbp_ks_distrb(:,:,:,:)
159  integer,ABI_CONTIGUOUS pointer :: kg_k(:,:)
160  real(dp) :: tmp_xc(2,Wfd%nspinor**2),tmp_xcval(2,Wfd%nspinor**2)
161  real(dp) :: tmp_H(2,Wfd%nspinor**2),tmp_U(2,Wfd%nspinor**2)
162  real(dp) :: tmp_h0ij(2,Wfd%nspinor**2),tmp_sigcx(2,Wfd%nspinor**2)
163  real(dp) :: dijU(2),strsxc(6),kpt(3),vxc1ab(2),vxc1ab_val(2)
164  real(dp),allocatable :: kxc_(:,:),xccc3d_(:),vxc_val(:,:),vxc_val_hybrid(:,:)
165  real(dp),allocatable :: kinpw(:),veffh0(:,:)
166  complex(dpc) :: tmp(3)
167  complex(gwpc),ABI_CONTIGUOUS pointer :: ur1_up(:),ur1_dwn(:),ur2_up(:),ur2_dwn(:),cg1(:),cg2(:)
168  complex(gwpc),target,allocatable :: ur1(:),ur2(:)
169  complex(dpc),allocatable :: vxcab(:),vxcab_val(:),vxcab_val_hybrid(:),u1cjg_u2dpc(:),kinwf2(:),veffh0_ab(:)
170  logical,allocatable :: bbp_mask(:,:)
171  type(pawcprj_type),allocatable ::  Cprj_b1ks(:,:),Cprj_b2ks(:,:)
172  type(libxc_functional_type) :: xc_funcs_hybrid(2)
173 
174 ! *************************************************************************
175 
176  DBG_ENTER("COLL")
177 
178  ABI_MALLOC(bbp_mask,(Wfd%mband, Wfd%mband))
179 
180  ! Usually FFT meshes for wavefunctions and potentials are not equal. Two approaches are possible:
181  ! Either we Fourier interpolate potentials on the coarse WF mesh or we FFT the wfs on the dense mesh.
182  ! The later approach is used, more CPU demanding but more accurate.
183  if ( ANY(ngfftf(1:3) /= Wfd%ngfft(1:3)) ) call wfd%change_ngfft(Cryst, Psps, ngfftf)
184 
185  ! Fake MPI_type for sequential part
186  rank = Wfd%my_rank
187  call initmpi_seq(MPI_enreg_seq)
188  call init_distribfft_seq(MPI_enreg_seq%distribfft,'f',ngfftf(2),ngfftf(3),'all')
189 
190  nspinor=Wfd%nspinor; nsppol =Wfd%nsppol; nspden =Wfd%nspden
191  if (nspinor == 2) ABI_WARNING("Remember to ADD SO")
192 
193  ! TODO not used for the time being but it should be a standard input of the routine.
194  !  bbks_mask(Wfd%mband,Wfd%mband,Wfd%nkibz,Wfd%nsppol)=Logical mask used to select
195  !  the matrix elements to be calculated.
196  ABI_MALLOC(kcalc2ibz,(Wfd%nkibz))
197  kcalc2ibz=0
198 
199  ! Index in the IBZ of the GW k-points.
200  ! Only these points will be considered.
201  nk_calc=0
202  do ik_ibz=1,Wfd%nkibz
203    if ( ALL(kstab(1,ik_ibz,:)/=0) .and. ALL(kstab(2,ik_ibz,:)/=0) ) then
204      nk_calc=nk_calc+1; kcalc2ibz(nk_calc) = ik_ibz
205    end if
206  end do
207 
208  call Mels%init(Mflags, nsppol, nspden, Wfd%nspinor, Wfd%nkibz, Wfd%kibz, kstab)
209 
210  if (Mflags%has_lexexch==1) then
211    ABI_ERROR("Local EXX not coded!")
212  end if
213 
214  ! Evaluate $v_\xc$ using only the valence charge.
215  call wrtout(std_out," calc_vhxc_braket: calculating v_xc[n_val] (excluding non-linear core corrections)")
216 
217  do isppol=1,nsppol
218    write(msg,'(a,i2,a,e16.6)')' For spin ',isppol,' Min density rhor = ',MINVAL(rhor(:,isppol))
219    call wrtout(std_out, msg)
220    if (Wfd%usepaw==1) then
221      write(msg,'(a,i2,a,e16.6)')' For spin ',isppol,' Min density nhat = ',MINVAL(nhat(:,isppol))
222      call wrtout(std_out, msg)
223      write(msg,'(a,i2,a,e16.6)')' For spin ',isppol,' Min density trho-nhat = ',MINVAL(rhor(:,isppol)-nhat(:,isppol))
224      call wrtout(std_out, msg)
225      write(msg,'(a,i2)')' using usexcnhat = ',usexcnhat
226      call wrtout(std_out, msg)
227    end if
228  end do
229 
230  option = 0 ! Only exc, vxc, strsxc
231  nkxc   = 0 ! No computation of XC kernel
232  n3xccc_= 0 ! No core
233  nk3xc  = 0 ! k3xc not needed
234  nmxc = Dtset%usepaw==1 .and. mod(abs(Dtset%usepawu),10) == 4
235 
236  ABI_MALLOC(xccc3d_,(n3xccc_))
237  ABI_MALLOC(kxc_,(nfftf,nkxc))
238  ABI_MALLOC(vxc_val,(nfftf,nspden))
239 
240  call xcdata_init(xcdata,dtset=Dtset)
241 
242  call rhotoxc(enxc_val,kxc_,MPI_enreg_seq,nfftf,ngfftf,&
243               nhat,Wfd%usepaw,nhatgr,nhatgrdim,nkxc,nk3xc,nmxc,n3xccc_,option,rhor,Cryst%rprimd,&
244               strsxc,usexcnhat,vxc_val,vxcval_avg,xccc3d_,xcdata,taur=taur)
245 
246  ! FABIEN's development
247  ! Hybrid functional treatment
248  if (Mflags%has_vxcval_hybrid ==1 ) then
249 
250    call wrtout(std_out,' Hybrid functional xc potential is being set')
251    ixc_sigma=Dtset%ixc_sigma
252    call get_auxc_ixc(auxc_ixc,ixc_sigma)
253    call xcdata_init(xcdata_hybrid,dtset=Dtset,auxc_ixc=auxc_ixc,ixc=ixc_sigma)
254 
255    if(ixc_sigma<0)then
256      if(libxc_functionals_check()) then
257        call libxc_functionals_init(ixc_sigma,Dtset%nspden,xc_functionals=xc_funcs_hybrid)
258 !      Do not forget, negative values of hyb_mixing(_sr),hyb_range_* means that they have been user-defined.
259        if (dtset%ixc==-402.or.dtset%ixc==-406.or.dtset%ixc==-427.or.dtset%ixc==-428 .or. dtset%ixc==-456 .or. &
260 &        min(Dtset%hyb_mixing,Dtset%hyb_mixing_sr,Dtset%hyb_range_dft,Dtset%hyb_range_fock)<-tol8)then
261          call libxc_functionals_set_hybridparams(hyb_range=abs(Dtset%hyb_range_dft),&
262 &          hyb_mixing=abs(Dtset%hyb_mixing),hyb_mixing_sr=abs(Dtset%hyb_mixing_sr),xc_functionals=xc_funcs_hybrid)
263        endif
264      else
265        call wrtout(std_out, 'LIBXC is not present: hybrid functionals are not available')
266      end if
267    end if
268 
269    write(msg, '(a, f4.2)') ' Fock fraction = ', max(abs(Dtset%hyb_mixing),abs(Dtset%hyb_mixing_sr))
270    call wrtout(std_out, msg)
271    write(msg, '(a, f5.2, a)') ' Fock inverse screening length = ',abs(Dtset%hyb_range_dft), ' (bohr^-1)'
272    call wrtout(std_out, msg)
273 
274    ABI_MALLOC(vxc_val_hybrid,(nfftf,nspden))
275 
276    if(ixc_sigma<0)then
277      call rhotoxc(enxc_hybrid_val,kxc_,MPI_enreg_seq,nfftf,ngfftf,&
278                   nhat,Wfd%usepaw,nhatgr,nhatgrdim,nkxc,nk3xc,nmxc,n3xccc_,option,rhor,Cryst%rprimd,&
279                   strsxc,usexcnhat,vxc_val_hybrid,vxcval_hybrid_avg,xccc3d_,xcdata_hybrid,xc_funcs=xc_funcs_hybrid)
280      call libxc_functionals_end(xc_functionals=xc_funcs_hybrid)
281    else
282      call rhotoxc(enxc_hybrid_val,kxc_,MPI_enreg_seq,nfftf,ngfftf,&
283                   nhat,Wfd%usepaw,nhatgr,nhatgrdim,nkxc,nk3xc,nmxc,n3xccc_,option,rhor,Cryst%rprimd,&
284                   strsxc,usexcnhat,vxc_val_hybrid,vxcval_hybrid_avg,xccc3d_,xcdata_hybrid)
285    end if
286 
287  endif
288 
289  ABI_FREE(xccc3d_)
290  ABI_FREE(kxc_)
291 
292  write(msg,'(a,f8.4,2a,f8.4,a)')' E_xc[n_val]  = ',enxc_val,  ' [Ha]. ','<V_xc[n_val]> = ',vxcval_avg,' [Ha]. '
293  call wrtout(std_out, msg)
294 
295  ! has_hbare uses veffh0. Why only use it with usepaw=1? Let it be available always
296  if (Mflags%has_hbare == 1) then
297    if (Mflags%has_kinetic/=1) then
298      ABI_ERROR("Kinetic energy mels are required for the construction of Hbare mels!")
299    end if
300    ! Effective potential of the bare Hamiltonian: valence term is subtracted.
301    ABI_MALLOC(veffh0,(nfftf,nspden))
302    veffh0=vtrial-vxc_val
303    !veffh0=vtrial !this is to retrieve the KS Hamiltonian
304  endif
305 
306  ! If PAW and qp-SCGW then update Paw_ij and calculate the matrix elements ===
307  ! We cannot simply rely on gwcalctyp because I need KS vxc in sigma.
308  if (Wfd%usepaw==1.and.Mflags%has_hbare==1) then
309    ABI_CHECK(Mflags%only_diago==0,"Wrong only_diago")
310 
311    call paw_mknewh0(Cryst%natom,nsppol,nspden,nfftf,Dtset%pawspnorb,Dtset%pawprtvol,Cryst,&
312                     Pawtab,Paw_an,Paw_ij,Pawang,Pawfgrtab,vxc,vxc_val,vtrial)
313 
314    ! Effective potential of the bare Hamiltonian: valence term is subtracted.
315    veffh0=vtrial-vxc_val
316    !veffh0=vtrial !this is to retrieve the KS Hamiltonian
317  end if
318 
319  ! Setup of the hermitian operator vxcab ===
320  ! if nspden==4 vxc contains (v^11, v^22, Re[V^12], Im[V^12].
321  ! Cannot use directly Re and Im since we also need off-diagonal elements.
322  if (wfd%nspden == 4) then
323    ABI_MALLOC(vxcab, (nfftf))
324    ABI_MALLOC(vxcab_val, (nfftf))
325    vxcab    (:) = DCMPLX(vxc    (:,3), vxc    (:,4))
326    vxcab_val(:) = DCMPLX(vxc_val(:,3), vxc_val(:,4))
327    if (Mflags%has_vxcval_hybrid==1) then
328      ABI_MALLOC(vxcab_val_hybrid,(nfftf))
329      vxcab_val_hybrid(:)=DCMPLX(vxc_val_hybrid(:,3),vxc_val_hybrid(:,4))
330    end if
331    if (Mflags%has_hbare==1) then
332      ABI_MALLOC(veffh0_ab,(nfftf))
333      veffh0_ab(:)=DCMPLX(veffh0(:,3),veffh0(:,4))
334    end if
335  end if
336 
337  ABI_MALLOC(ur1, (nfftf * nspinor))
338  ABI_MALLOC(ur2, (nfftf * nspinor))
339  ABI_MALLOC(u1cjg_u2dpc, (nfftf * nspinor))
340 
341  ! Create distribution table for tasks.
342  ! This section is parallelized inside wfd%comm
343  ! as all processors are calling the routine with all GW wavefunctions
344  ! TODO the table can be calculated at each (k,s) to save some memory.
345  got=0; my_nmels=0
346  ABI_MALLOC(bbp_ks_distrb,(Wfd%mband,Wfd%mband,nk_calc,nsppol))
347  do is=1,nsppol
348    do ikc=1,nk_calc
349      ik_ibz=kcalc2ibz(ikc)
350      bbp_mask=.FALSE.
351      b_start=kstab(1,ik_ibz,is)
352      b_stop =kstab(2,ik_ibz,is)
353      if (Mflags%only_diago==1) then
354        !do jb=b1,b2
355        do jb=b_start,b_stop
356          bbp_mask(jb,jb)=.TRUE.
357        end do
358      else
359        bbp_mask(b_start:b_stop,b_start:b_stop)=.TRUE.
360      end if
361 
362      call wfd%distribute_bbp(ik_ibz,is,"Upper",my_nbbp,bbp_ks_distrb(:,:,ikc,is),got,bbp_mask)
363      my_nmels = my_nmels + my_nbbp
364    end do
365  end do
366  ABI_FREE(bbp_mask)
367 
368  write(msg,'(a,i0,a)')" Will calculate ",my_nmels," <b,k,s|O|b',k,s> matrix elements in calc_vhxc_me."
369  call wrtout(std_out, msg)
370 
371  ! =====================================
372  ! ==== Loop over required k-points ====
373  ! =====================================
374  nfftfm1=one/nfftf
375 
376  do is=1,nsppol
377    if (ALL(bbp_ks_distrb(:,:,:,is)/=rank)) CYCLE
378    do ikc=1,nk_calc
379      if (ALL(bbp_ks_distrb(:,:,ikc,is)/=rank)) CYCLE
380 
381      ik_ibz = kcalc2ibz(ikc)
382      b_start = kstab(1,ik_ibz,is)
383      b_stop  = kstab(2,ik_ibz,is)
384      npw_k = Wfd%Kdata(ik_ibz)%npw
385      kpt = Wfd%kibz(:,ik_ibz)
386      kg_k => Wfd%kdata(ik_ibz)%kg_k
387      istwf_k = wfd%istwfk(ik_ibz)
388 
389      ! Calculate |k+G|^2 needed by hbareme and kineticme
390      ! MRM: Solved ecut problem
391      if (Mflags%has_kinetic == 1) then
392        ABI_MALLOC(kinpw, (npw_k))
393        ABI_MALLOC(kinwf2, (npw_k*nspinor))
394        call mkkin(Dtset%ecutwfn,Dtset%ecutsm,Dtset%effmass_free,Cryst%gmet,kg_k,kinpw,kpt,npw_k,0,0)
395        where (kinpw>HUGE(zero)*1.d-11)
396          kinpw=zero
397        end where
398      end if
399 
400      !do jb=b1,b2
401      do jb=b_start,b_stop
402        if (ALL(bbp_ks_distrb(:,jb,ikc,is)/=rank)) CYCLE
403 
404        ABI_CHECK(wfd%get_wave_ptr(jb, ik_ibz, is, wave_jb, msg) == 0, msg)
405 
406        if (Mflags%has_kinetic == 1) then
407          cg2 => wave_jb%ug
408          kinwf2(1:npw_k) = cg2(1:npw_k)*kinpw(:)
409          if (nspinor==2) kinwf2(npw_k+1:)=cg2(npw_k+1:)*kinpw(:)
410        end if
411 
412        call wfd%get_ur(jb,ik_ibz,is,ur2)
413 
414        !do ib=b1,jb ! Upper triangle
415        do ib=b_start,jb
416          if (bbp_ks_distrb(ib,jb,ikc,is)/=rank) CYCLE
417          ! Off-diagonal elements only for QPSCGW.
418          if (Mflags%only_diago==1.and.ib/=jb) CYCLE
419 
420          call wfd%get_ur(ib,ik_ibz,is,ur1)
421          u1cjg_u2dpc(:) = CONJG(ur1) *ur2
422 
423          if (Mflags%has_vxc == 1) then
424            Mels%vxc(ib, jb, ik_ibz, is) = sum(u1cjg_u2dpc(1:nfftf) * vxc(1:nfftf, is)) * nfftfm1
425            if (wfd%nspinor == 2 .and. wfd%nspden == 1) &
426              Mels%vxc(ib, jb, ik_ibz, 2) = sum(u1cjg_u2dpc(nfftf+1:) * vxc(1:nfftf, is)) * nfftfm1
427          end if
428          if (Mflags%has_vxcval == 1) then
429            Mels%vxcval(ib, jb, ik_ibz, is) = SUM(u1cjg_u2dpc(1:nfftf) * vxc_val(1:nfftf, is)) * nfftfm1
430            if (wfd%nspinor == 2 .and. wfd%nspden == 1) &
431              Mels%vxcval(ib, jb, ik_ibz, 2) = SUM(u1cjg_u2dpc(nfftf+1:) * vxc_val(1:nfftf, is)) * nfftfm1
432          end if
433          if (Mflags%has_vxcval_hybrid == 1) then
434            Mels%vxcval_hybrid(ib, jb, ik_ibz, is) = SUM(u1cjg_u2dpc(1:nfftf) * vxc_val_hybrid(1:nfftf, is)) * nfftfm1
435            if (wfd%nspinor == 2 .and. wfd%nspden == 1) &
436              Mels%vxcval_hybrid(ib, jb, ik_ibz, 2) = SUM(u1cjg_u2dpc(nfftf+1) * vxc_val_hybrid(1:nfftf, is)) * nfftfm1
437          end if
438          if (Mflags%has_vhartree==1) then
439            Mels%vhartree(ib, jb, ik_ibz, is) = SUM(u1cjg_u2dpc(1:nfftf) * vhartr(1:nfftf)) * nfftfm1
440            if (wfd%nspinor == 2 .and. wfd%nspden == 1) &
441              Mels%vhartree(ib, jb, ik_ibz, 2) = SUM(u1cjg_u2dpc(nfftf+1:) * vhartr(1:nfftf)) * nfftfm1
442          end if
443          if (Mflags%has_kinetic==1) then
444            ABI_CHECK(wfd%get_wave_ptr(ib, ik_ibz, is, wave_ib, msg) == 0, msg)
445            cg1 => wave_ib%ug(1:npw_k)
446            cdot = DOT_PRODUCT(cg1, kinwf2(1:npw_k))
447            !if (istwf_k /= 1) then
448            !  cdot = two * cdot; if (istwf_k == 2) cdot = cdot - GWPC_CONJG(cg1(1)) * kinwf2(1)
449            !end if
450            Mels%kinetic(ib, jb, ik_ibz, is) = cdot
451            if (wfd%nspinor == 2 .and. wfd%nspden == 1) then
452              cg1 => wave_ib%ug(npw_k+1:)
453              Mels%kinetic(ib, jb, ik_ibz, 2) = DOT_PRODUCT(cg1, kinwf2(npw_k+1:))
454            end if
455          end if
456          if (Mflags%has_hbare==1) then
457            Mels%hbare(ib, jb, ik_ibz, is) = Mels%kinetic(ib, jb, ik_ibz, is) &
458                  + SUM(u1cjg_u2dpc(1:nfftf) * veffh0(1:nfftf, is)) * nfftfm1
459            if (wfd%nspinor == 2 .and. wfd%nspden == 1) then
460              cg1 => wave_ib%ug(npw_k+1:)
461              Mels%hbare(ib, jb, ik_ibz, 2) = &
462                Mels%kinetic(ib, jb, ik_ibz, 2) + SUM(u1cjg_u2dpc(nfftf+1:) * veffh0(1:nfftf, is)) * nfftfm1
463            end if
464          end if
465 
466          if (nspinor == 2 .and. wfd%nspden == 4) then
467            ! Here I can skip 21 if ib==jb
468            ur1_up  => ur1(1:nfftf)
469            ur1_dwn => ur1(nfftf+1:2*nfftf)
470            ur2_up  => ur2(1:nfftf)
471            ur2_dwn => ur2(nfftf+1:2*nfftf)
472 
473            if (Mflags%has_kinetic==1) then
474              cg1 => wave_ib%ug(npw_k+1:)
475              tmp(1)=DOT_PRODUCT(cg1,kinwf2(npw_k+1:))
476              Mels%kinetic(ib,jb,ik_ibz,2  )=tmp(1)
477              Mels%kinetic(ib,jb,ik_ibz,3:4)=czero
478            end if
479            if (Mflags%has_hbare==1) then
480              cg1 => wave_ib%ug(npw_k+1:)
481              tmp(1)=SUM(CONJG(ur1_dwn)*veffh0(:,2)*ur2_dwn)*nfftfm1 + Mels%kinetic(ib,jb,ik_ibz,2)
482              tmp(2)=SUM(CONJG(ur1_dwn)*      veffh0_ab(:) *ur2_dwn)*nfftfm1
483              tmp(3)=SUM(CONJG(ur1_dwn)*CONJG(veffh0_ab(:))*ur2_dwn)*nfftfm1
484              Mels%hbare(ib,jb,ik_ibz,2:4)=tmp(:)
485            end if
486            if (Mflags%has_vxc==1) then
487              tmp(1) = SUM(CONJG(ur1_dwn)*      vxc(:,2) *ur2_dwn)*nfftfm1
488              tmp(2) = SUM(CONJG(ur1_up )*      vxcab(:) *ur2_dwn)*nfftfm1
489              tmp(3) = SUM(CONJG(ur1_dwn)*CONJG(vxcab(:))*ur2_up )*nfftfm1
490              Mels%vxc(ib,jb,ik_ibz,2:4)=tmp(:)
491            end if
492            if (Mflags%has_vxcval==1) then
493              tmp(1) = SUM(CONJG(ur1_dwn)*      vxc_val(:,2) *ur2_dwn)*nfftfm1
494              tmp(2) = SUM(CONJG(ur1_up )*      vxcab_val(:) *ur2_dwn)*nfftfm1
495              tmp(3) = SUM(CONJG(ur1_dwn)*CONJG(vxcab_val(:))*ur2_up )*nfftfm1
496              Mels%vxcval(ib,jb,ik_ibz,2:4)=tmp(:)
497            end if
498            if (Mflags%has_vxcval_hybrid==1) then
499              tmp(1) = SUM(CONJG(ur1_dwn)*      vxc_val_hybrid(:,2) *ur2_dwn)*nfftfm1
500              tmp(2) = SUM(CONJG(ur1_up )*      vxcab_val_hybrid(:) *ur2_dwn)*nfftfm1
501              tmp(3) = SUM(CONJG(ur1_dwn)*CONJG(vxcab_val_hybrid(:))*ur2_up )*nfftfm1
502              Mels%vxcval_hybrid(ib,jb,ik_ibz,2:4)=tmp(:)
503            end if
504            if (Mflags%has_vhartree==1) then
505              tmp(1) = SUM(CONJG(ur1_dwn)*vhartr(:)*ur2_dwn)*nfftfm1
506              Mels%vhartree(ib,jb,ik_ibz,2  )=tmp(1)
507              Mels%vhartree(ib,jb,ik_ibz,3:4)=czero
508            end if
509          end if !nspinor==2
510 
511        end do !ib
512      end do !jb
513 
514      if (Mflags%has_kinetic==1) then
515        ABI_FREE(kinpw)
516        ABI_FREE(kinwf2)
517      end if
518 
519    end do !ikc
520  end do !is
521 
522  ABI_FREE(ur1)
523  ABI_FREE(ur2)
524  ABI_FREE(vxc_val)
525  ABI_FREE(u1cjg_u2dpc)
526  if(Mflags%has_vxcval_hybrid==1) then
527    ABI_FREE(vxc_val_hybrid)
528  end if
529  if (wfd%nspden == 4)  then
530    ABI_FREE(vxcab)
531    ABI_FREE(vxcab_val)
532    if(Mflags%has_vxcval_hybrid==1) then
533      ABI_FREE(vxcab_val_hybrid)
534    end if
535  end if
536 
537  if (Mflags%has_hbare==1) then
538    ABI_FREE(veffh0)
539    if (nspinor==2)  then
540      ABI_FREE(veffh0_ab)
541    end if
542  end if
543 
544  ! ====================================
545  ! ===== Additional terms for PAW =====
546  ! ====================================
547  if (Wfd%usepaw==1) then
548    ! Tests if needed pointers in Paw_ij are allocated.
549    ltest=(allocated(Paw_ij(1)%dijxc).and.allocated(Paw_ij(1)%dijxc_hat).and.allocated(Paw_ij(1)%dijxc_val))
550    ABI_CHECK(ltest,"dijxc, dijxc_hat or dijxc_val not allocated")
551    ABI_CHECK(nspinor == 1, "PAW with nspinor not tested")
552 
553    ! For DFT+U
554    do iat=1,Cryst%natom
555      itypat=Cryst%typat(iat)
556      if (Pawtab(itypat)%usepawu/=0) then
557        ltest=(allocated(Paw_ij(iat)%dijU))
558        ABI_CHECK(ltest,"DFT+U but dijU not allocated")
559      end if
560    end do
561 
562    if (Dtset%pawspnorb>0) then
563      ltest=(allocated(Paw_ij(1)%dijso))
564      ABI_CHECK(ltest,"dijso not allocated")
565    end if
566 
567    lmn2_size_max=MAXVAL(Pawtab(:)%lmn2_size)
568 
569    if (Mflags%has_sxcore==1) then
570      if (     SIZE(dijexc_core,DIM=1) /= lmn2_size_max  &
571          .or. SIZE(dijexc_core,DIM=2) /= 1              &
572          .or. SIZE(dijexc_core,DIM=3) /= Cryst%ntypat ) then
573        ABI_BUG("Wrong sizes in dijexc_core")
574      end if
575    end if
576 
577    nsploop=nspinor**2
578 
579    ! ====================================
580    ! === Assemble PAW matrix elements ===
581    ! ====================================
582    ABI_MALLOC(dimlmn, (Cryst%natom))
583    do iat=1,Cryst%natom
584      dimlmn(iat)=Pawtab(Cryst%typat(iat))%lmn_size
585    end do
586 
587    ABI_MALLOC(Cprj_b1ks, (Cryst%natom,nspinor))
588    ABI_MALLOC(Cprj_b2ks, (Cryst%natom,nspinor))
589    call pawcprj_alloc(Cprj_b1ks, 0, dimlmn)
590    call pawcprj_alloc(Cprj_b2ks, 0, dimlmn)
591 
592    do is=1,nsppol
593      if (ALL(bbp_ks_distrb(:,:,:,is)/=rank)) CYCLE
594 
595      ! Loop over required k-points
596      do ikc=1,nk_calc
597        if (ALL(bbp_ks_distrb(:,:,ikc,is)/=rank)) CYCLE
598        ik_ibz=kcalc2ibz(ikc)
599        b_start=kstab(1,ik_ibz,is)
600        b_stop =kstab(2,ik_ibz,is)
601 
602        !do jb=b1,b2
603        do jb=b_start,b_stop
604          if (ALL(bbp_ks_distrb(:,jb,ikc,is)/=rank)) CYCLE
605 
606          ! Load projected wavefunctions for this k-point, spin and band ===
607          ! Cprj are unsorted, full correspondence with xred. See ctocprj.F90!!
608          call wfd%get_cprj(jb,ik_ibz,is,Cryst,Cprj_b2ks,sorted=.FALSE.)
609 
610          !do ib=b1,jb ! Upper triangle
611          do ib=b_start,jb
612            if (bbp_ks_distrb(ib,jb,ikc,is)/=rank) CYCLE
613 
614            ! Off-diagonal elements only for QPSCGW.
615            if (Mflags%only_diago==1.and.ib/=jb) CYCLE
616 
617            call wfd%get_cprj(ib,ik_ibz,is,Cryst,Cprj_b1ks,sorted=.FALSE.)
618            !
619            ! === Get onsite matrix elements summing over atoms and channels ===
620            ! * Spin is external and fixed (1,2) if collinear.
621            ! * if noncollinear loop internally over the four components ab.
622            tmp_xc = zero; tmp_xcval = zero; tmp_H = zero; tmp_U = zero; tmp_h0ij = zero; tmp_sigcx = zero
623 
624            do iat=1,Cryst%natom
625              itypat   =Cryst%typat(iat)
626              lmn_size =Pawtab(itypat)%lmn_size
627              cplex_dij=Paw_ij(iat)%cplex_dij
628              klmn1=1
629 
630              do jlmn=1,lmn_size
631                j0lmn=jlmn*(jlmn-1)/2
632                do ilmn=1,jlmn
633                  klmn=j0lmn+ilmn
634                  ! TODO Be careful, here I assume that the onsite terms ij are symmetric
635                  ! should check the spin-orbit case!
636                  fact=one; if (ilmn==jlmn) fact=half
637 
638                  ! Loop over four components if nspinor==2
639                  ! If collinear nsploop==1
640                  do iab=1,nsploop
641                    isp1=spinor_idxs(1,iab); isp2=spinor_idxs(2,iab)
642 
643                    re_p=  Cprj_b1ks(iat,isp1)%cp(1,ilmn) * Cprj_b2ks(iat,isp2)%cp(1,jlmn) &
644                          +Cprj_b1ks(iat,isp1)%cp(2,ilmn) * Cprj_b2ks(iat,isp2)%cp(2,jlmn) &
645                          +Cprj_b1ks(iat,isp1)%cp(1,jlmn) * Cprj_b2ks(iat,isp2)%cp(1,ilmn) &
646                          +Cprj_b1ks(iat,isp1)%cp(2,jlmn) * Cprj_b2ks(iat,isp2)%cp(2,ilmn)
647 
648                    im_p=  Cprj_b1ks(iat,isp1)%cp(1,ilmn) * Cprj_b2ks(iat,isp2)%cp(2,jlmn) &
649                          -Cprj_b1ks(iat,isp1)%cp(2,ilmn) * Cprj_b2ks(iat,isp2)%cp(1,jlmn) &
650                          +Cprj_b1ks(iat,isp1)%cp(1,jlmn) * Cprj_b2ks(iat,isp2)%cp(2,ilmn) &
651                          -Cprj_b1ks(iat,isp1)%cp(2,jlmn) * Cprj_b2ks(iat,isp2)%cp(1,ilmn)
652 
653                    ! ==================================================
654                    ! === Load onsite matrix elements and accumulate ===
655                    ! ==================================================
656                    if (nspinor==1) then
657 
658                      if (Mflags%has_hbare==1) then ! * Get new dij of h0 and accumulate.
659                        h0dij=Paw_ij(iat)%dij(klmn,is)
660                        tmp_h0ij(1,iab)=tmp_h0ij(1,iab) + h0dij*re_p*fact
661                        tmp_h0ij(2,iab)=tmp_h0ij(2,iab) + h0dij*im_p*fact
662                      end if
663 
664                      if (Mflags%has_sxcore==1) then ! * Fock operator generated by core electrons.
665                        dijsigcx = dijexc_core(klmn,1,itypat)
666                        tmp_sigcx(1,iab)=tmp_sigcx(1,iab) + dijsigcx*re_p*fact
667                        tmp_sigcx(2,iab)=tmp_sigcx(2,iab) + dijsigcx*im_p*fact
668                      end if
669 
670                      if (Mflags%has_vxc==1) then ! * Accumulate vxc[n1+nc] + vxc[n1+tn+nc].
671                        vxc1 = Paw_ij(iat)%dijxc(klmn,is)+Paw_ij(iat)%dijxc_hat(klmn,is)
672                        tmp_xc(1,iab)=tmp_xc(1,iab) + vxc1*re_p*fact
673                        tmp_xc(2,iab)=tmp_xc(2,iab) + vxc1*im_p*fact
674                      end if
675 
676                      if (Mflags%has_vxcval==1) then ! * Accumulate valence-only XC.
677                        vxc1_val=Paw_ij(iat)%dijxc_val(klmn,is)
678                        tmp_xcval(1,1)=tmp_xcval(1,1) + vxc1_val*re_p*fact
679                        tmp_xcval(2,1)=tmp_xcval(2,1) + vxc1_val*im_p*fact
680                      end if
681 
682                      if (Mflags%has_vhartree==1) then ! * Accumulate Hartree term of the PAW Hamiltonian.
683                        DijH=Paw_ij(iat)%dijhartree(klmn)
684                        tmp_H(1,1)=tmp_H(1,1) + DijH*re_p*fact
685                        tmp_H(2,1)=tmp_H(2,1) + DijH*im_p*fact
686                      end if
687 
688                      ! Accumulate U term of the PAW Hamiltonian (only onsite AE contribution)
689                      if (Mflags%has_vu==1) then
690                        if (Pawtab(itypat)%usepawu/=0) then
691                          dijU(1)=Paw_ij(iat)%dijU(klmn,is)
692                          tmp_U(1,1)=tmp_U(1,1) + dijU(1)*re_p*fact
693                          tmp_U(2,1)=tmp_U(2,1) + dijU(1)*im_p*fact
694                        end if
695                      end if
696 
697                    else
698                      ! Spinorial case
699 
700                      ! FIXME H0 + spinor not implemented
701                      if (Mflags%has_hbare==1.or.Mflags%has_sxcore==1) then
702                        ABI_ERROR("not implemented")
703                      end if
704 
705                      if (Mflags%has_vxc==1) then ! * Accumulate vxc[n1+nc] + vxc[n1+tn+nc].
706                        vxc1ab(1) = Paw_ij(iat)%dijxc(klmn1,  iab)+Paw_ij(iat)%dijxc_hat(klmn1,  iab)
707                        vxc1ab(2) = Paw_ij(iat)%dijxc(klmn1+1,iab)+Paw_ij(iat)%dijxc_hat(klmn1+1,iab)
708                        tmp_xc(1,iab) = tmp_xc(1,iab) + (vxc1ab(1)*re_p - vxc1ab(2)*im_p)*fact
709                        tmp_xc(2,iab) = tmp_xc(2,iab) + (vxc1ab(2)*re_p + vxc1ab(1)*im_p)*fact
710                      end if
711 
712                      if (Mflags%has_vxcval==1) then ! * Accumulate valence-only XC.
713                        vxc1ab_val(1) = Paw_ij(iat)%dijxc_val(klmn1,  iab)
714                        vxc1ab_val(2) = Paw_ij(iat)%dijxc_val(klmn1+1,iab)
715                        tmp_xcval(1,iab) = tmp_xcval(1,iab) + (vxc1ab_val(1)*re_p - vxc1ab_val(2)*im_p)*fact
716                        tmp_xcval(2,iab) = tmp_xcval(2,iab) + (vxc1ab_val(2)*re_p + vxc1ab_val(1)*im_p)*fact
717                      end if
718 
719                      ! * In GW, dijhartree is always real.
720                      if (Mflags%has_vhartree==1) then ! * Accumulate Hartree term of the PAW Hamiltonian.
721                        if (iab==1.or.iab==2) then
722                          DijH = Paw_ij(iat)%dijhartree(klmn)
723                          tmp_H(1,iab) = tmp_H(1,iab) + DijH*re_p*fact
724                          tmp_H(2,iab) = tmp_H(2,iab) + DijH*im_p*fact
725                        end if
726                      end if
727 
728                      ! TODO "ADD DFT+U and SO"
729                      ! check this part
730                      if (Mflags%has_vu==1) then
731                        if (Pawtab(itypat)%usepawu/=0) then
732                          ! Accumulate the U term of the PAW Hamiltonian (only onsite AE contribution)
733                          dijU(1)=Paw_ij(iat)%dijU(klmn1  ,iab)
734                          dijU(2)=Paw_ij(iat)%dijU(klmn1+1,iab)
735                          tmp_U(1,iab) = tmp_U(1,iab) + (dijU(1)*re_p - dijU(2)*im_p)*fact
736                          tmp_U(2,iab) = tmp_U(2,iab) + (dijU(2)*re_p + dijU(1)*im_p)*fact
737                        end if
738                      end if
739 
740                    end if
741                  end do !iab
742 
743                  klmn1=klmn1+cplex_dij
744 
745                end do !ilmn
746              end do !jlmn
747            end do !iat
748 
749            ! ========================================
750            ! ==== Add to plane wave contribution ====
751            ! ========================================
752            if (nspinor==1) then
753 
754              if (Mflags%has_hbare==1)    &
755 &              Mels%hbare(ib,jb,ik_ibz,is) = Mels%hbare(ib,jb,ik_ibz,is) + DCMPLX(tmp_h0ij(1,1),tmp_h0ij(2,1))
756 
757              if (Mflags%has_vxc==1)      &
758 &              Mels%vxc(ib,jb,ik_ibz,is) = Mels%vxc(ib,jb,ik_ibz,is) + DCMPLX(tmp_xc(1,1),tmp_xc(2,1))
759 
760              if (Mflags%has_vxcval==1)   &
761 &              Mels%vxcval(ib,jb,ik_ibz,is) = Mels%vxcval(ib,jb,ik_ibz,is) + DCMPLX(tmp_xcval(1,1),tmp_xcval(2,1))
762 
763              if (Mflags%has_vxcval_hybrid==1)   &
764 &              Mels%vxcval_hybrid(ib,jb,ik_ibz,is) = Mels%vxcval_hybrid(ib,jb,ik_ibz,is) + DCMPLX(tmp_xcval(1,1),tmp_xcval(2,1))
765 
766              if (Mflags%has_vhartree==1) &
767 &              Mels%vhartree(ib,jb,ik_ibz,is) = Mels%vhartree(ib,jb,ik_ibz,is) + DCMPLX(tmp_H (1,1),tmp_H (2,1))
768 
769              if (Mflags%has_vu==1)       &
770 &              Mels%vu(ib,jb,ik_ibz,is) = DCMPLX(tmp_U(1,1),tmp_U(2,1))
771 
772              if (Mflags%has_sxcore==1)   &
773 &              Mels%sxcore(ib,jb,ik_ibz,is) = DCMPLX(tmp_sigcx(1,1),tmp_sigcx(2,1))
774 
775            else
776 
777              if (Mflags%has_hbare==1)    &
778 &              Mels%hbare(ib,jb,ik_ibz,:) = Mels%hbare(ib,jb,ik_ibz,:) + DCMPLX(tmp_h0ij(1,:),tmp_h0ij(2,:))
779 
780              if (Mflags%has_vxc==1)      &
781 &              Mels%vxc(ib,jb,ik_ibz,:) = Mels%vxc(ib,jb,ik_ibz,:) + DCMPLX(tmp_xc(1,:),tmp_xc(2,:))
782 
783              if (Mflags%has_vxcval==1)   &
784 &              Mels%vxcval(ib,jb,ik_ibz,:) = Mels%vxcval(ib,jb,ik_ibz,:) + DCMPLX(tmp_xcval(1,:),tmp_xcval(2,:))
785 
786              if (Mflags%has_vxcval_hybrid==1)   &
787 &              Mels%vxcval_hybrid(ib,jb,ik_ibz,:) = Mels%vxcval_hybrid(ib,jb,ik_ibz,:) + DCMPLX(tmp_xcval(1,:),tmp_xcval(2,:))
788 
789              if (Mflags%has_vhartree==1) &
790 &              Mels%vhartree(ib,jb,ik_ibz,:) = Mels%vhartree(ib,jb,ik_ibz,:) + DCMPLX(tmp_H (1,:),tmp_H (2,:))
791 
792              if (Mflags%has_vu==1)       &
793 &              Mels%vu(ib,jb,ik_ibz,:) = DCMPLX(tmp_U(1,:),tmp_U(2,:))
794            end if
795 
796          end do !ib
797        end do !jb
798 
799      end do !is
800    end do !ikc
801 
802    ABI_FREE(dimlmn)
803    call pawcprj_free(Cprj_b1ks)
804    ABI_FREE(Cprj_b1ks)
805    call pawcprj_free(Cprj_b2ks)
806    ABI_FREE(Cprj_b2ks)
807  end if !PAW
808 
809  ABI_FREE(bbp_ks_distrb)
810 
811  ! Sum up contributions on each node
812  ! Set the corresponding has_* flags to 2.
813  call Mels%mpisum(wfd%comm)
814 
815  ! Reconstruct lower triangle.
816  call Mels%herm()
817 
818  ABI_FREE(kcalc2ibz)
819  call destroy_mpi_enreg(MPI_enreg_seq)
820 
821  DBG_EXIT("COLL")
822 
823 end subroutine calc_vhxc_me

ABINIT/m_vhxc_me [ Modules ]

[ Top ] [ Modules ]

NAME

 m_vhxc_me

FUNCTION

  Evaluate the matrix elements of $v_H$ and $v_{xc}$ and $v_U$

COPYRIGHT

  Copyright (C) 2008-2024 ABINIT group (MG)
  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_vhxc_me
23 
24  use defs_basis
25  use m_abicore
26  use m_errors
27  use m_xcdata
28  use libxc_functionals
29  use m_dtset
30  use m_distribfft
31 
32  use defs_datatypes,only : pseudopotential_type
33  use defs_abitypes, only : MPI_type
34  use m_pawang,      only : pawang_type
35  use m_pawtab,      only : pawtab_type
36  use m_paw_an,      only : paw_an_type
37  use m_paw_ij,      only : paw_ij_type
38  use m_pawfgrtab,   only : pawfgrtab_type
39  use m_pawcprj,     only : pawcprj_type, pawcprj_alloc, pawcprj_free
40  use m_paw_denpot,  only : paw_mknewh0
41  use m_hide_blas,   only : xdotc
42  use m_wfd,         only : wfdgw_t, wave_t
43  use m_crystal,     only : crystal_t
44  use m_melemts,     only : melflags_t, melements_t
45  use m_mpinfo,      only : destroy_mpi_enreg, initmpi_seq
46  use m_kg,          only : mkkin
47  use m_rhotoxc,     only : rhotoxc
48 
49  implicit none
50 
51  private