LCOV - code coverage report
Current view: top level - src/95_drive - m_screening_driver.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.3 % 1271 1071
Test Date: 2026-09-21 13:49:52 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !!****m* ABINIT/m_screening_driver
       2              : !! NAME
       3              : !!  m_screening_driver
       4              : !!
       5              : !! FUNCTION
       6              : !! Calculate screening and dielectric functions
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2008-2026 ABINIT group (MG, GMR, VO, LR, RWG, MT, RShaltaf, AS, FB)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_screening_driver
      23              : 
      24              :  use defs_basis
      25              :  use defs_wvltypes
      26              :  use m_abicore
      27              :  use m_dtset
      28              :  use m_xmpi
      29              :  use m_xomp
      30              :  use m_errors
      31              :  use m_abi_mixing
      32              :  use m_kxc
      33              :  use m_nctk
      34              :  use netcdf
      35              :  use libxc_functionals
      36              :  use m_hdr
      37              :  use m_dtfil
      38              :  use m_crystal
      39              : 
      40              :  use defs_datatypes,  only : pseudopotential_type
      41              :  use defs_abitypes,   only : MPI_type
      42              :  use m_time,          only : timab
      43              :  use m_io_tools,      only : open_file, file_exists, iomode_from_fname
      44              :  use m_fstrings,      only : int2char10, sjoin, strcat, itoa, ltoa, itoa
      45              :  use m_energies,      only : energies_type
      46              :  use m_numeric_tools, only : print_arr, coeffs_gausslegint, c2r
      47              :  use m_geometry,      only : normv, vdotw, mkrdim, metric
      48              :  use m_gwdefs,        only : GW_TOLQ0, GW_TOLQ, em1params_t, GW_Q0_DEFAULT
      49              :  use m_mpinfo,        only : destroy_mpi_enreg, initmpi_seq
      50              :  use m_ebands,        only : ebands_t,  gaps_t
      51              :  use m_bz_mesh,       only : kmesh_t, littlegroup_t, littlegroup_free, get_ng0sh
      52              :  use m_kg,            only : getph
      53              :  use m_gsphere,       only : gsphere_t, setshells
      54              :  use m_vcoul,         only : vcoul_t
      55              :  use m_qparticles,    only : rdqps, rdgw, show_QP
      56              :  use m_screening,     only : make_epsm1_driver, lwl_write, chi_t, chi_free, chi_new
      57              :  use m_io_screening,  only : hscr_new, write_screening, hscr_t
      58              :  use m_spectra,       only : spectra_t, W_EM_LF, W_EM_NLF, W_EELF
      59              :  use m_fftcore,       only : print_ngfft
      60              :  use m_fft_mesh,      only : rotate_FFT_mesh, cigfft, get_gfft, setmesh
      61              :  use m_fft,           only : fourdp
      62              :  use m_wfd,           only : wfdgw_t, wfdgw_copy, test_charge
      63              :  use m_wfk,           only : wfk_read_eigenvalues
      64              :  use m_io_kss,        only : make_gvec_kss
      65              :  use m_chi0tk,        only : output_chi0sumrule
      66              :  use m_pawang,        only : pawang_type
      67              :  use m_pawrad,        only : pawrad_type
      68              :  use m_pawtab,        only : pawtab_type, pawtab_print, pawtab_get_lsize
      69              :  use m_paw_an,        only : paw_an_type, paw_an_init, paw_an_free, paw_an_nullify
      70              :  use m_paw_ij,        only : paw_ij_type, paw_ij_init, paw_ij_free, paw_ij_nullify
      71              :  use m_pawfgrtab,     only : pawfgrtab_type, pawfgrtab_init, pawfgrtab_free
      72              :  use m_pawrhoij,      only : pawrhoij_type, pawrhoij_alloc, pawrhoij_copy,&
      73              : &                            pawrhoij_free, pawrhoij_symrhoij, pawrhoij_inquire_dim
      74              :  use m_pawdij,        only : pawdij, symdij_all
      75              :  use m_paw_pwaves_lmn,only : paw_pwaves_lmn_t, paw_pwaves_lmn_init, paw_pwaves_lmn_free
      76              :  use m_pawpwij,       only : pawpwff_t, pawpwff_init, pawpwff_free
      77              :  use m_pawfgr,        only : pawfgr_type, pawfgr_init, pawfgr_destroy
      78              :  use m_paw_sphharm,   only : setsym_ylm
      79              :  use m_paw_onsite,    only : pawnabla_init
      80              :  use m_paw_nhat,      only : nhatgrid, pawmknhat
      81              :  use m_paw_denpot,    only : pawdenpot
      82              :  use m_paw_init,      only : pawinit, paw_gencond
      83              :  use m_paw_tools,     only : chkpawovlp,pawprt
      84              :  use m_chi0,          only : cchi0, cchi0q0, chi0q0_intraband
      85              :  use m_setvtr,        only : setvtr
      86              :  use m_mkrho,         only : prtrhomxmn
      87              :  use m_pspini,        only : pspini
      88              :  use m_paw_correlations, only : pawpuxinit
      89              :  use m_plowannier,    only : plowannier_type,init_plowannier,get_plowannier, fullbz_plowannier,destroy_plowannier
      90              :  use minimax_grids,   only : gx_minimax_grid !, gx_get_error_message
      91              :  use m_pstat,         only : pstat_proc
      92              : 
      93              :  implicit none
      94              : 
      95              :  private
      96              : !!***
      97              : 
      98              :  public :: screening
      99              : !!***
     100              : 
     101              : contains
     102              : !!***
     103              : 
     104              : !!****f* m_screening_driver/screening
     105              : !! NAME
     106              : !! screening
     107              : !!
     108              : !! FUNCTION
     109              : !! Calculate screening and dielectric functions
     110              : !!
     111              : !! INPUTS
     112              : !! acell(3)=length scales of primitive translations (bohr)
     113              : !! codvsn=code version
     114              : !! Dtfil<datafiles_type)>=variables related to file names and unit numbers.
     115              : !! Pawang<pawang_type)>=paw angular mesh and related data
     116              : !! Pawrad(ntypat*usepaw) <type(pawrad_type)>=paw radial mesh and related data
     117              : !! Pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
     118              : !! Psps <type(pseudopotential_type)>=variables related to pseudopotentials
     119              : !!  Before entering the first time in screening, a significant part of Psps has been initialized:
     120              : !!  the integers dimekb,lmnmax,lnmax,mpssang,mpssoang,mpsso,mgrid, ntypat,n1xccc,usepaw,useylm,
     121              : !!  and the arrays dimensioned to npsp. All the remaining components of Psps are to be initialized in
     122              : !!  the call to pspini. The next time the code enters screening, Psps might be identical to the
     123              : !!  one of the previous Dtset, in which case, no reinitialisation is scheduled in pspini.F90.
     124              : !! rprim(3,3)=dimensionless real space primitive translations
     125              : !!
     126              : !! OUTPUT
     127              : !! Output is written on the main output file.
     128              : !! The symmetrical inverse dielectric matrix is stored in the _SCR file
     129              : !!
     130              : !! SIDE EFFECTS
     131              : !!  Dtset<type(dataset_type)>=all input variables for this dataset
     132              : !!
     133              : !! NOTES
     134              : !! USE OF FFT GRIDS:
     135              : !! =================
     136              : !! In case of PAW:
     137              : !! ---------------
     138              : !!    Two FFT grids are used:
     139              : !!    - A "coarse" FFT grid (defined by ecut) for the application of the Hamiltonian on the plane waves basis.
     140              : !!      It is defined by nfft, ngfft, mgfft, ...
     141              : !!      Hamiltonian, wave-functions, density related to WFs (rhor here), ... are expressed on this grid.
     142              : !!    - A "fine" FFT grid (defined) by ecutdg) for the computation of the density inside PAW spheres.
     143              : !!      It is defined by nfftf, ngfftf, mgfftf, ...Total density, potentials, ... are expressed on this grid.
     144              : !! In case of norm-conserving:
     145              : !! ---------------------------
     146              : !!    - Only the usual FFT grid (defined by ecut) is used. It is defined by nfft, ngfft, mgfft, ...
     147              : !!      For compatibility reasons, (nfftf,ngfftf,mgfftf) are set equal to (nfft,ngfft,mgfft) in that case.
     148              : !!
     149              : !! SOURCE
     150              : 
     151          148 : subroutine screening(acell,codvsn,Dtfil,Dtset,Pawang,Pawrad,Pawtab,Psps,rprim)
     152              : 
     153              : !Arguments ------------------------------------
     154              : !scalars
     155              :  character(len=8),intent(in) :: codvsn
     156              :  type(Datafiles_type),intent(in) :: Dtfil
     157              :  type(Dataset_type),intent(inout) :: Dtset
     158              :  type(Pawang_type),intent(inout) :: Pawang
     159              :  type(Pseudopotential_type),intent(inout) :: Psps
     160              : !arrays
     161              :  real(dp),intent(in) :: acell(3),rprim(3,3)
     162              :  type(Pawrad_type),intent(inout) :: Pawrad(Psps%ntypat*Dtset%usepaw)
     163              :  type(Pawtab_type),intent(inout) :: Pawtab(Psps%ntypat*Dtset%usepaw)
     164              : 
     165              : !Local variables ------------------------------
     166              :  character(len=4) :: ctype='RPA '
     167              : !scalars
     168              :  integer,parameter :: tim_fourdp4=4,NOMEGA_PRINTED=15,master=0
     169              :  integer :: spin,ik_ibz,my_nbks
     170              :  integer :: choice,cplex,cplex_rhoij,dim_kxcg,dim_wing,ount,omp_ncpus
     171              :  integer :: fform_chi0,fform_em1,gnt_option,iat,ider,idir,ierr,band
     172              :  integer :: ifft,ii,ikbz,ikxc,initialized,iomega,ios,ipert
     173              :  integer :: iqibz,iqcalc,is_qeq0,isym,izero,ifirst,ilast
     174              :  integer :: label,mgfftf,mgfftgw
     175              :  integer :: nt_per_proc,work_size
     176              :  integer :: moved_atm_inside,moved_rhor
     177              :  integer :: nbcw,nbsc,nbvw,nkxc,nkxc1,n3xccc,optene,istep
     178              :  integer :: nfftf,nfftf_tot,nfftgw,nfftgw_tot,ngrvdw,nhatgrdim,nprocs,nspden_rhoij
     179              :  integer :: nscf,nzlmopt,mband
     180              :  integer :: optcut,optgr0,optgr1,optgr2,option,approx_type,option_test,optgrad
     181              :  integer :: optrad,optrhoij,psp_gencond,my_rank, ig
     182              :  integer :: rhoxsp_method,comm,test_type,tordering,unt_em1,unt_susc,usexcnhat, ncerr, gap_err
     183              :  real(dp) :: compch_fft,compch_sph,domegareal,e0,ecore,ecut_eff,ecutdg_eff
     184              :  real(dp) :: gsqcutc_eff,gsqcutf_eff,gsqcut_shp,omegaplasma,ucvol,vxcavg,gw_gsq,r_s
     185              :  real(dp) :: alpha,rhoav,factor,ec_gm,el_temp
     186              :  real(dp):: eff,mempercpu_mb,max_wfsmem_mb,nonscal_mem,ug_mem,ur_mem,cprj_mem
     187              :  integer, parameter :: epsm1_win = xmpi_undefined
     188              :  logical :: found,iscompatibleFFT,is_dfpt=.false.,use_tr,is_first_qcalc
     189              :  logical :: add_chi0_intraband,update_energies,call_pawinit
     190              :  character(len=10) :: string
     191              :  character(len=500) :: msg
     192              :  character(len=80) :: bar
     193          296 :  type(ebands_t) :: ks_ebands, qp_ebands
     194         3848 :  type(kmesh_t) :: Kmesh,Qmesh
     195         3256 :  type(vcoul_t) :: Vcp
     196         7696 :  type(crystal_t) :: Cryst
     197          148 :  type(em1params_t) :: Ep
     198              :  type(Energies_type) :: KS_energies
     199          148 :  type(gsphere_t) :: Gsph_epsG0,Gsph_wfn
     200          148 :  type(Hdr_type) :: Hdr_wfk,Hdr_local
     201          148 :  type(MPI_type) :: MPI_enreg_seq
     202              :  type(Pawfgr_type) :: Pawfgr
     203         1036 :  type(hscr_t) :: Hem1,Hchi0
     204          148 :  type(wfdgw_t) :: Wfd,Wfdf
     205          148 :  type(spectra_t) :: spectra
     206              :  !type(chi_t) :: chihw
     207          148 :  type(wvl_data) :: wvl_dummy
     208              :  character(len=nctk_slen) :: wing_shape
     209              : !arrays
     210          296 :  integer :: ibocc(Dtset%nsppol),ngfft_gw(18),ngfftc(18),ngfftf(18), units(2)
     211          296 :  integer,allocatable :: irottb(:,:),ktabr(:,:),ktabrf(:,:),l_size_atm(:)
     212          296 :  integer,allocatable :: ks_vbik(:,:),ks_occ_idx(:,:),qp_vbik(:,:),nband(:,:)
     213          296 :  integer,allocatable :: nq_spl(:),nlmn_atm(:),gw_gfft(:,:)
     214              :  real(dp) :: gmet(3,3),gprimd(3,3),k0(3),qtmp(3),rmet(3,3),rprimd(3,3),tsec(2),strsxc(6)
     215          592 :  real(dp),allocatable :: igwene(:,:,:),chi0_sumrule(:),ec_rpa(:),rspower(:)
     216          148 :  real(dp),allocatable :: nhat(:,:),nhatgr(:,:,:),ph1d(:,:),ph1df(:,:)
     217          148 :  real(dp),allocatable :: rhog(:,:),rhor(:,:),rhor_p(:,:),rhor_kernel(:,:),taur(:,:)
     218          444 :  real(dp),allocatable :: z(:),zw(:),grchempottn(:,:),grewtn(:,:),grvdw(:,:),kxc(:,:),qmax(:)
     219          296 :  real(dp),allocatable :: ks_vhartr(:),vpsp(:),ks_vtrial(:,:),ks_vxc(:,:),xccc3d(:)
     220          444 :  complex(gwp),allocatable :: arr_99(:,:),kxcg(:,:),fxc_ADA(:,:,:)
     221          148 :  complex(dp),allocatable :: m_ks_to_qp(:,:,:,:)
     222          148 :  complex(dp),allocatable :: chi0_head(:,:,:), chi0_lwing(:,:,:), chi0_uwing(:,:,:)
     223          148 :  real(dp),allocatable :: rwork_wing(:,:,:,:), tmp_omega_wgs(:)
     224          296 :  complex(dp),allocatable :: chi0intra_lwing(:,:,:),chi0intra_uwing(:,:,:),chi0intra_head(:,:,:), tmp_omega(:)
     225          148 :  complex(gwp),allocatable,target :: chi0(:,:,:),chi0intra(:,:,:)
     226          148 :  complex(gwp),contiguous, pointer :: epsm1(:,:,:)
     227          148 :  logical,allocatable :: bks_mask(:,:,:),keep_ur(:,:,:)
     228              :  character(len=80) :: title(2)
     229              :  character(len=fnlen) :: gw_fname,wfk_fname,lwl_fname
     230          148 :  type(littlegroup_t),pointer :: Ltg_q(:)
     231          148 :  type(Paw_an_type),allocatable :: Paw_an(:)
     232          148 :  type(Paw_ij_type),allocatable :: Paw_ij(:)
     233          148 :  type(Pawfgrtab_type),allocatable :: Pawfgrtab(:)
     234          148 :  type(Pawrhoij_type),allocatable :: Pawrhoij(:),prev_Pawrhoij(:)
     235          148 :  type(pawpwff_t),allocatable :: Paw_pwff(:)
     236          148 :  type(paw_pwaves_lmn_t),allocatable :: Paw_onsite(:)
     237          148 :  type(plowannier_type) :: wanbz,wanibz,wanibz_in
     238              :  real(dp) :: te_min, te_max
     239          148 :  type(gaps_t) :: gaps
     240          148 :  real(dp),allocatable :: tau_mesh(:), tau_wgs(:), iw_mesh(:), iw_wgs(:)
     241          148 :  real(dp),allocatable :: t2w_cos_wgs(:,:), w2t_cos_wgs(:,:), t2w_sin_wgs(:,:)
     242              :  real(dp) :: ft_max_error(3), cosft_duality_error
     243              : !************************************************************************
     244              : 
     245          148 :  call timab(301,1,tsec) ! overall time
     246          148 :  call timab(302,1,tsec) ! screening(init
     247          444 :  units = [std_out, ab_out]
     248              : 
     249              :  write(msg,'(6a)')&
     250          148 :  ' SCREENING: Calculation of the susceptibility and dielectric matrices ',ch10,ch10,&
     251          148 :  ' Based on a program developped by R.W. Godby, V. Olevano, G. Onida, and L. Reining.',ch10,&
     252          296 :  ' Incorporated in ABINIT by V. Olevano, G.-M. Rignanese, and M. Torrent.'
     253          148 :  call wrtout(units, msg)
     254              : 
     255          148 :  if(dtset%ucrpa>0) then
     256            0 :    write(msg,'(6a)')ch10,&
     257            0 :     ' cRPA Calculation: The calculation of the polarisability is constrained (ucrpa/=0)',ch10
     258            0 :    call wrtout(units, msg)
     259              :  end if
     260              : #if defined HAVE_GW_DPC
     261              :  if (gwp/=8) then
     262              :    write(msg,'(6a)')ch10,&
     263              :     ' Number of bytes for double precision complex /=8 ',ch10,&
     264              :     ' Cannot continue due to kind mismatch in BLAS library ',ch10,&
     265              :     ' Some BLAS interfaces are not generated by abilint '
     266              :    ABI_ERROR(msg)
     267              :  end if
     268          148 :  write(msg,'(a,i2,a)')'.Using double precision arithmetic ; gwpc = ',gwp,ch10
     269              : #else
     270              :  write(msg,'(a,i2,a)')'.Using single precision arithmetic ; gwpc = ',gwp,ch10
     271              : #endif
     272          148 :  call wrtout(units, msg)
     273              : 
     274              :  ! === Initialize MPI variables, and parallelization level ===
     275              :  ! gwpara: 0--> sequential run, 1--> parallelism over k-points, 2--> parallelism over bands.
     276              :  ! gwpara==2, each node has both fully and partially occupied states while conduction bands are divided
     277          148 :  comm = xmpi_world; my_rank = xmpi_comm_rank(comm); nprocs  = xmpi_comm_size(comm)
     278              : 
     279          148 :  if (my_rank == master) then
     280          120 :    wfk_fname = dtfil%fnamewffk
     281          120 :    if (nctk_try_fort_or_ncfile(wfk_fname, msg) /= 0) then
     282            0 :      ABI_ERROR(msg)
     283              :    end if
     284              :  end if
     285          148 :  call xmpi_bcast(wfk_fname, master, comm, ierr)
     286              : 
     287              :  ! Some variables need to be initialized/nullify at start
     288          148 :  call KS_energies%init()
     289          148 :  usexcnhat=0
     290              : 
     291          148 :  call mkrdim(acell,rprim,rprimd)
     292          148 :  call metric(gmet,gprimd,ab_out,rmet,rprimd,ucvol)
     293              : 
     294              : !=== Define FFT grid(s) sizes ===
     295              : ! Be careful! This mesh is only used for densities and potentials. It is NOT the (usually coarser)
     296              : ! GW FFT mesh employed for the oscillator matrix elements that is defined in setmesh.F90.
     297              : ! See also NOTES in the comments at the beginning of this file.
     298              : ! NOTE: The mesh is defined in invars2m using ecutwfn, in GW Dtset%ecut is forced to be equal to Dtset%ecutwfn.
     299              : 
     300          148 :  k0(:)=zero
     301              :  call pawfgr_init(Pawfgr,Dtset,mgfftf,nfftf,ecut_eff,ecutdg_eff,ngfftc,ngfftf,&
     302          148 :                   gsqcutc_eff=gsqcutc_eff,gsqcutf_eff=gsqcutf_eff,gmet=gmet,k0=k0)
     303              : 
     304          296 :  call print_ngfft([std_out], ngfftf,'Dense FFT mesh used for densities and potentials')
     305          592 :  nfftf_tot=PRODUCT(ngfftf(1:3))
     306              : 
     307              :  ! We can intialize MPI_enreg and fft distrib here, now ngfft are known
     308          148 :  call initmpi_seq(MPI_enreg_seq) ! Fake MPI_type for the sequential part.
     309          148 :  call MPI_enreg_seq%distribfft%init_seq('c',ngfftc(2),ngfftc(3),'all')
     310          148 :  call MPI_enreg_seq%distribfft%init_seq('f',ngfftf(2),ngfftf(3),'all')
     311              : 
     312              : !=============================================
     313              : !==== Open and read pseudopotential files ====
     314              : !=============================================
     315          148 :  call pspini(Dtset,Dtfil,ecore,psp_gencond,gsqcutc_eff,gsqcutf_eff,Pawrad,Pawtab,Psps,rprimd,comm_mpi=comm)
     316              : 
     317              :  ! === Initialize dimensions and basic objects ===
     318              :  call setup_screening(codvsn,acell,rprim,wfk_fname,Dtset,Psps,Pawtab,&
     319          148 :    ngfft_gw,Hdr_wfk,Hdr_local,Cryst,Kmesh,Qmesh,ks_ebands,Ltg_q,Gsph_epsG0,Gsph_wfn,Vcp,Ep,comm)
     320              : 
     321          148 :  call pstat_proc%print(_PSTAT_ARGS_)
     322          148 :  call timab(302,2,tsec) ! screening(init)
     323          296 :  call print_ngfft([std_out], ngfft_gw, header='FFT mesh used for oscillator strengths')
     324              : 
     325          592 :  nfftgw_tot=PRODUCT(ngfft_gw(1:3))
     326              :  mgfftgw   =MAXVAL (ngfft_gw(1:3))
     327          148 :  nfftgw    =nfftgw_tot ! no FFT //
     328              : 
     329              : !TRYING TO RECREATE AN "ABINIT ENVIRONMENT"
     330          148 :  KS_energies%e_corepsp=ecore/Cryst%ucvol
     331              : 
     332              : !==========================
     333              : !=== PAW initialization ===
     334              : !==========================
     335          148 :  if (Dtset%usepaw==1) then
     336            5 :    call timab(315,1,tsec) ! screening(pawin
     337              : 
     338            5 :    call chkpawovlp(Cryst%natom,Cryst%ntypat,Dtset%pawovlp,Pawtab,Cryst%rmet,Cryst%typat,Cryst%xred)
     339              : 
     340           46 :    ABI_MALLOC(Pawrhoij,(Cryst%natom))
     341              :    call pawrhoij_inquire_dim(cplex_rhoij=cplex_rhoij,nspden_rhoij=nspden_rhoij,&
     342            5 : &              nspden=Dtset%nspden,spnorb=Dtset%pawspnorb,cpxocc=Dtset%pawcpxocc)
     343              :    call pawrhoij_alloc(Pawrhoij,cplex_rhoij,nspden_rhoij,Dtset%nspinor,Dtset%nsppol,&
     344            5 : &                      Cryst%typat,pawtab=Pawtab)
     345              : 
     346              :    ! Initialize values for several basic arrays stored in Pawinit
     347            5 :    gnt_option=1;if (dtset%pawxcdev==2.or.(dtset%pawxcdev==1.and.dtset%positron/=0)) gnt_option=2
     348              : 
     349              :    ! Test if we have to call pawinit
     350            5 :    call paw_gencond(Dtset,gnt_option,"test",call_pawinit)
     351              : 
     352            5 :    if (psp_gencond==1.or.call_pawinit) then
     353            1 :      gsqcut_shp=two*abs(dtset%diecut)*dtset%dilatmx**2/pi**2
     354              :      call pawinit(dtset%effmass_free,gnt_option,gsqcut_shp,zero,Dtset%pawlcutd,Dtset%pawlmix,&
     355              : &     Psps%mpsang,Dtset%pawnphi,Cryst%nsym,Dtset%pawntheta,Pawang,Pawrad,&
     356            1 : &     Dtset%pawspnorb,Pawtab,Dtset%pawxcdev,Dtset%ixc,Dtset%usepotzero)
     357              : 
     358              :      ! Update internal values
     359            1 :      call paw_gencond(Dtset,gnt_option,"save",call_pawinit)
     360              :    else
     361            4 :      if (Pawtab(1)%has_kij  ==1) Pawtab(1:Cryst%ntypat)%has_kij  =2
     362            4 :      if (Pawtab(1)%has_nabla==1) Pawtab(1:Cryst%ntypat)%has_nabla=2
     363              :    end if
     364           14 :    Psps%n1xccc=MAXVAL(Pawtab(1:Cryst%ntypat)%usetcore)
     365              : 
     366              : !  Initialize optional flags in Pawtab to zero
     367              : !  (Cannot be done in Pawinit since the routine is called only if some pars. are changed)
     368           14 :    Pawtab(:)%has_nabla = 0
     369           14 :    Pawtab(:)%usepawu   = 0
     370           14 :    Pawtab(:)%useexexch = 0
     371           14 :    Pawtab(:)%exchmix   =zero
     372           14 :    Pawtab(:)%lamb_shielding = zero
     373              : 
     374              :    ! Evaluate <phi_i|nabla|phi_j>-<tphi_i|nabla|tphi_j> for the long wavelength limit.
     375              :    ! TODO solve problem with memory leak and clean this part as well as the associated flag
     376            5 :    call pawnabla_init(Psps%mpsang,Cryst%ntypat,Pawrad,Pawtab)
     377              : 
     378            5 :    call setsym_ylm(gprimd,Pawang%l_max-1,Cryst%nsym,Dtset%pawprtvol,rprimd,Cryst%symrec,Pawang%zarot)
     379              : 
     380              :    ! Initialize and compute data for DFT+U.
     381              :    ! paw_dmft%use_dmft=dtset%usedmft
     382              :    call pawpuxinit(Dtset%dmatpuopt,Dtset%exchmix,Dtset%f4of2_sla,Dtset%f6of2_sla,&
     383              : &    is_dfpt,Dtset%jpawu,Dtset%lexexch,Dtset%lpawu,dtset%nspinor,Cryst%ntypat,dtset%optdcmagpawu,Pawang,Dtset%pawprtvol,&
     384            5 : &    Pawrad,Pawtab,Dtset%upawu,Dtset%usedmft,Dtset%useexexch,Dtset%usepawu,dtset%ucrpa)
     385              : 
     386            5 :    if (my_rank == master) call pawtab_print(Pawtab)
     387              : 
     388              :    ! Get Pawrhoij from the header of the WFK file.
     389            5 :    call pawrhoij_copy(Hdr_wfk%Pawrhoij,Pawrhoij)
     390              : 
     391              :    ! Re-symmetrize rhoij.
     392              : !  this call leads to a SIGFAULT, likely some pointer is not initialized correctly
     393            5 :    choice=1; optrhoij=1; ipert=0; idir=0
     394              :    !call pawrhoij_symrhoij(Pawrhoij,Pawrhoij,choice,Cryst%gprimd,Cryst%indsym,ipert,Cryst%natom,&
     395              :    !&             Cryst%nsym,Cryst%ntypat,optrhoij,Pawang,Dtset%pawprtvol,Pawtab,&
     396              :    !&             Cryst%rprimd,Cryst%symafm,Cryst%symrec,Cryst%typat)
     397              :    !
     398              :    ! Evaluate form factors for the radial part of phi.phj-tphi.tphj ===
     399              :    ! rhoxsp_method=1 ! Arnaud-Alouani
     400              :    ! rhoxsp_method=2 ! Shiskin-Kresse
     401            5 :    rhoxsp_method=2
     402              : 
     403              :    ! At least for ucrpa, the Arnaud Alouani is always a better choice but needs a larger cutoff
     404            5 :    if(dtset%ucrpa>0) rhoxsp_method=1
     405            5 :    if (Dtset%pawoptosc /= 0) rhoxsp_method = Dtset%pawoptosc
     406              : 
     407           15 :    ABI_MALLOC(gw_gfft,(3,nfftgw_tot))
     408            5 :    call get_gfft(ngfft_gw,(/zero,zero,zero/),gmet,gw_gsq,gw_gfft)
     409            5 :    ABI_FREE(gw_gfft)
     410              : 
     411              :    ! Set up q grids, make qmax 20% larger than largest expected:
     412           15 :    ABI_MALLOC(nq_spl,(Psps%ntypat))
     413           15 :    ABI_MALLOC(qmax,(Psps%ntypat))
     414           14 :    nq_spl = Psps%mqgrid_ff
     415           14 :    qmax = SQRT(gw_gsq)*1.2d0  !qmax = Psps%qgrid_ff(Psps%mqgrid_ff)
     416           84 :    ABI_MALLOC(Paw_pwff,(Psps%ntypat))
     417              : 
     418            5 :    call pawpwff_init(Paw_pwff,rhoxsp_method,nq_spl,qmax,gmet,Pawrad,Pawtab,Psps)
     419            5 :    ABI_FREE(nq_spl)
     420            5 :    ABI_FREE(qmax)
     421              : 
     422              :    ! Variables/arrays related to the fine FFT grid
     423           20 :    ABI_MALLOC(nhat,(nfftf,Dtset%nspden))
     424       132482 :    nhat=zero; cplex=1
     425           46 :    ABI_MALLOC(Pawfgrtab,(Cryst%natom))
     426            5 :    call pawtab_get_lsize(Pawtab,l_size_atm,Cryst%natom,Cryst%typat)
     427            5 :    call pawfgrtab_init(Pawfgrtab,cplex,l_size_atm,Dtset%nspden,Dtset%typat)
     428            5 :    ABI_FREE(l_size_atm)
     429            5 :    compch_fft=greatest_real
     430           14 :    usexcnhat=MAXVAL(Pawtab(:)%usexcnhat)
     431              :    ! * 0 --> Vloc in atomic data is Vbare    (Blochl s formulation)
     432              :    ! * 1 --> Vloc in atomic data is VH(tnzc) (Kresse s formulation)
     433            5 :    write(msg,'(a,i3)')' screening : using usexcnhat = ',usexcnhat
     434            5 :    call wrtout(std_out, msg)
     435              : 
     436              :    ! Identify parts of the rectangular grid where the density has to be calculated.
     437            5 :    optcut=0;optgr0=Dtset%pawstgylm; optgr1=0; optgr2=0; optrad=1-Dtset%pawstgylm
     438            5 :    if (Dtset%pawcross==1) optrad=1
     439            5 :    if (Dtset%xclevel==2.and.usexcnhat>0) optgr1=Dtset%pawstgylm
     440              : 
     441              :    call nhatgrid(Cryst%atindx1,gmet,Cryst%natom,Cryst%natom,Cryst%nattyp,ngfftf,Cryst%ntypat,&
     442            5 :                  optcut,optgr0,optgr1,optgr2,optrad,Pawfgrtab,Pawtab,Cryst%rprimd,Cryst%typat,Cryst%ucvol,Cryst%xred)
     443              : 
     444           15 :    call timab(315,2,tsec) ! screening(pawin
     445              :  else
     446              :    ! allocate empty structure for the sake of -fcheck=all...
     447          143 :    ABI_MALLOC(Paw_pwff,(0))
     448          143 :    ABI_MALLOC(Pawrhoij,(0))
     449          143 :    ABI_MALLOC(Pawfgrtab,(0))
     450              :  end if ! End of PAW initialization.
     451              : 
     452              :  ! Consistency check and additional stuff done only for GW with PAW.
     453          795 :  ABI_MALLOC(Paw_onsite,(Cryst%natom))
     454          148 :  if (Dtset%usepaw==1) then
     455            5 :    if (Dtset%ecutwfn < Dtset%ecut) then
     456              :      write(msg,"(5a)")&
     457            0 :      "WARNING - ",ch10,&
     458            0 :      "  It is highly recommended to use ecutwfn = ecut for GW calculations with PAW since ",ch10,&
     459            0 :      "  an excessive truncation of the planewave basis set can lead to unphysical results."
     460            0 :      call wrtout(ab_out, msg)
     461              :    end if
     462              : 
     463            5 :    ABI_CHECK(Dtset%useexexch==0,"LEXX not yet implemented in GW")
     464            5 :    ABI_CHECK(Dtset%usedmft==0,"DMFT + GW not available")
     465              : 
     466            5 :    if (Dtset%pawcross==1) then
     467            0 :      optgrad=1
     468              :      call paw_pwaves_lmn_init(Paw_onsite,Cryst%natom,Cryst%natom,Cryst%ntypat,Cryst%rprimd,&
     469            0 :                               Cryst%xcart,Pawtab,Pawrad,Pawfgrtab,optgrad)
     470              :    end if
     471              :  end if
     472              : 
     473              :  ! Allocate these arrays anyway, since they are passed to subroutines.
     474          148 :  if (.not.allocated(nhat)) then
     475          286 :    ABI_MALLOC(nhat,(nfftf,0))
     476              :  end if
     477              : 
     478          148 :  call timab(316,1,tsec) ! screening(wfs
     479              : 
     480              : !=====================================================
     481              : !=== Prepare the distribution of the wavefunctions ===
     482              : !=====================================================
     483              : ! valence and partially occupied are replicate on each node  while conduction bands are MPI distributed.
     484              : ! This method is mandatory if gwpara==2 and/or we are using awtr==1 or the spectral method.
     485              : ! If awtr==1, we evaluate chi0 taking advantage of time-reversal (speed-up~2)
     486              : ! Useful indices:
     487              : !       nbvw = Max. number of fully/partially occupied states over spin
     488              : !       nbcw = Max. number of unoccupied states considering the spin
     489              : !TODO:
     490              : !  Here for semiconducting systems we have to be sure that each processor has all the
     491              : !  states considered in the SCGW, moreover nbsc<nbvw
     492              : !  in case of SCGW vale and conduction has to be recalculated to avoid errors
     493              : !  if a metal becomes semiconductor or viceversa.
     494              : !  Ideally nbvw should include only the states v such that the transition
     495              : !  c-->v is taken into account in cchi0 (see GW_TOLDOCC). In the present implementation
     496              : 
     497          592 :  ABI_MALLOC(ks_occ_idx,(ks_ebands%nkpt, ks_ebands%nsppol))
     498          444 :  ABI_MALLOC(ks_vbik   ,(ks_ebands%nkpt, ks_ebands%nsppol))
     499          444 :  ABI_MALLOC(qp_vbik   ,(ks_ebands%nkpt, ks_ebands%nsppol))
     500              : 
     501          148 :  call ks_ebands%update_occ(Dtset%spinmagntarget, prtvol=0)
     502          148 :  ks_occ_idx = ks_ebands%get_occupied(tol8) ! tol8 to be consistent when the density
     503          148 :  ks_vbik    = ks_ebands%get_valence_idx()
     504              : 
     505          148 :  ibocc(:)=MAXVAL(ks_occ_idx(:,:),DIM=1) ! Max occupied band index for each spin.
     506          148 :  ABI_FREE(ks_occ_idx)
     507              : 
     508          148 :  use_tr =.FALSE.; nbvw=0
     509          148 :  if (Dtset%gwpara==2.or.Ep%awtr==1.or.Dtset%spmeth>0) then
     510          137 :    use_tr = .TRUE.
     511          276 :    nbvw=MAXVAL(ibocc)
     512          137 :    nbcw=Ep%nbnds-nbvw
     513          137 :    write(msg,'(4a,i0,2a,i0,2a,i0,a)')ch10,&
     514          137 :     '- screening: taking advantage of time-reversal symmetry ',ch10,&
     515          137 :     '- Maximum band index for partially occupied states nbvw = ',nbvw,ch10,&
     516          137 :     '- Remaining bands to be divided among processors   nbcw = ',nbcw,ch10,&
     517          274 :     '- Number of bands treated by each node ~',nbcw/nprocs,ch10
     518          137 :    call wrtout(ab_out, msg)
     519          137 :    if (Cryst%timrev/=2) then
     520            0 :      ABI_ERROR('Time-reversal cannot be used since cryst%timrev/=2')
     521              :    end if
     522              :  end if
     523              : 
     524          148 :  mband=Ep%nbnds
     525          592 :  ABI_MALLOC(nband,(Kmesh%nibz,Dtset%nsppol))
     526         1159 :  nband=mband
     527          740 :  ABI_MALLOC(bks_mask,(mband,Kmesh%nibz,Dtset%nsppol))
     528          592 :  ABI_MALLOC(keep_ur,(mband,Kmesh%nibz,Dtset%nsppol))
     529        46746 :  bks_mask=.FALSE.; keep_ur=.FALSE.
     530              : 
     531              :  ! autoparal section
     532          148 :  if (dtset%max_ncpus /=0) then
     533            0 :    ount = ab_out
     534              :    ! Temporary table needed to estimate memory
     535            0 :    ABI_MALLOC(nlmn_atm,(Cryst%natom))
     536            0 :    if (Dtset%usepaw==1) then
     537            0 :      do iat=1,Cryst%natom
     538            0 :        nlmn_atm(iat)=Pawtab(Cryst%typat(iat))%lmn_size
     539              :      end do
     540              :    end if
     541              : 
     542            0 :    write(ount,'(a)')"--- !Autoparal"
     543            0 :    write(ount,"(a)")"# Autoparal section for Screening runs"
     544            0 :    write(ount,"(a)")   "info:"
     545            0 :    write(ount,"(a,i0)")"    autoparal: ",dtset%autoparal
     546            0 :    write(ount,"(a,i0)")"    max_ncpus: ",dtset%max_ncpus
     547            0 :    write(ount,"(a,i0)")"    gwpara: ",dtset%gwpara
     548            0 :    write(ount,"(a,i0)")"    nkpt: ",dtset%nkpt
     549            0 :    write(ount,"(a,i0)")"    nsppol: ",dtset%nsppol
     550            0 :    write(ount,"(a,i0)")"    nspinor: ",dtset%nspinor
     551            0 :    write(ount,"(a,i0)")"    nbnds: ",Ep%nbnds
     552              : 
     553            0 :    work_size = nbvw * nbcw * Kmesh%nibz**2 * Dtset%nsppol
     554              : 
     555              :    ! Non-scalable memory in Mb i.e. memory that is not distribute with MPI.
     556            0 :    nonscal_mem = (two*gwp*Ep%npwe**2*(Ep%nomega*b2Mb)) * 1.1_dp
     557              : 
     558              :    ! List of configurations.
     559              :    ! Assuming an OpenMP implementation with perfect speedup!
     560            0 :    write(ount,"(a)")"configurations:"
     561              : 
     562            0 :    do ii=1,dtset%max_ncpus
     563            0 :      nt_per_proc = 0
     564            0 :      eff = HUGE(one)
     565            0 :      max_wfsmem_mb = zero
     566              : 
     567            0 :      do my_rank=0,ii-1
     568            0 :        call chi0_bksmask(Dtset,Ep,Kmesh,nbvw,nbcw,my_rank,ii,bks_mask,keep_ur,ierr)
     569            0 :        if (ierr /= 0) exit
     570            0 :        nt_per_proc = MAX(nt_per_proc, COUNT(bks_mask(1:nbvw,:,:)) * COUNT(bks_mask(nbvw+1:,:,:)))
     571            0 :        eff = MIN(eff, (one * work_size) / (ii * nt_per_proc))
     572              : 
     573              :        ! Memory needed for Fourier components ug.
     574            0 :        my_nbks = COUNT(bks_mask)
     575            0 :        ug_mem = two*gwp*Dtset%nspinor*Ep%npwwfn*my_nbks*b2Mb
     576              : 
     577              :        ! Memory needed for real space ur.
     578            0 :        ur_mem = two*gwp*Dtset%nspinor*nfftgw*COUNT(keep_ur)*b2Mb
     579              : 
     580              :        ! Memory needed for PAW projections Cprj
     581            0 :        cprj_mem = zero
     582            0 :        if (Dtset%usepaw==1) cprj_mem = dp*Dtset%nspinor*SUM(nlmn_atm)*my_nbks*b2Mb
     583              : 
     584            0 :        max_wfsmem_mb = MAX(max_wfsmem_mb, ug_mem + ur_mem + cprj_mem)
     585              :      end do
     586            0 :      if (ierr /= 0) cycle
     587              : 
     588              :      ! Add the non-scalable part and increase by 10% to account for other datastructures.
     589            0 :      mempercpu_mb = (max_wfsmem_mb + nonscal_mem) * 1.1_dp
     590              : 
     591            0 :      do omp_ncpus=1,xomp_get_max_threads()
     592            0 :        write(ount,"(a,i0)")"    - tot_ncpus: ",ii * omp_ncpus
     593            0 :        write(ount,"(a,i0)")"      mpi_ncpus: ",ii
     594            0 :        write(ount,"(a,i0)")"      omp_ncpus: ",omp_ncpus
     595            0 :        write(ount,"(a,f12.9)")"      efficiency: ",eff
     596            0 :        write(ount,"(a,f12.2)")"      mem_per_cpu: ",mempercpu_mb
     597              :      end do
     598              :    end do
     599            0 :    write(ount,'(a)')"..."
     600              : 
     601            0 :    ABI_FREE(nlmn_atm)
     602            0 :    ABI_ERROR_NODUMP("aborting now")
     603              :  else
     604          148 :    call chi0_bksmask(Dtset,Ep,Kmesh,nbvw,nbcw,my_rank,nprocs,bks_mask,keep_ur,ierr)
     605              :  end if
     606              : 
     607              :  ! Initialize the wf descriptor (allocate %ug and %ur if required).
     608              : 
     609              :  call wfd%init(Cryst,Pawtab,Psps,keep_ur,mband,nband,Ep%nkibz,Dtset%nsppol,bks_mask,&
     610              :   Dtset%nspden,Dtset%nspinor,Dtset%ecutwfn,Dtset%ecutsm,Dtset%dilatmx,Hdr_wfk%istwfk,Kmesh%ibz,ngfft_gw,&
     611          148 :   Dtset%nloalg,Dtset%prtvol,Dtset%pawprtvol,comm)
     612              : 
     613          148 :  if (Dtset%pawcross==1) then
     614              :    call Wfdf%init(Cryst,Pawtab,Psps,keep_ur,mband,nband,Ep%nkibz,Dtset%nsppol,bks_mask,&
     615              :     Dtset%nspden,Dtset%nspinor,dtset%ecutwfn,Dtset%ecutsm,Dtset%dilatmx,Hdr_wfk%istwfk,Kmesh%ibz,ngfft_gw,&
     616            0 :     Dtset%nloalg,Dtset%prtvol,Dtset%pawprtvol,comm)
     617              :  end if
     618              : 
     619          148 :  ABI_FREE(bks_mask)
     620          148 :  ABI_FREE(nband)
     621          148 :  ABI_FREE(keep_ur)
     622              : 
     623          296 :  call wfd%print([std_out])
     624              :  !FIXME: Rewrite the treatment of use_tr branches in cchi0 ...
     625              :  !Use a different nbvw for each spin.
     626              :  !Now use_tr means that one can use time-reversal symmetry.
     627              : 
     628              : !==================================================
     629              : !==== Read KS band structure from the KSS file ====
     630              : !==================================================
     631          148 :  call wfd%read_wfk(wfk_fname,iomode_from_fname(wfk_fname))
     632              : 
     633          148 :  if (Dtset%pawcross==1) then
     634            0 :    call wfdgw_copy(Wfd, Wfdf)
     635            0 :    call wfdf%change_ngfft(Cryst,Psps,ngfftf)
     636              :  end if
     637              : 
     638              :  ! This test has been disabled (too expensive!)
     639              :  if (.False.) call wfd%test_ortho(Cryst,Pawtab,unit=ab_out,mode_paral="COLL")
     640              : 
     641          148 :  call pstat_proc%print(_PSTAT_ARGS_)
     642          148 :  call timab(316,2,tsec) ! screening(wfs
     643          148 :  call timab(319,1,tsec) ! screening(1)
     644              : 
     645          148 :  if (Cryst%nsym/=Dtset%nsym .and. Dtset%usepaw==1) then
     646            0 :    ABI_ERROR('Cryst%nsym/=Dtset%nsym, check pawinit and pawrhoij_symrhoij')
     647              :  end if
     648              : 
     649              :  ! Get the FFT index of $ (R^{-1}(r-\tau)) $
     650              :  ! S= $\transpose R^{-1}$ and k_BZ = S k_IBZ
     651              :  ! irottb is the FFT index of $ R^{-1} (r-\tau) $ used to symmetrize u_Sk.
     652          592 :  ABI_MALLOC(irottb, (nfftgw, Cryst%nsym))
     653          148 :  call rotate_FFT_mesh(Cryst%nsym, Cryst%symrel, Cryst%tnons, ngfft_gw, irottb, iscompatibleFFT)
     654              : 
     655          592 :  ABI_MALLOC(ktabr,(nfftgw,Kmesh%nbz))
     656         7084 :  do ikbz=1,Kmesh%nbz
     657         6936 :    isym=Kmesh%tabo(ikbz)
     658     40401262 :    do ifft=1,nfftgw
     659     40401114 :      ktabr(ifft,ikbz)=irottb(ifft,isym)
     660              :    end do
     661              :  end do
     662          148 :  ABI_FREE(irottb)
     663              : 
     664          148 :  if (Dtset%usepaw==1 .and. Dtset%pawcross==1) then
     665            0 :    ABI_MALLOC(irottb,(nfftf,Cryst%nsym))
     666            0 :    call rotate_FFT_mesh(Cryst%nsym,Cryst%symrel,Cryst%tnons,ngfftf,irottb,iscompatibleFFT)
     667              : 
     668            0 :    ABI_MALLOC(ktabrf,(nfftf,Kmesh%nbz))
     669            0 :    do ikbz=1,Kmesh%nbz
     670            0 :      isym=Kmesh%tabo(ikbz)
     671            0 :      do ifft=1,nfftf
     672            0 :        ktabrf(ifft,ikbz)=irottb(ifft,isym)
     673              :      end do
     674              :    end do
     675            0 :    ABI_FREE(irottb)
     676              :  else
     677          148 :    ABI_MALLOC(ktabrf,(0,0))
     678              :  end if
     679              : 
     680              :  ! Compute structure factor phases and large sphere cut-off
     681          444 :  ABI_MALLOC(ph1d,(2,3*(2*Dtset%mgfft+1)*Cryst%natom))
     682          444 :  ABI_MALLOC(ph1df,(2,3*(2*mgfftf+1)*Cryst%natom))
     683          148 :  call getph(Cryst%atindx,Cryst%natom,ngfftc(1),ngfftc(2),ngfftc(3),ph1d,Cryst%xred)
     684              : 
     685          148 :  if (Psps%usepaw==1.and.Pawfgr%usefinegrid==1) then
     686            2 :    call getph(Cryst%atindx,Cryst%natom,ngfftf(1),ngfftf(2),ngfftf(3),ph1df,Cryst%xred)
     687              :  else
     688       140015 :    ph1df(:,:)=ph1d(:,:)
     689              :  end if
     690              : 
     691              :  ! Initialize qp_ebands using KS bands
     692              :  ! In case of SCGW, update qp_ebands using the QPS file.
     693          148 :  call ks_ebands%copy(qp_ebands)
     694          148 :  call timab(319,2,tsec) ! screening(1)
     695              : 
     696              : !============================
     697              : !==== Self-consistent GW ====
     698              : !============================
     699          148 :  if (Ep%gwcalctyp>=10) then
     700           49 :    call timab(304,1,tsec) ! KS => QP; [wfrg]
     701              : 
     702              :    ! Initialize with KS eigenvalues and eigenfunctions.
     703          294 :    ABI_MALLOC(m_ks_to_qp,(Wfd%mband,Wfd%mband,Wfd%nkibz,Wfd%nsppol))
     704        39764 :    m_ks_to_qp = czero
     705           98 :    do spin=1,Wfd%nsppol
     706          348 :      do ik_ibz=1,Wfd%nkibz
     707         3167 :        do band=1,Wfd%nband(ik_ibz,spin)
     708        24738 :          m_ks_to_qp(band,band,:,:) = cone
     709              :        end do
     710              :      end do
     711              :    end do
     712              : 
     713              :    ! Read unitary transformation and QP energies.
     714              :    ! TODO switch on the renormalization of n in screening, QPS should report bdgw
     715          196 :    ABI_MALLOC(rhor_p,(nfftf,Dtset%nspden))
     716          147 :    ABI_MALLOC(prev_Pawrhoij,(Cryst%natom*Psps%usepaw))
     717              : 
     718              :    call rdqps(qp_ebands,Dtfil%fnameabi_qps,Dtset%usepaw,Dtset%nspden,1,nscf,&
     719           49 :    nfftf,ngfftf,Cryst%ucvol,Cryst,Pawtab,MPI_enreg_seq,nbsc,m_ks_to_qp,rhor_p,prev_Pawrhoij)
     720              : 
     721           49 :    ABI_FREE(rhor_p)
     722           49 :    ABI_FREE(prev_Pawrhoij)
     723              : 
     724              :    ! FIXME this is to preserve the old implementation for the head and the wings in ccchi0q0
     725              :    ! But has to be rationalized
     726           49 :    if (dtset%use_oldchi == 1) then
     727         2981 :      ks_ebands%eig = qp_ebands%eig
     728              :    end if
     729              : 
     730              :    ! Calculate new occ. factors and fermi level.
     731           49 :    call qp_ebands%update_occ(Dtset%spinmagntarget)
     732           49 :    qp_vbik(:,:) = qp_ebands%get_valence_idx()
     733              : 
     734              :    ! === Update only the wfg treated with GW ===
     735              :    ! For PAW update and re-symmetrize cprj in the full BZ, TODO add rotation in spinor space
     736           49 :    if (nscf/=0) call wfd%rotate(Cryst,m_ks_to_qp)
     737              : 
     738           49 :    ABI_FREE(m_ks_to_qp)
     739           49 :    call timab(304,2,tsec)
     740              :  end if ! gwcalctyp>=10
     741              : 
     742          148 :  call timab(305,1,tsec) ! screening(densit
     743              : !
     744              : !=== In case update the eigenvalues ===
     745              : !* Either use a scissor operator or an external GW file.
     746          148 :  gw_fname = "__in.gw__"
     747          148 :  update_energies = file_exists(gw_fname)
     748              : 
     749          148 :  if (ABS(Ep%mbpt_sciss)>tol6) then
     750              :    write(msg,'(5a,f7.3,a)')&
     751            1 :    ' screening : performing a first self-consistency',ch10,&
     752            1 :    ' update of the energies in W by a scissor operator',ch10,&
     753            2 :    ' applying a scissor operator of [eV] : ',Ep%mbpt_sciss*Ha_eV,ch10
     754            1 :    call wrtout(units, msg)
     755            1 :    call qp_ebands%apply_scissors(Ep%mbpt_sciss)
     756          147 :  else if (update_energies) then
     757              :    write(msg,'(4a)')&
     758            0 :     ' screening : performing a first self-consistency',ch10,&
     759            0 :     ' update of the energies in W by a previous GW calculation via GW file: ',TRIM(gw_fname)
     760            0 :    call wrtout(units, msg)
     761            0 :    ABI_MALLOC(igwene,(qp_ebands%mband, qp_ebands%nkpt, qp_ebands%nsppol))
     762            0 :    call rdgw(qp_ebands,gw_fname,igwene,extrapolate=.FALSE.)
     763              :    !call rdgw(qp_ebands,gw_fname,igwene,extrapolate=.TRUE.)
     764            0 :    ABI_FREE(igwene)
     765            0 :    call qp_ebands%update_occ(Dtset%spinmagntarget)
     766              :  end if
     767              : 
     768              : !========================
     769              : !=== COMPUTE DENSITY ====
     770              : !========================
     771              : !* Evaluate PW part (complete charge in case of NC pseudos)
     772              : !TODO this part has to be rewritten. If I decrease the tol on the occupations
     773              : !I have to code some MPI stuff also if use_tr==.TRUE.
     774              : 
     775              :  !Get electronic temperature from dtset
     776          148 :  el_temp = merge(dtset%tphysel,dtset%tsmear,dtset%tphysel>tol8.and.dtset%occopt/=3.and.dtset%occopt/=9)
     777              : 
     778          592 :  ABI_MALLOC(rhor,(nfftf,Dtset%nspden))
     779          592 :  ABI_MALLOC(taur,(nfftf,Dtset%nspden*Dtset%usekden))
     780              : 
     781          148 :  call wfd%mkrho(cryst, psps, qp_ebands, ngfftf, nfftf, rhor)
     782          148 :  if (Dtset%usekden==1) call wfd%mkrho(cryst, psps, qp_ebands, ngfftf, nfftf, taur, optcalc=1)
     783              : 
     784          148 :  call timab(305,2,tsec) ! screening(densit
     785              : 
     786          148 :  nhatgrdim = 0
     787          148 :  if (Dtset%usepaw==1) then ! Additional computation for PAW.
     788            5 :    call timab(320,1,tsec) ! screening(paw
     789              : 
     790              :    ! Add the compensation charge to the PW density.
     791            5 :    nhatgrdim=0; if (Dtset%xclevel==2) nhatgrdim=usexcnhat*Dtset%pawnhatxc
     792            5 :    cplex=1; ider=2*nhatgrdim; izero=0
     793            5 :    if (nhatgrdim>0)  then
     794            5 :      ABI_MALLOC(nhatgr,(nfftf,Dtset%nspden,3))
     795              :    else
     796           12 :      ABI_MALLOC(nhatgr,(nfftf,Dtset%nspden,0))
     797              :    end if
     798              :    call pawmknhat(compch_fft,cplex,ider,idir,ipert,izero,Cryst%gprimd,&
     799              :     Cryst%natom,Cryst%natom,nfftf,ngfftf,nhatgrdim,Dtset%nspden,Cryst%ntypat,Pawang,&
     800            5 :     Pawfgrtab,nhatgr,nhat,Pawrhoij,Pawrhoij,Pawtab,k0,Cryst%rprimd,Cryst%ucvol,dtset%usewvl,Cryst%xred)
     801              : 
     802              :    !  === Evaluate onsite energies, potentials, densities ===
     803              :    !  * Initialize variables/arrays related to the PAW spheres.
     804              :    !  * Initialize also lmselect (index of non-zero LM-moments of densities).
     805            5 :    cplex=1
     806           46 :    ABI_MALLOC(Paw_ij,(Cryst%natom))
     807            5 :    call paw_ij_nullify(Paw_ij)
     808              :    call paw_ij_init(Paw_ij,cplex,Dtset%nspinor,Wfd%nsppol,&
     809              :     Wfd%nspden,Dtset%pawspnorb,Cryst%natom,Cryst%ntypat,Cryst%typat,Pawtab,&
     810            5 :     has_dij=1,has_dijhartree=1,has_exexch_pot=1,has_pawu_occ=1)
     811              : 
     812            5 :    nkxc1=0
     813           46 :    ABI_MALLOC(Paw_an,(Cryst%natom))
     814            5 :    call paw_an_nullify(Paw_an)
     815              :    call paw_an_init(Paw_an,Cryst%natom,Cryst%ntypat,nkxc1,0,Dtset%nspden,&
     816            5 :     cplex,Dtset%pawxcdev,Cryst%typat,Pawang,Pawtab,has_vxc=1,has_vxcval=0)
     817              : 
     818            5 :    nzlmopt=-1; option=0; compch_sph=greatest_real
     819              :    call pawdenpot(compch_sph,el_temp,Cryst%gprimd,ipert,Dtset%ixc,Cryst%natom,Cryst%natom,Dtset%nspden,&
     820              : &   Cryst%ntypat,Dtset%nucdipmom,nzlmopt,option,Paw_an,Paw_an,KS_energies%paw,Paw_ij,Pawang,&
     821              : &   Dtset%pawprtvol,Pawrad,Pawrhoij,Dtset%pawspnorb,Pawtab,Dtset%pawxcdev,Dtset%spnorbscl,&
     822            5 : &   Dtset%xclevel,Dtset%xc_denpos,Dtset%xc_taupos,Cryst%xred,Cryst%ucvol,Psps%znuclpsp,Dtset%spinaxis)
     823            5 :    call timab(320,2,tsec) ! screening(paw
     824              :  else
     825          143 :    ABI_MALLOC(Paw_ij,(0))
     826          143 :    ABI_MALLOC(Paw_an,(0))
     827              :  end if ! usepaw
     828              : 
     829          148 :  call timab(321,1,tsec) ! screening(2)
     830              : 
     831              :  !JB : Should be remove : cf. l 839
     832          148 :  if (.not.allocated(nhatgr))  then
     833          429 :    ABI_MALLOC(nhatgr,(nfftf,Dtset%nspden,0))
     834              :  end if
     835              : 
     836              :  call test_charge(nfftf,ks_ebands%nelect,Dtset%nspden,rhor,ucvol,&
     837          148 :    Dtset%usepaw,usexcnhat,Pawfgr%usefinegrid,compch_sph,compch_fft,omegaplasma)
     838              : 
     839              : !For PAW, add the compensation charge the FFT mesh, then get rho(G).
     840       132625 :  if (Dtset%usepaw==1) rhor(:,:)=rhor(:,:)+nhat(:,:)
     841              : 
     842          148 :  call prtrhomxmn(std_out,MPI_enreg_seq,nfftf,ngfftf,Dtset%nspden,1,rhor,ucvol=ucvol)
     843          148 :  if(Dtset%usekden==1)then
     844            0 :    call prtrhomxmn(std_out,MPI_enreg_seq,nfftf,ngfftf,Dtset%nspden,1,taur,ucvol=ucvol,optrhor=1)
     845              :  end if
     846              : 
     847          148 :  if (dtset%gwgamma>0 .or. dtset%gwgamma==-11) then
     848            8 :    ABI_MALLOC(rhor_kernel,(nfftf,Dtset%nspden))
     849              :  end if
     850              : 
     851          444 :  ABI_MALLOC(rhog,(2,nfftf))
     852          148 :  call fourdp(1,rhog,rhor(:,1),-1,MPI_enreg_seq,nfftf,1,ngfftf,tim_fourdp4)
     853              : 
     854              : !The following steps have been gathered in the setvtr routine:
     855              : !- get Ewald energy and Ewald forces
     856              : !- compute local ionic pseudopotential vpsp
     857              : !- eventually compute 3D core electron density xccc3d
     858              : !- eventually compute vxc and vhartr
     859              : !- set up ks_vtrial
     860              : !**************************************************************
     861              : !**** NOTE THAT Vxc CONTAINS THE CORE-DENSITY CONTRIBUTION ****
     862              : !**************************************************************
     863              : 
     864          148 :  ngrvdw=0
     865          148 :  ABI_MALLOC(grvdw,(3,ngrvdw))
     866          444 :  ABI_MALLOC(grchempottn,(3,Cryst%natom))
     867          296 :  ABI_MALLOC(grewtn,(3,Cryst%natom))
     868          148 :  nkxc=0
     869          148 :  if (Dtset%nspden==1) nkxc=2
     870          148 :  if (Dtset%nspden>=2) nkxc=3 ! check GGA and spinor that is messy !!!
     871              :  ! If MGGA, fxc and kxc are not available and we dont need them for the screening part (for now ...)
     872          148 :  if (Dtset%ixc<0 .and. libxc_functionals_ismgga()) nkxc=0
     873          148 :  if (nkxc/=0)  then
     874          592 :    ABI_MALLOC(kxc,(nfftf,nkxc))
     875              :  end if
     876              : 
     877          148 :  n3xccc=0; if (Psps%n1xccc/=0) n3xccc=nfftf
     878          444 :  ABI_MALLOC(xccc3d,(n3xccc))
     879          444 :  ABI_MALLOC(ks_vhartr,(nfftf))
     880          592 :  ABI_MALLOC(ks_vtrial,(nfftf,Dtset%nspden))
     881          296 :  ABI_MALLOC(vpsp,(nfftf))
     882          444 :  ABI_MALLOC(ks_vxc,(nfftf,Dtset%nspden))
     883              : 
     884          148 :  optene=4; moved_atm_inside=0; moved_rhor=0; initialized=1; istep=1
     885              :  call setvtr(Cryst%atindx1,Dtset,KS_energies,Cryst%gmet,Cryst%gprimd,grchempottn, &
     886              :      grewtn,grvdw,gsqcutf_eff,istep,kxc,mgfftf,moved_atm_inside,moved_rhor,MPI_enreg_seq, &
     887              :      Cryst%nattyp,nfftf,ngfftf,ngrvdw,nhat,nhatgr,nhatgrdim,nkxc,Cryst%ntypat,&
     888              :      Psps%n1xccc,n3xccc,optene,Pawang,Pawrad,Pawrhoij,Pawtab,ph1df,Psps,rhog,rhor, &
     889              :      Cryst%rmet,Cryst%rprimd,strsxc,Cryst%ucvol,usexcnhat,ks_vhartr,vpsp,ks_vtrial,ks_vxc, &
     890          148 :      vxcavg,wvl_dummy,xccc3d,Cryst%xred,taur=taur)
     891              : 
     892          148 :  if (nkxc/=0)  then
     893          148 :    ABI_FREE(kxc)
     894              :  end if
     895          148 :  ABI_FREE(grchempottn)
     896          148 :  ABI_FREE(grewtn)
     897          148 :  ABI_FREE(grvdw)
     898          148 :  ABI_FREE(xccc3d)
     899              : 
     900              : !============================
     901              : !==== Compute KS PAW Dij ====
     902              : !============================
     903          148 :  if (Dtset%usepaw==1) then
     904            5 :    call timab(561,1,tsec)
     905              : 
     906              : !  Calculate unsymmetrized Dij.
     907            5 :    cplex=1; ipert=0; idir=0
     908              :    call pawdij(cplex,Dtset%enunit,Cryst%gprimd,ipert,&
     909              : &   Cryst%natom,Cryst%natom,nfftf,ngfftf(1)*ngfftf(2)*ngfftf(3),&
     910              : &   Dtset%nspden,Cryst%ntypat,Paw_an,Paw_ij,Pawang,Pawfgrtab,Dtset%pawprtvol,&
     911              : &   Pawrad,Pawrhoij,Dtset%pawspnorb,Pawtab,Dtset%pawxcdev,k0,Dtset%spnorbscl,&
     912              : &   Cryst%ucvol,dtset%cellcharge(1),ks_vtrial,ks_vxc,Cryst%xred,Dtset%znucl,&
     913            5 : &   nucdipmom=Dtset%nucdipmom,spinaxis=Dtset%spinaxis)
     914              : 
     915              : !  Symmetrize KS Dij
     916              : #if 0
     917              :    call symdij(Cryst%gprimd,Cryst%indsym,ipert,Cryst%natom,Cryst%natom,&
     918              : &   Cryst%nsym,Cryst%ntypat,0,Paw_ij,Pawang,Dtset%pawprtvol,Pawtab,Cryst%rprimd,Cryst%symafm,&
     919              : &   Cryst%symrec)
     920              : #else
     921              :    call symdij_all(Cryst%gprimd,Cryst%indsym,ipert,Cryst%natom,Cryst%natom,&
     922              : &   Cryst%nsym,Cryst%ntypat,Paw_ij,Pawang,Dtset%pawprtvol,Pawtab,Cryst%rprimd,Cryst%symafm,&
     923            5 : &   Cryst%symrec)
     924              : #endif
     925              :    !  Output of the pseudopotential strengths Dij and the augmentation occupancies Rhoij.
     926            5 :    call pawprt(Dtset,Cryst%natom,Paw_ij,Pawrhoij,Pawtab)
     927            5 :    call timab(561,2,tsec)
     928              :  end if
     929              : 
     930              :  ! Calculate frequency mesh.
     931              :  ! First omega is always zero without broadening.
     932              :  ! FIXME what about metals? I think we should add eta,
     933              :  ! this means we need to know if the system is metallic, for example using occopt
     934              :  ! MS Modified to account for non-zero starting frequency (19-11-2010)
     935              :  ! MS Modified for tangent grid (07-01-2011)
     936          444 :  ABI_MALLOC(Ep%omega, (Ep%nomega))
     937          148 :  Ep%omega(1) = CMPLX(Ep%omegaermin, zero, kind=dp)
     938              : 
     939          148 :  ep%iw_mesh_type = "None"; ep%rw_mesh_type = "None"; ep%cw_mesh_type = "None"
     940         1399 :  ABI_CALLOC(Ep%omega_wgs, (Ep%nomega))
     941              : 
     942              :  ! Deal with real frequencies first.
     943          148 :  if (Ep%nomegaer > 1) then
     944              : 
     945           26 :    if (Dtset%gw_frqre_tangrid == 0 .and. Dtset%gw_frqre_inzgrid == 0) then
     946           24 :      ep%rw_mesh_type = "linear"
     947           24 :      domegareal = (Ep%omegaermax -Ep%omegaermin) / (Ep%nomegaer -1)
     948          290 :      do iomega=2,Ep%nomegaer
     949          290 :        Ep%omega(iomega)=CMPLX(Ep%omegaermin+(iomega-1)*domegareal,zero,kind=dp)
     950              :      end do
     951              : 
     952            2 :    else if (Dtset%gw_frqre_tangrid == 1.and. Dtset%gw_frqre_inzgrid == 0) then
     953              :      ! We have tangent transformed grid
     954            1 :      ep%rw_mesh_type = "tangent_transform"
     955            1 :      ABI_WARNING('EXPERIMENTAL - Using tangent transform grid for contour deformation.')
     956            1 :      Ep%omegaermax = Dtset%cd_max_freq
     957            1 :      Ep%omegaermin = zero
     958            1 :      ifirst=1; ilast=Ep%nomegaer
     959            1 :      if (Dtset%cd_subset_freq(1)/=0) then ! Only a subset of frequencies is being calculated
     960            0 :        ifirst=Dtset%cd_subset_freq(1); ilast=Dtset%cd_subset_freq(2)
     961              :      end if
     962            1 :      factor = Dtset%cd_halfway_freq/TAN(pi*quarter)
     963              :      ! Important: here nfreqre is used because the step is set by the original grid
     964            1 :      domegareal=(ATAN(Ep%omegaermax/factor)*two*piinv)/(Dtset%nfreqre-1) ! Stepsize in transformed variable
     965            6 :      do iomega=1,Ep%nomegaer
     966            6 :        Ep%omega(iomega)=CMPLX(factor*TAN((iomega+ifirst-2)*domegareal*pi*half),zero,kind=dp)
     967              :      end do
     968            1 :      Ep%omegaermin = REAL(Ep%omega(1))
     969            1 :      Ep%omegaermax = REAL(Ep%omega(Ep%nomegaer))
     970              : 
     971            1 :    else if (Dtset%gw_frqre_tangrid==0.and.Dtset%gw_frqre_inzgrid==1) then
     972            1 :      ep%rw_mesh_type = "equidistant_z"
     973            1 :      e0=Dtset%ppmfrq; if (e0<0.1d-4) e0=omegaplasma
     974            1 :      domegareal=one/(Ep%nomegaer)
     975            9 :      do iomega=1,Ep%nomegaer
     976            8 :        factor = (iomega-1)*domegareal
     977            9 :        Ep%omega(iomega)=CMPLX(e0*factor/(one-factor),zero,kind=dp)
     978              :      end do
     979            1 :      Ep%omegaermin = REAL(Ep%omega(1))
     980            1 :      Ep%omegaermax = REAL(Ep%omega(Ep%nomegaer))
     981              : 
     982              :    else
     983            0 :      ABI_ERROR('Error in specification of real frequency grid')
     984              :    end if
     985              :  end if
     986              : 
     987          148 :  if (Ep%plasmon_pole_model .and. Ep%nomega == 2) then
     988          104 :    e0= Dtset%ppmfrq; if (e0 < 0.1d-4) e0 = omegaplasma
     989          104 :    Ep%omega(2)=CMPLX(zero,e0, kind=dp)
     990              :  end if
     991              : 
     992          148 :  if (Ep%analytic_continuation) then
     993              :    ! Negative value of dtset%nfreqim activates the minimax mesh
     994           11 :    ep%iw_mesh_type = "gauss_legendre"
     995           11 :    if (dtset%nfreqim < 0) ep%iw_mesh_type = "minimax"
     996              : 
     997           11 :    select case (ep%iw_mesh_type)
     998              :    case ("gauss_legendre")
     999              :      ! Use Gauss-Legendre quadrature method.
    1000              :      ! Replace $ \int_0^\infty dx f(x) $ with $ \int_0^1 dz f(1/z - 1)/z^2 $.
    1001              :      ! Note that the grid is not log as required by CD thus we cannot use the same SCR file.
    1002              : 
    1003           33 :      ABI_MALLOC(z, (Ep%nomegaei))
    1004           22 :      ABI_MALLOC(zw, (Ep%nomegaei))
    1005           11 :      call coeffs_gausslegint(zero, one, z, zw, Ep%nomegaei)
    1006          315 :      do iomega=1,Ep%nomegaei
    1007          304 :        Ep%omega(Ep%nomegaer + iomega) = CMPLX(zero, one/z(iomega) - one, kind=dp)
    1008          315 :        Ep%omega_wgs(Ep%nomegaer + iomega) = zw(iomega)
    1009              :      end do
    1010           11 :      ABI_FREE(z)
    1011           11 :      ABI_FREE(zw)
    1012              : 
    1013              :    case ("minimax")
    1014            0 :      call wrtout(std_out, sjoin("Using minimax mesh with ntau:", itoa(dtset%nfreqim)))
    1015            0 :      gaps = ks_ebands%get_gaps(gap_err)
    1016            0 :      ABI_CHECK(gap_err == 0, "gap_err")
    1017              :      ! ================================
    1018              :      ! Setup tau/omega mesh and weights
    1019              :      ! ================================
    1020              :      ! Compute min/max transition energy taking into account nsppol if any.
    1021            0 :      te_min = minval(gaps%cb_min - gaps%vb_max)
    1022            0 :      te_max = maxval(ks_ebands%eig(mband,:,:) - ks_ebands%eig(1,:,:))
    1023            0 :      if (te_min <= tol6) then
    1024            0 :        te_min = tol6
    1025            0 :        ABI_ERROR("System is metallic or with a very small fundamental gap!")
    1026              :      end if
    1027              : 
    1028              :      call gx_minimax_grid(abs(dtset%nfreqim), te_min, te_max,  &  ! in
    1029              :                           tau_mesh, tau_wgs, &  ! all these args are out and allocated by the routine.
    1030              :                           iw_mesh, iw_wgs,   &
    1031              :                           t2w_cos_wgs, w2t_cos_wgs, t2w_sin_wgs, &
    1032            0 :                           ft_max_error, cosft_duality_error, ierr)
    1033            0 :      ABI_CHECK(ierr == 0, "Error in gx_minimax_grid")
    1034              : 
    1035            0 :      do iomega=1,Ep%nomegaei
    1036            0 :        Ep%omega(Ep%nomegaer + iomega) = CMPLX(zero, iw_mesh(iomega), kind=dp)
    1037            0 :        Ep%omega_wgs(Ep%nomegaer + iomega) = iw_wgs(iomega)
    1038              :      end do
    1039              : 
    1040            0 :      ABI_FREE_NOCOUNT(tau_mesh)
    1041            0 :      ABI_FREE_NOCOUNT(tau_wgs)
    1042            0 :      ABI_FREE_NOCOUNT(iw_mesh)
    1043            0 :      ABI_FREE_NOCOUNT(iw_wgs)
    1044            0 :      ABI_FREE_NOCOUNT(t2w_cos_wgs)
    1045            0 :      ABI_FREE_NOCOUNT(w2t_cos_wgs)
    1046            0 :      ABI_FREE_NOCOUNT(t2w_sin_wgs)
    1047            0 :      call gaps%free()
    1048              : 
    1049              :    case default
    1050           11 :      ABI_ERROR(sjoin("Invalid iw_mesh_type:", ep%iw_mesh_type))
    1051              :    end select
    1052              : 
    1053          137 :  else if (Ep%contour_deformation .and. Dtset%cd_customnimfrqs /= 0) then
    1054            1 :    ep%iw_mesh_type = "custom"
    1055            1 :    Ep%omega(Ep%nomegaer+1)=CMPLX(zero,Dtset%cd_imfrqs(1))
    1056            4 :    do iomega=2,Ep%nomegaei
    1057            3 :      if (Dtset%cd_imfrqs(iomega) <= Dtset%cd_imfrqs(iomega-1)) then
    1058            0 :        ABI_ERROR(' Specified imaginary frequencies need to be strictly increasing!')
    1059              :      end if
    1060            4 :      Ep%omega(Ep%nomegaer+iomega) = CMPLX(zero, Dtset%cd_imfrqs(iomega))
    1061              :    end do
    1062              : 
    1063          136 :  else if (Ep%contour_deformation .and. Dtset%gw_frqim_inzgrid /= 0) then
    1064            1 :    ep%iw_mesh_type = "equidistant_z"
    1065            1 :    e0 = Dtset%ppmfrq; if (e0 < 0.1d-4) e0 = omegaplasma
    1066            1 :    domegareal=one/(Ep%nomegaei+1)
    1067            9 :    do iomega=1,Ep%nomegaei
    1068            8 :      factor = iomega*domegareal
    1069            9 :      Ep%omega(Ep%nomegaer+iomega)=CMPLX(zero,e0*factor/(one-factor),kind=dp)
    1070              :    end do
    1071              : 
    1072          135 :  else if (Ep%contour_deformation.and. Ep%nomegaei /= 0) then
    1073              :    ! This is the default for CD. see calc_sigc_cd for the integration routine.
    1074           21 :    ep%iw_mesh_type = "logarithmic"
    1075           21 :    e0=Dtset%ppmfrq; if (e0<0.1d-4) e0=omegaplasma
    1076          115 :    do iomega=1,Ep%nomegaei
    1077              :      Ep%omega(Ep%nomegaer+iomega)=CMPLX(zero,e0/(Dtset%freqim_alpha-two)&
    1078          115 :        * (EXP(two/(Ep%nomegaei+1)*LOG(Dtset%freqim_alpha-one)*iomega)-one),kind=dp)
    1079              :    end do
    1080              :  end if
    1081              : 
    1082          148 :  if (Dtset%cd_full_grid/=0) then
    1083              :    ! Full grid will be calculated. Grid values are added after the last imaginary freq.
    1084            5 :    do ios=1,Ep%nomegaei
    1085           21 :      do iomega=2,Ep%nomegaer
    1086              :        Ep%omega(Ep%nomegaer+Ep%nomegaei+(ios-1)*(Ep%nomegaer-1)+(iomega-1)) = &
    1087           20 :            CMPLX(REAL(Ep%omega(iomega)),AIMAG(Ep%omega(Ep%nomegaer+ios)))
    1088              :      end do
    1089              :    end do
    1090              :  end if
    1091              : 
    1092              :  ! Here we change nomega and select a slice of frequencies.
    1093          436 :  if (any(dtset%scr_wrange /= 0)) then
    1094              :    ! Consistency check.
    1095            4 :    call wrtout(units, sjoin(" Selecting frequency range: ", trim(ltoa(dtset%scr_wrange))))
    1096            4 :    ifirst = dtset%scr_wrange(1); ilast = dtset%scr_wrange(2); ii = ilast - ifirst + 1
    1097            4 :    ABI_CHECK_IRANGE(ifirst, 1, ep%nomega, "Invalid scr_wrange(1)")
    1098            4 :    ABI_CHECK_IRANGE(ilast, 1, ep%nomega, "Invalid scr_wrange(2)")
    1099            4 :    ABI_CHECK_IGEQ(ilast, ifirst, "scr_wrange(2) should be >= scr_wrange(1)")
    1100              : 
    1101              :    ! New number of freqs.
    1102            4 :    ep%nomega = ii
    1103              : 
    1104              :    ! Trasfer freqs.
    1105           12 :    ABI_MALLOC(tmp_omega, (ii))
    1106           45 :    tmp_omega(:) = ep%omega(ifirst:ilast)
    1107            4 :    ABI_FREE(ep%omega)
    1108            4 :    ABI_MOVE_ALLOC(tmp_omega, ep%omega)
    1109              : 
    1110              :    ! Trasfer weights.
    1111           12 :    ABI_MALLOC(tmp_omega_wgs, (ii))
    1112           45 :    tmp_omega_wgs(:) = ep%omega_wgs(ifirst:ilast)
    1113            4 :    ABI_FREE(ep%omega_wgs)
    1114            4 :    ABI_MOVE_ALLOC(tmp_omega_wgs, ep%omega_wgs)
    1115              :  end if
    1116              : 
    1117              :  ! Report frequency mesh for chi0.
    1118          148 :  write(msg,'(2a)')ch10,' calculating chi0 at frequencies [eV] :'
    1119          148 :  call wrtout(units, msg)
    1120         1062 :  do iomega=1,Ep%nomega
    1121          914 :    write(msg,'(i3,2es16.6)')iomega,Ep%omega(iomega)*Ha_eV
    1122         1062 :    call wrtout(units, msg)
    1123              :  end do
    1124              : 
    1125              :  ! Allocate chi0, wings and array for chi0_sumrule check.
    1126          444 :  ABI_MALLOC(chi0_sumrule, (Ep%npwe))
    1127              : 
    1128          148 :  write(msg,'(a,f12.1,a)')' Memory required for chi0 matrix= ',two*gwp*Ep%npwe**2*Ep%nI*Ep%nJ*Ep%nomega*b2Mb," [Mb]."
    1129          148 :  call wrtout(std_out, msg)
    1130          740 :  ABI_MALLOC_OR_DIE(chi0, (Ep%npwe*Ep%nI,Ep%npwe*Ep%nJ,Ep%nomega), ierr)
    1131              : !
    1132              : !============================== END OF THE INITIALIZATION PART ===========================
    1133              : !
    1134              : !======================================================================
    1135              : !==== Loop over q-points. Calculate \epsilon^{-1} and save on disc ====
    1136              : !======================================================================
    1137          148 :  call pstat_proc%print(_PSTAT_ARGS_)
    1138          148 :  call timab(321,2,tsec) ! screening(2)
    1139              : 
    1140          148 :  iqcalc = 0
    1141          148 :  if(Dtset%plowan_compute >= 10) then
    1142              :    call init_plowannier(Dtset%plowan_bandf,Dtset%plowan_bandi,Dtset%plowan_compute,&
    1143              :                         Dtset%plowan_iatom,Dtset%plowan_it,Dtset%plowan_lcalc,Dtset%plowan_natom,&
    1144              :                         Dtset%plowan_nbl,Dtset%plowan_nt,Dtset%plowan_projcalc,Dtset%acell_orig,&
    1145              :                         Dtset%kptns,sum(Dtset%plowan_nbl),Dtset%nimage,Dtset%nkpt,Dtset%nspinor,&
    1146            0 :                         Dtset%nsppol,Dtset%wtk,Dtset%dmft_t2g,wanibz_in)
    1147            0 :    call get_plowannier(wanibz_in,wanibz,Dtset)
    1148            0 :    call fullbz_plowannier(Dtset,Kmesh,Cryst,Pawang,wanibz,wanbz)
    1149              :  end if
    1150              : 
    1151         1082 :  do iqibz=1,Qmesh%nibz
    1152          934 :    call timab(306,1,tsec)
    1153          934 :    is_first_qcalc=(iqibz==1)
    1154              : 
    1155              :    ! Selective q-point calculation.
    1156          934 :    found=.FALSE.; label=iqibz
    1157          934 :    if (Ep%nqcalc /= Ep%nqibz) then
    1158           44 :      do ii=1,Ep%nqcalc
    1159          128 :        qtmp(:)=Qmesh%ibz(:,iqibz)-Ep%qcalc(:,ii)
    1160           32 :        found=(normv(qtmp,gmet,'G')<GW_TOLQ)
    1161           44 :        if (found) then
    1162            6 :          label=ii; EXIT !ii
    1163              :        end if
    1164              :      end do
    1165           18 :      if (.not.found) CYCLE !iqibz
    1166           24 :      qtmp(:)=Ep%qcalc(:,1)-Qmesh%ibz(:,iqibz)
    1167            6 :      is_first_qcalc=(normv(qtmp,gmet,'G')<GW_TOLQ)
    1168              :    end if
    1169          922 :    iqcalc = iqcalc + 1
    1170              : 
    1171          922 :    bar=REPEAT('-',80)
    1172          922 :    write(msg,'(4a,1x,a,i2,a,f9.6,2(",",f9.6),3a)')ch10,ch10,bar,ch10,&
    1173         4610 :      ' q-point number ',label,'        q = (',(Qmesh%ibz(ii,iqibz),ii=1,3),') [r.l.u.]',ch10,bar
    1174          922 :    call wrtout(units, msg)
    1175          922 :    is_qeq0 = 0; if (normv(Qmesh%ibz(:,iqibz),gmet,'G')<GW_TOLQ0) is_qeq0=1
    1176              : 
    1177          922 :    call pstat_proc%print(_PSTAT_ARGS_)
    1178          922 :    call timab(306,2,tsec)
    1179              : 
    1180          922 :    if (is_qeq0 == 1) then
    1181              :      ! Special treatment of the long wavelength limit.
    1182          146 :      call timab(307,1,tsec)
    1183              : 
    1184          438 :      ABI_MALLOC(chi0_head, (3,3,Ep%nomega))
    1185          730 :      ABI_MALLOC(chi0_lwing, (Ep%npwe*Ep%nI, Ep%nomega,3))
    1186          730 :      ABI_MALLOC(chi0_uwing, (Ep%npwe*Ep%nJ, Ep%nomega,3))
    1187              : 
    1188              :      call cchi0q0(use_tr,Dtset,Cryst,Ep,Psps,Kmesh,qp_ebands,ks_ebands,Gsph_epsG0,&
    1189              :       Pawang,Pawrad,Pawtab,Paw_ij,Paw_pwff,Pawfgrtab,Paw_onsite,ktabr,ktabrf,nbvw,ngfft_gw,nfftgw,&
    1190          146 :       ngfftf,nfftf_tot,chi0,chi0_head,chi0_lwing,chi0_uwing,Ltg_q(iqibz),chi0_sumrule,Wfd,Wfdf,wanbz) !,mpi_enreg_seq
    1191              : 
    1192              :      !chihw = chi_new(ep%npwe, ep%nomega)
    1193              :      !chihw%head = chi0_head
    1194              :      !chihw%lwing = chi0_lwing
    1195              :      !chihw%uwing = chi0_uwing
    1196              : 
    1197              :      ! Add the intraband term if required and metallic occupation scheme is used.
    1198          146 :      add_chi0_intraband=.FALSE. !add_chi0_intraband=.TRUE.
    1199          146 :      if (add_chi0_intraband .and. qp_ebands%has_metal_scheme()) then
    1200              : 
    1201              :        ABI_MALLOC_OR_DIE(chi0intra,(Ep%npwe*Ep%nI,Ep%npwe*Ep%nJ,Ep%nomega), ierr)
    1202              : 
    1203              :        ABI_MALLOC(chi0intra_lwing,(Ep%npwe*Ep%nI,Ep%nomega,3))
    1204              :        ABI_MALLOC(chi0intra_uwing,(Ep%npwe*Ep%nJ,Ep%nomega,3))
    1205              :        ABI_MALLOC(chi0intra_head,(3,3,Ep%nomega))
    1206              : 
    1207              :        call chi0q0_intraband(Wfd,Cryst,Ep,Psps,qp_ebands,Gsph_epsG0,Pawang,Pawrad,Pawtab,Paw_ij,Paw_pwff,use_tr,Dtset%usepawu,&
    1208              :        ngfft_gw,chi0intra,chi0intra_head,chi0intra_lwing,chi0intra_uwing)
    1209              : 
    1210              :        call wrtout(std_out,"Head of chi0 and chi0_intra")
    1211              :        do iomega=1,Ep%nomega
    1212              :          write(std_out,*)Ep%omega(iomega)*Ha_eV,REAL(chi0(1,1,iomega)),REAL(chi0intra(1,1,iomega))
    1213              :          write(std_out,*)Ep%omega(iomega)*Ha_eV,AIMAG(chi0(1,1,iomega)),AIMAG(chi0intra(1,1,iomega))
    1214              :        end do
    1215              : 
    1216              :        chi0       = chi0       + chi0intra
    1217              :        chi0_head  = chi0_head  + chi0intra_head
    1218              :        chi0_lwing = chi0_lwing + chi0intra_lwing
    1219              :        chi0_uwing = chi0_uwing + chi0intra_uwing
    1220              : 
    1221              :        ABI_FREE(chi0intra)
    1222              :        ABI_FREE(chi0intra_lwing)
    1223              :        ABI_FREE(chi0intra_uwing)
    1224              :        ABI_FREE(chi0intra_head)
    1225              :      end if
    1226              : 
    1227              :      if (.False.) then
    1228              :        lwl_fname = strcat(dtfil%filnam_ds(4), "_LWL")
    1229              :        call lwl_write(lwl_fname,cryst,vcp,ep%npwe,ep%nomega,gsph_epsg0%gvec,chi0,chi0_head,chi0_lwing,chi0_uwing,comm)
    1230              :      end if
    1231              : 
    1232          146 :      call timab(307,2,tsec)
    1233              : 
    1234              :    else
    1235              :      ! Calculate cchi0 for q/=0.
    1236          776 :      call timab(308,1,tsec)
    1237              :      call cchi0(use_tr,Dtset,Cryst,Qmesh%ibz(:,iqibz),Ep,Psps,Kmesh,qp_ebands,Gsph_epsG0,&
    1238              :                 Pawtab,Pawang,Paw_pwff,Pawfgrtab,Paw_onsite,nbvw,ngfft_gw,nfftgw,ngfftf,nfftf_tot,chi0,ktabr,ktabrf,&
    1239          776 :                 Ltg_q(iqibz),chi0_sumrule,Wfd,Wfdf,wanbz)
    1240          776 :      call timab(308,2,tsec)
    1241              :    end if
    1242              : 
    1243              :    ! Print chi0(q,G,Gp,omega), then calculate epsilon and epsilon^-1 for this q-point.
    1244              :    ! Only master works but this part could be parallelized over frequencies.
    1245          922 :    call timab(309,1,tsec)
    1246              : 
    1247         5084 :    do iomega=1,MIN(Ep%nomega, NOMEGA_PRINTED)
    1248         4162 :      write(msg,'(1x,a,i4,a,2f9.4,a)')' chi0(G,G'') at the ',iomega,' th omega',Ep%omega(iomega)*Ha_eV,' [eV]'
    1249         4162 :      call wrtout(units, msg)
    1250         4162 :      write(msg,'(1x,a,i3,a,i4,a)')' chi0(q =',iqibz, ', omega =',iomega,', G,G'')'
    1251         4162 :      if (Ep%nqcalc /= Ep%nqibz) write(msg,'(a,i3,a,i4,a)')'  chi0(q=',iqcalc,', omega=',iomega,', G,G'')'
    1252         4162 :      call wrtout(std_out, msg)
    1253              :      ! arr99 is needed to avoid the update of all the tests. Now chi0 is divided by ucvol inside (cchi0|cchi0q0).
    1254              :      ! TODO should be removed but GW tests have to be updated.
    1255         4162 :      ii = MIN(9, Ep%npwe)
    1256        16648 :      ABI_MALLOC(arr_99,(ii, ii))
    1257       382904 :      arr_99 = chi0(1:ii,1:ii,iomega) * ucvol
    1258         8324 :      call print_arr([ab_out],  arr_99, max_r=2)
    1259         8324 :      call print_arr([std_out], arr_99)
    1260         5084 :      ABI_FREE(arr_99)
    1261              :    end do
    1262              : 
    1263          922 :    if (Ep%nomega > NOMEGA_PRINTED) then
    1264           84 :      write(msg,'(a,i3,a)')' No. of calculated frequencies > ',NOMEGA_PRINTED,', stop printing '
    1265           84 :      call wrtout(units, msg)
    1266              :    end if
    1267              : 
    1268              :    ! Write chi0 to _SUSC file
    1269              :    ! Master creates and write the header if this is the first q-point calculated.
    1270          922 :    if (Dtset%prtsuscep > 0 .and. my_rank == master) then
    1271           39 :      title(1)='CHI0 file: chi0'
    1272              :      title(2)=' '
    1273           39 :      if (is_qeq0 == 1) then
    1274            6 :        string='0'; if (Dtset%usepaw==0.and.Ep%inclvkb/=0) call int2char10(Ep%inclvkb,string)
    1275            6 :        title(1)=title(1)(1:21)//', calculated using inclvkb = '//string
    1276              :      end if
    1277              : 
    1278              :      ! Open file and write header for polarizability files.
    1279           39 :      if (is_first_qcalc) then
    1280            8 :        ikxc=0; test_type=0; tordering=1
    1281            8 :        hchi0 = hscr_new("polarizability",dtset,ep,hdr_local,ikxc,test_type,tordering,title,Ep%npwe,Gsph_epsG0%gvec)
    1282              : 
    1283            8 :        if (dtset%iomode == IO_MODE_ETSF) then
    1284            8 :          NCF_CHECK(nctk_open_create(unt_susc, nctk_ncify(dtfil%fnameabo_sus), xmpi_comm_self))
    1285            8 :          NCF_CHECK(cryst%ncwrite(unt_susc))
    1286            8 :          NCF_CHECK(qp_ebands%ncwrite(unt_susc))
    1287              :        else
    1288            0 :          unt_susc=Dtfil%unchi0
    1289            0 :          if (open_file(dtfil%fnameabo_sus,msg,unit=unt_susc,status='unknown',form='unformatted') /= 0) then
    1290            0 :            ABI_ERROR(msg)
    1291              :          end if
    1292              :        end if
    1293              : 
    1294            8 :        fform_chi0 = hchi0%fform
    1295            8 :        call hchi0%io(fform_chi0,2,unt_susc,xmpi_comm_self,0,Dtset%iomode)
    1296            8 :        call Hchi0%free()
    1297              :      end if
    1298              : 
    1299           39 :      call write_screening("polarizability", unt_susc, Dtset%iomode, Ep%npwe, Ep%nomega, iqcalc, chi0)
    1300              : 
    1301           39 :      if (dtset%iomode == IO_MODE_ETSF .and. is_qeq0 == 1 .and. Ep%nI == 1 .and. Ep%nJ == 1) then
    1302              :        ! Write head and wings to file. See cchi0 for the equations needed to build chi0(q) for q--> 0.
    1303            6 :        wing_shape = "two, three, number_of_coefficients_dielectric_function, number_of_frequencies_dielectric_function"
    1304              :        ncerr = nctk_def_arrays(unt_susc, [ &
    1305              :          nctkarr_t("sus_head", "dp", "two, three, three, number_of_frequencies_dielectric_function"),   &
    1306              :          nctkarr_t("sus_upper_wing", "dp", wing_shape),  &
    1307              :          nctkarr_t("sus_lower_wing", "dp", wing_shape) &
    1308           24 :          ], defmode=.True.)
    1309            6 :        NCF_CHECK(ncerr)
    1310              : 
    1311            6 :        NCF_CHECK(nctk_set_datamode(unt_susc))
    1312            6 :        NCF_CHECK(nf90_put_var(unt_susc, nctk_idname(unt_susc, "sus_head"), c2r(chi0_head)))
    1313              : 
    1314           24 :        ABI_MALLOC(rwork_wing, (2, 3, Ep%npwe * Ep%nI, Ep%nomega))
    1315           51 :        do iomega=1,Ep%nomega
    1316         1498 :          do ig=1, Ep%npwe * Ep%nI
    1317         5788 :            rwork_wing(1,:,ig,iomega) = real(chi0_lwing(ig,iomega,:))
    1318         5833 :            rwork_wing(2,:,ig,iomega) = aimag(chi0_lwing(ig,iomega,:))
    1319              :          end do
    1320              :        end do
    1321            6 :        NCF_CHECK(nf90_put_var(unt_susc, nctk_idname(unt_susc, "sus_lower_wing"), rwork_wing))
    1322              : 
    1323           51 :        do iomega=1,Ep%nomega
    1324         1498 :          do ig=1, Ep%npwe * Ep%nI
    1325         5788 :            rwork_wing(1,:,ig,iomega) = real(chi0_uwing(ig,iomega,:))
    1326         5833 :            rwork_wing(2,:,ig,iomega) = aimag(chi0_uwing(ig,iomega,:))
    1327              :          end do
    1328              :        end do
    1329            6 :        NCF_CHECK(nf90_put_var(unt_susc, nctk_idname(unt_susc, "sus_upper_wing"), rwork_wing))
    1330            6 :        ABI_FREE(rwork_wing)
    1331              :      end if
    1332              : 
    1333              :    end if ! is_first_qcalc
    1334              : 
    1335              :    ! Calculate the Galitskii-Migdal and RPA functionals for the correlation energy if the polarizability on a
    1336              :    ! Gauss-Legendre mesh along imaginary axis is available
    1337          922 :    if (Ep%analytic_continuation .and. Dtset%gwrpacorr>0 ) then
    1338           18 :      if (is_first_qcalc) then
    1339           15 :        ABI_MALLOC(ec_rpa,(Dtset%gwrpacorr))
    1340           17 :        ec_rpa(:)=zero
    1341            5 :        ec_gm=zero
    1342              :      end if
    1343           18 :      call calc_rpa_functional(Dtset%gwrpacorr,Dtset%gwgmcorr,label,iqibz,Ep,Vcp,Qmesh,Dtfil,gmet,chi0,comm,ec_rpa,ec_gm)
    1344           18 :      if (label==Ep%nqcalc) then
    1345            5 :        ABI_FREE(ec_rpa)
    1346              :      end if
    1347              :    end if
    1348              : 
    1349              :    !  ==========================================================
    1350              :    !  === Calculate RPA \tilde\epsilon^{-1} overwriting chi0 ===
    1351              :    !  ==========================================================
    1352          922 :    approx_type=0 ! RPA
    1353          922 :    option_test=0 ! TESTPARTICLE
    1354          922 :    dim_wing=0; if (is_qeq0==1) dim_wing=3
    1355              : 
    1356          922 :    if (dim_wing==0) then
    1357          776 :      dim_wing=1
    1358          776 :      if (.not.allocated(chi0_lwing))  then
    1359         3104 :        ABI_MALLOC(chi0_lwing,(Ep%npwe*Ep%nI,Ep%nomega,dim_wing))
    1360              :      end if
    1361          776 :      if (.not.allocated(chi0_uwing))  then
    1362         3104 :        ABI_MALLOC(chi0_uwing,(Ep%npwe*Ep%nJ,Ep%nomega,dim_wing))
    1363              :      end if
    1364          776 :      if (.not.allocated(chi0_head ))  then
    1365         2328 :        ABI_MALLOC(chi0_head,(dim_wing,dim_wing,Ep%nomega))
    1366              :      end if
    1367          776 :      dim_wing=0
    1368              :    end if
    1369              : 
    1370              : #if 0
    1371              :    ! Using the random q for the optical limit is one of the reasons
    1372              :    ! why sigma breaks the initial energy degeneracies.
    1373              :    chi0_lwing=czero
    1374              :    chi0_uwing=czero
    1375              :    chi0_head=czero
    1376              : #endif
    1377              : 
    1378              :    ! Setup flags for the computation of em1
    1379              :    ! If the vertex is being included for the spectrum, calculate the kernel now and pass it on
    1380        21184 :    if (dtset%gwgamma>0) rhor_kernel = rhor
    1381              : 
    1382          900 :    select case (dtset%gwgamma)
    1383              :    case (0)
    1384          900 :      approx_type=0; option_test=0; dim_kxcg=0
    1385         1800 :      ABI_MALLOC(kxcg, (nfftf_tot, dim_kxcg))
    1386              : 
    1387              :    case (1, 2)
    1388              :      ! ALDA TDDFT kernel vertex
    1389            6 :      ABI_CHECK(Dtset%usepaw==0,"GWGamma=1 or 2 + PAW not available")
    1390            6 :      ABI_WARNING('EXPERIMENTAL: Kernel is being added to screening, the SCR file will be non-standard!!')
    1391            6 :      ikxc=7; approx_type=1; dim_kxcg=1
    1392            6 :      if (Dtset%gwgamma==1) option_test=1 ! TESTELECTRON, vertex in chi0 *and* sigma
    1393            6 :      if (Dtset%gwgamma==2) option_test=0 ! TESTPARTICLE, vertex in chi0 only
    1394           18 :      ABI_MALLOC(kxcg,(nfftf_tot,dim_kxcg))
    1395              :      call kxc_driver(Dtset,Cryst,ikxc,ngfftf,nfftf_tot,Wfd%nspden,rhor_kernel,&
    1396            6 :      Ep%npwe,dim_kxcg,kxcg,Gsph_epsG0%gvec,xmpi_comm_self)
    1397              : 
    1398              :    case (3, 4)
    1399              :      ! ADA non-local kernel vertex
    1400            0 :      ABI_CHECK(Wfd%usepaw==0,"ADA vertex + PAW not available")
    1401            0 :      ABI_CHECK(Wfd%nsppol==1,"ADA vertex for GWGamma not available yet for spin-polarised cases")
    1402            0 :      ABI_WARNING('EXPERIMENTAL: Kernel is being added to screening, the SCR file will be non-standard!!')
    1403            0 :      ikxc=7; approx_type=2
    1404            0 :      if (Dtset%gwgamma==3) option_test=1 ! TESTELECTRON, vertex in chi0 *and* sigma
    1405            0 :      if (Dtset%gwgamma==4) option_test=0 ! TESTPARTICLE, vertex in chi0 only
    1406            0 :      ABI_MALLOC(fxc_ADA,(Ep%npwe,Ep%npwe,Ep%nqibz))
    1407              :      ! Use userrd to set kappa
    1408            0 :      if (Dtset%userrd==zero) Dtset%userrd = 2.1_dp
    1409              :      ! Set correct value of kappa (should be scaled with alpha*r_s where)
    1410              :      ! r_s is Wigner-Seitz radius and alpha=(4/(9*Pi))^(1/3)
    1411            0 :      rhoav = (omegaplasma*omegaplasma)/four_pi
    1412            0 :      r_s = (three/(four_pi*rhoav))**third
    1413            0 :      alpha = (four*ninth*piinv)**third
    1414            0 :      Dtset%userrd = Dtset%userrd*alpha*r_s
    1415              : 
    1416              :      call kxc_ADA(Dtset,Cryst,ikxc,ngfftf,nfftf,Wfd%nspden,rhor_kernel,Ep%npwe,Ep%nqibz,Ep%qibz,&
    1417            0 :      fxc_ADA,Gsph_epsG0%gvec,xmpi_comm_self,kappa_init=Dtset%userrd)
    1418              : 
    1419            0 :      dim_kxcg=0
    1420            0 :      ABI_MALLOC(kxcg,(nfftf_tot,dim_kxcg))
    1421              : 
    1422              :    case (-3, -4, -5, -6, -7, -8)
    1423              :      ! Bootstrap kernel and variants
    1424           12 :      ABI_CHECK(Dtset%usepaw==0,"GWGamma + PAW not available")
    1425           12 :      if (Dtset%gwgamma>-5) then
    1426            8 :        ABI_WARNING('EXPERIMENTAL: Bootstrap kernel is being added to screening')
    1427            8 :        approx_type=4
    1428            4 :      else if (Dtset%gwgamma>-7) then
    1429            4 :        ABI_WARNING('EXPERIMENTAL: Bootstrap kernel (head-only) is being added to screening')
    1430            4 :        approx_type=5
    1431              :      else
    1432            0 :        ABI_WARNING('EXPERIMENTAL: RPA Bootstrap kernel is being added to screening')
    1433            0 :        approx_type=6
    1434              :      end if
    1435           12 :      dim_kxcg=0
    1436           12 :      option_test=MOD(Dtset%gwgamma,2)
    1437              :      ! 1 -> TESTELECTRON, vertex in chi0 *and* sigma
    1438              :      ! 0 -> TESTPARTICLE, vertex in chi0 only
    1439           24 :      ABI_MALLOC(kxcg,(nfftf_tot,dim_kxcg))
    1440              : 
    1441              :    case (-11)
    1442              :      ! LR+ALDA hybrid vertex kernel
    1443            4 :      ABI_CHECK(Dtset%usepaw==0,"GWGamma + PAW not available")
    1444            4 :      ikxc=7; dim_kxcg=1
    1445            4 :      ABI_WARNING('EXPERIMENTAL: LR+ALDA hybrid kernel is being added to screening')
    1446            4 :      approx_type=7
    1447            4 :      option_test=1  ! TESTELECTRON
    1448           16 :      ABI_MALLOC(kxcg,(nfftf_tot,dim_kxcg))
    1449        55308 :      rhor_kernel = rhor
    1450              :      call kxc_driver(Dtset,Cryst,ikxc,ngfftf,nfftf_tot,Wfd%nspden,rhor_kernel,&
    1451            4 :        Ep%npwe,dim_kxcg,kxcg,Gsph_epsG0%gvec,xmpi_comm_self)
    1452            4 :      rhoav = (omegaplasma*omegaplasma)/four_pi
    1453              : 
    1454              :    case default
    1455          922 :      ABI_ERROR(sjoin("Wrong gwgamma:", itoa(dtset%gwgamma)))
    1456              :    end select
    1457              : 
    1458          922 :    if (approx_type<2) then
    1459              :      ! ALDA
    1460              :      call make_epsm1_driver(iqibz,dim_wing,Ep%npwe,Ep%nI,Ep%nJ,Ep%nomega,Ep%omega,&
    1461              :        approx_type,option_test,Vcp,nfftf_tot,ngfftf,dim_kxcg,kxcg,Gsph_epsG0%gvec,&
    1462          906 :        chi0_head,chi0_lwing,chi0_uwing,chi0,spectra,comm, epsm1_win)
    1463              : 
    1464           16 :    else if (approx_type<3) then
    1465              :      ! ADA
    1466              :      call make_epsm1_driver(iqibz,dim_wing,Ep%npwe,Ep%nI,Ep%nJ,Ep%nomega,Ep%omega,&
    1467              :        approx_type,option_test,Vcp,nfftf_tot,ngfftf,dim_kxcg,kxcg,Gsph_epsG0%gvec,&
    1468              :        chi0_head,chi0_lwing,chi0_uwing,chi0,spectra,comm, epsm1_win, &
    1469            0 :        fxc_ADA=fxc_ADA(:,:,iqibz))
    1470              : 
    1471           16 :    else if (approx_type<7) then
    1472              :       ! Bootstrap
    1473              :      call make_epsm1_driver(iqibz,dim_wing,Ep%npwe,Ep%nI,Ep%nJ,Ep%nomega,Ep%omega,&
    1474              :        approx_type,option_test,Vcp,nfftf_tot,ngfftf,dim_kxcg,kxcg,Gsph_epsG0%gvec,&
    1475           12 :        chi0_head,chi0_lwing,chi0_uwing,chi0,spectra,comm, epsm1_win)
    1476              : 
    1477            4 :    else if (approx_type<8) then
    1478              :      ! LR + ALDA
    1479              :      call make_epsm1_driver(iqibz,dim_wing,Ep%npwe,Ep%nI,Ep%nJ,Ep%nomega,Ep%omega,&
    1480              :        approx_type,option_test,Vcp,nfftf_tot,ngfftf,dim_kxcg,kxcg,Gsph_epsG0%gvec,&
    1481              :        chi0_head,chi0_lwing,chi0_uwing,chi0,spectra,comm, epsm1_win, &
    1482            4 :        rhor=rhoav)
    1483              : 
    1484              :    else
    1485            0 :      ABI_ERROR(sjoin("Wrong approx_type:", itoa(approx_type)))
    1486              :    end if
    1487              : 
    1488          922 :    ABI_FREE(chi0_lwing)
    1489          922 :    ABI_FREE(chi0_uwing)
    1490          922 :    ABI_FREE(chi0_head)
    1491              : 
    1492          922 :    if (my_rank == master .and. is_qeq0==1) then
    1493          118 :      call spectra%repr(msg)
    1494          118 :      call wrtout(units, msg)
    1495          118 :      if (Ep%nomegaer > 2) then
    1496           22 :        call spectra%write(W_EELF  ,Dtfil%fnameabo_eelf)
    1497           22 :        call spectra%write(W_EM_LF ,Dtfil%fnameabo_em1_lf)
    1498           22 :        call spectra%write(W_EM_NLF,Dtfil%fnameabo_em1_nlf)
    1499              :      end if
    1500              :    end if ! master and is_qeq0==1
    1501              : 
    1502              :    !if (is_qeq0==1) call chi_free(chihw)
    1503              : 
    1504          922 :    call spectra%free()
    1505          922 :    ABI_SFREE(kxcg)
    1506          922 :    ABI_SFREE(fxc_ADA)
    1507              :    !
    1508              :    ! Output the sum rule evaluation.
    1509              :    ! Vcp%vc_sqrt(:,iqibz) Contains vc^{1/2}(q,G), complex-valued due to a possible cutoff
    1510          922 :    epsm1 => chi0
    1511          922 :    call output_chi0sumrule((is_qeq0==1),iqibz,Ep%npwe,omegaplasma,chi0_sumrule,epsm1(:,:,1),Vcp%vc_sqrt(:,iqibz))
    1512              : 
    1513              :    ! If input variable npvel is larger than 0, trigger the Random Stopping Power calculation
    1514              :    ! Only the masternode is used
    1515          922 :    if (my_rank==master .and. Dtset%npvel>0) then
    1516           12 :      if (is_first_qcalc) then
    1517            6 :        ABI_MALLOC(rspower,(Dtset%npvel))
    1518           82 :        rspower(:)=zero
    1519              :      end if
    1520           12 :      call random_stopping_power(iqibz,Dtset%npvel,Dtset%pvelmax,Ep,Gsph_epsG0,Qmesh,Vcp,Cryst,Dtfil,epsm1,rspower)
    1521           12 :      if (label==Ep%nqcalc) then
    1522            2 :        ABI_FREE(rspower)
    1523              :      end if
    1524              :    end if
    1525              : 
    1526              :    ! Write heads and wings to main output file.
    1527          922 :    if (is_qeq0 == 1) then
    1528          146 :      write(msg,'(1x,2a)')' Heads and wings of the symmetrical epsilon^-1(G,G'') ',ch10
    1529          146 :      call wrtout(ab_out,msg)
    1530         1056 :      do iomega=1,Ep%nomega
    1531          910 :        write(msg,'(2x,a,i4,a,2f9.4,a)')' Upper and lower wings at the ',iomega,' th omega',Ep%omega(iomega)*Ha_eV,' [eV]'
    1532          910 :        call wrtout(ab_out, msg)
    1533         1820 :        call print_arr([ab_out], epsm1(1,:,iomega),max_r=9)
    1534         1820 :        call print_arr([ab_out], epsm1(:,1,iomega),max_r=9)
    1535         1056 :        call wrtout(ab_out, ch10)
    1536              :      end do
    1537              :    end if
    1538              : 
    1539          922 :    call pstat_proc%print(_PSTAT_ARGS_)
    1540          922 :    call timab(309,2,tsec)
    1541          922 :    call timab(310,1,tsec) ! wrscr
    1542              : 
    1543          922 :    if (my_rank==master) then
    1544              :      ! === Write the symmetrical epsilon^-1 on file ===
    1545          718 :      title(1)='SCR file: epsilon^-1'
    1546          718 :      if (is_qeq0==1) then
    1547          118 :        string='0'; if (Dtset%usepaw==0.and.Ep%inclvkb/=0) call int2char10(Ep%inclvkb,string)
    1548          118 :        title(1)=title(1)(1:21)//', calculated using inclvkb = '//string
    1549              :      end if
    1550          718 :      title(2)='TESTPARTICLE'
    1551          718 :      ctype='RPA'
    1552          718 :      title(2)(14:17)=ctype !this has to be modified
    1553              : 
    1554          718 :      if (is_first_qcalc) then
    1555              :        ! === Open file and write the header for the SCR file ===
    1556              :        ! * Here we write the RPA approximation for \tilde\epsilon^{-1}
    1557          120 :        ikxc=0; test_type=0; tordering=1
    1558              :        hem1 = hscr_new("inverse_dielectric_function",dtset,ep,hdr_local,ikxc,test_type,tordering,title,&
    1559          120 : &       Ep%npwe,Gsph_epsG0%gvec)
    1560          120 :        fform_em1 = hem1%fform
    1561          120 :        if (dtset%iomode == IO_MODE_ETSF) then
    1562          120 :          NCF_CHECK(nctk_open_create(unt_em1, nctk_ncify(dtfil%fnameabo_scr), xmpi_comm_self))
    1563          120 :          NCF_CHECK(cryst%ncwrite(unt_em1))
    1564          120 :          NCF_CHECK(qp_ebands%ncwrite(unt_em1))
    1565              :        else
    1566            0 :          unt_em1=Dtfil%unscr
    1567            0 :          if (open_file(dtfil%fnameabo_scr,msg,unit=unt_em1,status='unknown',form='unformatted') /= 0) then
    1568            0 :            ABI_ERROR(msg)
    1569              :          end if
    1570              :        end if
    1571          120 :        call hem1%io(fform_em1,2,unt_em1,xmpi_comm_self,0,Dtset%iomode)
    1572          120 :        call Hem1%free()
    1573              :      end if
    1574              : 
    1575          718 :      call write_screening("inverse_dielectric_function",unt_em1,Dtset%iomode,Ep%npwe,Ep%nomega,iqcalc,epsm1)
    1576              :    end if ! my_rank==master
    1577              : 
    1578         1082 :    call timab(310,2,tsec)
    1579              :  end do ! Loop over q-points
    1580              : 
    1581          148 :  if (Dtset%plowan_compute >= 10) call destroy_plowannier(wanbz)
    1582              : 
    1583              :  ! Close Files.
    1584          148 :  if (my_rank == master) then
    1585          120 :    if (dtset%iomode == IO_MODE_ETSF) then
    1586          120 :      NCF_CHECK(nf90_close(unt_em1))
    1587          120 :      if (dtset%prtsuscep > 0) then
    1588            8 :        NCF_CHECK(nf90_close(unt_susc))
    1589              :      end if
    1590              :    else
    1591            0 :      close(unt_em1)
    1592            0 :      if (dtset%prtsuscep > 0) close(unt_susc)
    1593              :    end if
    1594              :  end if
    1595              :  !
    1596              :  !=====================
    1597              :  !==== Free memory ====
    1598              :  !=====================
    1599          148 :  ABI_FREE(chi0_sumrule)
    1600          148 :  ABI_FREE(chi0)
    1601          148 :  ABI_SFREE(rhor_kernel)
    1602              : 
    1603          148 :  ABI_FREE(rhor)
    1604          148 :  ABI_FREE(rhog)
    1605          148 :  ABI_FREE(ks_vbik)
    1606          148 :  ABI_FREE(qp_vbik)
    1607          148 :  ABI_FREE(ktabr)
    1608          148 :  ABI_FREE(taur)
    1609          148 :  ABI_FREE(ks_vhartr)
    1610          148 :  ABI_FREE(ks_vtrial)
    1611          148 :  ABI_FREE(vpsp)
    1612          148 :  ABI_FREE(ks_vxc)
    1613          148 :  ABI_FREE(ph1d)
    1614          148 :  ABI_FREE(ph1df)
    1615          148 :  ABI_FREE(nhatgr)
    1616          148 :  ABI_FREE(nhat)
    1617          148 :  call pawfgr_destroy(Pawfgr)
    1618              : 
    1619          148 :  if (Dtset%usepaw==1) then ! Optional deallocation for PAW.
    1620            5 :    call pawrhoij_free(Pawrhoij)
    1621            5 :    call pawfgrtab_free(Pawfgrtab)
    1622            5 :    call paw_ij_free(Paw_ij)
    1623            5 :    call paw_an_free(Paw_an)
    1624            5 :    call pawpwff_free(Paw_pwff)
    1625            5 :    if (Dtset%pawcross==1) then
    1626            0 :      call paw_pwaves_lmn_free(Paw_onsite)
    1627            0 :      call wfdf%free()
    1628              :    end if
    1629              :  end if
    1630              : 
    1631          179 :  ABI_FREE(Pawfgrtab)
    1632          157 :  ABI_FREE(Paw_pwff)
    1633          179 :  ABI_FREE(Pawrhoij)
    1634          179 :  ABI_FREE(Paw_ij)
    1635          179 :  ABI_FREE(Paw_an)
    1636          148 :  ABI_FREE(ktabrf)
    1637          499 :  ABI_FREE(Paw_onsite)
    1638              : 
    1639          148 :  call wfd%free(); call Kmesh%free(); call Qmesh%free(); call cryst%free()
    1640          148 :  call Gsph_epsG0%free(); call Gsph_wfn%free(); call Vcp%free(); call Ep%free()
    1641          148 :  call Hdr_wfk%free(); call Hdr_local%free()
    1642          148 :  call ks_ebands%free(); call qp_ebands%free()
    1643          148 :  call destroy_mpi_enreg(MPI_enreg_seq)
    1644          148 :  call littlegroup_free(ltg_q)
    1645          148 :  ABI_FREE(Ltg_q)
    1646              : 
    1647          148 :  call timab(301,2,tsec)
    1648              : 
    1649          888 : end subroutine screening
    1650              : !!***
    1651              : 
    1652              : !!****f* m_screening_driver/setup_screening
    1653              : !! NAME
    1654              : !! setup_screening
    1655              : !!
    1656              : !! FUNCTION
    1657              : !!  Initialize the Ep% data type containing the parameters used during the screening calculation.
    1658              : !!  as well as basic objects describing the BZ sampling .... TODO list to be completed
    1659              : !!
    1660              : !! INPUTS
    1661              : !! wfk_fname=Name of the input WFK file.
    1662              : !! acell(3)=length scales of primitive translations (Bohr).
    1663              : !! rprim(3,3)=dimensionless real space primitive translations.
    1664              : !! dtfil <type(datafiles_type)>=variables related to files
    1665              : !!
    1666              : !! OUTPUT
    1667              : !! ngfft_gw(18)=Contain all needed information about the 3D FFT for the oscillator strengths.
    1668              : !!  See ~abinit/doc/variables/vargs.htm#ngfft
    1669              : !! Ltg_q(:)<littlegroup_t>,=
    1670              : !! Ep<em1params_t>=Parameters for the screening calculation.
    1671              : !!  Most part of it is Initialized and checked.
    1672              : !! Hdr_wfk type(Hdr_type)=Header of the KSS file.
    1673              : !! Cryst<crystal_t>=Definition of the unit cell and its symmetries.
    1674              : !! Kmesh<kmesh_t>=Structure defining the k-point sampling (wavefunctions).
    1675              : !! Qmesh<kmesh_t>=Structure defining the q-point sampling (screening)
    1676              : !! Gsph_wfn<gsphere_t>=Structure defining the G-sphere for the wavefunctions (not k-dependent).
    1677              : !! Gsph_epsG0<gsphere_t>=The G-sphere for the screening, enlarged to take into account for umklapps.
    1678              : !! Psps <Pseudopotential_type)>=Info on pseudopotential, only for consistency check of the KSS file
    1679              : !! Vcp <type vcoul_t> datatype gathering information on the coulombian cutoff technique
    1680              : !! comm=MPI communicator.
    1681              : !!
    1682              : !! SIDE EFFECTS
    1683              : !! Dtset<Dataset_type>=All input variables for this dataset.
    1684              : !!  %ecutwfn, %npwwfn,
    1685              : !!  %ecuteps, %npweps
    1686              : !!   might be redefined in setshells in order to close the shell.
    1687              : !!
    1688              : !! SOURCE
    1689              : 
    1690        14948 : subroutine setup_screening(codvsn,acell,rprim,wfk_fname,Dtset,Psps,Pawtab,&
    1691              :                            ngfft_gw,Hdr_wfk,Hdr_out,Cryst,Kmesh,Qmesh,ks_ebands,Ltg_q,Gsph_epsG0,Gsph_wfn,Vcp,Ep,comm)
    1692              : 
    1693              : !Arguments ------------------------------------
    1694              : !scalars
    1695              :  integer,intent(in) :: comm
    1696              :  character(len=8),intent(in) :: codvsn
    1697              :  character(len=fnlen),intent(in) :: wfk_fname
    1698              :  type(Dataset_type),intent(inout) :: Dtset !INOUT is due to setshells
    1699              :  type(Pseudopotential_type),intent(in) :: Psps
    1700              :  type(Pawtab_type),intent(in) :: Pawtab(Psps%ntypat*Dtset%usepaw)
    1701              :  type(em1params_t),intent(out) :: Ep
    1702              :  type(Hdr_type),intent(out) :: Hdr_wfk,Hdr_out
    1703              :  type(ebands_t),intent(out) :: ks_ebands
    1704              :  type(kmesh_t),intent(out) :: Kmesh,Qmesh
    1705              :  type(crystal_t),intent(out) :: Cryst
    1706              :  type(gsphere_t),intent(out) :: Gsph_epsG0,Gsph_wfn
    1707              :  type(vcoul_t),intent(out) :: Vcp
    1708              : !arrays
    1709              :  integer,intent(out) :: ngfft_gw(18)
    1710              :  real(dp),intent(in) :: acell(3),rprim(3,3)
    1711              :  type(littlegroup_t),pointer :: Ltg_q(:)
    1712              : 
    1713              : !Local variables-------------------------------
    1714              : !scalars
    1715              :  integer,parameter :: NOMEGAGAUSS=30,NOMEGAREAL=201,pertcase0=0,master=0
    1716              :  integer :: bantot,ib,ibtot,ikibz,iq,iqp,isppol,ig,ng,ierr
    1717              :  integer :: jj,mod10,mband,ng_kss,iqbz,isym,iq_ibz,itim
    1718              :  integer :: timrev,use_umklp !,ncerr
    1719              :  integer :: npwepG0,nshepspG0,method,enforce_sym,nfftgw_tot !,spin,band,ik_ibz,
    1720              :  integer :: istart,iend,test_npwkss,my_rank,nprocs !ii
    1721              :  real(dp),parameter :: OMEGAERMAX=100.0/Ha_eV
    1722              :  real(dp) :: ecutepspG0,ucvol,domegareal
    1723              :  logical :: remove_inv,ltest,found,is_static,has_q0
    1724              :  character(len=500) :: msg
    1725          148 :  type(wvl_internal_type) :: wvl
    1726              : !arrays
    1727              :  integer :: ng0sh_opt(3), units(2)
    1728          148 :  integer,allocatable :: npwarr(:)
    1729          148 :  integer,pointer :: gvec_kss(:,:)
    1730          148 :  integer,pointer :: test_gvec_kss(:,:)
    1731              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3),qtmp(3),sq(3),qbz(3)
    1732          148 :  real(dp),pointer :: energies_p(:,:,:)
    1733          148 :  real(dp),allocatable :: doccde(:),eigen(:),occfact(:)
    1734          148 :  type(Pawrhoij_type),allocatable :: Pawrhoij(:)
    1735              : 
    1736              : ! *************************************************************************
    1737              : 
    1738          444 :  units = [std_out, ab_out]
    1739              : 
    1740              :  ! Check for calculations that are not implemented
    1741         1009 :  ltest = ALL(Dtset%nband(1:Dtset%nkpt*Dtset%nsppol) == Dtset%nband(1))
    1742          148 :  ABI_CHECK(ltest, 'dtset%nband(:) must be constant in the GW code.')
    1743              : 
    1744          148 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    1745              : 
    1746          148 :  call mkrdim(acell,rprim,rprimd)
    1747          148 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
    1748              : 
    1749              :  ! Set up basic parameters of the calculation
    1750          148 :  Ep%gwcalctyp            =Dtset%gwcalctyp
    1751          148 :  Ep%plasmon_pole_model   =.TRUE.
    1752          148 :  Ep%analytic_continuation=.FALSE.
    1753          148 :  Ep%contour_deformation  =.FALSE.
    1754              : 
    1755          148 :  mod10=MOD(Ep%gwcalctyp,10)
    1756          148 :  if (mod10/=0.and.mod10/=8) Ep%plasmon_pole_model   =.FALSE.
    1757          148 :  if (mod10==1)              Ep%analytic_continuation=.TRUE.
    1758          148 :  if (mod10==2.or.mod10==9)  Ep%contour_deformation  =.TRUE.
    1759          148 :  is_static=(mod10==5.or.mod10==6.or.mod10==7)
    1760              : 
    1761          148 :  Ep%nbnds  =Dtset%nband(1)
    1762          148 :  Ep%symchi =Dtset%symchi
    1763          148 :  Ep%inclvkb=Dtset%inclvkb; if (Dtset%usepaw/=0) Ep%inclvkb=0
    1764          148 :  Ep%zcut   =Dtset%zcut
    1765              : 
    1766          148 :  write(msg,'(2a,i4,2a,f10.6,a)')ch10,&
    1767          148 :    ' GW calculation type              = ',Ep%gwcalctyp,ch10,&
    1768          296 :    ' zcut to avoid poles in chi0 [eV] = ',Ep%zcut*Ha_eV,ch10
    1769          148 :  call wrtout(std_out, msg)
    1770              : 
    1771          148 :  Ep%awtr  =Dtset%awtr
    1772          148 :  Ep%npwe  =Dtset%npweps
    1773          148 :  Ep%npwwfn=Dtset%npwwfn
    1774          148 :  Ep%npwvec=MAX(Ep%npwe,Ep%npwwfn)
    1775              : 
    1776          148 :  timrev = 2 ! This information is not reported in the header
    1777              :             ! 1 --> do not use time-reversal symmetry
    1778              :             ! 2 --> take advantage of time-reversal symmetry
    1779          148 :  if (any(dtset%kptopt == [3, 4])) timrev = 1
    1780              : 
    1781          148 :  if (timrev==1.and.Dtset%awtr/=0) then
    1782            0 :    ABI_ERROR("awtr/=0 cannot be used when time-reversal symmetry doesn't hold")
    1783              :  end if
    1784              : 
    1785              :  ! Read parameters from WFK and verifify them.
    1786          148 :  call wfk_read_eigenvalues(wfk_fname,energies_p,Hdr_wfk,comm)
    1787         1009 :  mband = MAXVAL(Hdr_wfk%nband)
    1788          148 :  call hdr_wfk%vs_dtset(dtset)
    1789          148 :  remove_inv=.FALSE.
    1790              : 
    1791          148 :  test_npwkss = 0
    1792              :  call make_gvec_kss(Dtset%nkpt,Dtset%kptns,Hdr_wfk%ecut_eff,Dtset%symmorphi,Dtset%nsym,Dtset%symrel,Dtset%tnons,&
    1793          148 :                     gprimd,Dtset%prtvol,test_npwkss,test_gvec_kss,ierr)
    1794          148 :  ABI_CHECK(ierr==0,"Fatal error in make_gvec_kss")
    1795              : 
    1796          444 :  ABI_MALLOC(gvec_kss,(3,test_npwkss))
    1797       959604 :  gvec_kss = test_gvec_kss
    1798          148 :  ng_kss = test_npwkss
    1799              : 
    1800          148 :  if (Ep%npwvec>ng_kss) then
    1801            1 :    Ep%npwvec=ng_kss
    1802            1 :    if (Ep%npwwfn> ng_kss) Ep%npwwfn=ng_kss
    1803            1 :    if (Ep%npwe  > ng_kss) Ep%npwe  =ng_kss
    1804            1 :    write(msg,'(3a,3(a,i6,a))')ch10,&
    1805            1 :     ' Number of G-vectors found less then required. Calculation will proceed with ',ch10,&
    1806            1 :     '  npwvec = ',Ep%npwvec,ch10,&
    1807            1 :     '  npweps = ',Ep%npwe  ,ch10,&
    1808            2 :     '  npwwfn = ',Ep%npwwfn,ch10
    1809            1 :    ABI_WARNING(msg)
    1810              :  end if
    1811              : 
    1812          148 :  ng = MIN(SIZE(gvec_kss,DIM=2),SIZE(test_gvec_kss,DIM=2))
    1813          148 :  ierr = 0
    1814       120080 :  do ig=1,ng
    1815       479876 :    if (ANY(gvec_kss(:,ig)/=test_gvec_kss(:,ig))) then
    1816            0 :      ierr=ierr+1
    1817            0 :      write(std_out,*)" gvec_kss ",ig,"/",ng,gvec_kss(:,ig),test_gvec_kss(:,ig)
    1818              :    end if
    1819              :  end do
    1820          148 :  ABI_CHECK(ierr == 0, "Mismatch between gvec_kss and test_gvec_kss")
    1821          148 :  ABI_FREE(test_gvec_kss)
    1822              : 
    1823              :  ! Get important dimension from Hdr_wfk
    1824              :  ! Check also the consistency btw Hdr_wfk and Dtset.
    1825          148 :  Ep%nsppol=Hdr_wfk%nsppol
    1826          148 :  Ep%nkibz =Hdr_wfk%nkpt
    1827              : 
    1828          148 :  if (Ep%nbnds>mband) then
    1829              :    write(msg,'(2a,2(a,i0))') &
    1830            0 :     'Number of bands stored in WFK file is less than required. ',ch10,&
    1831            0 :     "WFK mband:", mband, ", chi0 nband: ", Ep%nbnds
    1832            0 :    ABI_ERROR(msg)
    1833              :  end if
    1834              : 
    1835          148 :  cryst = Hdr_wfk%get_crystal(gw_timrev=timrev, remove_inv=remove_inv)
    1836          148 :  call cryst%print(mode_paral='COLL')
    1837              : 
    1838              :  ! === Create basic data types for the calculation ===
    1839              :  ! Kmesh defines the k-point sampling for the wavefunctions.
    1840              :  ! Qmesh defines the q-point sampling for chi0, all possible differences k1-k2 reduced to the IBZ.
    1841              :  ! TODO Kmesh%bz should be in [-half, half[ but this modification is painful!
    1842              : 
    1843          148 :  call Kmesh%init(cryst, ep%nkibz, hdr_wfk%kptns, dtset%kptopt, wrap_1zone=.FALSE.)
    1844              : 
    1845              :  ! Some required information are not filled up inside kmesh_init. So doing it here, even though it is not clean
    1846         1924 :  Kmesh%kptrlatt(:,:) = Dtset%kptrlatt(:,:)
    1847          148 :  Kmesh%nshift        = Dtset%nshiftk
    1848          444 :  ABI_MALLOC(Kmesh%shift, (3,Kmesh%nshift))
    1849          740 :  Kmesh%shift(:,:)    = Dtset%shiftk(:,1:Dtset%nshiftk)
    1850          148 :  call Kmesh%print(units, header="K-mesh for the wavefunctions", prtvol=Dtset%prtvol)
    1851              : 
    1852              :  ! === Find Q-mesh ===
    1853              :  ! Stop if a nonzero umklapp is needed to reconstruct the BZ.
    1854              :  ! epsilon^-1(Sq) indeed should be symmetrized in csigme using a different expression (G-G_o is needed)
    1855          148 :  call qmesh%find_qmesh(Cryst, Kmesh)
    1856          148 :  call qmesh%print(units, "Q-mesh for the screening function", prtvol=dtset%prtvol)
    1857              : 
    1858         7084 :  do iqbz=1,Qmesh%nbz
    1859         6936 :    call qmesh%get_BZ_item(iqbz, qbz, iq_ibz, isym, itim)
    1860       194208 :    sq = (3-2*itim) * MATMUL(cryst%symrec(:,:,isym), qmesh%ibz(:,iq_ibz))
    1861        27892 :    if (ANY(ABS(qbz-sq) > 1.0d-4)) then
    1862              :      write(msg,'(a,3f6.3,a,3f6.3,2a,9i3,a,i2,2a)')&
    1863            0 :       ' qpoint ',qbz,' is the symmetric of ',qmesh%ibz(:,iq_ibz),ch10,&
    1864            0 :       ' through operation ',cryst%symrec(:,:,isym),' and itim ',itim,ch10,&
    1865            0 :       ' however a non zero umklapp G_o vector is required and this is not yet allowed'
    1866            0 :      ABI_ERROR(msg)
    1867              :    end if
    1868              :  end do
    1869              : 
    1870              :  ! Setup for long wavelength limit
    1871          148 :  if (Dtset%gw_nqlwl==0) then
    1872          147 :    Ep%nqlwl=1
    1873          147 :    ABI_MALLOC(Ep%qlwl,(3,Ep%nqlwl))
    1874          588 :    Ep%qlwl(:,1)=GW_Q0_DEFAULT ! Use default shift 0.000010, 0.000020, 0.000030
    1875              :  else
    1876            1 :    Ep%nqlwl=Dtset%gw_nqlwl
    1877            3 :    ABI_MALLOC(Ep%qlwl,(3,Ep%nqlwl))
    1878            5 :    Ep%qlwl(:,:)=Dtset%gw_qlwl(:,1:Ep%nqlwl)
    1879            1 :    ABI_CHECK(Ep%nqlwl==1,"nqlwl/=1 not coded")
    1880              :  end if
    1881              :  !write(std_out,*)" Using qlwl = ",Ep%qlwl
    1882              : 
    1883              :  ! Find optimal value for G-sphere enlargment due to oscillator matrix elements
    1884          148 :  call get_ng0sh(Kmesh%nbz,Kmesh%bz,Qmesh%nibz,Qmesh%ibz,Kmesh%nbz,Kmesh%bz,GW_TOLQ0,ng0sh_opt)
    1885          148 :  call wrtout(std_out,sjoin(' Optimal value for ng0sh:',ltoa(ng0sh_opt)),"COLL")
    1886              : 
    1887          592 :  Ep%mG0(:)=ng0sh_opt(:) !Ep%mG0(:) = [3, 3, 3]
    1888              : 
    1889              :  ! === In case of symmetrization, find the little group of the q"s ===
    1890              :  ! * For the long-wavelength limit we consider a small but finite q. However the oscillators are
    1891              :  !  evaluated setting q==0. Thus it is possible to take advantage of symmetries also when q --> 0.
    1892              :  ! * Here we calculate the enlargement of the G-sphere, npwepG0, needed to account for umklapps.
    1893              :  ! TODO Switch on use_umklp, write all this stuff to ab_out
    1894              : 
    1895          148 :  Ep%npwepG0 = Ep%npwe
    1896         1378 :  ABI_MALLOC(Ltg_q, (Qmesh%nibz))
    1897              : 
    1898         1082 :  do iq=1,Qmesh%nibz
    1899         3736 :    qtmp = Qmesh%ibz(:,iq); if (normv(qtmp,gmet,'G') < GW_TOLQ0) qtmp(:) = zero; use_umklp = 0
    1900         1082 :    call Ltg_q(iq)%init(qtmp, Kmesh%nbz, Kmesh%bz, Cryst, use_umklp, Ep%npwe, gvec=gvec_kss)
    1901              :  end do
    1902              : 
    1903          148 :  ecutepspG0 = Dtset%ecuteps
    1904          148 :  ABI_CHECK(ecutepspG0 > zero, "ecuteps must be > 0")
    1905          148 :  if (Ep%symchi/=0) then
    1906         1117 :    ecutepspG0=MAXVAL(Ltg_q(:)%max_kin_gmG0)+tol6; npwepG0=0; nshepspG0=0
    1907          134 :    if (my_rank == master) write(std_out,*)" Due to umklapp processes : ecutepspg0= ",ecutepspG0
    1908          134 :    call setshells(ecutepspG0,npwepG0,nshepspG0,Cryst%nsym,gmet,gprimd,Cryst%symrel,'eps_pG0',Cryst%ucvol)
    1909          134 :    Ep%npwepG0=npwepG0
    1910              :  end if
    1911              : 
    1912          148 :  if (Ep%npwepG0>Ep%npwvec) then
    1913              :    write(msg,'(3a,i5,a,i5)')&
    1914            0 :     ' npwepG0 > npwvec, decrease npweps or increase npwwfn. ',ch10,&
    1915            0 :     ' npwepG0 = ',Ep%npwepG0,' npwvec = ',Ep%npwvec
    1916            0 :    ABI_ERROR(msg)
    1917              :  end if
    1918              : 
    1919              :  ! === Create structure describing the G-sphere used for chi0/espilon and Wfns ===
    1920              :  ! * The cutoff is >= ecuteps to allow for umklapp
    1921          148 :  call Gsph_wfn%init(Cryst, Ep%npwvec, gvec=gvec_kss)
    1922              : 
    1923          148 :  call Gsph_epsG0%init(Cryst, Ep%npwepG0, gvec=gvec_kss)
    1924              :  !
    1925              :  ! =======================================================================
    1926              :  ! ==== Setup of the FFT mesh used for the oscillator matrix elements ====
    1927              :  ! =======================================================================
    1928              :  ! * ngfft_gw(7:18) is the same as Dtset%ngfft(7:18), initialized before entering setup_screening.
    1929              :  !   Here we just redefine ngfft_gw(1:6) according to the following options:
    1930              :  !
    1931              :  !    method==0 ==> FFT grid read from __fft.in__ (only for debugging purpose)
    1932              :  !    method==1 ==> normal FFT grid
    1933              :  !    method==2 ==> slightly augmented FFT grid to calculate exactly rho_tw_g (see setmesh.F90)
    1934              :  !    method==3 ==> doubled FFT grid, to treat exactly the convolution defining the density,
    1935              :  !      Useful in sigma if ppmodel=[2,3,4] since rho(G-Gp) or to calculate matrix elements of v_Hxc.
    1936              :  !
    1937              :  !    enforce_sym==1 ==> enforce a direct space FFT mesh compatible with all symmetries operation
    1938              :  !    enforce_sym==0 ==> Find the smallest FFT grid compatibile with the library, do not care about symmetries
    1939              :  !
    1940         2812 :  ngfft_gw(1:18)=Dtset%ngfft(1:18); method=2
    1941          148 :  if (Dtset%fftgw==00 .or. Dtset%fftgw==01) method=0
    1942          148 :  if (Dtset%fftgw==10 .or. Dtset%fftgw==11) method=1
    1943          148 :  if (Dtset%fftgw==20 .or. Dtset%fftgw==21) method=2
    1944          148 :  if (Dtset%fftgw==30 .or. Dtset%fftgw==31) method=3
    1945          148 :  enforce_sym=MOD(Dtset%fftgw,10)
    1946              : 
    1947              :  ! Use npwepG0 to account for umklapps.
    1948          148 :  call setmesh(gmet,gvec_kss,ngfft_gw,Ep%npwvec,Ep%npwepG0,Ep%npwwfn,nfftgw_tot,method,Ep%mG0,Cryst,enforce_sym)
    1949              :  !call new_setmesh(Cryst,ecut_osc,ecutwfn,nkpt,kpoints,method,Ep%mG0,enforce_sym,ngfft_gw,nfftgw_tot)
    1950              : 
    1951          148 :  ABI_FREE(gvec_kss)
    1952              : 
    1953              :  ! FIXME this wont work if nqptdm/=0
    1954              :  call Vcp%init(Gsph_epsG0,Cryst,Qmesh,Kmesh,Dtset%gw_rcut,Dtset%gw_icutcoul,Dtset%vcutgeo,Dtset%ecuteps,Ep%npwe,Ep%nqlwl,&
    1955          148 :                Ep%qlwl,comm)
    1956              : 
    1957              : #if 0
    1958              :  ! Using the random q for the optical limit is one of the reasons
    1959              :  ! why sigma breaks the initial energy degeneracies.
    1960              :  Vcp%i_sz=zero
    1961              :  Vcp%vc_sqrt(1,:)=czero
    1962              :  Vcp%vcqlwl_sqrt(1,:)=czero
    1963              : #endif
    1964              : 
    1965              :  ! Value of scissor energy
    1966          148 :  Ep%mbpt_sciss=Dtset%mbpt_sciss
    1967              : 
    1968              :  ! Define the frequency mesh for epsilon according to the method used.
    1969          148 :  Ep%nomegaei=1
    1970          148 :  Ep%nomegaer=1; if (is_static) Ep%nomegaer=0
    1971          148 :  Ep%nomegaec=0
    1972          148 :  Ep%omegaermax=zero
    1973              : 
    1974              :  ! For ppmodels 2,3,4, only omega=0 is needed.
    1975          148 :  if (Ep%plasmon_pole_model.and.Dtset%nfreqre==1.and.Dtset%nfreqim==0) then
    1976            5 :    Ep%nomegaer=1; Ep%nomegaei=0
    1977            5 :    write(msg,'(7a)')ch10,&
    1978            5 :     ' The inverse dielectric matrix will be calculated on zero frequency only',ch10,&
    1979            5 :     ' please note that the calculated epsilon^-1 cannot be used ',ch10,&
    1980           10 :     ' to calculate QP corrections using plasmonpole model 1',ch10
    1981            5 :    call wrtout(units, msg)
    1982              :  end if
    1983              : 
    1984              :  ! Max number of omega along the imaginary axis
    1985          148 :  if (Ep%analytic_continuation.or.Ep%contour_deformation) then
    1986           37 :    Ep%nomegaei = abs(Dtset%nfreqim)
    1987           37 :    if (Dtset%gw_frqim_inzgrid==1) then
    1988            1 :      ABI_WARNING('iomega = z/1-z transfom grid will be used for imaginary frequency grid')
    1989              :    end if
    1990           37 :    if (Dtset%cd_customnimfrqs/=0) then
    1991            1 :      ABI_WARNING('Custom imaginary grid specified. Assuming experienced user.')
    1992            1 :      Ep%nomegaei=Dtset%cd_customnimfrqs
    1993              :    end if
    1994           37 :    if (Ep%nomegaei==-1) then
    1995            0 :      Ep%nomegaei=NOMEGAGAUSS
    1996            0 :      ABI_WARNING(sjoin('Number of imaginary frequencies set to default= ',itoa(NOMEGAGAUSS)))
    1997              :    end if
    1998           37 :    if (Ep%nomegaei==0) then
    1999            3 :      ABI_WARNING('nfreqim = 0! Assuming experienced user merging several frequency calculations.')
    2000              :    end if
    2001              :  end if
    2002              : 
    2003              :  ! Range and total number of real frequencies.
    2004          148 :  Ep%omegaermin = zero
    2005          148 :  if (Ep%contour_deformation) then
    2006           26 :    Ep%nomegaer=Dtset%nfreqre; Ep%omegaermin=Dtset%freqremin; Ep%omegaermax=Dtset%freqremax
    2007           26 :    if (Dtset%gw_frqre_tangrid==1) then
    2008            1 :      Ep%omegaermax=Dtset%cd_max_freq
    2009            1 :      ABI_WARNING('Tangent transfom grid will be used for real frequency grid')
    2010              :    end if
    2011           26 :    if (Dtset%gw_frqre_tangrid==1) then
    2012            1 :      ABI_WARNING('Tangent transfom grid will be used for real frequency grid')
    2013              :    end if
    2014           26 :    if (Ep%nomegaer==-1) then
    2015            0 :      Ep%nomegaer=NOMEGAREAL
    2016            0 :      ABI_WARNING(sjoin('Number of real frequencies set to default= ',itoa(NOMEGAREAL)))
    2017              :    end if
    2018           26 :    if (Ep%nomegaer==0) then
    2019            0 :      ABI_WARNING('nfreqre = 0 ! Assuming experienced user.')
    2020              :    end if
    2021           26 :    if (ABS(Ep%omegaermin)<TOL16) then
    2022           25 :      Ep%omegaermin=zero
    2023           25 :      write(msg,'(a,f8.4)')' Min real frequency set to default [Ha] = ',Ep%omegaermin
    2024           25 :      ABI_WARNING(msg)
    2025              :    end if
    2026           26 :    if (Ep%omegaermin>Ep%omegaermax) then
    2027            0 :      ABI_ERROR('freqremin > freqremax !')
    2028              :    end if
    2029           26 :    if (Ep%omegaermax<TOL16) then
    2030            4 :      Ep%omegaermax=OMEGAERMAX
    2031            4 :      write(msg,'(a,f8.4)')' Max real frequency set to default [Ha] = ',OMEGAERMAX
    2032            4 :      ABI_WARNING(msg)
    2033              :    end if
    2034              :    ! Check if a subset of the frequencies is to be used
    2035           26 :    if (Dtset%cd_subset_freq(1)/=0) then
    2036            0 :      istart = Dtset%cd_subset_freq(1)
    2037            0 :      iend   = Dtset%cd_subset_freq(2)
    2038            0 :      if (istart>iend.or.istart<0.or.iend<0) then
    2039            0 :        ABI_ERROR(' check indices of cd_subset_freq!')
    2040              :      end if
    2041            0 :      write(msg,'(2(a,i0))')' Using cd_subset_freq to only do freq. from ',istart,' to ',iend
    2042            0 :      ABI_WARNING(msg)
    2043              :      ! Reset the numbers
    2044            0 :      if (Dtset%gw_frqre_tangrid/=1) then ! Normal equidistant grid
    2045            0 :        Ep%nomegaer = iend-istart+1
    2046            0 :        domegareal=(Ep%omegaermax-Ep%omegaermin)/(Ep%nomegaer-1)
    2047            0 :        Ep%omegaermin = Ep%omegaermin+(istart-1)*domegareal
    2048            0 :        Ep%omegaermax = Ep%omegaermin+(iend-1)*domegareal
    2049              :      else
    2050            0 :        Ep%nomegaer = iend-istart+1
    2051              :      end if
    2052              :    end if
    2053              :  end if
    2054              : 
    2055              :  ! Check full grid calculations
    2056          148 :  if (Dtset%cd_full_grid/=0) then
    2057            1 :    ABI_WARNING("FULL GRID IN COMPLEX PLANE CALCULATED. YOU MIGHT NOT BE ABLE TO USE SCREENING FILES!")
    2058            1 :    if (Dtset%cd_subset_freq(1)/=0) then
    2059            0 :      ABI_ERROR('cd_subset_freq cannot be used with cd_full_grid!')
    2060              :    end if
    2061            1 :    Ep%nomegaec = Ep%nomegaei*(Ep%nomegaer-1)
    2062              :  end if
    2063              : 
    2064          148 :  Ep%nomega=Ep%nomegaer+Ep%nomegaei+Ep%nomegaec ! Total number of frequencies.
    2065              : 
    2066              :  ! ==== Setup of the spectral method ====
    2067          148 :  Ep%spmeth  =Dtset%spmeth; Ep%nomegasf=Dtset%nomegasf; Ep%spsmear =Dtset%spbroad
    2068              : 
    2069          148 :  if (Ep%spmeth/=0) then
    2070            6 :    write(msg,'(2a,i3,2a,i8)')ch10,&
    2071            6 :     ' setup_screening: using spectral method: ',Ep%spmeth,ch10,&
    2072           12 :     ' Number of frequencies for imaginary part: ',Ep%nomegasf
    2073            6 :    call wrtout(std_out, msg)
    2074            6 :    if (Ep%spmeth==2) then
    2075            1 :      write(msg,'(a,f8.5,a)')' Gaussian broadening = ',Ep%spsmear*Ha_eV,' [eV]'
    2076            1 :      call wrtout(std_out, msg)
    2077              :    end if
    2078              :  end if
    2079              : 
    2080          148 :  Ep%nI=1; Ep%nJ=1
    2081          148 :  if (Dtset%nspinor==2) then
    2082              :    !if (Dtset%usepaw==1.and.Dtset%pawspnorb>0) then
    2083              :    !  Ep%nI=1; Ep%nJ=4
    2084              :    !end if
    2085              :    ! For spin-spin interaction
    2086              :    ! Ep%nI=4; Ep%nJ=4
    2087            2 :    ABI_CHECK(Ep%npwepG0 == Ep%npwe, "npwepG0 must be == npwe if nspinor==2")
    2088              :    !ABI_CHECK(Ep%symchi == 0, "symchi/=0 and nspinor=2 not available")
    2089              :  end if
    2090              : 
    2091              :  ! === Enable the calculations of chi0 on user-specified q-points ===
    2092          148 :  Ep%nqibz=Qmesh%nibz
    2093          444 :  ABI_MALLOC(Ep%qibz,(3,Ep%nqibz))
    2094         3884 :  Ep%qibz(:,:)=Qmesh%ibz(:,:)
    2095              : 
    2096          148 :  Ep%nqcalc=Ep%nqibz
    2097          148 :  if (Dtset%nqptdm>0) Ep%nqcalc=Dtset%nqptdm
    2098              : 
    2099          444 :  ABI_MALLOC(Ep%qcalc,(3,Ep%nqcalc))
    2100          148 :  if (Ep%nqcalc/=Ep%nqibz) then
    2101            3 :    write(msg,'(6a)')ch10,&
    2102            3 :     ' Dielectric matrix will be calculated only for some ',ch10,&
    2103            3 :     ' selected q points provided by the user through the input variables ',ch10,&
    2104            6 :     ' nqptdm and qptdm'
    2105            3 :    call wrtout(units, msg)
    2106            3 :    ltest= Ep%nqcalc <= Qmesh%nibz
    2107            3 :    ABI_CHECK(ltest, 'nqptdm should not exceed the number of q points in the IBZ')
    2108           27 :    Ep%qcalc(:,:)=Dtset%qptdm(:,1:Ep%nqcalc)
    2109              :    ! Check whether the q-points provided are correct.
    2110            9 :    do iq=1,Ep%nqcalc
    2111            6 :      found=.FALSE.
    2112           21 :      do iqp=1,Qmesh%nibz
    2113           84 :        qtmp(:)=Ep%qcalc(:,iq)-Qmesh%ibz(:,iqp)
    2114           21 :        found=(normv(qtmp,gmet,'G')<GW_TOLQ)
    2115           21 :        if (found) EXIT
    2116              :      end do
    2117            9 :      ABI_CHECK(found, 'One or more points specified by Dtset%qptdm do not satisfy q=k1-k2')
    2118              :    end do
    2119              :  else
    2120         3809 :    Ep%qcalc(:,:)=Ep%qibz(:,:)
    2121              :  end if
    2122              : 
    2123              :  ! To write the SCR header correctly, with heads and wings, we have
    2124              :  ! to make sure that q==0, if present, is the first q-point in the list.
    2125          148 :  has_q0=.FALSE.
    2126          153 :  do iq=1,Ep%nqcalc
    2127          153 :    if (normv(Ep%qcalc(:,iq),gmet,'G')<GW_TOLQ0) then
    2128          148 :      has_q0=.TRUE.; EXIT
    2129              :    end if
    2130              :  end do
    2131              : 
    2132          148 :  if (has_q0.and.normv(Ep%qcalc(:,1),gmet,'G')>=GW_TOLQ0) then
    2133              :    write(msg,'(5a)')&
    2134            0 :     'The list of q-points to be calculated contains the Gamma point, ',ch10,&
    2135            0 :     'however Gamma is not the first point in the list. ' ,ch10,&
    2136            0 :     'Please, change your input file accordingly. '
    2137            0 :    ABI_ERROR(msg)
    2138              :  end if
    2139              : 
    2140              :  ! === Initialize the band structure datatype ===
    2141              :  ! * Copy KSS energies and occupations up to Ep%nbnds==Dtset%nband(:)
    2142              :  ! TODO Recheck symmorphy and inversion
    2143         1009 :  bantot = SUM(Dtset%nband(1:Dtset%nkpt*Dtset%nsppol))
    2144              : 
    2145        22732 :  ABI_CALLOC(doccde, (bantot))
    2146        22584 :  ABI_CALLOC(eigen, (bantot))
    2147        22584 :  ABI_CALLOC(occfact, (bantot))
    2148              : 
    2149              :  jj=0; ibtot=0
    2150          298 :  do isppol=1,Dtset%nsppol
    2151         1159 :    do ikibz=1,Dtset%nkpt
    2152        37761 :      do ib=1,Hdr_wfk%nband(ikibz+Dtset%nkpt*(isppol-1))
    2153        36750 :        ibtot=ibtot+1
    2154        37611 :        if (ib<=Ep%nbnds) then
    2155        22288 :          jj=jj+1
    2156        22288 :          occfact(jj)=Hdr_wfk%occ(ibtot)
    2157        22288 :          eigen  (jj)=energies_p(ib,ikibz,isppol)
    2158              :        end if
    2159              :      end do
    2160              :    end do
    2161              :  end do
    2162          148 :  ABI_FREE(energies_p)
    2163              : 
    2164              :  ! Make sure that Dtset%wtk==Kmesh%wt due to the dirty treatment of
    2165              :  ! the symmetry operations in the old GW code (symmorphy and inversion)
    2166         1001 :  ltest = (ALL(ABS(Dtset%wtk(1:Kmesh%nibz)-Kmesh%wt(1:Kmesh%nibz)) < tol6))
    2167          148 :  if (.not. ltest) then
    2168            0 :    do jj=1,Kmesh%nibz
    2169            0 :      write(std_out, *)"wtk dtset vs kmesh:", dtset%wtk(jj), kmesh%wt(jj)
    2170              :    end do
    2171              :  end if
    2172            0 :  ABI_CHECK(ltest, 'Mismatch between Dtset%wtk and Kmesh%wt')
    2173              : 
    2174          444 :  ABI_MALLOC(npwarr,(Hdr_wfk%nkpt))
    2175         1001 :  npwarr(:)=Ep%npwwfn
    2176              : 
    2177              :  call ks_ebands%init(bantot, Dtset%nelect,Dtset%ne_qFD,Dtset%nh_qFD,Dtset%ivalence,&
    2178              :                   doccde,eigen,Dtset%istwfk,Kmesh%ibz,Dtset%nband,&
    2179              :                   Kmesh%nibz,npwarr,Dtset%nsppol,Dtset%nspinor,Dtset%tphysel,Dtset%tsmear,Dtset%occopt,occfact,Kmesh%wt,&
    2180              :                   dtset%cellcharge(1), dtset%kptopt, dtset%kptrlatt_orig, dtset%nshiftk_orig, dtset%shiftk_orig, &
    2181          148 :                   dtset%kptrlatt, dtset%nshiftk, dtset%shiftk)
    2182              : 
    2183              :  ! TODO modify outkss in order to calculate the eigenvalues also if NSCF calculation.
    2184              :  ! this fails simply because in case of NSCF occ  are zero
    2185              :  !ltest=(ALL(ABS(occfact-ks_ebands%occ)<1.d-2))
    2186              :  !call assert(ltest,'difference in occfact')
    2187              :  !write(std_out,*)MAXVAL(ABS(occfact(:)-ks_ebands%occ(:)))
    2188              : 
    2189              :  !TODO call ebands_update_occ here
    2190              :  !call ks_ebands%update_occ(spinmagntarget,Dtset%prtvol)
    2191              : 
    2192          148 :  ABI_FREE(doccde)
    2193          148 :  ABI_FREE(eigen)
    2194          148 :  ABI_FREE(npwarr)
    2195              : 
    2196              :  ! Initialize abinit header for the screening part
    2197          148 :  call Hdr_out%init(ks_ebands,codvsn,Dtset,Pawtab,pertcase0,Psps,wvl)
    2198              : 
    2199              :  ! Get Pawrhoij from the header.
    2200          475 :  ABI_MALLOC(Pawrhoij,(Cryst%natom*Dtset%usepaw))
    2201          148 :  if (Dtset%usepaw==1) then
    2202            5 :    call pawrhoij_alloc(Pawrhoij,1,Dtset%nspden,Dtset%nspinor,Dtset%nsppol,Cryst%typat,pawtab=Pawtab)
    2203            5 :    call pawrhoij_copy(Hdr_wfk%Pawrhoij,Pawrhoij)
    2204              :  end if
    2205          148 :  call Hdr_out%update(bantot,1.0d20,1.0d20,1.0d20,1.0d20,Cryst%rprimd,occfact,Pawrhoij,Cryst%xred,dtset%amu_orig(:,1))
    2206              : 
    2207          148 :  ABI_FREE(occfact)
    2208          148 :  call pawrhoij_free(Pawrhoij)
    2209          179 :  ABI_FREE(Pawrhoij)
    2210              : 
    2211              :  ! ==== Setup of extrapolar technique ====
    2212          148 :  Ep%gwcomp = Dtset%gwcomp; Ep%gwencomp = Dtset%gwencomp
    2213          148 :  if (Ep%gwcomp == 1) then
    2214           19 :    write(msg,'(a,f8.2,a)')' Using the completeness correction with gwencomp ',Ep%gwencomp*Ha_eV,' [eV] '
    2215           19 :    call wrtout(std_out, msg)
    2216              :  end if
    2217              : 
    2218              :  ! Final compatibility tests
    2219         1009 :  ltest = (ks_ebands%mband == Ep%nbnds .and. ALL(ks_ebands%nband == Ep%nbnds))
    2220            0 :  ABI_CHECK(ltest, 'BUG in definition of ks_ebands%nband')
    2221              : 
    2222          148 :  if (Ep%gwcomp==1 .and. Ep%spmeth>0) then
    2223            0 :    ABI_ERROR("Hilbert transform and extrapolar method are not compatible")
    2224              :  end if
    2225              : 
    2226          444 : end subroutine setup_screening
    2227              : !!***
    2228              : 
    2229              : !----------------------------------------------------------------------
    2230              : 
    2231              : !!****f* m_screening_driver/chi0_bksmask
    2232              : !! NAME
    2233              : !! chi0_bksmask
    2234              : !!
    2235              : !! FUNCTION
    2236              : !!  Compute tables for the distribution and the storage of the wavefunctions in the SCREENING code.
    2237              : !!
    2238              : !! INPUTS
    2239              : !! Dtset<type(dataset_type)>=all input variables for this dataset
    2240              : !! Ep<em1params_t>=Parameters for the screening calculation.
    2241              : !! Kmesh <kmesh_t>=Structure describing the k-point sampling.
    2242              : !! nbvw = Max. number of fully/partially occupied states over spin
    2243              : !! nbcw = Max. number of unoccupied states considering the spin
    2244              : !! nprocs=Total number of MPI processors
    2245              : !! my_rank=Rank of this this processor.
    2246              : !!
    2247              : !! OUTPUT
    2248              : !! bks_mask(Ep%nbnds,Kmesh%nibz,Sigp%nsppol)=True if this node will treat this state.
    2249              : !! keep_ur(Ep%nbnds,Kmesh%nibz,Sigp%nsppol)=True if this node will store this state in real space.
    2250              : !! ierr=Exit status.
    2251              : !!
    2252              : !! SOURCE
    2253              : 
    2254          148 : subroutine chi0_bksmask(Dtset,Ep,Kmesh,nbvw,nbcw,my_rank,nprocs,bks_mask,keep_ur,ierr)
    2255              : 
    2256              : !Arguments ------------------------------------
    2257              : !scalars
    2258              :  integer,intent(in) :: my_rank,nprocs,nbvw,nbcw
    2259              :  integer,intent(out) :: ierr
    2260              :  type(Dataset_type),intent(in) :: Dtset
    2261              :  type(em1params_t),intent(in) :: Ep
    2262              :  type(kmesh_t),intent(in) :: Kmesh
    2263              : !arrays
    2264              :  logical,intent(out) :: bks_mask(Ep%nbnds,Kmesh%nibz,Dtset%nsppol)
    2265              :  logical,intent(out) :: keep_ur(Ep%nbnds,Kmesh%nibz,Dtset%nsppol)
    2266              : 
    2267              : !Local variables-------------------------------
    2268              : !scalars
    2269              :  integer :: my_nspins,my_maxb,my_minb,isp,spin,nsppol,band,rank_spin,ib
    2270              :  character(len=500) :: msg
    2271              :  logical :: store_ur
    2272              : !arrays
    2273          296 :  integer :: my_spins(Dtset%nsppol),nprocs_spin(Dtset%nsppol)
    2274          148 :  integer,allocatable :: istart(:),istop(:)
    2275              : 
    2276              : ! *************************************************************************
    2277              : 
    2278          148 :  ierr=0; nsppol=Dtset%nsppol
    2279              : 
    2280          448 :  my_nspins=Dtset%nsppol; my_spins= [(isp,isp=1,nsppol)]
    2281              : 
    2282              :  ! List of spins for each node, number of processors per each spin
    2283              :  ! and the MPI rank in the "spin" communicator.
    2284          298 :  nprocs_spin = nprocs; rank_spin = my_rank
    2285              : 
    2286          148 :  if (nsppol==2.and.nprocs>1) then
    2287              :    ! Distribute spins (optimal distribution if nprocs is even)
    2288            0 :    nprocs_spin(1) = nprocs/2
    2289            0 :    nprocs_spin(2) = nprocs - nprocs/2
    2290            0 :    my_nspins=1; my_spins(1)=1
    2291            0 :    if (my_rank+1>nprocs/2) then
    2292            0 :      my_spins(1)=2
    2293            0 :      rank_spin = my_rank - nprocs/2
    2294              :    end if
    2295              :  end if
    2296              : 
    2297          148 :  store_ur = (MODULO(Dtset%gwmem,10)==1)
    2298        46746 :  bks_mask=.FALSE.; keep_ur=.FALSE.
    2299              : 
    2300          180 :  select case (Dtset%gwpara)
    2301              :  case (1)
    2302              :    ! Parallelization over transitions **without** memory distributions (Except for the spin).
    2303           32 :    my_minb=1; my_maxb=Ep%nbnds
    2304           64 :    do isp=1,my_nspins
    2305           32 :      spin = my_spins(isp)
    2306         3888 :      bks_mask(my_minb:my_maxb,:,spin) = .TRUE.
    2307         3920 :      if (store_ur) keep_ur(my_minb:my_maxb,:,spin)=.TRUE.
    2308              :    end do
    2309              : 
    2310              :  case (2)
    2311              :    ! Distribute bands and spin.
    2312          234 :    do isp=1,my_nspins
    2313          118 :      spin = my_spins(isp)
    2314              : 
    2315          118 :      if (nprocs_spin(spin) <= nbcw) then
    2316              :        ! Distribute nbcw empty bands among nprocs_spin (block of bands without replicas).
    2317              :        ! Bands are distributed in contiguous blocks because
    2318              :        ! this distribution is well suited for the Hilber transform
    2319              :        ! since each node will allocate only a smaller frequency interval
    2320              :        ! for the spectral function whose size scales with the number of MPI nodes.
    2321              :        ! Note it is now meaningless to distinguish gwcomp=0 or 1 since the workload is well balanced later on
    2322          354 :        ABI_MALLOC(istart,(nprocs_spin(spin)))
    2323          236 :        ABI_MALLOC(istop,(nprocs_spin(spin)))
    2324              : 
    2325          118 :        call xmpi_split_work2_i4b(nbcw,nprocs_spin(spin),istart,istop)
    2326              : 
    2327          118 :        my_minb = nbvw + istart(rank_spin+1)
    2328          118 :        my_maxb = nbvw + istop (rank_spin+1)
    2329              : 
    2330          118 :        ABI_FREE(istart)
    2331          118 :        ABI_FREE(istop)
    2332              : 
    2333          118 :        if (my_maxb - my_minb + 1 <= 0) then
    2334              :          write(msg,'(3a,2(i0,a),2a)')&
    2335            0 :           'One or more processors has zero number of bands ',ch10,&
    2336            0 :           'my_minb= ',my_minb,' my_maxb= ',my_maxb,ch10,&
    2337            0 :           'This is a waste, decrease the number of processors.'
    2338            0 :          ABI_ERROR(msg)
    2339              :        end if
    2340              : 
    2341        13989 :        bks_mask(my_minb:my_maxb,:,spin)=.TRUE.
    2342        13637 :        if (store_ur) keep_ur(my_minb:my_maxb,:,spin)=.TRUE.
    2343              : 
    2344              :      else
    2345              :        ! New version (alternate bands with replicas if nprocs > nbcw)
    2346              :        ! FIXME: Fix segmentation fault with Hilbert transform.
    2347            0 :        do ib=1,nbcw
    2348            0 :          if (xmpi_distrib_with_replicas(ib,nbcw,rank_spin,nprocs_spin(spin))) then
    2349            0 :            band = ib + nbvw
    2350            0 :            bks_mask(band,:,spin)=.TRUE.
    2351            0 :            if (store_ur) keep_ur(band,:,spin)=.TRUE.
    2352              :          end if
    2353              :        end do
    2354              :      end if
    2355              : 
    2356              :      ! This is needed to have all the occupied states on each node.
    2357         3511 :      bks_mask(1:nbvw,:,spin) = .TRUE.
    2358         3519 :      if (store_ur) keep_ur(1:nbvw,:,spin)=.TRUE.
    2359              :    end do ! isp
    2360              : 
    2361              :  case default
    2362            0 :    ierr = 1
    2363          148 :    ABI_WARNING("Wrong value for gwpara")
    2364              :  end select
    2365              : 
    2366          148 : end subroutine chi0_bksmask
    2367              : !!***
    2368              : 
    2369              : !!****f* m_screening_driver/random_stopping_power
    2370              : !! NAME
    2371              : !! random_stopping_power
    2372              : !!
    2373              : !! FUNCTION
    2374              : !! Calculate the electronic random stopping power
    2375              : !!
    2376              : !! INPUTS
    2377              : !!
    2378              : !! OUTPUT
    2379              : !!
    2380              : !! SIDE EFFECTS
    2381              : !!
    2382              : !! SOURCE
    2383              : 
    2384           12 : subroutine random_stopping_power(iqibz,npvel,pvelmax,Ep,Gsph_epsG0,Qmesh,Vcp,Cryst,Dtfil,epsm1,rspower)
    2385              : 
    2386              :  use m_splines
    2387              : 
    2388              : !Arguments ------------------------------------
    2389              : !scalars
    2390              :  integer,intent(in)                    :: iqibz,npvel
    2391              :  real(dp),intent(in)                   :: pvelmax(3)
    2392              :  type(em1params_t),intent(in) :: Ep
    2393              :  type(gsphere_t),intent(in)            :: Gsph_epsG0
    2394              :  type(kmesh_t),intent(in)              :: Qmesh
    2395              :  type(vcoul_t),intent(in)              :: Vcp
    2396              :  type(crystal_t),intent(in)            :: Cryst
    2397              :  type(Datafiles_type),intent(in)       :: Dtfil
    2398              :  complex(gwp),intent(in)              :: epsm1(Ep%npwe,Ep%npwe,Ep%nomega)
    2399              :  real(dp),intent(inout)                :: rspower(npvel)
    2400              : 
    2401              : !Local variables ------------------------------
    2402              :  integer :: ipvel,ig, iq_bz,iq_ibz,isym_q,itim_q
    2403              :  integer :: iomega,iomegap,nomega_re,unt_rsp, units(2)
    2404           12 :  integer,allocatable :: iomega_re(:)
    2405              : 
    2406              :  real(dp),parameter :: zp=1.0_dp              ! Hard-coded charge of the impinging particle
    2407              :  real(dp) :: omega_p
    2408              :  real(dp) :: im_epsm1_int(1), qbz(3),qpgcart(3),qpg_red(3)
    2409           24 :  real(dp) :: pvel(3,npvel),pvel_norm(npvel),ypp_i(Ep%nomega),vcoul(Ep%npwe)
    2410           12 :  real(dp),allocatable :: im_epsm1_diag_qbz(:,:),tmp_data(:),omega_re(:)
    2411              :  character(len=500)     :: msg
    2412              :  character(len=fnlen+4) :: fname
    2413              : !************************************************************************
    2414              : 
    2415           36 :  units = [std_out, ab_out]
    2416              : 
    2417              :  ! First set up the velocities array from the input variables npvel and pvelmax(3)
    2418              :  ! Remember pvelmax is in Cartesian coordinates and so is pvel
    2419          492 :  do ipvel=1,npvel
    2420         1920 :    pvel(:,ipvel)    = REAL(ipvel,dp) / REAL(npvel,dp) * pvelmax(:)
    2421         1932 :    pvel_norm(ipvel) = SQRT( SUM( pvel(:,ipvel)**2 ) )
    2422              :  enddo
    2423              :  !
    2424              :  ! Select the purely real frequency in Ep%omega
    2425           12 :  nomega_re=0
    2426          492 :  do iomega=1,Ep%nomega
    2427          492 :    if( AIMAG(Ep%omega(iomega)) < 1.0e-4_dp ) then
    2428          480 :      nomega_re=nomega_re+1
    2429              :    endif
    2430              :  enddo
    2431           36 :  ABI_MALLOC(omega_re,(nomega_re))
    2432           36 :  ABI_MALLOC(iomega_re,(nomega_re))
    2433           48 :  ABI_MALLOC(im_epsm1_diag_qbz,(Ep%npwe,Ep%nomega))
    2434           36 :  ABI_MALLOC(tmp_data,(Ep%nomega))
    2435              : 
    2436          492 :  iomegap=0
    2437          492 :  do iomega=1,Ep%nomega
    2438          492 :    if( AIMAG(Ep%omega(iomega)) < 1.0e-4_dp ) then
    2439          480 :      iomegap=iomegap+1
    2440          480 :      iomega_re(iomegap)=iomega
    2441          480 :      omega_re(iomegap)=REAL(Ep%omega(iomega),dp)
    2442              :    endif
    2443              :  enddo
    2444              : 
    2445              :  ! Loop over all the q-points in the full Brillouin zone and select only the
    2446              :  ! ones that corresponds to the correct q-point in the irreducible wedge we are
    2447              :  ! currently treating (index iqibz)
    2448          396 :  do iq_bz=1,Qmesh%nbz
    2449              : 
    2450              :    ! Perform the check and obtain the symmetry information
    2451          384 :    call qmesh%get_BZ_item(iq_bz,qbz,iq_ibz,isym_q,itim_q)
    2452          384 :    if( iqibz /= iq_ibz ) cycle
    2453              : 
    2454              :    ! Apply the symmetry operation to the diagonal of epsm1
    2455         2624 :    do iomega=1,nomega_re
    2456        41024 :      do ig=1,Ep%npwe
    2457        40960 :        im_epsm1_diag_qbz(Gsph_epsG0%rottb(ig,itim_q,isym_q),iomega)= AIMAG( epsm1(ig,ig,iomega_re(iomega)) )
    2458              :      enddo
    2459              :    enddo
    2460              :    ! Apply the symmetry operation to the Coulomb interaction
    2461         1024 :    do ig=1,Ep%npwe
    2462         1024 :      vcoul(Gsph_epsG0%rottb(ig,itim_q,isym_q))=Vcp%vc_sqrt(ig,iqibz)**2
    2463              :    enddo
    2464              : 
    2465              :    ! Sum over G vectors
    2466         1036 :    do ig=1,Ep%npwe
    2467              :      !
    2468              :      ! Loop over velocities
    2469        39744 :      do ipvel=1,npvel
    2470              : 
    2471       153600 :        qpg_red(:) = qbz(:) + Gsph_epsG0%gvec(:,ig)
    2472              :        ! Transform q + G from reduced to cartesian with the symmetry operation
    2473              :        qpgcart(:) = two_pi * Cryst%gprimd(:,1) * qpg_red(1) &
    2474              :                   + two_pi * Cryst%gprimd(:,2) * qpg_red(2) &
    2475       153600 :                   + two_pi * Cryst%gprimd(:,3) * qpg_red(3)
    2476              : 
    2477              :        ! omega_p = ( q + G ) . v
    2478       153600 :        omega_p =  DOT_PRODUCT( qpgcart(:) , pvel(:,ipvel) )
    2479              : 
    2480              :        ! Check that the calculated frequency omega_p is within the omega
    2481              :        ! range of epsm1 and thus that the interpolation will go fine
    2482        38400 :        if ( ABS(omega_p) > omega_re(nomega_re) ) then
    2483            0 :          write(msg,'(a,e16.4,2a,e16.4)') ' freqremax is currently ',omega_re(nomega_re),ch10,&
    2484            0 :                                         ' increase it to at least ',omega_p
    2485            0 :          ABI_WARNING(msg)
    2486              :        endif
    2487              : 
    2488              :        ! Perform the spline interpolation to obtain epsm1 at the desired omega = omega_p
    2489      1612800 :        tmp_data = im_epsm1_diag_qbz(ig,:)
    2490              : 
    2491        38400 :        call spline( omega_re, tmp_data, nomega_re, 1.0e+32_dp, 1.0e+32_dp, ypp_i)
    2492        76800 :        call splint( nomega_re, omega_re, tmp_data, ypp_i, 1, (/ ABS(omega_p) /),  im_epsm1_int )
    2493              : 
    2494              :        ! Apply the odd parity of Im epsm1 in  omega to recover the causal response function
    2495        38400 :        if (omega_p<zero) im_epsm1_int(1)=-im_epsm1_int(1)
    2496              : 
    2497              :        ! Calculate 4 * pi / |q+G|**2 * omega_p * Im{ epsm1_GG(q,omega_p) }
    2498        38400 :        im_epsm1_int(1) = omega_p * vcoul(ig) * im_epsm1_int(1)
    2499              : 
    2500              :        ! Accumulate the final result without the prefactor
    2501              :        ! (It will be included at the very end)
    2502        39360 :        rspower(ipvel) = rspower(ipvel) + im_epsm1_int(1)
    2503              : 
    2504              :      end do ! end of velocity loop
    2505              :    end do ! end G-loop
    2506              : 
    2507              :  enddo ! end of q loop in the full BZ
    2508              : 
    2509              :  ! If it is the last q, write down the result in the main output file and in a
    2510              :  ! separate file _RSP (for Random Stopping Power)
    2511           12 :  if (iqibz == Qmesh%nibz ) then
    2512              : 
    2513              :    ! Multiply by the prefactors
    2514              :    ! Note that this expression differs from Eq. (3.11) in Campillo PRB 58, 10307 (1998) [[cite:Campillo1998]].
    2515              :    ! A factor one half is missing in the paper.
    2516           82 :    rspower(:) = - zp**2 / ( Cryst%ucvol * Qmesh%nbz * pvel_norm(:) ) * rspower(:)
    2517              : 
    2518            2 :    write(msg,'(2a)')         ch10,' ==== Random stopping power along Cartesian direction  === '
    2519            2 :    call wrtout(units, msg)
    2520            2 :    write(msg,'(a,3(f12.4,2x),a)') ' ====  ',pvelmax(:),'===='
    2521            2 :    call wrtout(units, msg)
    2522            2 :    write(msg,'(a)')               '#  |v| (a.u.) , RSP (a.u.) '
    2523            2 :    call wrtout(units, msg)
    2524           82 :    do ipvel=1,npvel
    2525           80 :      write(msg,'(f16.8,4x,f16.8)') pvel_norm(ipvel),rspower(ipvel)
    2526           82 :      call wrtout(units, msg)
    2527              :    enddo
    2528            2 :    write(msg,'(2a)')              ' ========================================================= ',ch10
    2529            2 :    call wrtout(units, msg)
    2530              : 
    2531            2 :    fname=TRIM(Dtfil%filnam_ds(4))//'_RSP'
    2532            2 :    if (open_file(fname,msg,newunit=unt_rsp,status='unknown',form='formatted') /= 0) then
    2533            0 :      ABI_ERROR(msg)
    2534              :    end if
    2535              : 
    2536            2 :    write(msg,'(a)')               '# ==== Random stopping power along Cartesian direction  === '
    2537            2 :    call wrtout(unt_rsp, msg)
    2538            2 :    write(msg,'(a,3(f12.4,2x))')   '# ====  ',pvelmax(:)
    2539            2 :    call wrtout(unt_rsp, msg)
    2540            2 :    write(msg,'(a)')               '#  |v| (a.u.) , RSP (a.u.) '
    2541            2 :    call wrtout(unt_rsp, msg)
    2542           82 :    do ipvel=1,npvel
    2543           80 :      write(msg,'(f16.8,4x,f16.8)') pvel_norm(ipvel),rspower(ipvel)
    2544           82 :      call wrtout(unt_rsp,msg)
    2545              :    enddo
    2546            2 :    close(unt_rsp)
    2547              :  end if
    2548              : 
    2549           12 :  ABI_FREE(omega_re)
    2550           12 :  ABI_FREE(iomega_re)
    2551           12 :  ABI_FREE(im_epsm1_diag_qbz)
    2552           12 :  ABI_FREE(tmp_data)
    2553              : 
    2554           12 : end subroutine random_stopping_power
    2555              : !!***
    2556              : 
    2557              : !!****f* m_screening_driver/calc_rpa_functional
    2558              : !! NAME
    2559              : !! calc_rpa_functional
    2560              : !!
    2561              : !! FUNCTION
    2562              : !!  Routine used to calculate the Galitskii-Migdal and RPA approximations to the correlation energy
    2563              : !!  from the irreducible polarizability.
    2564              : !!
    2565              : !! INPUTS
    2566              : !!  iq=index of the q-point in the array Qmesh%ibz where epsilon^-1 has to be calculated
    2567              : !!  Ep<em1params_t>=Structure with parameters and dimensions related to the inverse dielectric matrix.
    2568              : !!  Pvc<vcoul_t>=Structure gathering data on the Coulombian interaction
    2569              : !!  Qmesh<kmesh_t>=Data type with information on the q-sampling
    2570              : !!  Dtfil<Datafiles_type)>=variables related to files
    2571              : !!  comm=MPI communicator.
    2572              : !!
    2573              : !! OUTPUT
    2574              : !!
    2575              : !! SOURCE
    2576              : 
    2577           18 : subroutine calc_rpa_functional(gwrpacorr,gwgmcorr,iqcalc,iq,Ep,Pvc,Qmesh,Dtfil,gmet,chi0,comm,ec_rpa,ec_gm)
    2578              : 
    2579              :  use m_hide_lapack, only : xginv, xheev
    2580              : 
    2581              : !Arguments ------------------------------------
    2582              : !scalars
    2583              :  integer,intent(in) :: iqcalc,iq,gwrpacorr,gwgmcorr,comm
    2584              :  real(dp),intent(inout) :: ec_gm
    2585              :  type(kmesh_t),intent(in) :: Qmesh
    2586              :  type(vcoul_t),intent(in) :: Pvc
    2587              :  type(Datafiles_type),intent(in) :: Dtfil
    2588              :  type(em1params_t),intent(in) :: Ep
    2589              : !arrays
    2590              :  real(dp),intent(in) :: gmet(3,3)
    2591              :  real(dp),intent(inout) :: ec_rpa(gwrpacorr)
    2592              :  complex(gwp),intent(inout) :: chi0(Ep%npwe,Ep%npwe,Ep%nomega)
    2593              : 
    2594              : !Local variables-------------------------------
    2595              : !scalars
    2596              :  integer,parameter :: master = 0
    2597              :  integer :: ig1,ig2,ilambda,io,rank,nprocs,unt,ierr, units(2)
    2598              :  real(dp) :: ecorr,ecorr_gm,lambda
    2599              :  logical :: q_is_gamma
    2600              :  character(len=500) :: msg
    2601              : !arrays
    2602           18 :  real(dp),allocatable :: z(:),zl(:),zlw(:),zw(:)
    2603           18 :  complex(gwp),allocatable :: chi0_diag(:),chitmp(:,:),chi0_diag_gm(:),chitmp_gm(:,:)
    2604           18 :  real(gwp),allocatable :: eig(:)
    2605              : ! *************************************************************************
    2606              : 
    2607           54 :  units = [std_out, ab_out]
    2608              : 
    2609              :  ! initialize MPI data
    2610           18 :  rank   = xmpi_comm_rank(comm)
    2611           18 :  nprocs = xmpi_comm_size(comm)
    2612              : 
    2613           18 :  ABI_CHECK(ep%iw_mesh_type == "gauss_legendre", "only gauss legendre mesh is supported")
    2614              : 
    2615              :  !if (rank==master) then ! presently only master has chi0 in screening
    2616              : 
    2617              :  ! vc_sqrt contains vc^{1/2}(q,G), complex-valued to allow for a possible cutoff
    2618           18 :  q_is_gamma = normv(Qmesh%ibz(:,iq),gmet,'G')<GW_TOLQ0
    2619              : 
    2620              :  ! Calculate Gauss-Legendre quadrature knots and weights for the omega integration
    2621           54 :  ABI_MALLOC(zw, (Ep%nomegaei))
    2622           36 :  ABI_MALLOC(z, (Ep%nomegaei))
    2623           18 :  call coeffs_gausslegint(zero, one, z, zw, Ep%nomegaei)
    2624              : 
    2625              :  ! Calculate Gauss-Legendre quadrature knots and weights for the lambda integration
    2626           54 :  ABI_MALLOC(zlw, (gwrpacorr))
    2627           36 :  ABI_MALLOC(zl, (gwrpacorr))
    2628           18 :  call coeffs_gausslegint(zero,one,zl,zlw,gwrpacorr)
    2629              : 
    2630           54 :  ABI_MALLOC(chi0_diag,(Ep%npwe))
    2631           72 :  ABI_MALLOC_OR_DIE(chitmp,(Ep%npwe,Ep%npwe), ierr)
    2632           18 :  if(gwgmcorr==1) then
    2633           12 :    ABI_MALLOC(chi0_diag_gm,(Ep%npwe))
    2634           18 :    ABI_MALLOC_OR_DIE(chitmp_gm,(Ep%npwe,Ep%npwe), ierr)
    2635              :  end if
    2636              : 
    2637          810 :  do io=2,Ep%nomega
    2638              :    !if (q_is_gamma) then
    2639              :    !  call wrtout(units, "RPA: Ignoring q==0"); cycle
    2640              :    !end if
    2641              : 
    2642          810 :    if(gwrpacorr==1) then ! exact integration over the coupling constant
    2643              : 
    2644          774 :      if(modulo(io-2,nprocs)/=rank) cycle ! distributing the workload
    2645              : 
    2646        18972 :      do ig2=1,Ep%npwe
    2647      1194498 :        do ig1=1,Ep%npwe
    2648      1193724 :          chitmp(ig1,ig2) = Pvc%vc_sqrt(ig1,iq) * Pvc%vc_sqrt(ig2,iq) * chi0(ig1,ig2,io)
    2649              :        end do !ig1
    2650              :      end do !ig2
    2651              : 
    2652         2322 :      ABI_MALLOC(eig,(Ep%npwe))
    2653          774 :      call xheev('N','U',Ep%npwe,chitmp,eig)
    2654              : 
    2655        18972 :      do ig1=1,Ep%npwe
    2656              :        ec_rpa(:) = ec_rpa(:) &
    2657              : &         - zw(io-1) / ( z(io-1) * z(io-1) ) &
    2658        36396 : &              * Qmesh%wt(iq) * (-log( 1.0_dp-eig(ig1) )  - eig(ig1) ) / (2.0_dp * pi )
    2659              :        ec_gm = ec_gm &
    2660              : &         - zw(io-1) / ( z(io-1) * z(io-1) ) &
    2661        18972 : &              * Qmesh%wt(iq) * ( eig(ig1) / ( 1.0_dp-eig(ig1) ) - eig(ig1) ) / (2.0_dp * pi )
    2662              :      end do
    2663          774 :      ABI_FREE(eig)
    2664              : 
    2665              :    else ! numerical integration over the coupling constant
    2666              : 
    2667              :      !if(modulo( (ilambda-1)+gwrpacorr*(io-2),nprocs)/=rank) cycle ! distributing the workload
    2668              : 
    2669          162 :      do ilambda=1,gwrpacorr
    2670          144 :        if(modulo( (ilambda-1)+gwrpacorr*(io-2),nprocs)/=rank) cycle ! distributing the workload
    2671          144 :        lambda=zl(ilambda)
    2672        19872 :        do ig1=1,Ep%npwe
    2673        19872 :          chi0_diag(ig1) = Pvc%vc_sqrt(ig1,iq)**2 * chi0(ig1,ig1,io)
    2674              :        end do
    2675              : 
    2676          144 :        if(ilambda==1 .and. gwgmcorr==1) then     ! Copy v^1/2*Chi0*v^1/2 for Galitskii-Migdal
    2677            0 :          chi0_diag_gm(:) = chi0_diag(:)
    2678              :        end if
    2679              : 
    2680        19872 :        do ig2=1,Ep%npwe
    2681      2722464 :          do ig1=1,Ep%npwe
    2682      2702736 :            chitmp(ig1,ig2) = - lambda * Pvc%vc_sqrt(ig1,iq) * Pvc%vc_sqrt(ig1,iq) * chi0(ig1,ig2,io)
    2683              : 
    2684      2722464 :            if(ilambda==1 .and. gwgmcorr==1) then ! Use lambda=1 for Galitskii-Migdal
    2685            0 :              chitmp_gm(ig1,ig2) = - Pvc%vc_sqrt(ig1,iq) * Pvc%vc_sqrt(ig1,iq) * chi0(ig1,ig2,io)
    2686              :            end if
    2687              : 
    2688              :          end do !ig1
    2689        19728 :          chitmp(ig2,ig2) = chitmp(ig2,ig2) + 1.0_dp
    2690              : 
    2691        19872 :          if(ilambda==1 .and. gwgmcorr==1) then   ! Prepare (1-v^1/2*Chi0*v^1/2) for Galitskii-Migdal
    2692            0 :            chitmp_gm(ig2,ig2) = chitmp_gm(ig2,ig2) + 1.0_dp
    2693              :          end if
    2694              : 
    2695              :        end do !ig2
    2696          144 :        call xginv(chitmp(:,:),Ep%npwe)
    2697      2722752 :        chitmp(:,:) = matmul( chi0(:,:,io) , chitmp(:,:) )
    2698              : 
    2699          144 :        if(ilambda==1 .and. gwgmcorr==1) then   ! Prepare Chi = [(1-v^1/2*Chi0*v^1/2)]^-1 * Chi0 for Galitskii-Migdal
    2700            0 :          call xginv(chitmp_gm(:,:),Ep%npwe)
    2701            0 :          chitmp_gm(:,:) = matmul( chi0(:,:,io) , chitmp_gm(:,:) )
    2702              :        end if
    2703              : 
    2704        19872 :        do ig1=1,Ep%npwe
    2705        19728 :          chi0_diag(ig1) = Pvc%vc_sqrt(ig1,iq) * Pvc%vc_sqrt(ig1,iq) * chitmp(ig1,ig1) - chi0_diag(ig1)
    2706              : 
    2707        19872 :          if(ilambda==1 .and. gwgmcorr==1) then   ! Prepare v^1/2*Chi*v^1/2 - v^1/2*Chi0*v^1/2 for Galitskii-Migdal
    2708            0 :            chi0_diag_gm(ig1) = Pvc%vc_sqrt(ig1,iq) * Pvc%vc_sqrt(ig1,iq) * chitmp_gm(ig1,ig1) - chi0_diag_gm(ig1)
    2709              :          end if
    2710              : 
    2711              :        end do
    2712              : 
    2713        19890 :        do ig1=1,Ep%npwe
    2714              :          ec_rpa(ilambda) = ec_rpa(ilambda) &
    2715        19728 : &           - zw(io-1) / ( z(io-1) * z(io-1) ) * Qmesh%wt(iq) * real(  chi0_diag(ig1) ) / (2.0_dp * pi )
    2716              : 
    2717        19872 :          if(ilambda==1 .and. gwgmcorr==1) then   ! Integrate [v*Chi-v*Chi0](iw) dw for Galitskii-Migdal
    2718              :            ec_gm = ec_gm &
    2719            0 : &           - zw(io-1) / ( z(io-1) * z(io-1) ) * Qmesh%wt(iq) * real(  chi0_diag_gm(ig1) ) / (2.0_dp * pi )
    2720              :          end if
    2721              : 
    2722              :        end do
    2723              : 
    2724              :      end do ! ilambda
    2725              : 
    2726              :    end if ! exact or numerical integration over the coupling constant
    2727              : 
    2728              :  end do ! io
    2729              : 
    2730              : 
    2731              :  ! Output the correlation energy when the last q-point to be calculated is reached
    2732              :  ! This would allow for a manual parallelization over q-points
    2733           18 :  if(iqcalc==Ep%nqcalc) then
    2734              : 
    2735            5 :    call xmpi_sum_master(ec_rpa,master,comm,ierr)
    2736            5 :    call xmpi_sum_master(ec_gm,master,comm,ierr)
    2737              : 
    2738            5 :    if(rank==master) then
    2739           17 :      ecorr = sum( zlw(:)*ec_rpa(:) )
    2740            5 :      ecorr_gm = ec_gm
    2741            5 :      if (open_file(dtfil%fnameabo_rpa, msg, newunit=unt) /=0) then
    2742            0 :        ABI_ERROR(msg)
    2743              :      end if
    2744            5 :      write(unt,'(a,(2x,f14.8))') '#RPA',ecorr
    2745            5 :      write(msg,'(2a,(2x,f14.8))') ch10,' RPA energy [Ha] :',ecorr
    2746            5 :      call wrtout(units, msg)
    2747            5 :      if(gwrpacorr>1) then
    2748            9 :        do ilambda=1,gwrpacorr
    2749            8 :          write(unt,'(i6,2x,f10.6,2x,e13.6)') ilambda,zl(ilambda),ec_rpa(ilambda)
    2750            8 :          write(msg,'(i6,2x,f10.6,2x,e13.6)') ilambda,zl(ilambda),ec_rpa(ilambda)
    2751            9 :          call wrtout(units, msg)
    2752              :        end do
    2753              :      end if
    2754            5 :      if(gwgmcorr==1) then ! Only exact integration over the coupling constant
    2755            1 :        write(unt,'(a,(2x,f14.8))') '#GM',ecorr_gm
    2756            1 :        write(msg,'(2a,(2x,f14.8))') ch10,' Galitskii-Migdal energy [Ha] :',ecorr_gm
    2757            1 :        call wrtout(units, msg)
    2758            1 :        write(unt,'(a1)') ' '
    2759            1 :        write(msg,'(a1)') ' '
    2760            1 :        call wrtout(units, msg)
    2761              :      end if
    2762            5 :      close(unt)
    2763              :    end if
    2764              : 
    2765              :  end if
    2766              : 
    2767           18 :  if(gwgmcorr==1) then
    2768            6 :    ABI_FREE(chitmp_gm)
    2769            6 :    ABI_FREE(chi0_diag_gm)
    2770              :  end if
    2771           18 :  ABI_FREE(chi0_diag)
    2772           18 :  ABI_FREE(chitmp)
    2773           18 :  ABI_FREE(zl)
    2774           18 :  ABI_FREE(zlw)
    2775           18 :  ABI_FREE(z)
    2776           18 :  ABI_FREE(zw)
    2777              : 
    2778           18 : end subroutine calc_rpa_functional
    2779              : !!***
    2780              : 
    2781         6936 : end module m_screening_driver
    2782              : !!***
        

Generated by: LCOV version 2.3-1