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 (LDA+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.

COPYRIGHT

  Copyright (C) 2008-2018 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 .

INPUTS

  Mflags
   that of the basis sphere--appropriate for charge density rho(G),Hartree potential, and pseudopotentials
  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
     %natom=number of atoms in the unit cell
     %rprimd(3,3)=direct lattice vectors
     %ucvol=unit cell volume
     %ntypat= number of type of atoms
     %typat(natom)=type of each atom
  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
  Wfd <type (wfd_t)>=Structure gathering information on the wavefunctions.
  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
   %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 pseudopotials the usual mesh is defined by ecut.
  For PAW calculations the dense FFT grid defined bt ecutdg is used
  Besides, in case of PAW, the matrix elements of V_hartree do not contain the onsite
  contributions due to the coulombian potentials generate by ncore and tncore.
  These quantities, as well as the onsite kinetic terms, are stored in Paw_ij%dij0.

PARENTS

      sigma

CHILDREN

      destroy_mpi_enreg,get_auxc_ixc,init_distribfft_seq,initmpi_seq
      libxc_functionals_end,libxc_functionals_init
      libxc_functionals_set_hybridparams,melements_herm,melements_init
      melements_mpisum,mkkin,paw_mknewh0,pawcprj_alloc,pawcprj_free,rhotoxc
      wfd_change_ngfft,wfd_distribute_bbp,wfd_get_cprj,wfd_get_ur,wrtout
      xcdata_init

SOURCE

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