LCOV - code coverage report
Current view: top level - src/78_eph - m_gwpt.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.9 % 953 819
Test Date: 2026-11-08 08:00:28 Functions: 100.0 % 3 3
Branches: 47.8 % 3915 1873

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_gwpt
       2                 :             : !! NAME
       3                 :             : !!  m_gwpt
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Compute electron-phonon matrix elements within the GWPT formalism.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2008-2026 ABINIT group (MG)
      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_gwpt
      23                 :             : 
      24                 :             :  use, intrinsic :: iso_c_binding
      25                 :             :  use defs_basis
      26                 :             :  use m_abicore
      27                 :             :  USE_MPI
      28                 :             :  use m_xmpi
      29                 :             :  use m_mpinfo
      30                 :             :  use m_errors
      31                 :             :  use m_clib
      32                 :             :  use m_hide_blas
      33                 :             :  use m_copy
      34                 :             :  use m_fft
      35                 :             :  use m_hamiltonian
      36                 :             :  use m_pawcprj
      37                 :             :  use m_sort
      38                 :             :  use m_sigtk
      39                 :             :  use m_ephtk
      40                 :             :  use netcdf
      41                 :             :  use m_nctk
      42                 :             :  use m_mkffnl
      43                 :             :  use m_xcdata
      44                 :             : 
      45                 :             :  use m_gwdefs,         only : czero_gw
      46                 :             :  use defs_abitypes,    only : mpi_type
      47                 :             :  use defs_datatypes,   only : pseudopotential_type
      48                 :             :  use m_array,          only : array2_gwpc_t
      49                 :             :  use m_dtfil,          only : datafiles_type
      50                 :             :  use m_dtset,          only : dataset_type
      51                 :             :  use m_gwdefs,         only : GW_Q0_DEFAULT
      52                 :             :  use m_time,           only : cwtime, cwtime_report, timab, sec2str, timab
      53                 :             :  use m_fstrings,       only : itoa, ftoa, sjoin, ktoa, ltoa, strcat
      54                 :             :  use m_numeric_tools,  only : arth, c2r, r2c, get_diag, linfit, iseven, simpson_cplx, print_arr, inrange !, bins_t
      55                 :             :  use m_io_tools,       only : iomode_from_fname
      56                 :             :  use m_fftcore,        only : ngfft_seq, sphereboundary, print_ngfft
      57                 :             :  use m_fft_mesh,       only : setmesh
      58                 :             :  use m_cgtk,           only : cgtk_rotate, cgtk_change_gsphere
      59                 :             :  use m_crystal,        only : crystal_t
      60                 :             :  use m_kpts,           only : kpts_ibz_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map
      61                 :             :  use m_kg,             only : getph, mkkin
      62                 :             :  use m_bz_mesh,        only : isamek, kmesh_t
      63                 :             :  use m_gsphere,        only : gsphere_t
      64                 :             :  use m_getgh1c,        only : getgh1c, rf_transgrid_and_pack
      65                 :             :  use m_ioarr,          only : read_rhor
      66                 :             :  use m_hdr,            only : hdr_type
      67                 :             :  use m_dvdb,           only : dvdb_t
      68                 :             :  use m_ifc,            only : ifc_type
      69                 :             :  use m_wfd,            only : wfd_t
      70                 :             :  use m_pawang,         only : pawang_type
      71                 :             :  use m_pawrad,         only : pawrad_type
      72                 :             :  use m_pawtab,         only : pawtab_type
      73                 :             :  use m_pawrhoij,       only : pawrhoij_type
      74                 :             :  use m_pawfgr,         only : pawfgr_type
      75                 :             :  use m_dfpt_cgwf,      only : stern_t
      76                 :             :  use m_io_screening,   only : hscr_t, get_hscr_qmesh_gsph, read_screening
      77                 :             :  use m_vcoul,          only : vcoul_t
      78                 :             :  use m_gstore,         only : gstore_t, gqk_t, gstore_check_restart, gstore_prepare_mpiio, &
      79                 :             :                                GSTORE_KQ_MISSING, GSTORE_KQ_COMPUTED, GSTORE_GTYPE_GWPT, gstore_symmetrize
      80                 :             :  use m_rhotoxc,        only : rhotoxc
      81                 :             :  use m_drivexc,        only : check_kxc
      82                 :             :  use m_occ,            only : get_fact_spin_tol_empty
      83                 :             :  use m_ebands,         only : ebands_t
      84                 :             :  use m_pstat,          only : pstat_proc
      85                 :             :  use m_screen,         only : em1_symmetrize_op
      86                 :             :  use m_ppmodel,        only : ppmodel_t
      87                 :             :  use m_lgroup,         only : lgroup_t
      88                 :             :  use m_initylmg,       only : initylmg_k
      89                 :             : 
      90                 :             :  implicit none
      91                 :             : 
      92                 :             :  private
      93                 :             : !!***
      94                 :             : 
      95                 :             : #ifdef HAVE_MPI1
      96                 :             :  include 'mpif.h'
      97                 :             : #endif
      98                 :             : 
      99                 :             :  public :: gwpt_run  ! Main entry point to compute GWPT e-ph matrix elements
     100                 :             : 
     101                 :             : !----------------------------------------------------------------------
     102                 :             : 
     103                 :             : contains  !=====================================================
     104                 :             : !!***
     105                 :             : 
     106                 :             : !----------------------------------------------------------------------
     107                 :             : 
     108                 :             : !!****f* m_gwpt/gwpt_run
     109                 :             : !! NAME
     110                 :             : !!  gwpt_run
     111                 :             : !!
     112                 :             : !! FUNCTION
     113                 :             : !!  Compute e-ph matrix elements with the GWPT formalism.
     114                 :             : !!
     115                 :             : !! INPUTS
     116                 :             : !! wfk0_path=String with the path to the GS unperturbed WFK file.
     117                 :             : !! ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
     118                 :             : !! dtset<dataset_type>=All input variables for this dataset.
     119                 :             : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     120                 :             : !! dvdb=Database with the DFPT SCF potentials.
     121                 :             : !! drhovdb=Database with the DFPT SCF densities.
     122                 :             : !! ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
     123                 :             : !! wfk_hdr=Header of the WFK file.
     124                 :             : !! pawfgr <type(pawfgr_type)>=fine grid parameters and related data
     125                 :             : !! pawang<pawang_type)>=PAW angular mesh and related data.
     126                 :             : !! pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
     127                 :             : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
     128                 :             : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
     129                 :             : !! comm=MPI communicator.
     130                 :             : !!
     131                 :             : !! NOTES
     132                 :             : !!
     133                 :             : !!  1) Conventions used for g-spheres and the periodic part of the KS states:
     134                 :             : !!
     135                 :             : !!   _kq   --> k + q
     136                 :             : !!   _kmp  --> k - p
     137                 :             : !!   _kqmp  --> k + q - p
     138                 :             : !!
     139                 :             : !!  2) The routines used to symmetrize wavefunctions and DFPT scattering potentials
     140                 :             : !!     expect in input symmetry tables generated using different conventions.
     141                 :             : !!     For the wavefunctions, we use the symrel convention while for the scattering potentials we use the symrec convention.
     142                 :             : !!     We encode this in the name of the variable using e.g. mapc_qq for the symrec convention (C) and mapl_k convention (L)
     143                 :             : !!
     144                 :             : !!  3) The DFPT routines operate on double-precision wavefunctions stored in arrays with real/imag part e.g. cg(1:2,npw_k)
     145                 :             : !!     while the GW routines operate on complex arrays of kind=gwp where gwp is defined at configure-time.
     146                 :             : !!     The default value of gwp is single-precision.
     147                 :             : !!     We use the following conventions for the buffers used to store the wavefunctions:
     148                 :             : !!
     149                 :             : !!       cg_kq, cr_kq
     150                 :             : !!       cg1_kqmp, cr1_kqmp
     151                 :             : !!
     152                 :             : !! OUTPUT
     153                 :             : !!  GSTORE.nc file.
     154                 :             : !!
     155                 :             : !! TODO
     156                 :             : !! Problems to be addressed:
     157                 :             : !!
     158                 :             : !! 1)
     159                 :             : !! Sigma is usually split into Sigma_c(w) and Sigma_x where Sigma_x is the static Fock operator
     160                 :             : !! evaluated with KS orbitals. The advantage of such partitioning is that Sigma_x = iGv
     161                 :             : !! can be computed by summing over occupied states only. Sigma_x requires more G-vectors to converge
     162                 :             : !! as the bare Coulomb interaction goes as 1/|q+G|^2 that is not integrable in 3D but this "expensive"
     163                 :             : !! operations are needed only inside a sum over bands that is restricted to occupied states.
     164                 :             : !! On the other hand, Sigma_c(w) is way more expensive as we have to sum a large number of empty states
     165                 :             : !! while taking the w-dependence of the screening into account.
     166                 :             : !! Fortunately, all the operations can be restricted to a small G-sphere of kinetic energy ecuteps that can be handled
     167                 :             : !! with a coarser FFT mesh.
     168                 :             : !! Another distinct advantage of such splitting is that one can handle the divergence in v(q,G) for |q+G| --> 0
     169                 :             : !! using well know techniques from GW and the anisotropic behavior of eps-1(q) for q --> 0 in low-dimensional systems.
     170                 :             : !! The disavantage is that one needs to compute the GWPT e-ph matrix in two steps, first Sigma_c and then Sigma_x,
     171                 :             : !! so certain operations such as the k-point mapping, and the computation of the form factors are performed twice
     172                 :             : !! Note, however, that MG believes that Sigma_x is a much better approximation than v_xc when one is interested
     173                 :             : !! in the e-ph matrix elements connecting low-energy states such as band edges to high-energy states.
     174                 :             : !!
     175                 :             : !! 2)
     176                 :             : !! We need to solve the NSCF Sternheimer for q and -q. In principle one can solve the equation only at q
     177                 :             : !! and then use spatial inversion or TR to get the solution at -q but this requires solving the Sternheimer
     178                 :             : !! for all the pp wavevectors in the BZ (or better in the IBZ_{q,k,alpha}. The use of symmetries is rendered complicated
     179                 :             : !! by the parallelism over pp but perhaps one can precompute \Delta psi with all MPI procs and write the results to temporary files.
     180                 :             : !!
     181                 :             : !! 3) Check gstore_brange less than nband
     182                 :             : !!
     183                 :             : !! Debugging options:
     184                 :             : !! useria =  1 # write gvals=gxc to GSTORE.nc
     185                 :             : !! useria =  0 (default) # write gvals=gks-gxc+gsigx+gsigc to GSTORE.nc
     186                 :             : !! useria = -1 # write gvals=gsigx (when userid=0) + gsigc (when useric=0) to GSTORE.nc
     187                 :             : !!
     188                 :             : !! userib = 0 (default) # calculate all k and q
     189                 :             : !! userib = 1 # filter k and q, only calculate k=Lambda, and q=L (for comparesion with finite difference GW)
     190                 :             : !!
     191                 :             : !! userra = 0 (default) # neglect the dG0/de additional term at q=Gamma
     192                 :             : !! userra = 1 # include the additional term at q=Gamma arising from the first-order change of the KS eigenvalues
     193                 :             : !!
     194                 :             : !! userrb = 0 (default) # sum over all n'' terms in chi, i.e. the basis-invariant degenerate-block form -chi_{n'} dWtilde/de
     195                 :             : !! userrb = 1 # debug: sum over only the n'' = n' term in chi, i.e. the non-degenerate form -(d eps_{n'}) dWtilde/de
     196                 :             : !!
     197                 :             : !! useric = 0 (default) # include the correlation part of Sigma
     198                 :             : !! useric = 1 # exclude the correlation part of Sigma
     199                 :             : !!
     200                 :             : !! userid = 0 (default) # include the exchange part of Sigma
     201                 :             : !! userid = 1 # exclude the exchange part of Sigma
     202                 :             : !!
     203                 :             : !! userie =  1 : Use only pp = Gamma
     204                 :             : !! userie =  0 (default): Use all pp of the given p-grid
     205                 :             : !! userie = -1 : Exclude pp = Gamma
     206                 :             : !!
     207                 :             : !! SOURCE
     208                 :             : 
     209                 :           3 : subroutine gwpt_run(wfk0_path, dtfil, ngfft, ngfftf, dtset, cryst, ebands, dvdb, drhodb, ifc, wfk_hdr, &
     210                 :           3 :                     pawfgr, pawang, pawrad, pawtab, psps, mpi_enreg, comm)
     211                 :             : 
     212                 :             : !Arguments ------------------------------------
     213                 :             : !scalars
     214                 :             :  character(len=*),intent(in) :: wfk0_path
     215                 :             :  integer,intent(in) :: comm
     216                 :             :  type(datafiles_type),intent(in) :: dtfil
     217                 :             :  type(dataset_type),intent(inout) :: dtset
     218                 :             :  type(crystal_t),intent(in) :: cryst
     219                 :             :  type(ebands_t),target,intent(in) :: ebands
     220                 :             :  type(dvdb_t),intent(inout) :: dvdb, drhodb
     221                 :             :  type(pawang_type),intent(in) :: pawang
     222                 :             :  type(pseudopotential_type),intent(in) :: psps
     223                 :             :  type(pawfgr_type),intent(in) :: pawfgr
     224                 :             :  type(ifc_type),intent(in) :: ifc
     225                 :             :  type(hdr_type),intent(in) :: wfk_hdr
     226                 :             :  type(mpi_type),intent(inout) :: mpi_enreg
     227                 :             : !arrays
     228                 :             :  integer,intent(in) :: ngfft(18), ngfftf(18)
     229                 :             :  type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
     230                 :             :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
     231                 :             : 
     232                 :             : !Local variables ------------------------------
     233                 :             : !scalars
     234                 :             :  integer,parameter :: LOG_MODQ = 1, LOG_MODK = 4, LOG_MODP = 4, ENOUGH_STERN = 5
     235                 :             :  integer,parameter :: tim_getgh1c1 = 1, berryopt0 = 0, ider0 = 0, idir0 = 0, istwfk1 = 1, cplex1 = 1, pawread0 = 0
     236                 :             :  integer,parameter :: master = 0, ndat1 = 1, with_cplex0 = 0, n3xccc0 = 0, optder0 = 0
     237                 :             :  integer :: band, band_me, nband_me, stern_comm, nkpt, my_rank, nsppol, iq_ibz, iq_bz, my_npert
     238                 :             :  integer :: nb_k, nb_kq, bstart_k, bstop_k, bstart_kq, bstop_kq, matblk, method, enforce_sym
     239                 :             :  integer :: cplex,drho_cplex,nkxc,nk3xc,option,usexcnhat,db_iqpt,natom,natom3,ipc,nspinor,nproc
     240                 :             :  integer :: ib_sum, ii, u1_band !,u1c_ib_k,  jj, iw !ib_kq, band_ks, ib_k, ibsum_kq, u1_master, ip
     241                 :             :  integer :: my_is, spin, idir,ipert, ig, max_npw_xc, min_npw_xc, npw_x, npw_c, nw_nk, nw_mkq
     242                 :             :  integer :: isym_q, trev_q, ip_ibz
     243                 :             :  integer :: ik_ibz, isym_k, trev_k, npw_k, istwf_k, npw_k_ibz, istwf_k_ibz, ik_glob, ik_bz
     244                 :             :  integer :: ikq_ibz, isym_kq, trev_kq, npw_kq, istwf_kq,  npw_kq_ibz, istwf_kq_ibz
     245                 :             :  integer :: ikmp_ibz, isym_kmp, trev_kmp, npw_kmp, istwf_kmp
     246                 :             :  integer :: ikqmp_ibz, isym_kqmp, trev_kqmp, npw_kqmp, istwf_kqmp, npw_kqmp_ibz, istwf_kqmp_ibz, mpw,ierr,nqbz,ncerr !,spad
     247                 :             :  integer :: n1,n2,n3,n4,n5,n6,nspden, mqmem, im_kq, m_kq, in_k, n_k, restart, root_ncid, spin_ncid, usecprj
     248                 :             :  integer :: nfft,nfftf,mgfft,mgfftf,nkpg_k,nkpg_kq,nkpg_kqmp,nkpg_kmp,imyp, cnt, nvloc, iw_nk, iw_mkq, ndone, nmiss, jb_sum
     249                 :             :  integer :: my_ipp, ipp_bz, ipp_ibz, isym_pp, itim_pp, comm_rpt, nqlwl, scr_iomode, stern_qq_ierr, stern_mq_ierr
     250                 :             :  integer :: qptopt, my_iq, my_ik, qbuf_size, iqbuf_cnt, timrev_k, timrev_q
     251                 :             :  real(dp) :: cpu_all, wall_all, gflops_all, cpu_qq, wall_qq, gflops_qq, cpu_kk, wall_kk, gflops_kk, cpu_pp, wall_pp, gflops_pp
     252                 :             :  real(dp) :: drude_plsmf, my_plsmf !, rtmp
     253                 :             :  real(dp) :: en_high, dyn_shift, e_high
     254                 :             :  real(dp) :: fact_spin, theta_mu_minus_e0i, tol_empty, tol_empty_in, e_nk, e_mkq, ebsum_kmp, ebsum_kqmp ! e0i
     255                 :             :  real(dp) :: eta_sum, delta_E, inv_delta_E, wgt_dg0
     256                 :           3 :  real(dp),contiguous, pointer :: qp_ene(:,:,:), qp_occ(:,:,:)
     257                 :             :  real(dp) :: weight_q,bigexc,bigsxc,vxcavg ! ediff, eshift, q0rad, bz_vol
     258                 :             :  logical :: isirr_k, isirr_kq, isirr_kmp, isirr_kqmp, qq_is_gamma, pp_is_gamma, isirr_q, use_dg0
     259                 :             :  logical :: stern_use_cache, need_ftinterp, symmetrize, use_lgk
     260                 :             :  logical :: print_time_qq, print_time_kk, print_time_pp, non_magnetic_xc, need_x_kmp, need_x_kqmp, test_sigma
     261                 :             :  complex(dp) :: ieta !, idelta_sum
     262                 :           3 :  type(wfd_t) :: wfd
     263                 :           3 :  type(gs_hamiltonian_type) :: gs_ham_kqmp, gs_ham_kmp
     264                 :           3 :  type(rf_hamiltonian_type) :: rf_ham_kqmp, rf_ham_kmp
     265   [ +  +  +  +  :         312 :  type(crystal_t) :: pot_cryst, den_cryst
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
     266                 :           6 :  type(hdr_type) :: pot_hdr, den_hdr
     267                 :           3 :  type(stern_t) :: stern_kmp, stern_kqmp
     268   [ +  +  +  +  :          78 :  type(kmesh_t),target :: pp_mesh, kmesh
             +  +  +  + ]
     269                 :             :  type(kmesh_t),pointer :: vc_kmesh
     270                 :           3 :  type(gsphere_t),target :: gsph_x, gsph_c
     271         [ +  + ]:          12 :  type(hscr_t),target :: hscr
     272   [ +  +  +  +  :          66 :  type(vcoul_t) :: vcp
          +  +  +  +  +  
                      + ]
     273         [ +  + ]:          12 :  type(gstore_t),target :: gstore
     274                 :             :  type(gqk_t),pointer :: gqk
     275                 :           3 :  type(lgroup_t) :: lg_myq
     276                 :             :  type(xcdata_type) :: xcdata
     277                 :           3 :  type(ppmodel_t) :: ppm
     278                 :             :  character(len=fnlen) :: screen_filepath, gstore_filepath
     279                 :             :  character(len=5000) :: msg, qq_bz_string, kk_string, qkp_string, pp_string
     280                 :             :  character(len=500) :: init_mode
     281                 :             : !arrays
     282                 :           6 :  integer :: nbsum, my_bsum_start(dtset%nsppol), my_bsum_stop(dtset%nsppol), my_nbsum(dtset%nsppol)
     283                 :             :  integer :: g0_k(3), g0_q(3), g0_kq(3), g0_kmp(3), g0_kqmp(3), units(2), work_ngfft(18), gmax(3)
     284                 :             :  integer :: mapl_k(6), mapl_kq(6), mapl_kqmp(6), mapl_kmp(6), mapc_qq(6), mapc_qq2dvdb(6)
     285                 :           9 :  integer :: my_pp_start_spin(dtset%nsppol), my_pp_stop_spin(dtset%nsppol), my_npp(dtset%nsppol)
     286                 :           3 :  integer(i1b),allocatable :: itreatq_dvdb(:)
     287                 :           6 :  integer,allocatable :: kg_k(:,:), kg_kq(:,:), kg_kmp(:,:), kg_kqmp(:,:), my_pp_inds(:)
     288                 :           3 :  integer,allocatable :: gbound_k(:,:), gbound_kq(:,:), gbound_kmp(:,:), gbound_kqmp(:,:), gbound_c(:,:), gbound_x(:,:)
     289                 :           9 :  integer,allocatable :: nband(:,:), wfd_istwfk(:), qibz2dvdb(:) ! count_bk(:,:),
     290                 :           6 :  integer,allocatable :: iq_buf(:,:), done_qbz_spin(:,:), state_kq(:,:)
     291                 :           3 :  integer(i1b),allocatable :: itreat_qibz(:)
     292                 :           3 :  integer, contiguous, pointer :: kg_c(:,:), kg_x(:,:)
     293                 :             :  !real(dp) :: eig0nk !, cpu, wall, gflops !, cpu_q, wall_q, gflops_q, cpu_all, wall_all, gflops_all
     294                 :             :  complex(gwp) :: ctmp_gwpc, xdot_tmp, dg0_tmp
     295                 :             :  complex(dp) :: ctmp_dp
     296                 :             :  !type(bins_t) :: bins
     297                 :             : !arrays
     298                 :           6 :  real(dp) :: fermie1_idir_ipert(3,cryst%natom), ylmgr_dum(1,1,1), dum_nhat(0), dum_xccc3d(0), tsec(2)
     299                 :             :  real(dp) :: kk(3),kq(3),kk_ibz(3),kq_ibz(3), kqmp(3), kmp(3), pp(3), kmp_ibz(3), kqmp_ibz(3), qq_ibz(3), qq_bz(3)
     300                 :           6 :  real(dp),allocatable :: qlwl(:,:), kpg_k(:,:),kpg_kq(:,:),kpg_kmp(:,:),kpg_kqmp(:,:)
     301                 :           9 :  real(dp),allocatable :: ffnl_kmp(:,:,:,:),ffnl_kqmp(:,:,:,:), kinpw_kqmp(:), kinpw_kmp(:), ph3d_kqmp(:,:,:), ph3d_kmp(:,:,:)
     302                 :           3 :  real(dp),allocatable, target :: vxc1_qq(:,:,:,:)
     303                 :           3 :  real(dp),allocatable :: gxc_atm(:,:,:,:), gks_atm(:,:,:,:), gks_atm2(:,:,:,:), gsig_atm(:,:,:,:)
     304                 :           9 :  real(dp),allocatable :: cg_work(:,:), ug_k(:,:), ug_kq(:,:), ph1d(:,:)
     305                 :           6 :  real(dp),allocatable :: vlocal(:,:,:,:), vlocal1_qq(:,:,:,:,:), v1scf_qq(:,:,:,:), vlocal1_mqq(:,:,:,:,:), v1scf_mq(:,:,:,:)
     306                 :           9 :  real(dp),allocatable :: ylm_kmp(:,:), ylm_kqmp(:,:), vtrial(:,:), work(:,:,:,:), rhor(:,:), vxc(:,:), kxc(:,:)
     307                 :           3 :  real(dp),allocatable :: omegame0i_nk(:), omegame0i_mkq(:), omegas_nk(:), omegas_mkq(:)
     308                 :           3 :  real(dp),allocatable :: my_gbuf(:,:,:,:,:,:), my_gbuf_ks(:,:,:,:,:,:)
     309                 :           9 :  real(dp),allocatable :: cg_kmp(:,:), cg_kqmp(:,:), cg1_kqmp(:,:), cg1_kmp(:,:), full_cg1_kqmp(:,:), full_cg1_kmp(:,:), vxc_nk(:,:)
     310                 :           3 :  complex(dp), contiguous, pointer :: cvxc1_qq_ptr(:,:,:)
     311                 :           6 :  complex(gwp),allocatable :: ur_star_kmp(:), ur_star_kqmp(:), cwork_ur(:), rhotwg_c(:), rhotwg_x(:), vc_sqrt_gx(:)
     312                 :           6 :  complex(gwp),allocatable :: full_ur1_kqmp(:), full_ur1_star_kmp(:), sigcme_nk(:), sigcme_mkq(:), ur_nk(:,:), ur_mkq(:,:)
     313                 :           3 :  complex(gwp),allocatable :: vec_gwc_nk(:,:,:), vec_gwc_mkq(:,:,:), vec_gx_nk(:,:), vec_gx_mkq(:,:)
     314                 :           3 :  complex(gwp),allocatable :: vec_comp_nk(:,:), vec_comp_mkq(:,:)
     315                 :           9 :  complex(gwp),allocatable :: vec_dgwc_nk(:,:,:), chi_ug_kqmp(:), chi_ur_kqmp(:), rhotwg_chi(:)
     316                 :           3 :  complex(gwp),allocatable :: vec_coh_nk(:,:), vec_coh_mkq(:,:), wc0_pbz(:,:)
     317                 :           9 :  complex(gwp),allocatable :: botsq_pbz(:,:), otq_pbz(:,:), dmeig_pbz(:,:), epsm1_ggw(:,:,:)
     318                 :           3 :  complex(gwp),allocatable :: trans_botsq_pbz(:,:), trans_otq_pbz(:,:), trans_dmeig_pbz(:,:), sigx_nk(:,:), sigce0_nk(:,:)
     319                 :           6 :  logical,allocatable :: bks_mask(:,:,:), keep_ur(:,:,:)
     320                 :           3 :  type(pawcprj_type),allocatable :: cwaveprj0(:,:), cwaveprj(:,:)
     321                 :           6 :  type(pawrhoij_type),allocatable :: pot_pawrhoij(:), den_pawrhoij(:)
     322                 :           3 :  type(lgroup_t),allocatable :: lg_myk(:)
     323                 :           3 :  type(array2_gwpc_t),allocatable :: wc0_pibz(:)
     324                 :             : !************************************************************************
     325                 :             : 
     326         [ -  + ]:           3 :  if (psps%usepaw == 1) then
     327                 :           0 :    ABI_ERROR("PAW not implemented")
     328                 :             :    ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/))
     329                 :             :  end if
     330                 :             : 
     331         [ -  + ]:           3 :  ABI_CHECK_IEQ(dtset%nspinor, 1, "GWPT with nspinor 2 not coded")
     332         [ -  + ]:           3 :  ABI_CHECK_IEQ(dtset%nsppol, 1, "GWPT with nsppol 2 not tested")
     333                 :             : 
     334                 :           3 :  test_sigma = .False.
     335                 :             :  !test_sigma = my_rank == 2
     336                 :             : 
     337                 :             :  !dtset%useric = 1 ! exclude the correlation part of Sigma
     338                 :             :  !dtset%userid = 1 ! exclude the exchange part of Sigma
     339                 :             : 
     340                 :           3 :  call cwtime(cpu_all, wall_all, gflops_all, "start")
     341                 :             : 
     342                 :             :  ! Copy important dimensions
     343         [ +  + ]:           9 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm); units = [std_out, ab_out]
     344                 :           3 :  natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands%nsppol; nspinor = ebands%nspinor; nspden = dtset%nspden
     345                 :           3 :  ieta = +j_dpc * dtset%zcut
     346                 :             :  !idelta_sum = +j_dpc * dtset%elph2_imagden
     347                 :           3 :  eta_sum = dtset%elph2_imagden
     348                 :             : 
     349                 :             :  ! Set tolerance used to decide if a band is empty
     350                 :             :  ! and normalization of theta_mu_minus_esum. If nsppol == 2, qp_occ $\in [0,1]$
     351                 :           3 :  tol_empty_in = 0.01
     352                 :           3 :  call get_fact_spin_tol_empty(nsppol, nspinor, tol_empty_in, fact_spin, tol_empty)
     353                 :             : 
     354                 :           3 :  qp_ene => ebands%eig; qp_occ => ebands%occ
     355                 :             : 
     356                 :             :  ! Check if a previous GSTORE.nc file is present to restart the calculation if dtset%eph_restart == 1,
     357                 :             :  ! and use done_qbz_spin mask to cycle the loops below if restart /= 0.
     358         [ +  - ]:           3 :  gstore_filepath = strcat(dtfil%filnam_ds(4), "_GSTORE.nc")
     359                 :             : 
     360                 :             :  !gstore_filepath = dtfil%filgstorein
     361         [ -  + ]:           3 :  call gstore_check_restart(gstore_filepath, dtset, nqbz, done_qbz_spin, restart, comm)
     362                 :             : 
     363         [ +  - ]:           3 :  if (restart == 0) then
     364                 :             :    ! Build new gstore object from dtset input variables.
     365                 :           3 :    call gstore%init(gstore_filepath, dtset, dtfil, wfk_hdr, cryst, ebands, ifc, comm, gtype=GSTORE_GTYPE_GWPT)
     366   [ -  +  -  +  :          12 :    ABI_REMALLOC(done_qbz_spin, (gstore%nqbz, nsppol))
          +  -  -  +  +  
          -  +  -  +  -  
          -  +  -  +  -  
                      + ]
     367   [ +  +  +  + ]:          86 :    done_qbz_spin = 0
     368                 :             :  else
     369                 :             :    ! Init gstore from pre-existent file. gstore_gname and read_dw are not relevant here.
     370                 :             :    call gstore%from_ncpath(gstore_filepath, with_cplex0, dtset, dtfil, cryst, ebands, ifc, &
     371                 :           0 :                            "atom", dtset%gstore_gname, .False., comm)
     372                 :             :  end if
     373                 :             : 
     374         [ -  + ]:           3 :  if (nqbz /= 0) then
     375         [ #  # ]:           0 :    ABI_CHECK_IEQ(nqbz, gstore%nqbz, "nqbz from file differs from gstore%nqbz")
     376                 :             :  else
     377                 :           3 :    nqbz = gstore%nqbz
     378                 :             :  end if
     379                 :             : 
     380                 :             :  ! Open GSTORE.nc file and go to data mode.
     381                 :             :  ! SC: Open with xmpi_comm_self (independent IO) instead of comm, otherwise there will be a deadlock on lemaitre4
     382                 :             :  !NCF_CHECK(nctk_open_modify(root_ncid, gstore%path, xmpi_comm_self))
     383                 :             :  ! Follow-up: Open with comm again. xmpi_comm_self avoided a hang in the open caused by the MPI
     384                 :             :  ! stack of the lemaitre4 compute nodes, which has changed since. The run that hung in June 2026
     385                 :             :  ! (32 procs) no longer hangs (checked on the compute nodes on 2026-10-05).
     386         [ -  + ]:           3 :  NCF_CHECK(nctk_open_modify(root_ncid, gstore%path, comm))
     387         [ -  + ]:           3 :  NCF_CHECK(nctk_set_datamode(root_ncid))
     388                 :             :  ! SC: Load the metadata of all the variables now, with all the procs of comm.
     389                 :           3 :  call gstore_prepare_mpiio(root_ncid, gstore%nsppol)
     390                 :             : 
     391                 :           3 :  call gstore%get_missing_qbz_spin(done_qbz_spin, ndone, nmiss)
     392                 :             :  !call wrtout(units, sjoin("- Number of q-points/spin completed:", itoa(count(done_qbz_spin == 1)))
     393                 :             : 
     394                 :             :  ! TODO: Check restart capabilities. It seems they don't work properly.
     395                 :             :  ! NB: Write phonon data here as we are not guaranteed to have all the IBZ q-points
     396                 :             :  ! inside the loop over my_iq if filtering has been used.
     397                 :             :  ! Make sure internal table with gstore_done_qbz_spin is properly filled.
     398         [ +  - ]:           3 :  if (ndone == 0) then
     399                 :           3 :    call gstore%compute_and_write_ph(root_ncid)
     400                 :             :  else
     401                 :           0 :    call wrtout(units, sjoin("- Restarting GSTORE calculation from file:", gstore%path))
     402                 :           0 :    call wrtout(units, sjoin(" Found: ", itoa(ndone), " (qpt, spin) entries already computed"))
     403                 :             :  end if
     404                 :             : 
     405                 :             :  ! ================
     406                 :             :  ! HANDLE SCREENING
     407                 :             :  ! ================
     408                 :             :  ! Read g-sphere and pp_mesh from SCR file and init gsph_c for the correlated part.
     409                 :           3 :  screen_filepath = dtfil%fnameabi_scr
     410         [ -  + ]:           3 :  ABI_CHECK(dtfil%fnameabi_scr /= ABI_NOFILE, "SCR file must be specified")
     411         [ -  + ]:           3 :  call get_hscr_qmesh_gsph(screen_filepath , dtset, cryst, hscr, pp_mesh, gsph_c, qlwl, comm)
     412                 :           3 :  call hscr%print(units, dtset%prtvol, header="Header of the SCR file")
     413                 :             : 
     414                 :           3 :  nqlwl = size(qlwl, dim=2)
     415         [ -  + ]:           3 :  if (nqlwl == 0) then
     416                 :           0 :    nqlwl=1
     417   [ #  #  #  # ]:           0 :    ABI_MALLOC(qlwl,(3,nqlwl))
     418         [ #  # ]:           0 :    qlwl(:,nqlwl)= GW_Q0_DEFAULT
     419                 :             :    write(msg,'(3a,i0,a,3f9.6)')&
     420                 :           0 :      "The Header of the screening file does not contain the list of q-point for the optical limit ",ch10,&
     421                 :           0 :      "Using nqlwl= ",nqlwl," and qlwl = ",qlwl(:,1)
     422                 :           0 :    ABI_COMMENT(msg)
     423                 :             :  end if
     424                 :             : 
     425                 :             :  ! Init g-sphere for the exchange part from ecutsigx.
     426                 :           3 :  call gsph_c%extend(cryst, dtset%ecutsigx, gsph_x)
     427                 :             : 
     428                 :           3 :  call gsph_c%print(units, dtset%prtvol, header="Header of the correlation g-sphere")
     429                 :           3 :  call gsph_x%print(units, dtset%prtvol, header="Header of the exchange g-sphere")
     430                 :             : 
     431                 :             :  ! TODO:
     432                 :             :  ! Here we sort the pp_mesh by stars so that we can split the pp wavevectors in blocks and therefore
     433                 :             :  ! reduce the number of wavevectors in the IBZ that must be stored in memory.
     434                 :             :  !call pp_mesh%pack_by_stars()
     435                 :             : 
     436                 :             :  ! Distribute the sum over pp wavevectors inside pp_sum_comm using block distribution.
     437   [ +  +  +  + ]:           9 :  my_pp_start_spin = 1; my_pp_stop_spin = 0
     438         [ +  + ]:           6 :  do my_is=1,gstore%my_nspins
     439                 :           3 :    spin = gstore%my_spins(my_is); gqk => gstore%gqk(my_is)
     440         [ -  + ]:           3 :    call xmpi_split_block(pp_mesh%nbz, gqk%pp_sum_comm%value, my_npp(spin), my_pp_inds)
     441         [ +  - ]:           3 :    if (my_npp(spin) > 0) then
     442                 :           3 :      my_pp_start_spin(spin) = my_pp_inds(1); my_pp_stop_spin(spin) = my_pp_inds(my_npp(spin))
     443                 :             :    end if
     444         [ +  - ]:           6 :    ABI_SFREE(my_pp_inds)
     445                 :             :  end do ! my_is
     446                 :             : 
     447                 :             :  ! TODO: Use same FFT mesh as GW code but make sure that all potentials are properly interpolated.
     448                 :             : 
     449                 :             :  ! === Setup of the FFT mesh for the oscillator strengths ===
     450                 :             :  ! * Init gwc_ngfft(7:18) and gwx_ngfft(7:18) with Dtset%ngfft(7:18)
     451                 :             :  ! * Here we redefine gwc_ngfft(1:6) according to the following options:
     452                 :             :  !
     453                 :             :  ! method == 0 --> FFT grid read from fft.in (debugging purpose)
     454                 :             :  ! method == 1 --> Normal FFT mesh
     455                 :             :  ! method == 2 --> Slightly augmented FFT grid to calculate exactly rho_tw_g (see setmesh.F90)
     456                 :             :  ! method == 3 --> Doubled FFT grid, same as the the FFT for the density,
     457                 :             :  !
     458                 :             :  ! enforce_sym == 1 --> Enforce a FFT mesh compatible with all the symmetry operation and FFT library
     459                 :             :  ! enforce_sym == 0 --> Find the smallest FFT grid compatible with the library, do not care about symmetries
     460                 :             :  !
     461                 :             :  !gwc_ngfft(1:18) = dtset%ngfft(1:18)
     462                 :             :  !gwx_ngfft(1:18) = dtset%ngfft(1:18)
     463                 :             : 
     464                 :             :  method = 2
     465                 :           3 :  if (dtset%fftgw == 00 .or. dtset%fftgw == 01) method = 0
     466                 :             :  if (dtset%fftgw == 10 .or. dtset%fftgw == 11) method = 1
     467                 :             :  if (dtset%fftgw == 20 .or. dtset%fftgw == 21) method = 2
     468                 :           3 :  if (dtset%fftgw == 30 .or. dtset%fftgw == 31) method = 3
     469                 :           3 :  enforce_sym = mod(dtset%fftgw, 10)
     470                 :             : 
     471                 :             : #if 0
     472                 :             :  ! FFT mesh for sigma_x.
     473                 :             :  call setmesh(cryst%gmet, Gsph_Max%gvec, gwx_ngfft, Sigp%npwvec, Sigp%npwx, Sigp%npwwfn, &
     474                 :             :               gwx_nfftot, method, Sigp%mG0, cryst, enforce_sym)
     475                 :             : 
     476                 :             :  ! FFT mesh for sigma_c.
     477                 :             :  call setmesh(cryst%gmet, Gsph_Max%gvec, gwc_ngfft, Sigp%npwvec, epsm1%npwe, Sigp%npwwfn,&
     478                 :             :               gwc_nfftot, method, Sigp%mG0, cryst, enforce_sym, unit=dev_null)
     479                 :             : #endif
     480                 :             : 
     481                 :             :  ! Initialize Coulomb term on the IBZ of the pp_mesh. Use largest G-sphere.
     482                 :           3 :  call kmesh%init(cryst, wfk_hdr%nkpt, wfk_hdr%kptns, dtset%kptopt)
     483                 :             : 
     484                 :             :  ! Some required information are not filled up inside kmesh_init
     485                 :             :  ! So doing it here, even though it is not clean.
     486   [ +  +  +  + ]:          39 :  Kmesh%kptrlatt(:,:) =Dtset%kptrlatt(:,:)
     487                 :           3 :  Kmesh%nshift        =Dtset%nshiftk
     488   [ -  +  +  -  :           9 :  ABI_MALLOC(Kmesh%shift,(3,Kmesh%nshift))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     489   [ +  +  +  + ]:          15 :  Kmesh%shift(:,:)    =Dtset%shiftk(:,1:Dtset%nshiftk)
     490                 :             : 
     491                 :             :  ! The treatment of the Coulomb singularity at p --> 0 must be consistent with the BZ sum over the pp_mesh
     492                 :             :  ! (the q-mesh of the SCR file, normalized with 1/pp_mesh%nbz), not with the k-mesh of the WFK file.
     493                 :             :  ! vcoul_init uses Kmesh%nbz for CRYSTAL, Beigi and MINIBZ and, for the auxiliary-function modes (ERF,
     494                 :             :  ! AUXILIARY_FUNCTION, AUX_GB), replaces Qmesh with the k1-k2 mesh if Qmesh%nbz /= Kmesh%nbz.
     495                 :             :  ! The latter is correct in the sigma driver but not here, as the pp_mesh can be coarser than the k-mesh.
     496                 :             :  ! Hence pp_mesh is passed as Kmesh if the two meshes differ.
     497                 :             :  ! The MINIBZ (Monte Carlo) modes also need Kmesh%kptrlatt, which is not available for the pp_mesh read
     498                 :             :  ! from the SCR file: they are allowed only if the two meshes have the same number of points.
     499                 :             :  ! TODO: set pp_mesh%kptrlatt from the q-mesh of the SCR file to support MINIBZ with different meshes.
     500                 :           3 :  vc_kmesh => kmesh
     501         [ -  + ]:           3 :  if (pp_mesh%nbz /= kmesh%nbz) then
     502         [ #  # ]:           0 :    if (any(dtset%gw_icutcoul == [14, 15, 16])) then
     503                 :             :      write(msg, "(3a,2(a,i0),2a)") &
     504                 :           0 :        "The Monte Carlo integration of the Coulomb singularity (gw_icutcoul 14, 15, 16) is not supported", ch10, &
     505                 :           0 :        "if the q-mesh of the SCR file differs from the k-mesh of the WFK file.", &
     506                 :           0 :        " pp_mesh%nbz: ", pp_mesh%nbz, ", kmesh%nbz: ", kmesh%nbz, ch10, &
     507                 :           0 :        "Use another gw_icutcoul (e.g. 6) or a SCR file computed with the same k-mesh."
     508                 :           0 :      ABI_ERROR(msg)
     509                 :             :    end if
     510                 :             :    vc_kmesh => pp_mesh
     511                 :             :  end if
     512                 :             : 
     513                 :           3 :  npw_x = gsph_x%ng; npw_c = gsph_c%ng
     514                 :           3 :  min_npw_xc = min(npw_x, npw_c)
     515                 :           3 :  max_npw_xc = max(npw_x, npw_c)
     516         [ +  - ]:           3 :  if (gsph_x%ng >= gsph_c%ng) then
     517                 :             :    call vcp%init(gsph_x, cryst, pp_mesh, vc_kmesh, dtset%gw_rcut, dtset%gw_icutcoul, dtset%vcutgeo, gsph_x%ng, &
     518                 :           3 :                  nqlwl, qlwl, comm)
     519                 :             :  else
     520                 :             :    call vcp%init(gsph_c, cryst, pp_mesh, vc_kmesh, dtset%gw_rcut, dtset%gw_icutcoul, dtset%vcutgeo, gsph_c%ng, &
     521                 :           0 :                  nqlwl, qlwl, comm)
     522                 :             :  end if
     523         [ -  + ]:           3 :  ABI_FREE(qlwl)
     524                 :             : 
     525         [ +  - ]:           3 :  if (my_rank == master) then
     526                 :           3 :    call kmesh%print(units, header="K-mesh for wavefunctions", prtvol=dtset%prtvol)
     527                 :           3 :    call pp_mesh%print(units, header="P-mesh for Screening", prtvol=dtset%prtvol)
     528                 :           3 :    call gsph_x%print(units, dtset%prtvol, header="G-sphere for exchange")
     529                 :           3 :    call gsph_c%print(units, dtset%prtvol, header="G-sphere for correlation")
     530                 :           3 :    call vcp%print(units, prtvol=dtset%prtvol)
     531                 :             :  end if
     532                 :           3 :  call kmesh%free()
     533                 :             : 
     534         [ -  + ]:           3 :  ABI_CHECK_IGE(npw_x, 1, "npw_x <= 1")
     535         [ -  + ]:           3 :  ABI_CHECK_IGE(npw_c, 1, "npw_c <= 1")
     536         [ -  + ]:           3 :  ABI_CHECK_IGEQ(npw_x, npw_c, "npw_x < npw_c is not supported")
     537                 :             : 
     538                 :             :  ! Initialize the wave function descriptor.
     539                 :             :  ! Each node has all k-points and spins and all the nbsum bands: the Sternheimer solver needs the full set
     540                 :             :  ! of bands in stern%cgq, only the sum over bands is distributed inside bsum_comm (see my_bsum_start below).
     541                 :             :  ! TODO: One can exploit qq, kk and pp parallelism to find the wavevectors in the IBZ
     542                 :             :  ! that will be needed in the loops below and allocate only these wavevectors so that memory scales.
     543                 :             : 
     544   [ +  +  +  + ]:           9 :  nbsum = dtset%mband; my_bsum_start = 1; my_bsum_stop = nbsum
     545                 :             :  ! FIXME: This term is needed in metals.
     546   [ +  +  +  + ]:          27 :  fermie1_idir_ipert = zero
     547                 :             : 
     548                 :           3 :  nkpt = wfk_hdr%nkpt
     549   [ -  +  +  -  :          12 :  ABI_MALLOC(nband, (nkpt, nsppol))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     550   [ -  +  +  -  :          15 :  ABI_MALLOC(bks_mask, (dtset%mband, nkpt, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     551   [ -  +  +  -  :          12 :  ABI_MALLOC(keep_ur, (dtset%mband, nkpt, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
                   -  + ]
     552   [ +  +  +  +  :         493 :  nband = dtset%mband; bks_mask = .False.; keep_ur = .False.
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
     553                 :             : 
     554                 :             :  ! Distribute wavefunctions according to the set of kk, qq and pp wavevectors treated by this MPI proc.
     555                 :             :  ! Also, compute mpw and gmax including the additional pp
     556                 :             :  ! This is the maximum number of PWs for all possible k+q treated.
     557                 :             :  call gstore%fill_bks_mask_pp_mesh(dtset%ecut, dtset%mband, nkpt, nsppol, my_pp_start_spin, my_pp_stop_spin, pp_mesh, &
     558                 :           3 :                                    my_bsum_start, my_bsum_stop, bks_mask, mpw, gmax)
     559                 :             : 
     560                 :             :  ! Distribute the sum over bands inside bsum_comm using block distribution.
     561                 :             :  ! Procs in the same pert_comm have the same bsum rank, hence the same bands (xmpi_sum inside the ib_sum loop).
     562   [ +  +  +  + ]:           9 :  my_bsum_start = 1; my_bsum_stop = 0
     563         [ +  + ]:           6 :  do my_is=1,gstore%my_nspins
     564                 :           3 :    spin = gstore%my_spins(my_is); gqk => gstore%gqk(my_is)
     565                 :           6 :    call xmpi_split_work(nbsum, gqk%bsum_comm%value, my_bsum_start(spin), my_bsum_stop(spin))
     566                 :             :  end do ! my_is
     567         [ +  + ]:           6 :  my_nbsum = my_bsum_stop - my_bsum_start + 1
     568                 :             : 
     569                 :             :  ! Init work_ngfft
     570         [ +  + ]:          12 :  gmax = gmax + 4 ! FIXME: this is to account for umklapp, should also consider Gamma-only and istwfk
     571         [ +  + ]:          12 :  gmax = 2*gmax + 1
     572                 :             :  !gmax = 12*gmax + 1
     573                 :             : 
     574                 :           3 :  call ngfft_seq(work_ngfft, gmax)
     575                 :             :  !print *, "gmax:", gmax
     576                 :             :  !write(std_out,*)"work_ngfft(1:3): ",work_ngfft(1:3)
     577   [ -  +  +  -  :          15 :  ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6)))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     578                 :             : 
     579                 :             :  !if (dtset%userie == 124) then
     580                 :             :  !  ! Debugging section have all states on each MPI rank.
     581                 :             :  !  bks_mask = .True.; call wrtout(std_out, " Storing all bands for debugging purposes.")
     582                 :             :  !end if
     583                 :             : 
     584                 :             :  ! Impose istwfk=1 for all k points. This is also done in respfn (see inkpts)
     585                 :             :  ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
     586   [ -  +  +  -  :           9 :  ABI_MALLOC(wfd_istwfk, (nkpt))
          +  -  +  -  -  
                +  -  + ]
     587         [ +  + ]:          22 :  wfd_istwfk = 1
     588                 :             : 
     589                 :             :  call wfd%init(cryst, pawtab, psps, keep_ur, dtset%mband, nband, nkpt, nsppol, bks_mask,&
     590                 :             :                nspden, nspinor, dtset%ecut, dtset%ecutsm, dtset%dilatmx, wfd_istwfk, ebands%kptns, ngfft,&
     591                 :           3 :                dtset%nloalg, dtset%prtvol, dtset%pawprtvol, comm)
     592                 :             : 
     593         [ -  + ]:           3 :  ABI_FREE(nband)
     594         [ -  + ]:           3 :  ABI_FREE(bks_mask)
     595         [ -  + ]:           3 :  ABI_FREE(keep_ur)
     596         [ -  + ]:           3 :  ABI_FREE(wfd_istwfk)
     597                 :           3 :  call pstat_proc%print(_PSTAT_ARGS_)
     598                 :             : 
     599                 :             :  ! Read wavefunctions.
     600                 :           3 :  call wfd%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
     601                 :             : 
     602                 :             :  ! FFT meshes from input file, not necessarily equal to the ones found in the external files.
     603                 :             :  ! NB: ur arrays are always allocated with nfft and not with product(ngfft(4:6)).
     604         [ +  + ]:          12 :  nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3))
     605   [ +  +  +  + ]:          21 :  nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3))
     606                 :           3 :  n1 = ngfft(1); n2 = ngfft(2); n3 = ngfft(3); n4 = ngfft(4); n5 = ngfft(5); n6 = ngfft(6)
     607                 :             : 
     608         [ +  + ]:           6 :  call print_ngfft([std_out], ngfft, header="FFT mesh")
     609                 :             : 
     610                 :             :  ! Set the FFT mesh
     611                 :           3 :  call wfd%change_ngfft(cryst, psps, ngfft)
     612                 :           3 :  call wfd%print(units, header="Wavefunctions for GWPT calculation.")
     613                 :             : 
     614                 :           3 :  usecprj = dtset%usepaw
     615   [ -  +  +  -  :          12 :  ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj))
          +  -  -  -  +  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
             -  -  -  - ]
     616   [ -  +  +  -  :          12 :  ABI_MALLOC(cwaveprj, (natom, nspinor*usecprj))
          +  -  -  -  +  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
             -  -  -  - ]
     617   [ +  -  -  +  :          12 :  ABI_MALLOC(gbound_k, (2*mgfft+8, 2))
          +  -  +  -  +  
          -  +  -  -  +  
                   -  + ]
     618   [ -  +  +  -  :           6 :  ABI_MALLOC(gbound_kq, (2*mgfft+8, 2))
             -  +  -  + ]
     619   [ -  +  +  -  :           6 :  ABI_MALLOC(gbound_kmp, (2*mgfft+8, 2))
             -  +  -  + ]
     620   [ -  +  +  -  :           6 :  ABI_MALLOC(gbound_kqmp, (2*mgfft+8, 2))
             -  +  -  + ]
     621   [ -  +  +  -  :           6 :  ABI_MALLOC(gbound_c, (2*mgfft+8, 2))
             -  +  -  + ]
     622   [ -  +  +  -  :           6 :  ABI_MALLOC(gbound_x, (2*mgfft+8, 2))
             -  +  -  + ]
     623   [ -  +  +  -  :           9 :  ABI_MALLOC(cg_work, (2, mpw*nspinor))
          +  -  +  -  -  
                +  -  + ]
     624   [ -  +  +  -  :           9 :  ABI_MALLOC(full_ur1_kqmp, (nfft*nspinor))
          +  -  +  -  -  
                +  -  + ]
     625   [ -  +  +  -  :           6 :  ABI_MALLOC(full_ur1_star_kmp, (nfft*nspinor))
             -  +  -  + ]
     626         [ -  + ]:           3 :  if (dtset%userra /= zero) then
     627                 :             :    ! Real-space buffer for the auxiliary state chi_{n'k-p} entering the dG0/de term at q=Gamma (Appendix A).
     628   [ #  #  #  #  :           0 :    ABI_MALLOC(chi_ur_kqmp, (nfft*nspinor))
             #  #  #  # ]
     629                 :           0 :    call wrtout(std_out, " Including the dG0/de term at q=Gamma (Appendix A) with the degenerate-block auxiliary state chi.")
     630                 :             :  end if
     631                 :             : 
     632                 :             :  ! ============================
     633                 :             :  ! Compute v_nk matrix elements
     634                 :             :  ! ============================
     635                 :             :  ! Diagonal elements of velocity operator in cartesian coordinates for all kk in the IBZ.
     636                 :             :  ! Use ndone to understand if velocities have been already compured in a previous run.
     637   [ +  -  +  - ]:           3 :  if (gstore%with_vk /= 0 .and. ndone == 0) then
     638                 :           3 :    call gstore%compute_and_write_vk(mpw, wfd, ebands, psps, pawtab, root_ncid)
     639                 :             :  end if
     640                 :             : 
     641                 :             :  ! Radius of sphere with volume equivalent to the micro zone.
     642                 :             :  !q0rad = two_pi * (three / (four_pi * cryst%ucvol * gstore%nqbz)) ** third
     643                 :             :  !bz_vol = two_pi**3 / cryst%ucvol
     644                 :             : 
     645                 :             :  ! Open the DVDB file with first-order potentials and drhodb with the first-order densities.
     646                 :           3 :  call dvdb%open_read(ngfftf, xmpi_comm_self)
     647                 :           3 :  call drhodb%open_read(ngfftf, xmpi_comm_self)
     648         [ -  + ]:           3 :  ABI_CHECK(dvdb%has_fields("pot1", msg), msg)
     649         [ -  + ]:           3 :  ABI_CHECK(drhodb%has_fields("den1", msg), msg)
     650                 :             : 
     651                 :             :  ! Make sure that dvdb and drhodb have the same q-points.
     652         [ -  + ]:           3 :  ABI_CHECK_IEQ(dvdb%nqpt, drhodb%nqpt, "Different number of q-points in DVDB and DRHODB")
     653                 :           3 :  ierr = 0
     654         [ +  + ]:          22 :  do ii=1,dvdb%nqpt
     655   [ +  +  +  -  :          79 :    if (any(abs(dvdb%qpts(:, ii) - drhodb%qpts(:, ii)) > tol12)) then
                   -  + ]
     656                 :           0 :      ierr = ierr + 1; call wrtout(std_out, sjoin(ktoa(dvdb%qpts(:, ii)), " /= ", ktoa(drhodb%qpts(:, ii))))
     657                 :             :    end if
     658                 :             :  end do
     659         [ -  + ]:           3 :  ABI_CHECK(ierr == 0, "Found different q-points in DVDB and DRHODB. See messages above!")
     660                 :             : 
     661                 :             :  ! Check if the q-points are present in the DVDB
     662                 :             :  ! qmap_symrec gives the mapping gstore%ibz --> dvdb%ibz
     663                 :             :  !call dvdb%need_ftinterp(gstore%nqibz, gstore%qibz, gstore%qptopt, qmap_symrec, need_ftinterp)
     664                 :             :  !ABI_FREE(qmap_symrec)
     665                 :             :  !need_ftinterp = .True.
     666                 :             : 
     667                 :             :  !if (.not. need_ftinterp .and. dtset%eph_need_ftinterp /= 0) then
     668                 :             :  !  ABI_WARNING("Enforcing FT interpolation for q-points even if it's not strictly needed.")
     669                 :             :  !  need_ftinterp = .True.
     670                 :             :  !end if
     671                 :             : 
     672                 :             :  !if (need_ftinterp) then
     673                 :             :  !  call wrtout(units, " Cannot find all q-points in the DVDB --> Activating Fourier interpolation.")
     674                 :             :  !  call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt, 1, dtset%ddb_shiftq, nfftf, ngfftf, xmpi_comm_self)
     675                 :             :  !else
     676                 :             :  !  call wrtout(units, " DVDB file contains all q-points along the path --> Reading DFPT potentials from file.")
     677                 :             :  !end if
     678                 :             : 
     679                 :             :  ! Activate parallelism over perturbations at the level of the DVDB, my_npert is output
     680                 :           3 :  call gstore%set_perts_distrib(cryst, dvdb, my_npert)
     681                 :           3 :  call gstore%set_perts_distrib(cryst, drhodb, my_npert)
     682                 :             :  !print *, "Treating my_npert", my_npert
     683                 :             : 
     684                 :             :  ! This part is taken from dfpt_vtorho
     685                 :             :  !==== Initialize most of the Hamiltonian (and derivative) ====
     686                 :             :  ! 1) Allocate all arrays and initialize quantities that do not depend on k and spin.
     687                 :             :  ! 2) Perform the setup needed for the non-local factors:
     688                 :             :  !
     689                 :             :  ! Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_ham_kqmp.
     690                 :             :  ! PAW: Initialize the overlap coefficients and allocate the Dij coefficients.
     691                 :             : 
     692                 :             :  ! Get one-dimensional structure factor information on the coarse grid.
     693   [ +  -  -  +  :           9 :  ABI_MALLOC(ph1d, (2,3*(2*mgfft+1)*natom))
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     694                 :           3 :  call getph(cryst%atindx, natom, n1, n2, n3, ph1d, cryst%xred)
     695                 :             : 
     696                 :             :  call gs_ham_kqmp%init(psps, pawtab, nspinor, nsppol, nspden, natom, &
     697                 :             :    dtset%typat, cryst%xred, nfft, mgfft, ngfft, cryst%rprimd, dtset%nloalg, &
     698                 :             :    comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab, mpi_spintab=mpi_enreg%my_isppoltab, &
     699                 :           3 :    usecprj=usecprj, ph1d=ph1d, nucdipmom=dtset%nucdipmom, gpu_option=dtset%gpu_option)
     700                 :             : 
     701                 :             :  call gs_ham_kmp%init(psps, pawtab, nspinor, nsppol, nspden, natom, &
     702                 :             :    dtset%typat, cryst%xred, nfft, mgfft, ngfft, cryst%rprimd, dtset%nloalg, &
     703                 :             :    comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab, mpi_spintab=mpi_enreg%my_isppoltab, &
     704                 :           3 :    usecprj=usecprj, ph1d=ph1d, nucdipmom=dtset%nucdipmom, gpu_option=dtset%gpu_option)
     705                 :             : 
     706                 :           3 :  matblk = gs_ham_kmp%matblk
     707                 :             : 
     708                 :             :  ! Allocate workspace arrays.
     709                 :             :  ! vtrial and vlocal are required for Sternheimer (H0). DFPT routines do not need it.
     710                 :             :  ! Note nvloc in vlocal (we will select one/four spin components afterwards)
     711                 :           3 :  nvloc = gs_ham_kqmp%nvloc
     712   [ -  +  +  -  :       14039 :  ABI_CALLOC(vtrial, (nfftf, nspden))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     713   [ -  +  +  -  :       16703 :  ABI_CALLOC(vlocal, (n4, n5, n6, nvloc))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  +  +  +  
             +  +  +  +  
                      + ]
     714                 :             : 
     715                 :             :  ! Read the GS potential (vtrial) from input POT file
     716                 :             :  ! In principle one may store GS vtrial in the DVDB but getpot_filepath is simpler to implement.
     717                 :           3 :  call wrtout(units, sjoin(" Reading KS GS potential for Sternheimer from: ", dtfil%filpotin))
     718                 :             :  call read_rhor(dtfil%filpotin, cplex1, nspden, nfftf, ngfftf, pawread0, mpi_enreg, vtrial, pot_hdr, pot_pawrhoij, comm, &
     719                 :           3 :                 allow_interp=.True., want_varname="vtrial")
     720   [ -  +  -  +  :           3 :  pot_cryst = pot_hdr%get_crystal()
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                   -  + ]
     721         [ -  + ]:           3 :  if (cryst%compare(pot_cryst, header=" Comparing input crystal with POT crystal") /= 0) then
     722                 :           0 :    ABI_ERROR("Crystal structure from WFK and POT do not agree! Check messages above!")
     723                 :             :  end if
     724                 :           3 :  call pot_cryst%free(); call pot_hdr%free()
     725                 :             : 
     726                 :             :  ! Find correspondence IBZ --> set of q-points in DVDB.
     727                 :             :  ! need_ftinterp selects whether DFPT potentials should be read from the DVDB or Fourier-interpolated on the fly.
     728                 :             :  ! Activate FT interpolation automatically if required q-points in the IBZ are not found in the DVDB.
     729                 :             : 
     730                 :             :  ! qibz2dvdb gives the mapping gstore%ibz --> dvdb%ibz
     731                 :             :  ! TODO: Make sure we have the same ibz in rho1%ibz
     732                 :           3 :  need_ftinterp = .False.
     733   [ -  +  +  -  :           9 :  ABI_MALLOC(qibz2dvdb, (gstore%nqibz))
          +  -  +  -  -  
                +  -  + ]
     734         [ -  + ]:           3 :  if (dvdb%find_qpts(gstore%nqibz, gstore%qibz, qibz2dvdb, comm) /= 0) then
     735                 :           0 :    call wrtout(units, " Cannot find eph_ngqpt_fine q-points in DVDB --> Activating Fourier interpolation.")
     736                 :           0 :    need_ftinterp = .True.
     737                 :             :  else
     738                 :           3 :    call wrtout(units, " DVDB file contains all q-points in the IBZ --> Reading DFPT potentials from file.")
     739                 :           3 :    need_ftinterp = .False.
     740                 :             :  end if
     741                 :             :  !need_ftinterp = .True.
     742                 :             : 
     743                 :             :  ! Distribute DFPT potentials (IBZ q-points) inside qpt_comm.
     744                 :             :  ! Note that we distribute IBZ instead of the full BZ or the IBZ_k inside the loop over ikcalc.
     745                 :             :  ! This means that the load won't be equally distributed but memory will scale with qpt_comm%nproc.
     746                 :             :  ! To reduce load imbalance, we sort the qibz points by norm and use cyclic distribution inside qpt_comm
     747                 :             : 
     748                 :             :  ! itreat_qibz(nqibz)
     749                 :             :  ! Table used to distribute potentials over q-points in the IBZ.
     750                 :             :  ! The loop over qpts in the IBZ(k) is MPI distributed inside qpt_comm according to this table.
     751                 :             :  ! 0 if this IBZ point is not treated by this proc.
     752                 :             :  ! 1 if this IBZ is treated.
     753                 :             : 
     754                 :             :  ! TODO: Recheck this part
     755   [ -  +  +  -  :          28 :  ABI_ICALLOC(itreat_qibz, (gstore%nqibz))
          +  -  -  +  -  
                +  +  + ]
     756         [ +  + ]:          22 :  itreat_qibz = 1
     757                 :             :  !call sort_rpts(gstore%nqibz, gstore%qibz, cryst%gmet, iperm)
     758                 :             :  !do ii=1,gstore%nqibz
     759                 :             :  !  iq_ibz = iperm(ii)
     760                 :             :  !  do my_spin=1,gstore%my_nspins
     761                 :             :  !    gqk => gstore%gqk(my_spin)
     762                 :             :  !    if (mod(ii, gqk%qpt_comm%nproc) == gqk%qpt_comm%me) itreat_qibz(iq_ibz) = 1
     763                 :             :  !  end do
     764                 :             :  !end do
     765                 :             :  !ABI_FREE(iperm)
     766                 :             : 
     767   [ +  +  +  - ]:          22 :  call wrtout(std_out, sjoin("P Number of q-points in the IBZ treated by this proc: " ,itoa(count(itreat_qibz == 1))))
     768                 :             : 
     769         [ -  + ]:           3 :  if (need_ftinterp) then
     770                 :             :    ! Use ddb_ngqpt q-mesh to compute the real-space representation of DFPT v1scf_qq potentials to prepare Fourier interpolation.
     771                 :             :    ! R-points are distributed inside comm_rpt
     772                 :             :    ! Note that when R-points are distributed inside qpt_comm we cannot interpolate potentials on-the-fly
     773                 :             :    ! inside the loop over q-points.
     774                 :             :    ! In this case, indeed, the interpolation must be done in gwpt_setup_qloop once we know the q-points contributing
     775                 :             :    ! to the integral and the potentials must be cached.
     776                 :             :    !FIXME: qpt_comm is buggy.
     777                 :             :    !if (gwpt%imag_only) comm_rpt = xmpi_comm_self
     778                 :             :    !comm_rpt = gwpt%bsum_comm%value
     779                 :           0 :    comm_rpt = xmpi_comm_self
     780         [ #  # ]:           0 :    qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt
     781                 :           0 :    call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt)
     782                 :           0 :    call drhodb%ftinterp_setup(dtset%ddb_ngqpt, qptopt, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt)
     783                 :             :  end if
     784                 :             : 
     785         [ +  + ]:           6 :  call dvdb%print([std_out], "DVDB file", dtset%prtvol)
     786         [ +  + ]:           6 :  call drhodb%print([std_out], "DRHODB file", dtset%prtvol)
     787                 :           3 :  call pstat_proc%print(_PSTAT_ARGS_)
     788                 :             : 
     789         [ +  - ]:           3 :  if (.not. need_ftinterp) then
     790                 :             :    ! Need to translate itreat_qibz into itreatq_dvdb.
     791   [ -  +  +  -  :          28 :    ABI_ICALLOC(itreatq_dvdb, (dvdb%nqpt))
          +  -  -  +  -  
                +  +  + ]
     792         [ +  + ]:          22 :    do iq_ibz=1,gstore%nqibz
     793         [ -  + ]:          19 :      if (itreat_qibz(iq_ibz) == 0) cycle
     794                 :          19 :      db_iqpt = qibz2dvdb(iq_ibz)
     795         [ -  + ]:          19 :      ABI_CHECK(db_iqpt /= -1, sjoin("Could not find IBZ q-point:", ktoa(gstore%qibz(:, iq_ibz)), "in the DVDB file."))
     796                 :          22 :      itreatq_dvdb(db_iqpt) = 1
     797                 :             :    end do
     798         [ -  + ]:           3 :    ABI_FREE(itreatq_dvdb)
     799                 :             :  end if
     800                 :             : 
     801         [ -  + ]:           3 :  ABI_FREE(itreat_qibz)
     802         [ -  + ]:           3 :  ABI_FREE(qibz2dvdb)
     803                 :             : 
     804                 :             :  ! Read the GS density needed to compute vxc1_qq.
     805   [ -  +  +  -  :       14039 :  ABI_CALLOC(rhor, (nfftf, nspden))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
     806                 :             :  call read_rhor(dtfil%fildensin, cplex1, nspden, nfftf, ngfftf, pawread0, mpi_enreg, rhor, den_hdr, den_pawrhoij, comm, &
     807                 :           3 :                 allow_interp=.True., want_varname="density")
     808   [ -  +  -  +  :           3 :  den_cryst = den_hdr%get_crystal()
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                   -  + ]
     809         [ -  + ]:           3 :  if (cryst%compare(den_cryst, header=" Comparing input crystal with DEN crystal") /= 0) then
     810                 :           0 :    ABI_ERROR("Crystal structures from WFK and DEN do not agree! Check messages above!")
     811                 :             :  end if
     812                 :           3 :  call den_cryst%free(); call den_hdr%free()
     813                 :             : 
     814                 :             :  ! Initialize plasmon-pole object.
     815                 :           3 :  mqmem = pp_mesh%nibz
     816                 :           3 :  drude_plsmf = sqrt(four_pi * ebands%nelect / cryst%ucvol)
     817         [ -  + ]:           3 :  my_plsmf = drude_plsmf; if (dtset%ppmfrq > tol6) my_plsmf = dtset%ppmfrq
     818                 :           3 :  call ppm%init(mqmem, pp_mesh%nibz, npw_c, dtset%ppmodel, my_plsmf, dtset%gw_invalid_freq)
     819         [ +  - ]:           3 :  if (my_rank == master) call ppm%print(units)
     820                 :             : 
     821                 :             :  ! Completeness corrections for the states above nbsum: extrapolar (gwcomp 1) [[cite:Bruneval2008]] or
     822                 :             :  ! dynamic remainder (gwcomp -2). All the states above nbsum are given a common energy E_high.
     823                 :             :  ! With frozen screening, the closure term does not depend on the wavefunctions and its derivative vanishes:
     824                 :             :  ! only the partial sum over the nbsum states survives, i.e. the PPM term of an empty state at E_high with
     825                 :             :  ! the first-order wavefunctions, with a minus sign. The first-order change of E_high at q = Gamma is neglected.
     826                 :           3 :  en_high = zero; dyn_shift = zero
     827         [ -  + ]:           3 :  if (dtset%gwcomp == 1) then
     828                 :             :    ! Global E_high, as in m_sigc.
     829   [ #  #  #  #  :           0 :    en_high = maxval(qp_ene(nbsum,:,:)) + dtset%gwencomp
          #  #  #  #  #  
                #  #  # ]
     830                 :           0 :    call wrtout(units, sjoin(" Activating extrapolar technique (gwcomp 1) with E_high:", ftoa(en_high*Ha_eV), "[eV]"))
     831                 :             :  end if
     832         [ -  + ]:           3 :  if (dtset%gwcomp == -2) then
     833                 :             :    ! E_high = average of e_{nbsum} at k-p and k+q-p + shift, the same for the +q and -q terms so that the derivative
     834                 :             :    ! of the closure term vanishes. If gwencomp < 0, use 1.7 times the Drude plasma frequency (see m_sigc).
     835         [ #  # ]:           0 :    dyn_shift = dtset%gwencomp; if (dyn_shift < zero) dyn_shift = 1.7_dp * drude_plsmf
     836                 :             :    call wrtout(units, sjoin(" Activating COH dynamic remainder technique (gwcomp -2) with energy shift:", &
     837                 :           0 :                ftoa(dyn_shift*Ha_eV), "[eV]"))
     838                 :             :  end if
     839                 :             : 
     840                 :             :  ! Read symmetrized em1 from file and build ppmodel parameters.
     841                 :             :  ! TODO: MPI-shared memory + compute only my set of pp-vectors in ppm%new_setup
     842                 :           3 :  scr_iomode = iomode_from_fname(screen_filepath)
     843   [ -  +  +  -  :          15 :  ABI_MALLOC(epsm1_ggw, (npw_c, npw_c, hscr%nomega))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     844                 :             : 
     845         [ -  + ]:           3 :  if (dtset%gwcomp == 2) then
     846                 :             :    ! Allocate memory to store static screening in the IBZ and workspace array for the value at pp_bz in the BZ.
     847                 :             :    ! TODO: Store only the ip_ibz needed by this MPI rank to save memory.
     848                 :           0 :    call wrtout(units, " Activating COH remainder technique")
     849   [ #  #  #  #  :           0 :    ABI_MALLOC(wc0_pibz, (pp_mesh%nibz))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     850   [ #  #  #  #  :           0 :    ABI_MALLOC(wc0_pbz, (npw_c, npw_c))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     851                 :             :  end if
     852                 :             : 
     853         [ +  + ]:          22 :  do iq_ibz=1,pp_mesh%nibz
     854                 :             :    call read_screening("inverse_dielectric_function", screen_filepath, &
     855                 :          19 :                        npw_c, 1, hscr%nomega, epsm1_ggw, scr_iomode, comm, iqiA=iq_ibz)
     856                 :             : 
     857                 :          19 :    call ppm%new_setup(iq_ibz, cryst, pp_mesh, npw_c, hscr%nomega, hscr%omega, epsm1_ggw, nfftf, gsph_c%gvec, ngfftf, rhor(:,1))
     858                 :             : 
     859         [ -  + ]:          22 :    if (dtset%gwcomp == 2) then
     860                 :             :      ! Keep static limit of Wc in memory.
     861         [ #  # ]:           0 :      do ii=1,npw_c
     862                 :           0 :        epsm1_ggw(ii,ii,1) = epsm1_ggw(ii,ii,1) - one
     863                 :             :      end do
     864   [ #  #  #  #  :           0 :      ABI_MALLOC(wc0_pibz(iq_ibz)%vals, (npw_c, npw_c))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     865   [ #  #  #  #  :           0 :      wc0_pibz(iq_ibz)%vals = epsm1_ggw(:,:,1)
          #  #  #  #  #  
                #  #  # ]
     866                 :             :    end if
     867                 :             :  end do ! iq_ibz
     868                 :             : 
     869         [ -  + ]:           3 :  ABI_FREE(epsm1_ggw)
     870                 :           3 :  call hscr%free()
     871                 :             : 
     872                 :             :  ! Allocate g-vectors centered on k, k+q, k-p, and k+q-p.
     873   [ -  +  +  -  :           9 :  ABI_MALLOC(kg_k, (3, mpw))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     874   [ -  +  +  -  :           6 :  ABI_MALLOC(kg_kq, (3, mpw))
          -  +  -  +  -  
                      + ]
     875   [ -  +  +  -  :           6 :  ABI_MALLOC(kg_kmp, (3, mpw))
          -  +  -  +  -  
                      + ]
     876   [ -  +  +  -  :           6 :  ABI_MALLOC(kg_kqmp, (3, mpw))
          -  +  -  +  -  
                      + ]
     877                 :             : 
     878                 :             :  ! GS wavefunctions
     879   [ -  +  +  -  :           9 :  ABI_MALLOC(ur_star_kmp, (nfft*nspinor))
          +  -  +  -  -  
                +  -  + ]
     880   [ -  +  +  -  :           6 :  ABI_MALLOC(ur_star_kqmp, (nfft*nspinor))
             -  +  -  + ]
     881   [ -  +  +  -  :           6 :  ABI_MALLOC(cwork_ur, (nfft*nspinor))
             -  +  -  + ]
     882   [ -  +  +  -  :           9 :  ABI_MALLOC(cg_kmp, (2, mpw*nspinor))
          +  -  +  -  -  
                +  -  + ]
     883   [ -  +  +  -  :           6 :  ABI_MALLOC(cg_kqmp, (2, mpw*nspinor))
             -  +  -  + ]
     884                 :             :  ! First order change (full term including the active space).
     885   [ -  +  +  -  :           6 :  ABI_MALLOC(cg1_kqmp, (2, mpw*nspinor))
             -  +  -  + ]
     886   [ -  +  +  -  :           6 :  ABI_MALLOC(cg1_kmp, (2, mpw*nspinor))
             -  +  -  + ]
     887                 :             : 
     888                 :             :  !stern_use_cache = merge(.True., .False., dtset%eph_stern == 1)
     889                 :           3 :  stern_use_cache = .False.
     890                 :             : 
     891   [ +  -  +  + ]:           6 :  if (my_rank == master) call gstore%print([std_out])
     892                 :           3 :  call pstat_proc%print(_PSTAT_ARGS_)
     893                 :             : 
     894                 :             :  ! TODO
     895                 :             :  !if (dtset%gstore_iv1p_comm /= 0) then
     896                 :             :  !  call gstore%compute_and_write_commutator(mpw, gmax, ngfft, ngfftf, dtset, cryst, pawfgr, psps, &
     897                 :             :  !                                           wfd, mpi_enreg, kg_k, ebands, dvdb, gs_ham_kq, root_ncid)
     898                 :             :  !end if
     899                 :             : 
     900                 :             :  ! This parameter defines the size of the q-buffer used to store the g(k, q) e-ph matrix elements
     901                 :             :  ! for all the k-point treated by this MPI rank.
     902                 :             :  ! Increasing the buffer size increases the memory requirements
     903                 :             :  ! but it leads to better performance as the number of IO operations is decreased.
     904                 :             :  ! TODO: Should compute it on the basis of my_nkpt and my_nqpt
     905                 :             :  !
     906                 :             :  ! The q-buffer flush logic has ONLY been validated for qbuf_size == 1.
     907                 :             :  ! dump_my_gbuf() resets iqbuf_cnt and iq_buf, so the flush after the my_iq loop only writes q-points
     908                 :             :  ! that are still in the buffer. With qbuf_size > 1 there is another problem:
     909                 :             :  ! dump_my_gbuf() writes a block of iqbuf_cnt q-slices starting at iq_buf(1,1), i.e. it ASSUMES
     910                 :             :  ! the buffered q are consecutive. A `cycle` at the q-level of the my_iq loop (eph_restart done_qbz_spin, userib)
     911                 :             :  ! breaks that assumption and the slices would be written to the WRONG file offsets => silent data corruption
     912                 :             :  ! in gvals/gvals_ks. The k-filters (gstore_use_lgk, gstore_use_lgq) cycle the my_ik loop only and are not affected.
     913                 :             :  ! m_gstore handles non-contiguous buffers by writing slice by slice: do the same before using qbuf_size > 1.
     914                 :           3 :  qbuf_size = 1
     915                 :             :  !qbuf_size = 16
     916                 :           3 :  call wrtout(std_out, sjoin(" Begin computation of GWPT e-ph matrix elements with qbuf_size:", itoa(qbuf_size)), pre_newlines=1)
     917                 :             : 
     918                 :             :  ! If True, only k-points in the IBZ and q-points in the IBZ_k are computed.
     919                 :             :  ! Matrix elements in full BZs are then reconstructed by symmetry at the end of the run by calling
     920                 :             :  ! gstore_symmetrize.
     921   [ -  +  -  -  :           3 :  symmetrize = (dtset%gstore_kzone == "bz" .and. dtset%gstore_qzone == "bz" .and. dtset%gstore_sym > 0)
                   -  - ]
     922                 :             : 
     923                 :             :  ! Compute kxc needed for vxc1.
     924                 :             :  ! A similar piece of code is used in m_respfn_driver.
     925                 :             :  ! option 2 for xc and kxc (no paramagnetic part if xcdata%nspden=1).
     926                 :             :  ! Note usage of dum_xccc3d to ignore non-linear core correction.
     927         [ +  - ]:           3 :  nkxc = 2*min(dtset%nspden,2)-1; if (dtset%xclevel==2) nkxc = 12*min(dtset%nspden,2)-5
     928                 :           3 :  call xcdata_init(xcdata, dtset=dtset)
     929   [ -  +  -  - ]:           3 :  non_magnetic_xc = (dtset%usepaw==1.and.mod(abs(dtset%usepawu),10)==4)
     930                 :             : 
     931                 :           3 :  call check_kxc(dtset%ixc, dtset%optdriver)
     932   [ -  +  +  -  :          12 :  ABI_MALLOC(kxc, (nfft, nkxc))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     933   [ -  +  +  -  :          12 :  ABI_MALLOC(vxc, (nfft, dtset%nspden))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     934                 :             : 
     935                 :           3 :  nk3xc=1; option=2; usexcnhat=0
     936                 :             :  call rhotoxc(bigexc, bigsxc, kxc, mpi_enreg, nfft, ngfft, &
     937                 :             :               dum_nhat, 0, dum_nhat, 0, nkxc, nk3xc, non_magnetic_xc, n3xccc0, option, rhor, &
     938                 :           3 :               cryst%rprimd, usexcnhat, vxc, vxcavg, dum_xccc3d, xcdata)
     939                 :             : 
     940                 :             :  ! Here we decide if the q-points can be reduced to the IBZ(k)
     941   [ -  +  -  - ]:           3 :  use_lgk = (dtset%gstore_use_lgk /= 0 .or. dtset%gstore_sym == 2)
     942                 :             :  if (use_lgk) then
     943                 :           3 :    call wrtout(units, " Only q-points in the IBZ_k will be computed.")
     944         [ #  # ]:           0 :  else if (dtset%gstore_use_lgq /= 0) then
     945                 :           0 :    call wrtout(units, " Only k-points in the IBZ_q will be computed.")
     946                 :             :  else
     947                 :           0 :    call wrtout(units, " Little group operations won't be used")
     948                 :             :  end if
     949                 :             : 
     950                 :             :  ! ===================================================
     951                 :             :  ! Loop over MPI distributed spins in Sigma (gqk%comm)
     952                 :             :  ! ===================================================
     953                 :           3 :  call pstat_proc%print(_PSTAT_ARGS_)
     954                 :             : 
     955                 :           3 :  stern_qq_ierr = 0; stern_mq_ierr = 0
     956                 :             : 
     957         [ +  + ]:           6 :  do my_is=1,gstore%my_nspins
     958                 :           3 :    spin = gstore%my_spins(my_is); gqk => gstore%gqk(my_is); my_npert = gqk%my_npert
     959                 :             :    ABI_CHECK_IEQ(my_npert, gqk%my_npert, "my_npert")
     960         [ -  + ]:           3 :    ABI_CHECK_IEQ(gqk%bstart_kq, 1, "bstart_qk should be 1")
     961         [ -  + ]:           3 :    ABI_CHECK_IGEQ(nbsum, gqk%bstop_kq, "nband must be greater than the max band in the e-ph matrix elements")
     962                 :             : 
     963         [ -  + ]:           3 :    NCF_CHECK(nf90_inq_ncid(root_ncid, strcat("gqk", "_spin", itoa(spin)), spin_ncid))
     964                 :             :    ! SC: these nctk_prepare_mpiio are not needed anymore: gstore_prepare_mpiio has accessed all the variables after the open,
     965                 :             :    ! and netcdf reads the metadata of a variable only at the first access, so these calls would do nothing.
     966                 :             :    !NCF_CHECK(nctk_prepare_mpiio(root_ncid, "gstore_done_qbz_spin"))
     967                 :             :    !NCF_CHECK(nctk_prepare_mpiio(spin_ncid, "gvals"))
     968                 :             :    !NCF_CHECK(nctk_prepare_mpiio(spin_ncid, "gvals_ks"))
     969                 :             : 
     970                 :             :    ! Note the possibility of specifying different number of states for the incoming and the intermediate states.
     971                 :           3 :    nb_k = gqk%nb_k; bstart_k = gqk%bstart_k; bstop_k = gqk%bstop_k
     972                 :           3 :    nb_kq = gqk%nb_kq; bstart_kq = gqk%bstart_kq; bstop_kq = gqk%bstop_kq
     973                 :             : 
     974   [ -  +  +  -  :           9 :    ABI_MALLOC(iq_buf, (2, qbuf_size))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     975   [ +  +  +  + ]:          12 :    iq_buf = 0
     976   [ -  +  +  -  :          12 :    ABI_MALLOC(state_kq, (gqk%my_nk, qbuf_size))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     977   [ +  +  +  + ]:          11 :    state_kq = GSTORE_KQ_MISSING
     978   [ -  +  +  -  :          15 :    ABI_MALLOC(gsig_atm, (2, nb_kq, nb_k, natom3))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     979   [ -  +  +  -  :          12 :    ABI_MALLOC(gks_atm, (2, nb_kq, nb_k, natom3))
          -  +  +  -  -  
          +  +  -  -  +  
             -  +  -  + ]
     980   [ -  +  +  -  :          12 :    ABI_MALLOC(gks_atm2, (2, nb_kq, nb_k, natom3))
          -  +  +  -  -  
          +  +  -  -  +  
             -  +  -  + ]
     981   [ -  +  +  -  :          12 :    ABI_MALLOC(gxc_atm, (2, nb_kq, nb_k, natom3))
          -  +  +  -  -  
          +  +  -  -  +  
             -  +  -  + ]
     982                 :             : 
     983                 :             :    ! Arrays used to compare gwpt with gw
     984                 :             :    if (test_sigma) then
     985                 :             :      ABI_CALLOC(vxc_nk, (nb_k, gqk%glob_nk))
     986                 :             :      ABI_CALLOC(sigx_nk, (nb_k, gqk%glob_nk))
     987                 :             :      ABI_CALLOC(sigce0_nk, (nb_k, gqk%glob_nk))
     988                 :             :    end if
     989                 :             : 
     990   [ -  +  +  -  :          12 :    ABI_MALLOC(ur_nk,  (nfft*nspinor, bstart_k:bstop_k))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     991   [ -  +  +  -  :          12 :    ABI_MALLOC(ur_mkq, (nfft*nspinor, bstart_kq:bstop_kq))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     992                 :             : 
     993                 :             :    ! Inside the loops, we compute gsig_atm(2, nb_kq, nb_k, natom3)
     994   [ -  +  +  -  :          24 :    ABI_MALLOC(my_gbuf, (gqk%cplex, nb_kq, nb_k, natom3, gqk%my_nk, qbuf_size))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
          -  -  +  +  -  
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     995   [ -  +  +  -  :          24 :    ABI_MALLOC(my_gbuf_ks, (gqk%cplex, nb_kq, nb_k, natom3, gqk%my_nk, qbuf_size))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
          -  -  +  +  -  
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     996                 :             : 
     997                 :             :    ! Allocate memory to deal with frequencies in Sigma(w).
     998                 :             : 
     999                 :           5 :    select case (dtset%gwpt_wmode)
    1000                 :             :    case (1)
    1001                 :             :      ! Prepare list of omegas: first e_nk then e_mkq for all m indices.
    1002                 :             :      ! Note that nw_nk depends on bstart_kq and bstop_kq so nw_nk depends on bands at _kq.
    1003                 :           2 :      nw_nk = 1 + (bstop_kq - bstart_kq + 1)
    1004                 :           2 :      nw_mkq = 1 + (bstop_k - bstart_k + 1)
    1005                 :           2 :      call wrtout(units, " GWPT frequency convolution is evaluated at E_nk and E_mkq$ and the average is taken.")
    1006                 :             :    case (2)
    1007                 :           1 :      nw_nk = 1
    1008                 :           1 :      nw_mkq = (bstop_k - bstart_k + 1)
    1009                 :           1 :      call wrtout(units, " GWPT frequency convolution is evaluated at E_nk.")
    1010                 :             :    case default
    1011      [ +  +  - ]:           3 :      ABI_ERROR(sjoin("Invalid gwpt_wmode:", itoa(dtset%gwpt_wmode)))
    1012                 :             :    end select
    1013                 :             : 
    1014   [ -  +  +  -  :           9 :    ABI_MALLOC(omegame0i_nk, (nw_nk))
          +  -  +  -  -  
                +  -  + ]
    1015   [ -  +  +  -  :           9 :    ABI_MALLOC(omegame0i_mkq, (nw_mkq))
          +  -  +  -  -  
                +  -  + ]
    1016   [ -  +  +  -  :           6 :    ABI_MALLOC(omegas_nk, (nw_nk))
             -  +  -  + ]
    1017   [ -  +  +  -  :           6 :    ABI_MALLOC(omegas_mkq, (nw_mkq))
             -  +  -  + ]
    1018   [ -  +  +  -  :           9 :    ABI_MALLOC(sigcme_nk, (nw_nk))
          +  -  +  -  -  
                +  -  + ]
    1019   [ -  +  +  -  :           9 :    ABI_MALLOC(sigcme_mkq, (nw_mkq))
          +  -  +  -  -  
                +  -  + ]
    1020                 :             : 
    1021                 :             :    ! Correlated part
    1022   [ -  +  +  -  :          15 :    ABI_MALLOC(vec_gwc_nk, (npw_c*nspinor, nw_nk, bstart_k:bstop_k))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1023   [ -  +  +  -  :          15 :    ABI_MALLOC(vec_gwc_mkq, (npw_c*nspinor, nw_mkq, bstart_kq:bstop_kq))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1024         [ -  + ]:           3 :    if (any(dtset%gwcomp == [1, -2])) then
    1025   [ #  #  #  #  :           0 :      ABI_MALLOC(vec_comp_nk, (npw_c*nspinor, nw_nk))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1026   [ #  #  #  #  :           0 :      ABI_MALLOC(vec_comp_mkq, (npw_c*nspinor, nw_mkq))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1027                 :             :    end if
    1028                 :             :    ! Exchange part
    1029   [ -  +  +  -  :          12 :    ABI_MALLOC(vec_gx_nk, (npw_x*nspinor,  bstart_k:bstop_k))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1030   [ -  +  +  -  :          12 :    ABI_MALLOC(vec_gx_mkq, (npw_x*nspinor, bstart_kq:bstop_kq))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1031                 :             : 
    1032         [ -  + ]:           3 :    if (dtset%userra /= zero) then
    1033                 :             :      ! Additional dG0/de term at q=Gamma (Appendix A): dWtilde/de contracted with the n-side oscillators.
    1034   [ #  #  #  #  :           0 :      ABI_MALLOC(vec_dgwc_nk, (npw_c*nspinor, nw_nk, bstart_k:bstop_k))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1035                 :             :    end if
    1036                 :             : 
    1037         [ -  + ]:           3 :    if (dtset%gwcomp == 2) then
    1038   [ #  #  #  #  :           0 :      ABI_MALLOC(vec_coh_nk, (npw_c, bstart_k:bstop_k))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1039   [ #  #  #  #  :           0 :      ABI_MALLOC(vec_coh_mkq, (npw_c, bstart_kq:bstop_kq))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1040                 :             :    end if
    1041                 :             : 
    1042                 :             :    ! Compute the little group of the k-point so that we can compute g(k,q) only for q in the IBZ_k
    1043         [ +  - ]:           3 :    if (use_lgk) then
    1044                 :           3 :      timrev_k = kpts_timrev_from_kptopt(ebands%kptopt)
    1045   [ -  +  +  -  :          14 :      ABI_MALLOC(lg_myk, (gqk%my_nk))
          +  -  +  -  -  
          +  -  +  -  +  
          +  +  +  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
    1046         [ +  + ]:           8 :      do my_ik=1,gqk%my_nk
    1047         [ +  + ]:          20 :        kk = gqk%my_kpts(:, my_ik)
    1048                 :           8 :        call lg_myk(my_ik)%init(cryst, kk, timrev_k, gstore%nqbz, gstore%qbz, gstore%nqibz, gstore%qibz, xmpi_comm_self)
    1049                 :             :      end do
    1050                 :             :    end if
    1051                 :             : 
    1052                 :             :    ! ============================================================
    1053                 :             :    ! Loop over MPI distributed q-points in Sigma_q (gqk%qpt_comm)
    1054                 :             :    ! ============================================================
    1055                 :             :    ! the loop of my_iq can be cycled, so it is good to set iqbuf_cnt to 0 before entering the loop
    1056                 :           3 :    iqbuf_cnt = 0
    1057         [ +  + ]:          83 :    do my_iq=1,gqk%my_nq
    1058                 :          80 :      call gqk%myqpt(my_iq, gstore, weight_q, qq_bz)
    1059                 :             : 
    1060   [ +  +  +  +  :         115 :      if (dtset%userib /= 0 .and. (any(abs(qq_bz - [0.5, 0.0, 0.0]) > tol14))) cycle
             -  +  -  - ]
    1061                 :             : 
    1062         [ +  + ]:         320 :      iq_bz = gqk%my_q2bz(my_iq); qq_is_gamma = sum(qq_bz**2) < tol14; qq_bz_string = ktoa(qq_bz)
    1063   [ +  +  +  - ]:          80 :      use_dg0 = qq_is_gamma .and. dtset%userra /= zero
    1064                 :             : 
    1065                 :             :      ! Handle possible restart.
    1066         [ -  + ]:          80 :      if (done_qbz_spin(iq_bz, spin) == 1) then
    1067                 :           0 :        call wrtout(std_out, sjoin(" iq_bz:", itoa(iq_bz), ", spin: ", itoa(spin), " already computed --> skipping iteration"), do_flush=.True.)
    1068                 :           0 :        cycle
    1069                 :             :      end if
    1070                 :             : 
    1071                 :             :      ! Compute the little group of the q-point so that we can compute g(k,q) only for k in the IBZ_q
    1072         [ -  + ]:          80 :      if (dtset%gstore_use_lgq /= 0) then
    1073                 :           0 :        timrev_q = kpts_timrev_from_kptopt(gstore%qptopt)
    1074   [ #  #  #  #  :           0 :        call lg_myq%init(cryst, qq_bz, timrev_q, gstore%nkbz, gstore%kbz, gstore%nkibz, gstore%kibz, xmpi_comm_self)
          #  #  #  #  #  
                      # ]
    1075                 :             :      end if
    1076                 :             : 
    1077                 :             :      ! Position of this q-point in the q-buffer (set at the q-level so that it is also defined when my_nk == 0).
    1078                 :          80 :      iqbuf_cnt = 1 + mod(my_iq - 1, qbuf_size)
    1079         [ +  + ]:         240 :      iq_buf(:, iqbuf_cnt) = [my_iq, iq_bz]
    1080                 :             : 
    1081                 :             :      ! Note symrec conventions here as needed to symmetrize the DFPT potentials.
    1082                 :          80 :      iq_ibz = gqk%my_q2ibz(1, my_iq) ; isym_q = gqk%my_q2ibz(2, my_iq)
    1083                 :          80 :      trev_q = gqk%my_q2ibz(6, my_iq) ; g0_q = gqk%my_q2ibz(3:5, my_iq)
    1084                 :             :      isirr_q = (isym_q == 1 .and. trev_q == 0 .and. all(g0_q == 0))
    1085                 :             :      !tsign_q = 1; if (trev_q == 1) tsign_q = -1
    1086         [ +  + ]:         320 :      qq_ibz = gstore%qibz(:, iq_ibz)
    1087         [ +  + ]:         560 :      mapc_qq = gqk%my_q2ibz(:, my_iq)
    1088                 :             : 
    1089                 :          80 :      print_time_qq = my_rank == 0 .and. (my_iq <= LOG_MODQ .or. mod(my_iq, LOG_MODQ) == 0)
    1090         [ +  - ]:          80 :      if (print_time_qq) then
    1091                 :          80 :        call cwtime(cpu_qq, wall_qq, gflops_qq, "start")
    1092                 :          80 :        call inds2str(0, sjoin(" Computing g^Sigma(k, q) for qq_bz:", qq_bz_string), my_iq, gqk%my_nq, gqk%glob_nq, msg)
    1093                 :          80 :        call wrtout(std_out, sjoin(msg, ", and spin:", itoa(spin)), pre_newlines=1)
    1094                 :             :        !print *, "iq_ibz:", iq_ibz, "qq_bz:", qq_bz, "qq_ibz:", qq_ibz
    1095                 :             :      end if
    1096                 :             : 
    1097                 :             :      ! ==================================================
    1098                 :             :      ! Get DFPT potentials and densities for this q-point
    1099                 :             :      ! ==================================================
    1100                 :             :      ! After this branch we know `cplex` and we have allocated:
    1101                 :             :      !
    1102                 :             :      !   v1scf_qq(cplex, nfftf, nspden, my_npert))
    1103                 :             :      !   vxc1_qq(cplex, nfft, nspden, my_npert)
    1104                 :             :      !
    1105                 :             :      ! Important: vxc1_qq does not include the contribution due to the model core charge (if any).
    1106                 :             : 
    1107         [ -  + ]:          80 :      if (need_ftinterp) then
    1108                 :             :        ! Use Fourier interpolation to get DFPT potentials and DFPT densities for this qpt.
    1109         [ #  # ]:           0 :        call dvdb%get_ftqbz(qq_bz, cplex, nfftf, ngfftf, v1scf_qq, gqk%pert_comm%value)
    1110                 :             : 
    1111                 :             :        call drhodb%get_vxc1_ftqbz(dtset, cryst, qq_bz, drho_cplex, nfftf, ngfftf, nkxc, kxc, &
    1112         [ #  # ]:           0 :                                   vxc1_qq, non_magnetic_xc, usexcnhat, gqk%pert_comm%value)
    1113                 :             :      else
    1114                 :             :        ! Read and reconstruct the dvscf potentials and the densities for this qq_bz and my_npert perturbations.
    1115                 :          80 :        db_iqpt = dvdb%findq(qq_ibz)
    1116         [ -  + ]:          80 :        ABI_CHECK(db_iqpt /= -1, sjoin("Could not find symmetric of q-point:", ktoa(qq_bz), "in DVDB file."))
    1117                 :             :        ! The first entry in mapc_qq2dvdb gives the index in dvdb%qpts. The other entries in mapc_qq are OK as they refer to symmetries.
    1118                 :          80 :        mapc_qq2dvdb = mapc_qq; mapc_qq2dvdb(1) = db_iqpt
    1119         [ -  + ]:          80 :        call dvdb%readsym_qbz(cryst, qq_bz, mapc_qq2dvdb, cplex, nfftf, ngfftf, v1scf_qq, gqk%pert_comm%value)
    1120                 :             : 
    1121                 :          80 :        db_iqpt = drhodb%findq(qq_ibz)
    1122         [ -  + ]:          80 :        ABI_CHECK(db_iqpt /= -1, sjoin("Could not find symmetric of q-point:", ktoa(qq_bz), "in DRHODB file."))
    1123                 :          80 :        mapc_qq2dvdb = mapc_qq; mapc_qq2dvdb(1) = db_iqpt
    1124                 :             :        call drhodb%read_vxc1_qbz(dtset, cryst, qq_bz, mapc_qq2dvdb, drho_cplex, nfftf, ngfftf, nkxc, kxc, &
    1125         [ -  + ]:          80 :                                  vxc1_qq, non_magnetic_xc, usexcnhat, gqk%pert_comm%value)
    1126                 :             :      end if
    1127                 :             : 
    1128         [ -  + ]:          80 :      ABI_CHECK_IEQ(cplex, drho_cplex, "Different values of cplex for v1 and rho1!")
    1129   [ +  +  +  + ]:         311 :      cvxc1_qq_ptr => null(); if (cplex == 2) call c_f_pointer(c_loc(vxc1_qq), cvxc1_qq_ptr, [nfft, nspden, my_npert])
    1130                 :             : 
    1131                 :             :      ! Allocate vlocal1_qq with correct cplex and nvloc.
    1132   [ -  +  +  -  :         560 :      ABI_MALLOC(vlocal1_qq, (cplex*n4, n5, n6, nvloc, my_npert))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
          -  +  -  +  -  
             -  +  -  + ]
    1133   [ -  +  +  -  :         480 :      ABI_MALLOC(vlocal1_mqq, (cplex*n4, n5, n6, nvloc, my_npert))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
             -  -  +  -  
                      + ]
    1134                 :             : 
    1135                 :             :      ! Build DFPT potential at -qq by taking CC.
    1136   [ +  +  +  +  :    10364596 :      v1scf_mq = v1scf_qq; if (cplex == 2) v1scf_mq(2,:,:,:) = -v1scf_mq(2,:,:,:)
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
    1137                 :             : 
    1138                 :             :      ! =============================================================
    1139                 :             :      ! Loop over k-points in the e-ph matrix elements (gqk%kpt_comm)
    1140                 :             :      ! =============================================================
    1141         [ +  + ]:         176 :      do my_ik=1,gqk%my_nk
    1142         [ +  + ]:         384 :        kk = gqk%my_kpts(:, my_ik); kk_string = ktoa(kk); ik_glob = gqk%my_k2glob(my_ik)
    1143                 :             : 
    1144                 :             :        ! NB: All procs in gqk%pert_comm and gqk%bsum_comm and gqk%pp_sum_comm enter this section.
    1145                 :             :        ! Set entry to zero BEFORE the cycle instructions below, otherwise cycled (filtered)
    1146                 :             :        ! k-points may keep stale data in my_gbuf and write them to disk.
    1147   [ +  +  +  +  :       90912 :        my_gbuf(:,:,:,:, my_ik, iqbuf_cnt) = zero
             +  +  +  + ]
    1148   [ +  +  +  +  :       90912 :        my_gbuf_ks(:,:,:,:, my_ik, iqbuf_cnt) = zero
             +  +  +  + ]
    1149                 :             : 
    1150                 :             :        ! The k-point and the symmetries relating the BZ k-point to the IBZ.
    1151                 :          96 :        ik_ibz = gqk%my_k2ibz(1, my_ik) ; isym_k = gqk%my_k2ibz(2, my_ik)
    1152         [ +  + ]:         384 :        trev_k = gqk%my_k2ibz(6, my_ik); g0_k = gqk%my_k2ibz(3:5,my_ik)
    1153   [ +  +  +  -  :         384 :        isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
             +  -  -  + ]
    1154         [ +  + ]:         672 :        mapl_k = gqk%my_k2ibz(:, my_ik)
    1155                 :             : 
    1156         [ +  + ]:         384 :        kk_ibz = ebands%kptns(:,ik_ibz)
    1157                 :             : 
    1158                 :             :        ! If we are going to reconstruct g(k,q) in the full BZ by symmetry at the end of the run,
    1159                 :             :        ! only k-points in the IBZ need to be computed here.
    1160         [ -  + ]:          96 :        if (symmetrize .and. .not. isirr_k) then
    1161                 :           0 :          state_kq(my_ik, iqbuf_cnt) = GSTORE_KQ_MISSING; cycle
    1162                 :             :        end if
    1163                 :             : 
    1164         [ -  + ]:          96 :        if (dtset%userib /= 0) then
    1165   [ #  #  #  #  :           0 :          if (any(abs(gqk%my_kpts(:, my_ik) - [0.25, 0.0, 0.0]) > tol14) .and. &
          #  #  #  #  #  
                      # ]
    1166                 :             :              any(abs(gqk%my_kpts(:, my_ik) - [-0.25, 0.0, 0.0]) > tol14)) then
    1167                 :           0 :            state_kq(my_ik, iqbuf_cnt) = GSTORE_KQ_MISSING; cycle
    1168                 :             :          end if
    1169                 :             :        end if
    1170                 :             : 
    1171                 :             :        ! Here we skip points if little group tricks are activated.
    1172         [ +  - ]:          96 :        if (use_lgk) then
    1173         [ +  + ]:          96 :          if (lg_myk(my_ik)%findq_ibzk(qq_bz) == -1) then
    1174                 :          65 :            state_kq(my_ik, iqbuf_cnt) = GSTORE_KQ_MISSING; cycle
    1175                 :             :          end if
    1176                 :             :        end if
    1177                 :             : 
    1178         [ -  + ]:          31 :        if (dtset%gstore_use_lgq /= 0) then
    1179         [ #  # ]:           0 :          if (lg_myq%findq_ibzk(kk) == -1) then
    1180                 :           0 :            state_kq(my_ik, iqbuf_cnt) = GSTORE_KQ_MISSING; cycle
    1181                 :             :          end if
    1182                 :             :        end if
    1183                 :             : 
    1184   [ +  +  +  +  :       36805 :        gks_atm = zero
             +  +  +  + ]
    1185   [ +  +  +  +  :       36805 :        gks_atm2 = zero
             +  +  +  + ]
    1186                 :             : 
    1187                 :          31 :        call inds2str(0, sjoin(" Computing g^Sigma(k,q) for kpt:", kk_string), my_ik, gqk%my_nk, gqk%glob_nk, msg)
    1188                 :          31 :        call wrtout(std_out, sjoin(msg, ", for spin:", itoa(spin)), pre_newlines=1)
    1189                 :          31 :        call timab(1940, 1, tsec)
    1190                 :             : 
    1191                 :          31 :        istwf_k_ibz = wfd%istwfk(ik_ibz); npw_k_ibz = wfd%npwarr(ik_ibz)
    1192                 :             : 
    1193   [ +  -  -  +  :          31 :        print_time_kk = my_rank == 0 .and. (my_ik <= LOG_MODK .or. mod(my_ik, LOG_MODK) == 0)
                   -  - ]
    1194                 :          31 :        if (print_time_kk) call cwtime(cpu_kk, wall_kk, gflops_kk, "start")
    1195                 :             : 
    1196                 :             :        ! Get npw_k, kg_k for kk
    1197                 :             :        call wfd%get_gvec_gbound(cryst%gmet, dtset%ecut, kk, ik_ibz, isirr_k, dtset%nloalg, & ! in
    1198         [ -  + ]:          31 :                                 istwf_k, npw_k, kg_k, nkpg_k, kpg_k, gbound_k)               ! out
    1199         [ -  + ]:          31 :        ABI_CHECK_ILEQ(npw_k, mpw, "npw_k > mpw!")
    1200                 :             : 
    1201                 :             :        ! Find k + q in the extended zone and extract symmetry info.
    1202                 :             :        ! Be careful here because there are two umklapp vectors to be considered as:
    1203                 :             :        !
    1204                 :             :        !   k + q = k_bz + g0_bz = IS(k_ibz) + g0_ibz + g0_bz
    1205                 :             :        !
    1206         [ +  + ]:         124 :        kq = kk + qq_bz
    1207                 :             : 
    1208         [ -  + ]:          31 :        if (kpts_map("symrel", ebands%kptopt, cryst, gstore%krank_ibz, 1, kq, mapl_kq) /= 0) then
    1209         [ #  # ]:           0 :          write(msg, '(4a)' )"k-mesh is not closed!",ch10, "k+q could not be generated from a symmetrical one.",trim(ltoa(kq))
    1210                 :           0 :          ABI_ERROR(msg)
    1211                 :             :        end if
    1212         [ +  + ]:         124 :        ikq_ibz = mapl_kq(1); isym_kq = mapl_kq(2); trev_kq = mapl_kq(6); g0_kq = mapl_kq(3:5)
    1213   [ +  +  +  +  :          99 :        isirr_kq = (isym_kq == 1 .and. trev_kq == 0 .and. all(g0_kq == 0))
             +  +  +  + ]
    1214         [ +  + ]:         124 :        kq_ibz = ebands%kptns(:, ikq_ibz)
    1215                 :          31 :        istwf_kq_ibz = wfd%istwfk(ikq_ibz); npw_kq_ibz = wfd%npwarr(ikq_ibz)
    1216                 :             : 
    1217                 :             :        ! Get npw_kq, kg_kq for k+q.
    1218                 :             :        call wfd%get_gvec_gbound(cryst%gmet, dtset%ecut, kq, ikq_ibz, isirr_kq, dtset%nloalg, &  ! in
    1219         [ -  + ]:          31 :                                 istwf_kq, npw_kq, kg_kq, nkpg_kq, kpg_kq, gbound_kq)            ! out
    1220         [ -  + ]:          31 :        ABI_CHECK_ILEQ(npw_kq, mpw, "npw_kq > mpw!")
    1221                 :             : 
    1222   [ -  +  +  -  :      104952 :        ABI_CALLOC(ug_k, (2, npw_k*nspinor))
          +  -  +  -  -  
          +  -  +  +  +  
                   +  + ]
    1223   [ -  +  +  -  :      106581 :        ABI_CALLOC(ug_kq, (2, npw_kq*nspinor))
          +  -  +  -  -  
          +  -  +  +  +  
                   +  + ]
    1224                 :             : 
    1225                 :             :        ! Precompute ur_nk and ur_mkq for all m and n band indices treated.
    1226                 :             :        ! TODO: Can distribute operations inside gqk%pert_comm
    1227                 :             : 
    1228         [ +  + ]:         201 :        do n_k=bstart_k, bstop_k
    1229                 :         170 :          in_k = n_k - bstart_k + 1 !; if (gqk%pert_ppsum_comm%skip(in_k)) cycle ! MPI parallelism inside pert_comm
    1230                 :             :          call wfd%rotate_cg(n_k, ndat1, spin, kk_ibz, npw_k, kg_k, istwf_k, &
    1231                 :         170 :                             cryst, mapl_k, gbound_k, work_ngfft, work, ug_k, urs_kbz=ur_nk(:,n_k))
    1232                 :          31 :          if (test_sigma) vxc_nk(in_k, ik_glob) = dot_product(ur_nk(:,n_k), vxc(:, spin) * ur_nk(:,n_k)) / nfftf
    1233                 :             :        end do
    1234                 :             :        !call xmpi_sum(ur_nk, gqk%pert_ppsum_comm%value, ierr)
    1235                 :             : 
    1236         [ +  + ]:         387 :        do m_kq=bstart_kq, bstop_kq
    1237                 :         356 :          im_kq = m_kq - bstart_kq + 1 !; if (gqk%pert_ppsum_comm%skip(im_kq)) cycle ! MPI parallelism inside pert_comm
    1238                 :             :          call wfd%rotate_cg(m_kq, ndat1, spin, kq_ibz, npw_kq, kg_kq, istwf_kq, &
    1239                 :         387 :                             cryst, mapl_kq, gbound_kq, work_ngfft, work, ug_kq, urs_kbz=ur_mkq(:,m_kq))
    1240                 :             :        end do
    1241                 :             :        !call xmpi_sum(ur_mkq, gqk%pert_ppsum_comm%value, ierr)
    1242                 :             : 
    1243                 :             :        ! ===========================
    1244                 :             :        ! Compute <m,k+q|vxc1_qq|n,k>
    1245                 :             :        ! ===========================
    1246                 :             : 
    1247   [ +  +  +  +  :       36805 :        gxc_atm = czero; cnt = 0
             +  +  +  + ]
    1248         [ +  + ]:         387 :        do m_kq=bstart_kq, bstop_kq
    1249                 :         356 :          im_kq = m_kq - bstart_kq + 1
    1250         [ +  + ]:        2363 :          do n_k=bstart_k, bstop_k
    1251                 :        1976 :             in_k = n_k - bstart_k + 1
    1252                 :        1976 :             cnt = cnt + 1
    1253         [ +  - ]:        1976 :             if (gqk%pp_sum_comm%skip(cnt)) cycle ! MPI parallelism inside pp_sum_comm
    1254         [ +  + ]:       14188 :             do imyp=1,gqk%my_npert
    1255         [ +  + ]:       11856 :               if (cplex == 1) then
    1256         [ +  + ]:     8479536 :                 ctmp_gwpc = sum(GWPC_CONJG(ur_mkq(:,m_kq)) * ur_nk(:,n_k) * vxc1_qq(1,:,spin,imyp)) / nfftf
    1257                 :             :               else
    1258         [ +  + ]:    43427616 :                 ctmp_gwpc = sum(GWPC_CONJG(ur_mkq(:,m_kq)) * ur_nk(:,n_k) * cvxc1_qq_ptr(:,spin,imyp)) / nfftf
    1259                 :             :               end if
    1260                 :       11856 :               ipc = gqk%my_pertcases(imyp)
    1261         [ +  + ]:       37544 :               gxc_atm(:, im_kq, in_k, ipc) = [real(ctmp_gwpc), aimag(ctmp_gwpc)]
    1262                 :             :             end do ! imyp
    1263                 :             :          end do ! n_k
    1264                 :             :        end do ! m_kq
    1265                 :             : 
    1266                 :             :        ! TODO: this is an all_gatherv but oh well.
    1267                 :          31 :        call xmpi_sum(gxc_atm, gqk%pert_ppsum_comm%value, ierr)
    1268                 :          31 :        call timab(1940, 2, tsec)
    1269                 :             : 
    1270                 :             :        ! ==========================================================
    1271                 :             :        ! MPI sum over the pp momenta in the full BZ gqk%pp_sum_comm
    1272                 :             :        ! ==========================================================
    1273                 :             :        !
    1274                 :             :        ! Be careful here because pp should run over the list of wavevectors in the screening matrix!
    1275                 :             :        ! as pp_mesh%bz is not necessarily equivalent to the k-mesh for the wavefunctions.
    1276                 :             :        ! Moreover we have to use the ipp_bz index to symmetrize W(pp_bz) from W(pp_ibz).
    1277                 :             :        !
    1278                 :             :        ! TODO: Should order nbz in shells so that one can reduce the memory required
    1279                 :             :        ! to store W(pp) if pp_parallelism is activated.
    1280   [ +  +  +  +  :       36805 :        gsig_atm = zero
             +  +  +  + ]
    1281                 :             : 
    1282         [ +  + ]:         727 :        do ipp_bz=my_pp_start_spin(spin), my_pp_stop_spin(spin)
    1283                 :             :          ! All procs in gqk%pert_comm and gqk%bsum_com enter this section.
    1284                 :         696 :          call timab(1941, 1, tsec)
    1285                 :             : 
    1286                 :         696 :          my_ipp = ipp_bz - my_pp_start_spin(spin) + 1
    1287   [ +  -  +  +  :         696 :          print_time_pp = my_rank == 0 .and. (my_ipp <= LOG_MODP .or. mod(my_ipp, LOG_MODP) == 0)
                   +  + ]
    1288                 :         267 :          if (print_time_pp) call cwtime(cpu_pp, wall_pp, gflops_pp, "start")
    1289                 :             : 
    1290   [ +  +  +  + ]:        4872 :          pp = pp_mesh%bz(:,ipp_bz); pp_is_gamma = sum(pp**2) < tol14; pp_string = ktoa(pp)
    1291                 :             : 
    1292                 :             :          ! Debug, include only pp=Gamma
    1293         [ -  + ]:         696 :          if (dtset%userie > 0) then
    1294         [ #  # ]:           0 :             if (.not. pp_is_gamma) cycle
    1295                 :             :          end if
    1296                 :             : 
    1297         [ +  - ]:         696 :          qkp_string = sjoin("While treating qq_bz: ", qq_bz_string, "kpt:", kk_string, "pp:", pp_string, ch10)
    1298                 :             : 
    1299                 :             :          ! Symmetry tables and g-sphere centered on k-p.
    1300         [ +  + ]:        2784 :          kmp = kk - pp
    1301         [ -  + ]:         696 :          if (kpts_map("symrel", ebands%kptopt, cryst, gstore%krank_ibz, 1, kmp, mapl_kmp) /= 0) then
    1302                 :           0 :            write(msg, '(4a)' )"k-mesh is not closed!",ch10, &
    1303         [ #  # ]:           0 :              "k-p could not be generated from a symmetrical one.",trim(ltoa(kmp))
    1304                 :           0 :            ABI_ERROR(msg)
    1305                 :             :          end if
    1306         [ +  + ]:        2784 :          ikmp_ibz = mapl_kmp(1); isym_kmp = mapl_kmp(2); trev_kmp = mapl_kmp(6); g0_kmp = mapl_kmp(3:5)
    1307   [ +  +  +  +  :        2349 :          isirr_kmp = (isym_kmp == 1 .and. trev_kmp == 0 .and. all(g0_kmp == 0))
             +  +  +  + ]
    1308         [ +  + ]:        2784 :          kmp_ibz = ebands%kptns(:, ikmp_ibz)
    1309                 :             : 
    1310                 :             :          ! Get npw_kmp, kg_kmp for k-p.
    1311                 :             :          call wfd%get_gvec_gbound(cryst%gmet, dtset%ecut, kmp, ikmp_ibz, isirr_kmp, dtset%nloalg, &  ! in
    1312         [ -  + ]:         696 :                                   istwf_kmp, npw_kmp, kg_kmp, nkpg_kmp, kpg_kmp, gbound_kmp)         ! out
    1313         [ -  + ]:         696 :          ABI_CHECK_ILEQ(npw_kmp, mpw, "npw_kmp > mpw!")
    1314                 :             : 
    1315   [ -  +  +  -  :        2784 :          ABI_MALLOC(ph3d_kmp, (2, npw_kmp, matblk))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1316   [ -  +  +  -  :        2088 :          ABI_MALLOC(kinpw_kmp, (npw_kmp))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1317                 :         696 :          call mkkin(dtset%ecut, dtset%ecutsm, dtset%effmass_free, cryst%gmet, kg_kmp, kinpw_kmp, kmp, npw_kmp, 0, 0)
    1318                 :             : 
    1319                 :             :          ! Compute nonlocal form factors ffnl_kmp at (k-p+G).
    1320   [ -  +  +  -  :        3480 :          ABI_MALLOC(ffnl_kmp, (npw_kmp, 1, psps%lmnmax, psps%ntypat))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1321                 :             : 
    1322   [ -  +  +  -  :        2784 :          ABI_MALLOC(ylm_kmp, (npw_kmp, psps%mpsang**2 * psps%useylm))
          +  -  -  -  +  
          -  -  +  -  +  
             -  +  -  + ]
    1323         [ -  + ]:         696 :          if (psps%useylm == 1) then
    1324                 :           0 :            call initylmg_k(npw_kmp, psps%mpsang, optder0, cryst%rprimd, cryst%gprimd, kmp, kg_kmp, ylm_kmp, ylmgr_dum)
    1325                 :             :          end if
    1326                 :             : 
    1327                 :             :          call mkffnl_objs(cryst, psps, 1, ffnl_kmp, ider0, idir0, kg_kmp, kpg_kmp, kmp, nkpg_kmp, &
    1328                 :         696 :                           npw_kmp, ylm_kmp, ylmgr_dum) !, comm=gqk%pert_comm%value, request=ffnl_kmp_request)
    1329                 :             : 
    1330                 :             :          ! Symmetry tables and g-sphere centered on k+q-p.
    1331         [ +  + ]:        2784 :          kqmp = kq - pp
    1332         [ -  + ]:         696 :          if (kpts_map("symrel", ebands%kptopt, cryst, gstore%krank_ibz, 1, kqmp, mapl_kqmp) /= 0) then
    1333         [ #  # ]:           0 :            ABI_ERROR(sjoin("k-mesh not closed!",ch10, "k+q-p could not be generated from a symmetrical one:",trim(ltoa(kqmp))))
    1334                 :             :          end if
    1335         [ +  + ]:        2784 :          ikqmp_ibz = mapl_kqmp(1); isym_kqmp = mapl_kqmp(2); trev_kqmp = mapl_kqmp(6); g0_kqmp = mapl_kqmp(3:5)
    1336   [ +  +  +  +  :        1832 :          isirr_kqmp = (isym_kqmp == 1 .and. trev_kqmp == 0 .and. all(g0_kqmp == 0))
             +  +  +  + ]
    1337         [ +  + ]:        2784 :          kqmp_ibz = ebands%kptns(:, ikqmp_ibz)
    1338                 :         696 :          istwf_kqmp_ibz = wfd%istwfk(ikqmp_ibz); npw_kqmp_ibz = wfd%npwarr(ikqmp_ibz)
    1339                 :             : 
    1340                 :             :          ! Get npw_kqmp, kg_kqmp for k+q-p.
    1341                 :             :          call wfd%get_gvec_gbound(cryst%gmet, dtset%ecut, kqmp, ikqmp_ibz, isirr_kqmp, dtset%nloalg, &  ! in
    1342         [ -  + ]:         696 :                                   istwf_kqmp, npw_kqmp, kg_kqmp, nkpg_kqmp, kpg_kqmp, gbound_kqmp)      ! out
    1343         [ -  + ]:         696 :          ABI_CHECK_ILEQ(npw_kqmp, mpw, "npw_kqmp > mpw!")
    1344                 :             : 
    1345   [ -  +  +  -  :        2088 :          ABI_MALLOC(full_cg1_kqmp, (2, npw_kqmp*nspinor))
          +  -  +  -  -  
                +  -  + ]
    1346   [ -  +  +  -  :        2088 :          ABI_MALLOC(full_cg1_kmp, (2, npw_kmp*nspinor))
          +  -  +  -  -  
                +  -  + ]
    1347                 :             : 
    1348   [ -  +  +  -  :        2784 :          ABI_MALLOC(ph3d_kqmp, (2, npw_kqmp, matblk))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1349   [ -  +  +  -  :        2088 :          ABI_MALLOC(kinpw_kqmp, (npw_kqmp))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1350                 :         696 :          call mkkin(dtset%ecut, dtset%ecutsm, dtset%effmass_free, cryst%gmet, kg_kqmp, kinpw_kqmp, kqmp, npw_kqmp, 0, 0)
    1351                 :             : 
    1352                 :             :          ! Compute nonlocal form factors ffnl_kqmp at (k+q-p+G).
    1353   [ -  +  +  -  :        3480 :          ABI_MALLOC(ffnl_kqmp, (npw_kqmp, 1, psps%lmnmax, psps%ntypat))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    1354                 :             : 
    1355   [ -  +  +  -  :        2784 :          ABI_MALLOC(ylm_kqmp, (npw_kqmp, psps%mpsang**2 * psps%useylm))
          +  -  -  -  +  
          -  -  +  -  +  
             -  +  -  + ]
    1356         [ -  + ]:         696 :          if (psps%useylm == 1) then
    1357                 :           0 :            call initylmg_k(npw_kqmp, psps%mpsang, optder0, cryst%rprimd, cryst%gprimd, kqmp, kg_kqmp, ylm_kqmp, ylmgr_dum)
    1358                 :             :          end if
    1359                 :             : 
    1360                 :             :          call mkffnl_objs(cryst, psps, 1, ffnl_kqmp, ider0, idir0, kg_kqmp, kpg_kqmp, kqmp, nkpg_kqmp, &
    1361                 :         696 :                           npw_kqmp, ylm_kqmp, ylmgr_dum) ! , comm=gqk%pert_comm%value, request=ffnl_kqmp_request)
    1362                 :             : 
    1363                 :             :          ! =============================================
    1364                 :             :          ! Load the k dependent parts of the Hamiltonian
    1365                 :             :          ! =============================================
    1366                 :             : 
    1367                 :             :          ! (k+q-p, k-p)
    1368                 :             :          call gs_ham_kqmp%load_k(kpt_k=kmp, npw_k=npw_kmp, istwf_k=istwf_kmp, kg_k=kg_kmp, kpg_k=kpg_kmp, kinpw_k=kinpw_kmp, &
    1369                 :         696 :            ph3d_k=ph3d_kmp, ffnl_k=ffnl_kmp, compute_ph3d=.true., compute_gbound=.true.)
    1370                 :             : 
    1371                 :             :          call gs_ham_kqmp%load_kprime(kpt_kp=kqmp, npw_kp=npw_kqmp, istwf_kp=istwf_kqmp, kg_kp=kg_kqmp, kpg_kp=kpg_kqmp, &
    1372                 :         696 :            kinpw_kp=kinpw_kqmp, ph3d_kp=ph3d_kqmp, ffnl_kp=ffnl_kqmp, compute_ph3d=.true., compute_gbound=.true.)
    1373                 :             : 
    1374                 :             :          ! (k-p, k+q-p)
    1375                 :             :          call gs_ham_kmp%load_k(kpt_k=kqmp, npw_k=npw_kqmp, istwf_k=istwf_kqmp, kg_k=kg_kqmp, kpg_k=kpg_kqmp, kinpw_k=kinpw_kqmp, &
    1376                 :         696 :            ph3d_k=ph3d_kqmp, ffnl_k=ffnl_kqmp, compute_ph3d=.true., compute_gbound=.true.)
    1377                 :             : 
    1378                 :             :          call gs_ham_kmp%load_kprime(kpt_kp=kmp, npw_kp=npw_kmp, istwf_kp=istwf_kmp, kg_kp=kg_kmp, kpg_kp=kpg_kmp, &
    1379                 :         696 :            kinpw_kp=kinpw_kmp, ph3d_kp=ph3d_kmp, ffnl_kp=ffnl_kmp, compute_ph3d=.true., compute_gbound=.true.)
    1380                 :             : 
    1381                 :             :          ! ====================================
    1382                 :             :          ! This is the g-sphere for W_{gg'}(pp)
    1383                 :             :          ! ====================================
    1384                 :             :          ! Note that in this case, the spheres are always Gamma-centered i.e. it does not depend on the pp wavevector.
    1385                 :         696 :          kg_c => gsph_c%gvec(:, 1:npw_c)
    1386                 :         696 :          kg_x => gsph_x%gvec(:, 1:npw_x)
    1387                 :         696 :          call sphereboundary(gbound_c, istwfk1, kg_c, mgfft, npw_c)
    1388                 :         696 :          call sphereboundary(gbound_x, istwfk1, kg_x, mgfft, npw_x)
    1389                 :             : 
    1390   [ -  +  +  -  :        2088 :          ABI_MALLOC(rhotwg_c, (npw_c*nspinor))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1391   [ -  +  +  -  :        2088 :          ABI_MALLOC(rhotwg_x, (npw_x*nspinor))
          +  -  +  -  -  
                +  -  + ]
    1392   [ -  +  +  -  :        2088 :          ABI_MALLOC(vc_sqrt_gx, (npw_x))
          +  -  +  -  -  
                +  -  + ]
    1393         [ -  + ]:         696 :          if (dtset%userra /= zero) then
    1394                 :             :            ! Auxiliary state chi_{n'k-p} on the k+q-p g-sphere and its oscillator (dG0/de term at q=Gamma).
    1395   [ #  #  #  #  :           0 :            ABI_MALLOC(chi_ug_kqmp, (npw_kqmp*nspinor))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1396   [ #  #  #  #  :           0 :            ABI_MALLOC(rhotwg_chi, (npw_c*nspinor))
          #  #  #  #  #  
                      # ]
    1397                 :             :          end if
    1398                 :             : 
    1399                 :             :          ! We need two stern_t objects to compute the first order change of the wavefunctions at k-p and k+q-p.
    1400                 :             :          ! Clearly, we should not duplicate the work when pp = 0.
    1401                 :             :          ! When pp == 0, we also get the gks matrix elements after stern_solve.
    1402                 :             :          ! Alternatively, one can solve the Sternheimer in the IBZ(kappa, alpha), store the results on disk
    1403                 :             :          ! and then use symmetries to reconstruct delta_u in the full BZ on the fly assuming spatial inversion or TR.
    1404                 :             :          ! Also, one should handle more carefully the integration in g_sigma around pp = Gamma in the case of semiconductors.
    1405                 :             : 
    1406                 :         696 :          nband_me = nbsum; stern_comm = xmpi_comm_self
    1407                 :             : 
    1408                 :             :          ! =======================
    1409                 :             :          ! Delta_{qka} psi_{n'k-p}
    1410                 :             :          ! =======================
    1411                 :             :          ! (k+q-p, k-p)
    1412                 :             :          call stern_kmp%init(dtset, npw_kmp, npw_kqmp, nspinor, nbsum, nband_me, fermie1_idir_ipert, &
    1413                 :         696 :                              stern_use_cache, work_ngfft, mpi_enreg, stern_comm)
    1414                 :             : 
    1415                 :             :          ! Use symmetries to reconstruct GS wavefunctions at k+q-p and store them in stern_kmp%cgq.
    1416                 :             :          ! NB: all the nbsum bands are needed here, also when the sum over bands is distributed.
    1417         [ +  + ]:        8024 :          do ib_sum=1,nbsum
    1418                 :             :            call wfd%rotate_cg(ib_sum, ndat1, spin, kqmp_ibz, npw_kqmp, kg_kqmp, istwf_kqmp, &
    1419                 :        7328 :                               cryst, mapl_kqmp, gbound_kqmp, work_ngfft, work, cg_kqmp)
    1420                 :             : 
    1421                 :             :            ! NB: cg_kqmp is dimensioned with mpw --> have to slice cg_kqmp
    1422   [ +  +  +  + ]:    27033572 :            stern_kmp%cgq(:,:,ib_sum) = cg_kqmp(:,1:npw_kqmp*nspinor)
    1423                 :             :          end do ! ib_sum
    1424                 :             : 
    1425                 :             :          ! ==========================
    1426                 :             :          ! Delta_{-qka} psi_{n'k+q-p}
    1427                 :             :          ! ==========================
    1428                 :             :          ! (k-p, k+q-p)
    1429                 :             :          call stern_kqmp%init(dtset, npw_kqmp, npw_kmp, nspinor, nbsum, nband_me, fermie1_idir_ipert, &
    1430                 :         696 :                               stern_use_cache, work_ngfft, mpi_enreg, stern_comm)
    1431                 :             : 
    1432                 :             :          ! Use symmetries to reconstruct GS wavefunctions at k-p and store them in stern_kqmp%cgq.
    1433         [ +  + ]:        8024 :          do ib_sum=1,nbsum
    1434                 :             :            call wfd%rotate_cg(ib_sum, ndat1, spin, kmp_ibz, npw_kmp, kg_kmp, istwf_kmp, &
    1435                 :        7328 :                               cryst, mapl_kmp, gbound_kmp, work_ngfft, work, cg_kmp)
    1436                 :             : 
    1437                 :             :            ! NB: cg_kmp is dimensioned with mpw --> have to slice cg_kmp
    1438   [ +  +  +  + ]:    27033572 :            stern_kqmp%cgq(:,:,ib_sum) = cg_kmp(:,1:npw_kmp*nspinor)
    1439                 :             :          end do ! ib_sum
    1440                 :             : 
    1441                 :             :          ! Get PPM parameters at pp_bz to applying W_{gg'}(pp_bz).
    1442                 :             :          ! Note: Sq_ibz = q_bz + G0 with non-zero G0 is not supported here
    1443   [ -  +  -  +  :         696 :          call ppm%get_qbz(gsph_c, pp_mesh, ipp_bz, botsq_pbz, otq_pbz, dmeig_pbz)
                   -  + ]
    1444                 :             : 
    1445                 :             :          ! Need transpose of PPM matrices when summing over the G index.
    1446         [ +  - ]:         696 :          if (ppm%dm2_botsq /= 0) then
    1447         [ -  + ]:         696 :            call alloc_copy(botsq_pbz, trans_botsq_pbz)
    1448                 :         696 :            call sqmat_itranspose(npw_c, trans_botsq_pbz)
    1449                 :             :          end if
    1450         [ +  - ]:         696 :          if (ppm%dm2_otq /= 0) then
    1451         [ -  + ]:         696 :            call alloc_copy(otq_pbz, trans_otq_pbz)
    1452                 :         696 :            call sqmat_itranspose(npw_c, trans_otq_pbz)
    1453                 :             :          end if
    1454         [ +  - ]:         696 :          if (ppm%dm_eig /= 0) then
    1455         [ -  + ]:         696 :            call alloc_copy(dmeig_pbz, trans_dmeig_pbz)
    1456                 :         696 :            call sqmat_itranspose(ppm%dm_eig, trans_dmeig_pbz)
    1457                 :             :          end if
    1458                 :             : 
    1459                 :             :          ! Find the corresponding irred pp-point in the pp_mesh.
    1460                 :         696 :          call pp_mesh%get_bz_item(ipp_bz, pp, ipp_ibz, isym_pp, itim_pp)
    1461                 :             : 
    1462                 :             :          ! Get Fourier components of the Coulomb interaction in the BZ
    1463                 :             :          ! In 3D systems, neglecting umklapp: vc(Sq,sG) = vc(q,G) = 4pi/|q+G|**2
    1464                 :             :          ! The same relation holds for 0-D systems, but not in 1-D or 2D systems. It depends on S.
    1465                 :             :          ! NOTE: vc_sqrt_gx is dimensioned with npw_x --> use rottb table from gsph_x.
    1466         [ +  + ]:      396144 :          do ig=1,npw_x
    1467                 :      396144 :            vc_sqrt_gx(gsph_x%rottb(ig, itim_pp, isym_pp)) = vcp%vc_sqrt(ig, ipp_ibz)
    1468                 :             :          end do
    1469                 :             : 
    1470         [ -  + ]:         696 :          if (dtset%gwcomp == 2) then
    1471                 :             :            ! Compute static limit at pp_bz from the symmetrical image in the IBZ
    1472                 :           0 :            call em1_symmetrize_op(ipp_bz, npw_c, 1, gsph_c, pp_mesh, wc0_pibz(ipp_ibz)%vals, wc0_pbz)
    1473                 :             :          end if
    1474                 :         696 :          call timab(1941, 2, tsec)
    1475                 :             : 
    1476                 :             :          ! ===========================================
    1477                 :             :          ! Sum over bands (n' index in equations), distributed inside bsum_comm.
    1478                 :             :          ! All procs in gqk%pert_comm enter this part.
    1479                 :             :          ! ===========================================
    1480                 :             : 
    1481         [ +  + ]:        8024 :          do ib_sum=my_bsum_start(spin), my_bsum_stop(spin)
    1482                 :        7328 :            call timab(1942, 1, tsec)
    1483                 :             :            ! Get u_{n',k-p}(r)^*, stored in ur_star_kmp.
    1484                 :             :            call wfd%rotate_cg(ib_sum, ndat1, spin, kmp_ibz, npw_kmp, kg_kmp, istwf_kmp, &
    1485                 :        7328 :                               cryst, mapl_kmp, gbound_kmp, work_ngfft, work, cg_kmp, urs_kbz=ur_star_kmp)
    1486                 :             : 
    1487         [ +  + ]:    38911136 :            ur_star_kmp = GWPC_CONJG(ur_star_kmp)
    1488                 :        7328 :            ebsum_kmp = ebands%eig(ib_sum, ikmp_ibz, spin)
    1489                 :        7328 :            ebsum_kqmp = ebands%eig(ib_sum, ikqmp_ibz, spin)
    1490                 :             : 
    1491                 :             :            ! Energy of the states above nbsum for gwcomp 1 and -2.
    1492                 :        7328 :            e_high = en_high
    1493         [ -  + ]:        7328 :            if (dtset%gwcomp == -2) e_high = half * (qp_ene(nbsum, ikmp_ibz, spin) + qp_ene(nbsum, ikqmp_ibz, spin)) + dyn_shift
    1494                 :             : 
    1495                 :             :            ! =====================================
    1496                 :             :            ! Precompute oscillator matrix elements
    1497                 :             :            ! =====================================
    1498                 :             :            ! These terms do not depend on (idir, ipert) and can be reused in the loop over perturbations below.
    1499                 :             :            ! If the n' bands in the sum are distributed, one should transmit the (m, n) indices.
    1500                 :             : 
    1501                 :        7328 :            theta_mu_minus_e0i = fact_spin * qp_occ(ib_sum, ikmp_ibz, spin)
    1502                 :        7328 :            need_x_kmp = (abs(theta_mu_minus_e0i / fact_spin) >= tol_empty) ! allow negative occ numbers
    1503                 :             :            !need_x_kmp = .True.
    1504                 :             :            !print *, "kmp, ib_sum, theta_mu_minus_e0i", ib_sum, theta_mu_minus_e0i
    1505                 :             : 
    1506                 :             :            ! Contract immediately over g' with the frequency convolution:
    1507                 :             :            !
    1508                 :             :            !    \int de' Wc_{gg'}(pp, e') / (omega - e_{bsum, kmp) - e')
    1509                 :             :            !
    1510                 :             :            ! vec_gwc_nk(:,:,n_k) stores:
    1511                 :             :            !
    1512                 :             :            !    sum_g' \int de' Wc_{gg'}(pp, e') / (omega - e_{bsum, kmp) - e') <bsum,k-p|e^{-i(p+g')}r|n,k>
    1513                 :             :            !
    1514         [ -  + ]:        7328 :            if (gqk%pert_comm%nproc > 1) then
    1515   [ #  #  #  #  :           0 :              vec_gwc_nk = zero
                   #  # ]
    1516   [ #  #  #  # ]:           0 :              vec_gx_nk = zero
    1517   [ #  #  #  #  :           0 :              if (use_dg0) vec_dgwc_nk = zero
             #  #  #  # ]
    1518   [ #  #  #  #  :           0 :              if (dtset%gwcomp == 2) vec_coh_nk = zero
                   #  # ]
    1519                 :             :            end if
    1520                 :             : 
    1521         [ +  + ]:       41056 :            do n_k=bstart_k, bstop_k
    1522         [ +  - ]:       33728 :              in_k = n_k - bstart_k + 1; if (gqk%pert_comm%skip(in_k)) cycle ! MPI parallelism inside pert_comm
    1523                 :             : 
    1524                 :             :              ! Compute <bsum,k-p|e^{-i(p+G')}r|n,k> * vc_sqrt(p,G')
    1525   [ +  -  -  +  :   173770624 :              cwork_ur = ur_star_kmp * ur_nk(:,n_k)
             -  -  +  + ]
    1526                 :             : 
    1527         [ +  + ]:       33728 :              if (need_x_kmp) then
    1528                 :       20800 :                call fft_ur(npw_x, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_x, gbound_x, cwork_ur, rhotwg_x)
    1529                 :       20800 :                call sigtk_multiply_by_vc_sqrt("N", npw_x, nspinor, ndat1, vc_sqrt_gx, rhotwg_x)
    1530         [ +  + ]:       20800 :                if (pp_is_gamma) then
    1531         [ +  + ]:         808 :                  rhotwg_x(1) = czero_gw; if (ib_sum == n_k) rhotwg_x(1) = cmplx(sqrt(vcp%i_sz),0.0_gwp)
    1532                 :             :                end if
    1533                 :             : 
    1534         [ +  + ]:    12579456 :                vec_gx_nk(:,n_k) = rhotwg_x(1:npw_x*nspinor)
    1535   [ -  +  -  - ]:       20800 :                if (dtset%userid /= 0) vec_gx_nk(:,n_k) = zero
    1536                 :             :                ! FIXME: This is wrong if nspinor == 2
    1537         [ +  + ]:      553600 :                rhotwg_c(:) = rhotwg_x(1:npw_c*nspinor)
    1538                 :             : 
    1539                 :             :                if (qq_is_gamma .and. test_sigma) then
    1540                 :             :                  sigx_nk(in_k, ik_glob) = sigx_nk(in_k, ik_glob) + dot_product(rhotwg_x, rhotwg_x)
    1541                 :             :                end if
    1542                 :             : 
    1543                 :             :              else
    1544                 :       12928 :                call fft_ur(npw_c, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_c, gbound_c, cwork_ur, rhotwg_c)
    1545                 :       12928 :                call sigtk_multiply_by_vc_sqrt("N", npw_c, nspinor, ndat1, vc_sqrt_gx, rhotwg_c)
    1546         [ +  + ]:       12928 :                if (pp_is_gamma) then
    1547         [ +  + ]:        1168 :                  rhotwg_c(1) = czero_gw; if (ib_sum == n_k) rhotwg_c(1) = cmplx(sqrt(vcp%i_sz),0.0_gwp)
    1548                 :             :                end if
    1549                 :             :              end if
    1550                 :             : 
    1551                 :             :              ! Prepare list of omegas: first e_nk then e_mkq for all m indices.
    1552                 :       33728 :              omegas_nk(1) = qp_ene(n_k, ik_ibz, spin); cnt = 1
    1553                 :             : 
    1554         [ +  + ]:       33728 :              if (dtset%gwpt_wmode == 1) then
    1555         [ +  + ]:      172224 :                do m_kq=bstart_kq, bstop_kq
    1556                 :      172224 :                  cnt = cnt + 1; omegas_nk(cnt) = qp_ene(m_kq, ikq_ibz, spin)
    1557                 :             :                end do
    1558                 :             :              end if
    1559   [ -  +  +  + ]:      260160 :              omegame0i_nk = omegas_nk - qp_ene(ib_sum, ikmp_ibz, spin)
    1560                 :             : 
    1561                 :             :              ! Note that the i/two_pi factor in Sigma(w) is included in calc_sigc
    1562   [ +  +  +  + ]:    11728192 :              vec_gwc_nk(:,:,n_k) = zero
    1563                 :             :              call ppm%calc_sigc(nspinor, npw_c, nw_nk, rhotwg_c, botsq_pbz, otq_pbz, &
    1564                 :             :                                 omegame0i_nk, dtset%zcut, theta_mu_minus_e0i, dmeig_pbz, npw_c, &
    1565                 :       33728 :                                 vec_gwc_nk(:,:,n_k), sigcme_nk)
    1566                 :             : 
    1567         [ -  + ]:       33728 :              if (use_dg0) then
    1568                 :             :                ! Same contraction but with the omega-derivative of the PPM kernel (dWtilde/de).
    1569                 :             :                ! Contracted with the oscillator of the auxiliary state chi_{bsum,k-p} in the perturbation loop below.
    1570   [ #  #  #  # ]:           0 :                vec_dgwc_nk(:,:,n_k) = zero
    1571                 :             :                call ppm%calc_dsigc(nspinor, npw_c, nw_nk, rhotwg_c, botsq_pbz, otq_pbz, &
    1572                 :           0 :                                    omegame0i_nk, dtset%zcut, theta_mu_minus_e0i, npw_c, vec_dgwc_nk(:,:,n_k))
    1573   [ #  #  #  #  :           0 :                if (dtset%useric /= 0) vec_dgwc_nk(:,:,n_k) = zero
                   #  # ]
    1574                 :             :              end if
    1575                 :             : 
    1576         [ -  + ]:       33728 :              if (dtset%gwcomp == 2) then
    1577   [ #  #  #  #  :           0 :                vec_coh_nk(:, n_k) = matmul(wc0_pbz, rhotwg_c)
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1578                 :             :                !call xgemv("N", npw_c, npw_c, cone_gw, wc0_pbz, npw_c, rhotwg_c, 1, czero_gw, vec_coh_nk(:, n_k), 1)
    1579                 :             :              end if
    1580                 :             : 
    1581                 :             :              if (qq_is_gamma .and. test_sigma) then
    1582                 :             :                sigce0_nk(in_k, ik_glob) = sigce0_nk(in_k, ik_glob) + dot_product(rhotwg_c, vec_gwc_nk(:,1,n_k))
    1583                 :             :              end if
    1584                 :             : 
    1585         [ -  + ]:       33728 :              if (any(dtset%gwcomp == [1, -2])) then
    1586                 :             :                ! Subtract the PPM term of the same state moved to E_high (empty, theta = 0).
    1587                 :             :                ! NB: vec_comp_nk must be zeroed because calc_sigc multiplies the whole ket by 1/2.
    1588   [ #  #  #  # ]:           0 :                omegame0i_nk = omegas_nk - e_high
    1589   [ #  #  #  # ]:           0 :                vec_comp_nk = zero
    1590                 :             :                call ppm%calc_sigc(nspinor, npw_c, nw_nk, rhotwg_c, botsq_pbz, otq_pbz, &
    1591                 :           0 :                                   omegame0i_nk, dtset%zcut, zero, dmeig_pbz, npw_c, vec_comp_nk, sigcme_nk)
    1592   [ #  #  #  # ]:           0 :                vec_gwc_nk(:,:,n_k) = vec_gwc_nk(:,:,n_k) - vec_comp_nk
    1593                 :             :              end if
    1594                 :             : 
    1595   [ -  +  -  -  :       41056 :              if (dtset%useric /= 0) vec_gwc_nk(:,:,n_k) = zero
                   -  - ]
    1596                 :             :            end do ! n_k
    1597                 :             : 
    1598                 :             :            ! TODO: this is an all_gatherv but oh well.
    1599         [ -  + ]:        7328 :            if (gqk%pert_comm%nproc > 1) then
    1600                 :           0 :              call xmpi_sum(vec_gx_nk, gqk%pert_comm%value, ierr)
    1601                 :           0 :              call xmpi_sum(vec_gwc_nk, gqk%pert_comm%value, ierr)
    1602         [ #  # ]:           0 :              if (use_dg0) call xmpi_sum(vec_dgwc_nk, gqk%pert_comm%value, ierr)
    1603         [ #  # ]:           0 :              if (dtset%gwcomp == 2) call xmpi_sum(vec_coh_nk, gqk%pert_comm%value, ierr)
    1604                 :             :            end if
    1605                 :             : 
    1606                 :        7328 :            call timab(1942, 2, tsec)
    1607                 :        7328 :            call timab(1943, 1, tsec)
    1608                 :             : 
    1609                 :             :            ! Get u_{n',k+q-p}(r), stored in ur_star_kqmp
    1610                 :             :            call wfd%rotate_cg(ib_sum, ndat1, spin, kqmp_ibz, npw_kqmp, kg_kqmp, istwf_kqmp, &
    1611                 :        7328 :                               cryst, mapl_kqmp, gbound_kqmp, work_ngfft, work, cg_kqmp, urs_kbz=ur_star_kqmp)
    1612                 :             : 
    1613         [ +  + ]:    38911136 :            ur_star_kqmp = GWPC_CONJG(ur_star_kqmp)
    1614                 :        7328 :            theta_mu_minus_e0i = fact_spin * qp_occ(ib_sum, ikqmp_ibz, spin)
    1615                 :             : 
    1616                 :        7328 :            need_x_kqmp = (abs(theta_mu_minus_e0i / fact_spin) >= tol_empty) ! allow negative occ numbers
    1617                 :             :            !print *, "kqmp, ib_sum, theta_mu_minus_e0i", ib_sum, theta_mu_minus_e0i
    1618                 :             :            !need_x_kqmp = .True.
    1619                 :             : 
    1620                 :             :            ! Contract immediately over g with the frequency convolution:
    1621                 :             :            !
    1622                 :             :            !    \int de' Wc_{gg'}(pp, e') / (omega - e_{bsum, kqmp) - e')
    1623                 :             :            !
    1624                 :             :            ! Store results in vec_gwc_mkq(:,:,m_kq).
    1625                 :             :            !
    1626                 :             :            !    sum_g \int de' Wc_{gg'}(pp, e') / (omega - e_{bsum, kqmp) - e') <m,k+q|e^{+i(p+g)}r|bsum,k+q-p>
    1627                 :             :            !
    1628         [ -  + ]:        7328 :            if (gqk%pert_comm%nproc > 1) then
    1629   [ #  #  #  #  :           0 :              vec_gwc_mkq = zero
                   #  # ]
    1630   [ #  #  #  #  :           0 :              if (need_x_kqmp) vec_gx_mkq = zero
                   #  # ]
    1631   [ #  #  #  #  :           0 :              if (dtset%gwcomp == 2) vec_coh_mkq = zero
                   #  # ]
    1632                 :             :            end if
    1633                 :             : 
    1634         [ +  + ]:       85024 :            do m_kq=bstart_kq, bstop_kq
    1635         [ +  - ]:       77696 :              im_kq = m_kq - bstart_kq + 1; if (gqk%pert_comm%skip(im_kq)) cycle ! MPI parallelism inside pert_comm
    1636                 :             : 
    1637                 :             :              ! <m,k+q|e^{i(p+G)}r|bsum,k+q-p> * vc_sqrt(p,G).
    1638                 :             :              ! Exchange bra and ket and take the CC of the FFT in sigtk_multiply_by_vc_sqrt.
    1639   [ +  -  -  +  :   407281408 :              cwork_ur = ur_star_kqmp * ur_mkq(:,m_kq)
             -  -  +  + ]
    1640                 :             : 
    1641         [ +  + ]:       77696 :              if (need_x_kqmp) then
    1642                 :       49792 :                call fft_ur(npw_x, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_x, gbound_x, cwork_ur, rhotwg_x)
    1643                 :       49792 :                call sigtk_multiply_by_vc_sqrt("C", npw_x, nspinor, ndat1, vc_sqrt_gx, rhotwg_x)
    1644         [ +  + ]:       49792 :                if (pp_is_gamma) then
    1645         [ +  + ]:        1744 :                  rhotwg_x(1) = czero_gw; if (ib_sum == m_kq) rhotwg_x(1) = cmplx(sqrt(vcp%i_sz),0.0_gwp)
    1646                 :             :                end if
    1647                 :             : 
    1648         [ +  + ]:    31302912 :                vec_gx_mkq(:,m_kq) = rhotwg_x(1:npw_x*nspinor)
    1649   [ -  +  -  - ]:       49792 :                if (dtset%userid /= 0) vec_gx_mkq(:,m_kq) = zero
    1650         [ +  + ]:     1238272 :                rhotwg_c(:) = rhotwg_x(1:npw_c*nspinor)
    1651                 :             : 
    1652                 :             :              else
    1653                 :       27904 :                call fft_ur(npw_c, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_c, gbound_c, cwork_ur, rhotwg_c)
    1654                 :       27904 :                call sigtk_multiply_by_vc_sqrt("C", npw_c, nspinor, ndat1, vc_sqrt_gx, rhotwg_c)
    1655         [ +  + ]:       27904 :                if (pp_is_gamma) then
    1656         [ +  + ]:        2368 :                  rhotwg_c(1) = czero_gw; if (ib_sum == m_kq) rhotwg_c(1) = cmplx(sqrt(vcp%i_sz),0.0_gwp)
    1657                 :             :                end if
    1658                 :             :              end if
    1659                 :             : 
    1660         [ +  + ]:       77696 :              if (dtset%gwpt_wmode == 1) then
    1661                 :             :                ! Prepare list of omegas: first e_mkq then e_nk for all n indices.
    1662                 :       26496 :                omegas_mkq(1) = qp_ene(m_kq, ikq_ibz, spin); cnt = 1
    1663         [ +  + ]:      185472 :                do n_k=bstart_k, bstop_k
    1664                 :      185472 :                  cnt = cnt + 1; omegas_mkq(cnt) = qp_ene(n_k, ik_ibz, spin)
    1665                 :             :                end do
    1666                 :             :              else
    1667                 :             :                 ! Here we compute the convolution at e_nk for all n_k bands at fixed m_kq
    1668                 :       51200 :                 cnt = 0
    1669         [ +  + ]:      256000 :                 do n_k=bstart_k, bstop_k
    1670                 :      256000 :                   cnt = cnt + 1; omegas_mkq(cnt) = qp_ene(n_k, ik_ibz, spin)
    1671                 :             :                 end do
    1672                 :             :              end if
    1673                 :             : 
    1674   [ -  +  +  + ]:      545664 :              omegame0i_mkq = omegas_mkq - qp_ene(ib_sum, ikqmp_ibz, spin)
    1675                 :             : 
    1676                 :             :              ! Here we sum over G instead of G' so we have to pass the transpose of the PPM matrix elements.
    1677                 :             :              ! TODO: Generalize ppm%calc_sigc with BLAS-like API.
    1678   [ +  +  +  + ]:    15595648 :              vec_gwc_mkq(:,:,m_kq) = zero
    1679                 :             :              call ppm%calc_sigc(nspinor, npw_c, nw_mkq, rhotwg_c, trans_botsq_pbz, trans_otq_pbz, &
    1680                 :             :                                 omegame0i_mkq, dtset%zcut, theta_mu_minus_e0i, trans_dmeig_pbz, npw_c, &
    1681                 :       77696 :                                 vec_gwc_mkq(:,:,m_kq), sigcme_mkq)
    1682                 :             : 
    1683         [ -  + ]:       77696 :              if (any(dtset%gwcomp == [1, -2])) then
    1684                 :             :                ! Subtract the PPM term of the same state moved to E_high (empty, theta = 0), transposed PPM matrices.
    1685   [ #  #  #  # ]:           0 :                omegame0i_mkq = omegas_mkq - e_high
    1686   [ #  #  #  # ]:           0 :                vec_comp_mkq = zero
    1687                 :             :                call ppm%calc_sigc(nspinor, npw_c, nw_mkq, rhotwg_c, trans_botsq_pbz, trans_otq_pbz, &
    1688                 :           0 :                                   omegame0i_mkq, dtset%zcut, zero, trans_dmeig_pbz, npw_c, vec_comp_mkq, sigcme_mkq)
    1689   [ #  #  #  # ]:           0 :                vec_gwc_mkq(:,:,m_kq) = vec_gwc_mkq(:,:,m_kq) - vec_comp_mkq
    1690                 :             :              end if
    1691                 :             : 
    1692         [ -  + ]:       77696 :              if (dtset%gwcomp == 2) then
    1693                 :             :                ! Same contraction as the -q main term (transposed PPM matrices applied to rhotwg_c, no complex conjugate):
    1694                 :             :                ! the static limit of calc_sigc with trans_botsq_pbz is (1/2 - f) W^c(0)^T rhotwg_c.
    1695   [ #  #  #  #  :           0 :                vec_coh_mkq(:, m_kq) = matmul(rhotwg_c, wc0_pbz)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1696                 :             :                !call xgemv("H", npw_c, npw_c, cone_gw, wc0_pbz, npw_c, rhotwg_c, 1, czero_gw, vec_coh_mkq(:, m_kq), 1)
    1697                 :             :              end if
    1698                 :             : 
    1699   [ -  +  -  -  :       85024 :              if (dtset%useric /= 0) vec_gwc_mkq(:,:,m_kq) = zero
                   -  - ]
    1700                 :             :            end do ! m_kq
    1701                 :             : 
    1702                 :             :            ! TODO: this is an all_gatherv but oh well.
    1703         [ -  + ]:        7328 :            if (gqk%pert_comm%nproc > 1) then
    1704                 :           0 :              call xmpi_sum(vec_gwc_mkq, gqk%pert_comm%value, ierr)
    1705         [ #  # ]:           0 :              if (need_x_kqmp) call xmpi_sum(vec_gx_mkq, gqk%pert_comm%value, ierr)
    1706         [ #  # ]:           0 :              if (dtset%gwcomp == 2) call xmpi_sum(vec_coh_mkq, gqk%pert_comm%value, ierr)
    1707                 :             :            end if
    1708                 :             : 
    1709                 :        7328 :            call timab(1943, 2, tsec)
    1710                 :             : 
    1711                 :             :            ! ========================================
    1712                 :             :            ! Loop over my set of atomic perturbations
    1713                 :             :            ! ========================================
    1714                 :             :            ! For each perturbation:
    1715                 :             :            !    - setup H1 from vlocal1_qq or vlocal1_mqq.
    1716                 :             :            !    For each band in band_sum:
    1717                 :             :            !        - Solve the Sternheimer non-self-consistently and get the KS e-ph matrix elements.
    1718                 :             :            !        - Build the full first-order wavefunction including the active subspace.
    1719                 :             : 
    1720         [ +  + ]:       51296 :            do imyp=1,gqk%my_npert
    1721                 :       43968 :              call timab(1944, 1, tsec)
    1722                 :             :              ! NB: Only one proc enters this section. No MPI parallelism is allowed here.
    1723                 :       43968 :              idir = dvdb%my_pinfo(1, imyp); ipert = dvdb%my_pinfo(2, imyp); ipc = dvdb%my_pinfo(3, imyp)
    1724                 :             :              !print *, "For kk, ", kk, "pp:", pp, "idir, ipert", idir, ipert
    1725                 :             : 
    1726                 :             :              ! Set up local potential vlocal1_qq with proper dimensioning, from vtrial1 taking into account the spin
    1727                 :             :              ! and prepare application of the NL part. Each MPI rank prepares its own potential.
    1728                 :             :              call rf_transgrid_and_pack(spin, nspden, psps%usepaw, cplex, nfftf, nfft, ngfft, nvloc, &
    1729                 :       43968 :                                         pawfgr, mpi_enreg, vtrial, v1scf_qq(:,:,:,imyp), vlocal, vlocal1_qq(:,:,:,:,imyp))
    1730                 :             : 
    1731                 :       43968 :              call gs_ham_kqmp%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.)
    1732                 :             : 
    1733                 :       43968 :              call rf_ham_kqmp%init(cplex, gs_ham_kqmp, ipert, has_e1kbsc=.true.)
    1734                 :       43968 :              call rf_ham_kqmp%load_spin(spin, vlocal1=vlocal1_qq(:,:,:,:,imyp), with_nonlocal=.true.)
    1735                 :             : 
    1736                 :             :              ! ======================
    1737                 :             :              ! NSCF Sternheimer at qq
    1738                 :             :              ! ======================
    1739                 :             :              ! Compute Delta_{q,idir,ipert} \psi_{bsum, k-p}
    1740                 :             :              call wfd%rotate_cg(ib_sum, ndat1, spin, kmp_ibz, npw_kmp, kg_kmp, istwf_kmp, &
    1741                 :       43968 :                                 cryst, mapl_kmp, gbound_kmp, work_ngfft, work, cg_kmp)
    1742                 :             : 
    1743         [ +  + ]:      510144 :              stern_kmp%bands_treated_now(:) = 0; stern_kmp%bands_treated_now(ib_sum) = 1
    1744         [ +  + ]:      510144 :              stern_kmp%rank_band = 0; u1_band = ib_sum; band_me = ib_sum
    1745                 :             : 
    1746                 :             :              ! (k+q-p, k-p)
    1747                 :       43968 :              init_mode = "None"
    1748                 :             :              call stern_kmp%solve(u1_band, band_me, idir, ipert, qq_bz, gs_ham_kqmp, rf_ham_kqmp, &
    1749                 :             :                                   ebands%eig(:,ikmp_ibz,spin), ebands%eig(:,ikqmp_ibz,spin), &
    1750                 :             :                                   cg_kmp, cwaveprj0, cg1_kqmp, cwaveprj, msg, ierr, &
    1751                 :       43968 :                                   full_cg1=full_cg1_kqmp, full_ur1=full_ur1_kqmp, init_mode=init_mode)
    1752                 :             : 
    1753                 :             :              ! The last bands may fail to converge with resid=-two. In this case we ignore the contribution.
    1754         [ +  + ]:       43968 :              if (ierr /= 0) then
    1755   [ +  +  +  +  :     1446230 :                full_cg1_kqmp = zero; full_ur1_kqmp = zero; stern_qq_ierr = stern_qq_ierr + 1
                   +  + ]
    1756         [ +  + ]:         182 :                if (stern_qq_ierr <= ENOUGH_STERN) then
    1757                 :          15 :                  ABI_WARNING(sjoin("Stern at +q", qkp_string, msg))
    1758                 :             :                end if
    1759                 :             :              end if
    1760                 :             : 
    1761                 :             :              ! Store KS e-ph matrix elements for this ipc perturbation.
    1762   [ +  +  +  +  :       43968 :              if (pp_is_gamma .and. (ib_sum >= gqk%bstart_k .and. ib_sum <= gqk%bstop_k)) then
                   +  + ]
    1763                 :        1020 :                ii = ib_sum - bstart_k + 1
    1764   [ +  +  +  + ]:       36588 :                gks_atm(:,:,ii,ipc) = stern_kmp%eig1_k(:, bstart_kq:bstop_kq, ib_sum)
    1765                 :             :              end if
    1766                 :             : 
    1767         [ -  + ]:       43968 :              if (use_dg0) then
    1768                 :             :                ! -----------------------------------------------------------------------------------------
    1769                 :             :                ! Auxiliary state for the dG0/de term at q=Gamma (Appendix A, degenerate intermediate states):
    1770                 :             :                !
    1771                 :             :                !   |chi_{n'k-p}> = sum_{n''} eta^2/(Delta^2+eta^2) g^KS_{n''n'} |psi_{n''k-p}>,
    1772                 :             :                !    Delta = e_{n''} - e_{n'}.
    1773                 :             :                !
    1774                 :             :                ! The exact variation dG0 = G0 dV G0 gives, for each pair (n'', n'), the partial fractions
    1775                 :             :                ! [1/(e-e_{n''}) - 1/(e-e_{n'})] / Delta. The +q/-q dpsi terms reproduce them with 1/Delta
    1776                 :             :                ! regularized as Delta/(Delta^2+eta^2) (see full_active_wf1), i.e. only the fraction
    1777                 :             :                ! Delta^2/(Delta^2+eta^2). The missing Lorentzian-weighted remainder is approximated by the
    1778                 :             :                ! double pole 1/(e-e_{n'})^2 (exact for Delta=0, error O(Delta) damped by the weight) and
    1779                 :             :                ! contributes -<m|e^{i(p+G)r}|chi_{n'}> dWtilde_{n'}/de(G,G') <n'|e^{-i(p+G')r'}|n>.
    1780                 :             :                ! For a non-degenerate n' the weight collapses to delta_{n''n'} and chi -> (d eps_{n'}) psi_{n'}.
    1781                 :             :                ! Inside a degenerate manifold the full block P dV P enters, so the result is basis-invariant.
    1782                 :             :                ! n'' runs over the active space only: the Sternheimer complement is not regularized.
    1783                 :             :                ! -----------------------------------------------------------------------------------------
    1784         [ #  # ]:           0 :                chi_ug_kqmp = czero_gw
    1785         [ #  # ]:           0 :                do jb_sum=1,nbsum
    1786   [ #  #  #  # ]:           0 :                  if (dtset%userrb /= zero .and. jb_sum /= ib_sum) cycle ! debug: non-degenerate (diagonal) form
    1787                 :           0 :                  delta_E = ebsum_kmp - ebands%eig(jb_sum, ikqmp_ibz, spin)
    1788                 :           0 :                  wgt_dg0 = eta_sum ** 2 / (delta_E ** 2 + eta_sum ** 2)
    1789                 :           0 :                  ctmp_dp = wgt_dg0 * r2c(stern_kmp%eig1_k(:, jb_sum, ib_sum))
    1790                 :             :                  chi_ug_kqmp = chi_ug_kqmp + cmplx(ctmp_dp, kind=gwp) * &
    1791   [ #  #  #  # ]:           0 :                    cmplx(stern_kmp%cgq(1,:,jb_sum), stern_kmp%cgq(2,:,jb_sum), kind=gwp)
    1792                 :             :                end do
    1793                 :             :                ! Store chi^*(r): the oscillator is computed with bra and ket exchanged, as for Delta_q psi below.
    1794                 :           0 :                call fft_ug(npw_kqmp, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_kqmp, gbound_kqmp, chi_ug_kqmp, chi_ur_kqmp)
    1795         [ #  # ]:           0 :                chi_ur_kqmp = GWPC_CONJG(chi_ur_kqmp)
    1796                 :             :              end if
    1797                 :             : 
    1798                 :             :              ! Compute <m,k+q|e^{i(p+G)r}|Delta_q psi_{bsum,k-p}>
    1799                 :             :              ! Exchange bra and ket and take the CC of the FFT.
    1800         [ +  + ]:   233466816 :              full_ur1_kqmp = GWPC_CONJG(full_ur1_kqmp)
    1801                 :             : 
    1802         [ +  + ]:      510144 :              do m_kq=bstart_kq, bstop_kq
    1803                 :      466176 :                im_kq = m_kq - bstart_kq + 1
    1804   [ +  -  -  +  :  2443688448 :                cwork_ur = full_ur1_kqmp * ur_mkq(:,m_kq)
             -  -  +  + ]
    1805                 :             : 
    1806                 :      466176 :                ctmp_dp = r2c(stern_kmp%eig1_k(:, m_kq, ib_sum))
    1807                 :      466176 :                e_mkq = ebands%eig(m_kq, ikq_ibz, spin)
    1808                 :      466176 :                delta_E = ebsum_kmp - e_mkq
    1809                 :      466176 :                inv_delta_E = delta_E / ( delta_E ** 2 + eta_sum ** 2)
    1810                 :      466176 :                ctmp_dp = ctmp_dp * inv_delta_E * sqrt(vcp%i_sz)
    1811                 :             :                !ctmp_dp = zero
    1812                 :             :                !if (qq_is_gamma) ctmp_dp = zero
    1813                 :             : 
    1814                 :             :                ! SC: the bare-exchange occupation factor belongs to the intermediate state entering tilde_v
    1815                 :             :                ! i.e. f(ib_sum, k-p) for the +q term of Delta Sigma. See Eqs. (eq:sigma_g) & (tv_bare) in the paper.
    1816         [ +  + ]:      466176 :                if (need_x_kmp) then
    1817                 :      298752 :                  call fft_ur(npw_x, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_x, gbound_x, cwork_ur, rhotwg_x)
    1818                 :             :                  !if (pp_is_gamma) print *, "rhotwg_x(1)", rhotwg_x(1), "vc(0)", vc_sqrt_gx(1)
    1819                 :      298752 :                  ctmp_gwpc = rhotwg_x(1)
    1820                 :      298752 :                  call sigtk_multiply_by_vc_sqrt("C", npw_x, nspinor, ndat1, vc_sqrt_gx, rhotwg_x)
    1821         [ +  + ]:      298752 :                  if (pp_is_gamma) then
    1822                 :             :                    ! SC: the FFT gives the CC of the wanted oscillator (bra/ket exchanged, see above);
    1823                 :             :                    ! mode "C" conjugates the body (G/=0), so the head (G=0) saved BEFORE that call
    1824                 :             :                    ! must be conjugated here as well. The -q term keeps the derivative wfn in the
    1825                 :             :                    ! bra, uses mode "N", and thus needs no conjugation.
    1826                 :       10464 :                    rhotwg_x(1) = GWPC_CONJG(ctmp_gwpc) * cmplx(sqrt(vcp%i_sz), 0.0_gwp)
    1827                 :             :                    !print *, "ctmp_dp +qq", ctmp_gwpc
    1828                 :             :                    !print *, "rhotwg_x(1)", rhotwg_x(1)
    1829                 :             :                    !rhotwg_x(1) = ctmp_dp
    1830                 :             :                  end if
    1831         [ +  + ]:     7429632 :                  rhotwg_c(:) = rhotwg_x(1:npw_c*nspinor)
    1832                 :             :                else
    1833                 :      167424 :                  call fft_ur(npw_c, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_c, gbound_c, cwork_ur, rhotwg_c)
    1834                 :      167424 :                  ctmp_gwpc = rhotwg_c(1)
    1835                 :      167424 :                  call sigtk_multiply_by_vc_sqrt("C", npw_c, nspinor, ndat1, vc_sqrt_gx, rhotwg_c)
    1836         [ +  + ]:      167424 :                  if (pp_is_gamma) then
    1837                 :             :                    ! SC: the FFT gives the CC of the wanted oscillator (bra/ket exchanged, see above);
    1838                 :             :                    ! mode "C" conjugates the body (G/=0), so the head (G=0) saved BEFORE that call
    1839                 :             :                    ! must be conjugated here as well. The -q term keeps the derivative wfn in the
    1840                 :             :                    ! bra, uses mode "N", and thus needs no conjugation.
    1841                 :       14208 :                    rhotwg_c(1) = GWPC_CONJG(ctmp_gwpc) * cmplx(sqrt(vcp%i_sz), 0.0_gwp)
    1842                 :             :                    !rhotwg_c(1) = ctmp_dp
    1843                 :             :                  end if
    1844                 :             :                end if
    1845                 :             : 
    1846         [ -  + ]:      466176 :                if (use_dg0) then
    1847                 :             :                  ! <m,k+q| e^{i(p+G)r} |chi_{bsum,k-p}> * vc_sqrt(p,G): bra and ket exchanged as above, hence mode "C".
    1848                 :             :                  ! Only the correlation sphere is needed since the bare v is frequency-independent.
    1849   [ #  #  #  #  :           0 :                  cwork_ur = chi_ur_kqmp * ur_mkq(:,m_kq)
             #  #  #  # ]
    1850                 :           0 :                  call fft_ur(npw_c, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_c, gbound_c, cwork_ur, rhotwg_chi)
    1851                 :           0 :                  call sigtk_multiply_by_vc_sqrt("C", npw_c, nspinor, ndat1, vc_sqrt_gx, rhotwg_chi)
    1852         [ #  # ]:           0 :                  if (pp_is_gamma) then
    1853                 :             :                    ! Analytic head: <m,k|chi_{bsum,k}> = eta^2/(Delta^2+eta^2) g^KS_{m,bsum} since m is in the active space.
    1854                 :           0 :                    wgt_dg0 = eta_sum ** 2 / (delta_E ** 2 + eta_sum ** 2)
    1855   [ #  #  #  # ]:           0 :                    if (dtset%userrb /= zero) wgt_dg0 = merge(one, zero, m_kq == ib_sum) ! debug: diagonal form
    1856                 :           0 :                    rhotwg_chi(1) = cmplx(wgt_dg0 * r2c(stern_kmp%eig1_k(:, m_kq, ib_sum)) * sqrt(vcp%i_sz), kind=gwp)
    1857                 :             :                  end if
    1858                 :             :                end if
    1859                 :             : 
    1860         [ +  + ]:     2692800 :                do n_k=bstart_k, bstop_k
    1861                 :     2182656 :                  in_k = n_k - bstart_k + 1
    1862                 :             : 
    1863         [ +  + ]:     2182656 :                  if (dtset%gwpt_wmode == 1) then
    1864                 :             :                    ! SC: +2 because omegas_nk(1) = e_nk and omegas_nk(2:cnt) = e_mkq for all m_kq bands
    1865                 :      953856 :                    iw_mkq = m_kq - bstart_kq + 2
    1866                 :             :                    ! Take the average at e_nk and e_mkq
    1867         [ +  + ]:    62954496 :                    ctmp_gwpc = half * sum(rhotwg_c(:) * (vec_gwc_nk(:,1,n_k) + vec_gwc_nk(:,iw_mkq,n_k)))
    1868                 :             :                  else
    1869                 :             :                    ! Use the value at e_nk
    1870         [ +  + ]:    19660800 :                    ctmp_gwpc = sum(rhotwg_c(:) * (vec_gwc_nk(:,1,n_k)))
    1871                 :             :                  end if
    1872                 :             : 
    1873         [ -  + ]:     2182656 :                  if (use_dg0) then
    1874                 :             :                    ! Additional dG0/de term at q=Gamma (Appendix A):
    1875                 :             :                    !   -<m,k| e^{i(p+G)r} |chi_{bsum,k-p}> dWtilde/de(G,G') <bsum,k-p| e^{-i(p+G')r'} |n,k>
    1876                 :             :                    ! This term appears once (it is neither the +q nor the -q dpsi term), hence it is added only here.
    1877         [ #  # ]:           0 :                    if (dtset%gwpt_wmode == 1) then
    1878         [ #  # ]:           0 :                      dg0_tmp = half * sum(rhotwg_chi(:) * (vec_dgwc_nk(:,1,n_k) + vec_dgwc_nk(:,iw_mkq,n_k)))
    1879                 :             :                    else
    1880         [ #  # ]:           0 :                      dg0_tmp = sum(rhotwg_chi(:) * vec_dgwc_nk(:,1,n_k))
    1881                 :             :                    end if
    1882                 :           0 :                    ctmp_gwpc = ctmp_gwpc - dg0_tmp
    1883                 :             :                  end if
    1884                 :             : 
    1885         [ +  + ]:     2182656 :                  if (need_x_kmp) then
    1886                 :     1300992 :                    xdot_tmp = - xdotu(npw_x*nspinor, rhotwg_x, 1, vec_gx_nk(:,n_k), 1)
    1887                 :     1300992 :                    ctmp_gwpc = ctmp_gwpc + xdot_tmp ! * theta_mu_minus_e0i  ! theta_mu_minus_e0i is only needed for metals
    1888                 :             :                  end if
    1889                 :             : 
    1890         [ -  + ]:     2182656 :                  if (dtset%gwcomp == 2) then
    1891         [ #  # ]:           0 :                    ctmp_gwpc = ctmp_gwpc - quarter * dot_product(conjg(rhotwg_c), vec_coh_nk(:, n_k))
    1892                 :             :                  end if
    1893                 :             : 
    1894         [ -  + ]:     2648832 :                  if (dtset%userie < 0) then
    1895         [ #  # ]:           0 :                     if (pp_is_gamma) then
    1896                 :             :                       gsig_atm(1, im_kq, in_k, ipc) = gsig_atm(1, im_kq, in_k, ipc)
    1897                 :             :                       gsig_atm(2, im_kq, in_k, ipc) = gsig_atm(2, im_kq, in_k, ipc)
    1898                 :             :                     else
    1899                 :           0 :                       gsig_atm(1, im_kq, in_k, ipc) = gsig_atm(1, im_kq, in_k, ipc) + real(ctmp_gwpc)
    1900                 :           0 :                       gsig_atm(2, im_kq, in_k, ipc) = gsig_atm(2, im_kq, in_k, ipc) + aimag(ctmp_gwpc)
    1901                 :             :                     end if
    1902                 :             :                  else
    1903                 :     2182656 :                    gsig_atm(1, im_kq, in_k, ipc) = gsig_atm(1, im_kq, in_k, ipc) + real(ctmp_gwpc)
    1904                 :     2182656 :                    gsig_atm(2, im_kq, in_k, ipc) = gsig_atm(2, im_kq, in_k, ipc) + aimag(ctmp_gwpc)
    1905                 :             :                  end if
    1906                 :             : 
    1907                 :             :                end do ! n_k
    1908                 :             :              end do ! m_kq
    1909                 :             : 
    1910                 :             :              !if (.not. qq_is_gamma) then
    1911                 :             :              ! ==========================
    1912                 :             :              ! Same operations but for -q
    1913                 :             :              ! ==========================
    1914                 :             :              ! Set up local potential vlocal1_qq with proper dimensioning, from vtrial1 taking into account the spin
    1915                 :             :              ! and prepare application of the NL part. Each MPI rank prepares its own potential.
    1916                 :             :              call rf_transgrid_and_pack(spin, nspden, psps%usepaw, cplex, nfftf, nfft, ngfft, nvloc, &
    1917                 :       43968 :                                         pawfgr, mpi_enreg, vtrial, v1scf_mq(:,:,:,imyp), vlocal, vlocal1_mqq(:,:,:,:,imyp))
    1918                 :             : 
    1919                 :       43968 :              call gs_ham_kmp%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.)
    1920                 :             : 
    1921                 :       43968 :              call rf_ham_kmp%init(cplex, gs_ham_kmp, ipert, has_e1kbsc=.true.)
    1922                 :       43968 :              call rf_ham_kmp%load_spin(spin, vlocal1=vlocal1_mqq(:,:,:,:,imyp), with_nonlocal=.true.)
    1923                 :             : 
    1924                 :             :              ! ======================
    1925                 :             :              ! NSCF Sternheimer at -q
    1926                 :             :              ! ======================
    1927                 :             :              ! Compute Delta_{-q,idir,ipert} \psi_{bsum, k+q-p}
    1928                 :             :              call wfd%rotate_cg(ib_sum, ndat1, spin, kqmp_ibz, npw_kqmp, kg_kqmp, istwf_kqmp, &
    1929                 :       43968 :                                 cryst, mapl_kqmp, gbound_kqmp, work_ngfft, work, cg_kqmp)
    1930                 :             : 
    1931         [ +  + ]:      510144 :              stern_kqmp%bands_treated_now(:) = 0; stern_kqmp%bands_treated_now(ib_sum) = 1
    1932         [ +  + ]:      510144 :              stern_kqmp%rank_band = 0; u1_band = ib_sum; band_me = ib_sum
    1933                 :             : 
    1934                 :             :              !init_mode = "input"
    1935                 :       43968 :              init_mode = "None"
    1936         [ -  + ]:       43968 :              if (init_mode == "input") then
    1937                 :             :                call cgtk_change_gsphere(nspinor, &
    1938                 :             :                                         npw_kqmp, istwfk1, kg_kqmp, cg1_kqmp, &
    1939                 :           0 :                                         npw_kmp,  istwfk1, kg_kmp, cg1_kmp, work_ngfft, work)
    1940                 :             :              end if
    1941                 :             : 
    1942                 :             :              ! (k-p, k+q-p)
    1943                 :             :              call stern_kqmp%solve(u1_band, band_me, idir, ipert, -qq_bz, gs_ham_kmp, rf_ham_kmp, &
    1944                 :             :                                    ebands%eig(:,ikqmp_ibz,spin), ebands%eig(:,ikmp_ibz,spin), &
    1945                 :             :                                    cg_kqmp, cwaveprj0, cg1_kmp, cwaveprj, msg, ierr, &
    1946         [ +  + ]:      175872 :                                    full_cg1=full_cg1_kmp, full_ur1=full_ur1_star_kmp, init_mode=init_mode)
    1947                 :             : 
    1948         [ +  + ]:   233466816 :              full_ur1_star_kmp = GWPC_CONJG(full_ur1_star_kmp)
    1949                 :             : 
    1950                 :             :              ! The last bands may fail to converge with resid=-two. In this case we ignore the contribution.
    1951         [ +  + ]:       43968 :              if (ierr /= 0) then
    1952   [ +  +  +  +  :     1446230 :                full_cg1_kmp = zero; full_ur1_star_kmp = zero; stern_mq_ierr = stern_mq_ierr + 1
                   +  + ]
    1953         [ +  + ]:         182 :                if (stern_mq_ierr <= ENOUGH_STERN) then
    1954                 :          15 :                  ABI_WARNING(sjoin("Stern at -q:", qkp_string, msg))
    1955                 :             :                end if
    1956                 :             :              end if
    1957                 :             : 
    1958                 :             :              ! For debug, gks_atm2 and gks_atm should be consistent
    1959   [ +  +  +  +  :       43968 :              if (pp_is_gamma .and. (ib_sum >= gqk%bstart_k .and. ib_sum <= gqk%bstop_k)) then
                   +  + ]
    1960                 :        1020 :                in_k = ib_sum - bstart_k + 1
    1961   [ +  +  +  + ]:       36588 :                gks_atm2(:,:,in_k,ipc) = stern_kqmp%eig1_k(:, bstart_kq:bstop_kq, ib_sum)
    1962                 :             :              end if
    1963                 :             : 
    1964                 :       43968 :              call timab(1944, 2, tsec)
    1965                 :       43968 :              call timab(1945, 1, tsec)
    1966         [ +  + ]:      246336 :              do n_k=bstart_k, bstop_k
    1967                 :      202368 :                in_k = n_k - bstart_k + 1
    1968                 :             : 
    1969                 :             :                ! <Delta_{-q} psi_{bsum,k+q-p}|e^{-i(p+G')r}|n,k>
    1970   [ +  -  -  +  :  1042623744 :                cwork_ur = full_ur1_star_kmp * ur_nk(:,n_k)
             -  -  +  + ]
    1971                 :             : 
    1972                 :             :                ! TODO: Recheck equations, may need a complex conjugate
    1973                 :      202368 :                ctmp_dp = r2c(stern_kqmp%eig1_k(:, n_k, ib_sum))
    1974                 :      202368 :                e_nk = ebands%eig(n_k, ik_ibz, spin)
    1975                 :      202368 :                delta_E = ebsum_kqmp - e_nk
    1976                 :      202368 :                inv_delta_E = delta_E / ( delta_E ** 2 + eta_sum ** 2)
    1977                 :      202368 :                ctmp_dp = ctmp_dp * inv_delta_E * sqrt(vcp%i_sz)
    1978                 :             :                !ctmp_dp = zero
    1979                 :             :                !if (qq_is_gamma) ctmp_dp = zero
    1980                 :             : 
    1981                 :             :                ! SC: the bare-exchange occupation factor belongs to the intermediate state entering tilde_v
    1982                 :             :                ! i.e. f(ib_sum, k+q-p) for the -q term of Delta Sigma. See Eqs. (eq:sigma_g) & (tv_bare) in the paper.
    1983         [ +  + ]:      202368 :                if (need_x_kqmp) then
    1984                 :      124800 :                  call fft_ur(npw_x, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_x, gbound_x, cwork_ur, rhotwg_x)
    1985                 :      124800 :                  ctmp_gwpc = rhotwg_x(1)
    1986                 :      124800 :                  call sigtk_multiply_by_vc_sqrt("N", npw_x, nspinor, ndat1, vc_sqrt_gx, rhotwg_x)
    1987         [ +  + ]:      124800 :                  if (pp_is_gamma) then
    1988                 :        4848 :                    rhotwg_x(1) = ctmp_gwpc * cmplx(sqrt(vcp%i_sz),0.0_gwp)
    1989                 :             :                    !print *, "ctmp_dp -qq", ctmp_dp
    1990                 :             :                    !print *, "rhotwg_x(1)", rhotwg_x(1)
    1991                 :             :                    !rhotwg_x(1) = ctmp_dp
    1992                 :             :                  end if
    1993                 :             : 
    1994         [ +  + ]:     3321600 :                  rhotwg_c(:) = rhotwg_x(1:npw_c*nspinor)
    1995                 :             :                else
    1996                 :       77568 :                  call fft_ur(npw_c, nfft, nspinor, ndat1, mgfft, ngfft, istwfk1, kg_c, gbound_c, cwork_ur, rhotwg_c)
    1997                 :       77568 :                  ctmp_gwpc = rhotwg_c(1)
    1998                 :       77568 :                  call sigtk_multiply_by_vc_sqrt("N", npw_c, nspinor, ndat1, vc_sqrt_gx, rhotwg_c)
    1999         [ +  + ]:       77568 :                  if (pp_is_gamma) then
    2000                 :        7008 :                    rhotwg_c(1) = ctmp_gwpc * cmplx(sqrt(vcp%i_sz),0.0_gwp)
    2001                 :             :                    !rhotwg_c(1) = ctmp_dp
    2002                 :             :                  end if
    2003                 :             :                end if
    2004                 :             : 
    2005         [ +  + ]:     2428992 :                do m_kq=bstart_kq, bstop_kq
    2006                 :     2182656 :                  im_kq = m_kq - bstart_kq + 1
    2007                 :             : 
    2008         [ +  + ]:     2182656 :                  if (dtset%gwpt_wmode == 1) then
    2009                 :             :                    ! SC: +2 because omegas_mkq(1) = e_mkq and omegas_mkq(2:cnt) = e_nk for all n_k bands
    2010                 :      953856 :                    iw_nk = n_k - bstart_k + 2
    2011                 :             :                    ! Take the average at e_nk and e_mkq
    2012         [ +  + ]:    62954496 :                    ctmp_gwpc = half * sum(rhotwg_c(:) * (vec_gwc_mkq(:,1,m_kq) + vec_gwc_mkq(:,iw_nk,m_kq)))
    2013                 :             :                  else
    2014                 :             :                    ! Use the value at e_nk. Note in_k index
    2015         [ +  + ]:    19660800 :                    ctmp_gwpc = sum(rhotwg_c(:) * vec_gwc_mkq(:,in_k,m_kq))
    2016                 :             :                  end if
    2017                 :             : 
    2018         [ +  + ]:     2182656 :                  if (need_x_kqmp) then
    2019                 :             :                    ! TODO recheck
    2020                 :     1300992 :                    xdot_tmp = - xdotu(npw_x*nspinor, vec_gx_mkq(:,m_kq), 1, rhotwg_x, 1)
    2021                 :     1300992 :                    ctmp_gwpc = ctmp_gwpc + xdot_tmp ! * theta_mu_minus_e0i ! theta_mu_minus_e0i is only needed for metals
    2022                 :             :                  end if
    2023                 :             : 
    2024         [ -  + ]:     2182656 :                  if (dtset%gwcomp == 2) then
    2025         [ #  # ]:           0 :                    ctmp_gwpc = ctmp_gwpc - quarter * dot_product(conjg(rhotwg_c), vec_coh_mkq(:, m_kq))
    2026                 :             :                  end if
    2027                 :             : 
    2028         [ -  + ]:     2385024 :                  if (dtset%userie < 0) then
    2029         [ #  # ]:           0 :                     if (pp_is_gamma) then
    2030                 :             :                       gsig_atm(1, im_kq, in_k, ipc) = gsig_atm(1, im_kq, in_k, ipc)
    2031                 :             :                       gsig_atm(2, im_kq, in_k, ipc) = gsig_atm(2, im_kq, in_k, ipc)
    2032                 :             :                     else
    2033                 :           0 :                       gsig_atm(1, im_kq, in_k, ipc) = gsig_atm(1, im_kq, in_k, ipc) + real(ctmp_gwpc)
    2034                 :           0 :                       gsig_atm(2, im_kq, in_k, ipc) = gsig_atm(2, im_kq, in_k, ipc) + aimag(ctmp_gwpc)
    2035                 :             :                     end if
    2036                 :             :                  else
    2037                 :     2182656 :                    gsig_atm(1, im_kq, in_k, ipc) = gsig_atm(1, im_kq, in_k, ipc) + real(ctmp_gwpc)
    2038                 :     2182656 :                    gsig_atm(2, im_kq, in_k, ipc) = gsig_atm(2, im_kq, in_k, ipc) + aimag(ctmp_gwpc)
    2039                 :             :                  end if
    2040                 :             : 
    2041                 :             :                  ! DEBUG: sanity check that the +q and -q Sternheimer solutions agree when
    2042                 :             :                  ! qq=pp=Gamma. Note: Disabled it in production as each sum(abs(stern%cgq - ...))
    2043                 :             :                  ! is O(2*npw_kq*nbsum) and is executed inside the innermost m_kq/n_k/ib_sum/imyp loops,
    2044                 :             :                  ! i.e. ~nbsum * my_npert * (bdgw_size)^2 times per (qq=Gamma, pp=Gamma) sub-task.
    2045                 :             :                  ! For a typical run (nbsum~300, npw_kq~few*10^3, bdgw=8) this is ~TB of memory
    2046                 :             :                  ! traffic and turns the Gamma-Gamma sub-task from ~minutes into ~hours.
    2047                 :             :                  !
    2048                 :             :                  !if (qq_is_gamma .and. pp_is_gamma) then
    2049                 :             :                  !  !print '(A7, A7, A7, A7, A7, A7)', 'my_is', 'im_kq', 'in_k', 'ipp_bz', 'ib_sum', 'ipc'
    2050                 :             :                  !  !print '(I7, I7, I7, I7, I7, I7)', my_is,  im_kq,  in_k,  ipp_bz,  ib_sum,  ipc
    2051                 :             :                  !  !print *, "gsig_atm(:, im_kq, in_k, ipc):", gsig_atm(:, im_kq, in_k, ipc)
    2052                 :             :                  !  !print *, "gks_atm(:, im_kq, in_k, ipc):", gks_atm(:, im_kq, in_k, ipc)
    2053                 :             :                  !  !print *, "gks_atm2(:, im_kq, in_k, ipc):", gks_atm2(:, im_kq, in_k, ipc)
    2054                 :             :                  !  !print *, ' '
    2055                 :             : 
    2056                 :             :                  !  rtmp = sum(abs(stern_kqmp%cgq - stern_kmp%cgq)) / size(stern_kqmp%cgq)
    2057                 :             :                  !  if (rtmp > tol14) then
    2058                 :             :                  !    print *, "Sternheimer cgq diff",  rtmp; stop
    2059                 :             :                  !  end if
    2060                 :             : 
    2061                 :             :                  !  ii = npw_kqmp * nspinor
    2062                 :             :                  !  rtmp = sum(abs(cg_kmp(:,1:ii) - cg_kqmp(:,1:ii))) / (two * ii)
    2063                 :             :                  !  if (rtmp > tol14) then
    2064                 :             :                  !    print *, "Sternheimer cg_kmp diff", rtmp; stop
    2065                 :             :                  !  end if
    2066                 :             : 
    2067                 :             :                  !  ii = npw_kqmp * nspinor
    2068                 :             :                  !  rtmp = sum(abs(full_cg1_kmp(:,1:ii) - full_cg1_kqmp(:,1:ii))) / (two * ii)
    2069                 :             :                  !  if (rtmp > tol14) then
    2070                 :             :                  !    print *, "full_cg1_kmp", rtmp; stop
    2071                 :             :                  !  end if
    2072                 :             : 
    2073                 :             :                  !  rtmp = sum(abs(full_ur1_star_kmp - full_ur1_kqmp)) / (nfft * nspinor)
    2074                 :             :                  !  if (rtmp > tol14) then
    2075                 :             :                  !    print *, "full_ur1_kmp diff", rtmp; stop
    2076                 :             :                  !  end if
    2077                 :             :                  !end if ! qq == pp = gamma
    2078                 :             : 
    2079                 :             :                end do ! m_kq
    2080                 :             :              end do ! n_k
    2081                 :       51296 :              call timab(1945, 2, tsec)
    2082                 :             :              !end if ! .not qq_is_gamma.
    2083                 :             :            end do  ! imyp (my perturbations)
    2084                 :             : 
    2085                 :        8024 :            call rf_ham_kqmp%free(); call rf_ham_kmp%free()
    2086                 :             :          end do ! ib_sum (sum over bands)
    2087                 :             : 
    2088                 :             :          ! Show progress of all pp points.
    2089         [ +  + ]:         696 :          if (print_time_pp) then
    2090                 :         267 :            call inds2str(1, " My pp-point:", my_ipp, my_npp(spin), pp_mesh%nbz, msg)
    2091                 :         267 :            call cwtime_report(msg, cpu_pp, wall_pp, gflops_pp);
    2092         [ +  + ]:         267 :            if (my_ipp == LOG_MODP) call wrtout(std_out, "...", do_flush=.True.)
    2093                 :             :          end if
    2094                 :             : 
    2095         [ -  + ]:         696 :          ABI_FREE(kpg_kmp)
    2096         [ -  + ]:         696 :          ABI_FREE(kpg_kqmp)
    2097         [ -  + ]:         696 :          ABI_FREE(ffnl_kmp)
    2098         [ -  + ]:         696 :          ABI_FREE(ffnl_kqmp)
    2099         [ -  + ]:         696 :          ABI_FREE(full_cg1_kqmp)
    2100         [ -  + ]:         696 :          ABI_FREE(full_cg1_kmp)
    2101         [ -  + ]:         696 :          ABI_FREE(rhotwg_c)
    2102         [ -  + ]:         696 :          ABI_FREE(rhotwg_x)
    2103         [ -  + ]:         696 :          ABI_FREE(vc_sqrt_gx)
    2104         [ -  + ]:         696 :          ABI_SFREE(chi_ug_kqmp)
    2105         [ -  + ]:         696 :          ABI_SFREE(rhotwg_chi)
    2106         [ -  + ]:         696 :          ABI_FREE(kinpw_kmp)
    2107         [ -  + ]:         696 :          ABI_FREE(kinpw_kqmp)
    2108         [ -  + ]:         696 :          ABI_FREE(ph3d_kmp)
    2109         [ -  + ]:         696 :          ABI_FREE(ph3d_kqmp)
    2110                 :             : 
    2111         [ +  - ]:         696 :          ABI_SFREE(ylm_kmp)
    2112         [ +  - ]:         696 :          ABI_SFREE(ylm_kqmp)
    2113         [ +  - ]:         696 :          ABI_SFREE(botsq_pbz)
    2114         [ +  - ]:         696 :          ABI_SFREE(otq_pbz)
    2115         [ +  - ]:         696 :          ABI_SFREE(dmeig_pbz)
    2116         [ +  - ]:         696 :          ABI_SFREE(trans_botsq_pbz)
    2117         [ +  - ]:         696 :          ABI_SFREE(trans_otq_pbz)
    2118         [ +  - ]:         696 :          ABI_SFREE(trans_dmeig_pbz)
    2119                 :             : 
    2120                 :         727 :          call stern_kmp%free(); call stern_kqmp%free()
    2121                 :             :        end do ! ipp_bz
    2122                 :             : 
    2123         [ -  + ]:          31 :        ABI_FREE(kpg_k)
    2124         [ -  + ]:          31 :        ABI_FREE(kpg_kq)
    2125         [ -  + ]:          31 :        ABI_FREE(ug_k)
    2126         [ -  + ]:          31 :        ABI_FREE(ug_kq)
    2127                 :             : 
    2128                 :             :        ! Here we are outside of the loop over pp_sum, band_sum and perturbations.
    2129                 :             :        ! Collect gsig_atm and gks_atm inside pert_ppsum_bsum_comm so that all procs can write the data.
    2130                 :             :        !call xmpi_sum_master(gsig_atm, master, gqk%pert_ppsum_bsum_comm%value, ierr)
    2131                 :             :        !call xmpi_sum_master(gks_atm , master, gqk%pert_ppsum_bsum_comm%value, ierr)
    2132                 :             :        !call xmpi_sum_master(gks_atm2, master, gqk%pert_ppsum_bsum_comm%value, ierr)
    2133                 :             :        ! SC: not sure why, but xmpi_sum_master sometimes causes gvals to be filled
    2134                 :             :        ! with zeros and none in the GSTORE.nc file when running in parallel (observed
    2135                 :             :        ! on my desktop, lemaitre4, and lucia).
    2136                 :          31 :        call xmpi_sum(gsig_atm, gqk%pert_ppsum_bsum_comm%value, ierr)
    2137                 :          31 :        call xmpi_sum(gks_atm, gqk%pert_ppsum_bsum_comm%value, ierr)
    2138                 :          31 :        call xmpi_sum(gks_atm2, gqk%pert_ppsum_bsum_comm%value, ierr)
    2139                 :             : 
    2140   [ +  +  +  +  :       36805 :        gsig_atm = gsig_atm / (cryst%ucvol * pp_mesh%nbz)
             +  +  +  + ]
    2141                 :             : 
    2142         [ +  - ]:          31 :        if (dtset%useria == 0) then
    2143   [ -  +  +  +  :       36836 :          gsig_atm = gsig_atm + gks_atm - gxc_atm
          +  +  +  +  +  
                      + ]
    2144         [ #  # ]:           0 :        else if (dtset%useria > 0) then
    2145   [ #  #  #  #  :           0 :          gsig_atm = gxc_atm
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    2146                 :             :        else if (dtset%useria < 0) then
    2147                 :             :          gsig_atm = gsig_atm
    2148                 :             :        end if
    2149                 :             : 
    2150                 :             :        ! Save e-ph matrix elements in the buffer.
    2151   [ +  +  +  +  :       36805 :        my_gbuf(:,:,:,:, my_ik, iqbuf_cnt) = gsig_atm
             +  +  +  + ]
    2152   [ +  +  +  +  :       36805 :        my_gbuf_ks(:,:,:,:, my_ik, iqbuf_cnt) = gks_atm
             +  +  +  + ]
    2153                 :          31 :        state_kq(my_ik, iqbuf_cnt) = GSTORE_KQ_COMPUTED
    2154                 :             : 
    2155         [ -  + ]:         173 :        if (print_time_kk) then
    2156                 :          31 :          call inds2str(3, "My k-point", my_ik, gqk%my_nk, gqk%glob_nk, msg)
    2157         [ +  - ]:          31 :          call cwtime_report(msg, cpu_kk, wall_kk, gflops_kk); if (my_ik == LOG_MODK) call wrtout(std_out, "...", do_flush=.True.)
    2158                 :             :        end if
    2159                 :             :      end do ! my_ik
    2160                 :             : 
    2161                 :             :      ! Dump buffer inside the loop over my_iq (and outside of my_ik) otherwise when restarting GWPT some my_ik points will be missing
    2162         [ +  - ]:          80 :      if (iqbuf_cnt == qbuf_size) call dump_my_gbuf()
    2163                 :             : 
    2164         [ -  + ]:          80 :      ABI_FREE(v1scf_qq)
    2165         [ -  + ]:          80 :      ABI_FREE(vlocal1_qq)
    2166         [ -  + ]:          80 :      ABI_FREE(vlocal1_mqq)
    2167         [ -  + ]:          80 :      ABI_FREE(vxc1_qq)
    2168                 :             : 
    2169   [ +  -  +  - ]:          80 :      if (print_time_qq .and. wall_qq > tol3) then
    2170                 :          80 :        call inds2str(2, "My q-point", my_iq, gqk%my_nq, gqk%glob_nq, msg)
    2171         [ +  + ]:          80 :        call cwtime_report(msg, cpu_qq, wall_qq, gflops_qq); if (my_iq == LOG_MODQ) call wrtout(std_out, "...", do_flush=.True.)
    2172                 :             :      end if
    2173                 :          83 :      call lg_myq%free()
    2174                 :             :    end do ! my_iq
    2175                 :             : 
    2176                 :             :    ! Dump the remainder.
    2177         [ -  + ]:           3 :    if (iqbuf_cnt /= 0) call dump_my_gbuf()
    2178                 :             : 
    2179         [ -  + ]:           3 :    ABI_FREE(ur_nk)
    2180         [ -  + ]:           3 :    ABI_FREE(ur_mkq)
    2181         [ -  + ]:           3 :    ABI_FREE(iq_buf)
    2182         [ -  + ]:           3 :    ABI_FREE(state_kq)
    2183         [ -  + ]:           3 :    ABI_FREE(my_gbuf)
    2184         [ -  + ]:           3 :    ABI_FREE(my_gbuf_ks)
    2185         [ -  + ]:           3 :    ABI_FREE(gsig_atm)
    2186         [ -  + ]:           3 :    ABI_FREE(gks_atm)
    2187         [ -  + ]:           3 :    ABI_FREE(gks_atm2)
    2188         [ -  + ]:           3 :    ABI_FREE(gxc_atm)
    2189         [ -  + ]:           3 :    ABI_FREE(omegas_nk)
    2190         [ -  + ]:           3 :    ABI_FREE(omegas_mkq)
    2191         [ -  + ]:           3 :    ABI_FREE(omegame0i_nk)
    2192         [ -  + ]:           3 :    ABI_FREE(omegame0i_mkq)
    2193         [ -  + ]:           3 :    ABI_FREE(vec_gwc_nk)
    2194         [ -  + ]:           3 :    ABI_SFREE(vec_dgwc_nk)
    2195         [ -  + ]:           3 :    ABI_FREE(vec_gwc_mkq)
    2196         [ -  + ]:           3 :    ABI_SFREE(vec_comp_nk)
    2197         [ -  + ]:           3 :    ABI_SFREE(vec_comp_mkq)
    2198         [ -  + ]:           3 :    ABI_FREE(vec_gx_nk)
    2199         [ -  + ]:           3 :    ABI_FREE(vec_gx_mkq)
    2200         [ -  + ]:           3 :    ABI_FREE(sigcme_nk)
    2201         [ -  + ]:           3 :    ABI_FREE(sigcme_mkq)
    2202         [ -  + ]:           3 :    ABI_SFREE(vec_coh_nk)
    2203         [ -  + ]:           3 :    ABI_SFREE(vec_coh_mkq)
    2204                 :             : 
    2205                 :             :    ! Collect self-energy matrix elements.
    2206                 :             :    if (test_sigma) then
    2207                 :             :      call xmpi_sum(vxc_nk, gqk%kpt_comm%value, ierr)
    2208                 :             :      call xmpi_sum(sigx_nk, gqk%kpt_comm%value, ierr)
    2209                 :             :      call xmpi_sum(sigce0_nk, gqk%kpt_comm%value, ierr)
    2210                 :             :      sigx_nk = -sigx_nk * (one / (cryst%ucvol * pp_mesh%nbz))
    2211                 :             :      sigce0_nk =  sigce0_nk * (one / (cryst%ucvol * pp_mesh%nbz))
    2212                 :             : 
    2213                 :             :      if (gqk%comm%me == master) then
    2214                 :             :        write(ab_out, "(2a)") ch10, " Sigma^x_nk and Sigma^c_nk(E0) in eV:"
    2215                 :             :        do ik_glob=1, gqk%glob_nk
    2216                 :             :          ik_bz = gstore%kglob2bz(ik_glob, spin)
    2217                 :             :          ik_ibz = gstore%kbz2ibz(1, ik_bz)
    2218                 :             :          write(ab_out, "(2a)") "Band     E0    <VxcDFT>   SigX SigC(E0)  for k-point:", trim(ktoa(gstore%kbz(:, ik_bz)))
    2219                 :             :          do band=gqk%bstart_k, gqk%bstop_k
    2220                 :             :            in_k = band - gqk%bstart_k + 1
    2221                 :             :            write(ab_out, "(i5, 4(f8.3))") &
    2222                 :             :              band, ebands%eig(band, ik_ibz, spin) * Ha_eV, &
    2223                 :             :              vxc_nk(in_k, ik_glob) * Ha_eV,  &
    2224                 :             :              real(sigx_nk(in_k, ik_glob)) * Ha_eV, &
    2225                 :             :              real(sigce0_nk(in_k, ik_glob)) * Ha_eV
    2226                 :             :          end do
    2227                 :             :        end do
    2228                 :             :      end if
    2229                 :             : 
    2230                 :             :      ABI_SFREE(vxc_nk)
    2231                 :             :      ABI_SFREE(sigx_nk)
    2232                 :             :      ABI_SFREE(sigce0_nk)
    2233                 :             :    end if ! test_sigma
    2234                 :             : 
    2235         [ +  - ]:           6 :    if (use_lgk) then
    2236         [ +  + ]:           8 :      do my_ik=1,gqk%my_nk
    2237                 :           8 :        call lg_myk(my_ik)%free()
    2238                 :             :      end do
    2239   [ +  -  +  +  :           8 :      ABI_FREE(lg_myk)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                      + ]
    2240                 :             :    end if
    2241                 :             :  end do ! my_is
    2242                 :             : 
    2243                 :           3 :  call xmpi_sum(stern_qq_ierr, comm, ierr)
    2244                 :           3 :  call xmpi_sum(stern_mq_ierr, comm, ierr)
    2245                 :           3 :  call wrtout(units, sjoin(" Total number of failures in Sternheimer solvers at +q:", itoa(stern_qq_ierr)))
    2246                 :           3 :  call wrtout(units, sjoin(" Total number of failures in Sternheimer solvers at -q:", itoa(stern_mq_ierr)))
    2247                 :             : 
    2248                 :           3 :  call cwtime_report(" gwpt_eph full calculation", cpu_all, wall_all, gflops_all, end_str=ch10)
    2249                 :             : 
    2250                 :             :  ! Set gstore_completed to 1 so that we can easily check if restarted is needed.
    2251                 :             :  !if (my_rank == master) then
    2252         [ -  + ]:           3 :    NCF_CHECK(nf90_put_var(root_ncid, root_vid("gstore_completed"), 1))
    2253                 :             :    ! 1 if the DFPT potentials and densities have been Fourier-interpolated (same convention as gstore_compute).
    2254         [ -  + ]:           3 :    NCF_CHECK(nf90_put_var(root_ncid, root_vid("used_ftinterp"), merge(1, 0, need_ftinterp)))
    2255                 :             :    ! gwcomp = 2 means that the COH static remainder has been added to the GWPT matrix elements.
    2256         [ -  + ]:           3 :    NCF_CHECK(nf90_put_var(root_ncid, root_vid("gwcomp"), dtset%gwcomp))
    2257                 :             :  !end if
    2258                 :             :  ! SC: not sure why, but nf90_sync sometimes can cause a deadlock, observed on lemaitre4
    2259                 :             :  ! Follow-up: This sync was not the cause. The deadlock took place because the procs were
    2260                 :             :  ! already out of step because of an earlier collective operation.
    2261         [ -  + ]:           3 :  NCF_CHECK(nf90_sync(root_ncid))
    2262         [ -  + ]:           3 :  NCF_CHECK(nf90_close(root_ncid))
    2263                 :           3 :  call xmpi_barrier(comm)
    2264                 :             : 
    2265                 :             :  ! Reconstruct g(k,q) and g_KS(k,q) matrix elements in the full BZ by symmetry.
    2266         [ -  + ]:           3 :  if (symmetrize) then
    2267                 :           0 :    call gstore_symmetrize(gstore%path, wfk0_path, ngfft, dtset, dtfil, cryst, psps, pawtab, ebands, ifc, comm)
    2268                 :             :  end if
    2269                 :             : 
    2270                 :             :  ! Output some of the results to ab_out for testing purposes
    2271                 :           3 :  call gstore%print_for_abitests(dtset, ebands, .True., with_ks=.True.)
    2272                 :             : 
    2273                 :             :  ! Free memory
    2274         [ -  + ]:           3 :  ABI_FREE(kg_k)
    2275         [ -  + ]:           3 :  ABI_FREE(kg_kq)
    2276         [ -  + ]:           3 :  ABI_FREE(kg_kmp)
    2277         [ -  + ]:           3 :  ABI_FREE(kg_kqmp)
    2278         [ -  + ]:           3 :  ABI_FREE(cg_work)
    2279         [ -  + ]:           3 :  ABI_FREE(ur_star_kmp)
    2280         [ -  + ]:           3 :  ABI_FREE(ur_star_kqmp)
    2281         [ -  + ]:           3 :  ABI_FREE(full_ur1_kqmp)
    2282         [ -  + ]:           3 :  ABI_FREE(full_ur1_star_kmp)
    2283         [ -  + ]:           3 :  ABI_SFREE(chi_ur_kqmp)
    2284         [ -  + ]:           3 :  ABI_FREE(cwork_ur)
    2285         [ -  + ]:           3 :  ABI_FREE(cg_kmp)
    2286         [ -  + ]:           3 :  ABI_FREE(cg_kqmp)
    2287         [ -  + ]:           3 :  ABI_FREE(cg1_kqmp)
    2288         [ -  + ]:           3 :  ABI_FREE(cg1_kmp)
    2289         [ -  + ]:           3 :  ABI_FREE(vtrial)
    2290         [ -  + ]:           3 :  ABI_FREE(work)
    2291         [ -  + ]:           3 :  ABI_FREE(ph1d)
    2292         [ -  + ]:           3 :  ABI_FREE(vlocal)
    2293         [ -  + ]:           3 :  ABI_FREE(gbound_k)
    2294         [ -  + ]:           3 :  ABI_FREE(gbound_kq)
    2295         [ -  + ]:           3 :  ABI_FREE(gbound_kmp)
    2296         [ -  + ]:           3 :  ABI_FREE(gbound_kqmp)
    2297         [ -  + ]:           3 :  ABI_FREE(gbound_c)
    2298         [ -  + ]:           3 :  ABI_FREE(gbound_x)
    2299         [ -  + ]:           3 :  ABI_FREE(done_qbz_spin)
    2300         [ -  + ]:           3 :  ABI_FREE(rhor)
    2301         [ -  + ]:           3 :  ABI_FREE(kxc)
    2302         [ -  + ]:           3 :  ABI_FREE(vxc)
    2303                 :             : 
    2304         [ -  + ]:           3 :  if (dtset%gwcomp == 2) then
    2305         [ #  # ]:           0 :    ABI_FREE(wc0_pbz)
    2306         [ #  # ]:           0 :    do ip_ibz=1,pp_mesh%nibz
    2307                 :           0 :      call wc0_pibz(ip_ibz)%free()
    2308                 :             :    end do
    2309   [ #  #  #  #  :           0 :    ABI_FREE(wc0_pibz)
             #  #  #  # ]
    2310                 :             :  end if
    2311                 :             : 
    2312                 :           3 :  call gs_ham_kqmp%free(); call gs_ham_kmp%free(); call wfd%free(); call vcp%free(); call ppm%free()
    2313                 :           3 :  call pp_mesh%free(); call gsph_c%free(); call gsph_x%free(); call gstore%free()
    2314                 :           3 :  call pawcprj_free(cwaveprj0); call pawcprj_free(cwaveprj)
    2315   [ +  -  -  +  :           3 :  ABI_FREE(cwaveprj0)
          -  -  -  -  -  
                      + ]
    2316   [ +  -  -  +  :           3 :  ABI_FREE(cwaveprj)
          -  -  -  -  -  
                      + ]
    2317                 :             : 
    2318                 :           3 :  call xmpi_barrier(comm) ! This to make sure that the parallel output of GSTORE is completed
    2319   [ -  +  -  +  :          27 :  call cwtime_report(" gwpt_run: MPI barrier before returning.", cpu_all, wall_all, gflops_all, end_str=ch10, comm=comm)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  +  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  +  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  +  -  
          -  -  -  -  +  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          +  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
                   -  + ]
    2320                 :             : 
    2321                 :             : contains
    2322                 :             : 
    2323                 :         489 : subroutine inds2str(level, prefix, my_ik, my_nk, nk_tot, out_str)
    2324                 :             :  integer,intent(in) :: level, my_ik, my_nk, nk_tot
    2325                 :             :  character(len=*),intent(in) :: prefix
    2326                 :             :  character(len=*),intent(out) :: out_str
    2327                 :             : 
    2328   [ +  -  +  - ]:         489 :  out_str = sjoin(prefix, itoa(my_ik), "/", itoa(my_nk), "[", itoa(nk_tot), "]")
    2329   [ -  +  +  +  :        2569 :  out_str = repeat(' ', 4 * level) // trim(out_str)
                   +  - ]
    2330                 :         489 : end subroutine  inds2str
    2331                 :             : 
    2332                 :          80 : subroutine dump_my_gbuf()
    2333                 :             : 
    2334                 :             :  ! This function is called inside the double loop over (my_is, my_iq) or when we exit
    2335                 :             :  ! from the my_iq loop to dump the remainder that is still in the q-buffer,
    2336                 :             :  ! All the MPI procs in the (kpt_comm x pert_comm) grid shall call this contained routine
    2337                 :             :  ! as we have side-effects i.e. iqbuf_cnt set to 0.
    2338                 :             : 
    2339                 :             :  ! On disk we have the global arrays:
    2340                 :             :  !
    2341                 :             :  !      nctkarr_t("gvals", "dp", "two, nb_kq, nb_k, natom3, glob_nk, glob_nq")
    2342                 :             :  !
    2343                 :             :  ! while the local MPI buffers are dimensioned as follows:
    2344                 :             :  !
    2345                 :             :  !      my_gbuf(2, nb_kq, nb_k, natom3, gqk%my_nk, qbuf_size)
    2346                 :             : 
    2347                 :             :  ! If parallelism over perturbation is activated, only the procs treating the first perturbation
    2348                 :             :  ! i.e. the procs treating different k-points for this q are involved in IO
    2349                 :             :  ! as all the local buffers store results for all natom3 perturbations.
    2350                 :             : 
    2351                 :             :  ! NOTE: A similar routine is used in m_gstore. The two implementations should be kept in synch.
    2352                 :             : 
    2353                 :             :  integer :: ii, iq_bz, iq_glob, my_iq
    2354                 :             : 
    2355                 :             :  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    2356                 :             :  ! FIXME: Recheck this part as we have way more levels of parallelism in GWPT
    2357                 :             :  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    2358         [ +  - ]:          80 :  if (gqk%coords_qkpb_sumbp(3) /= 0) goto 10 ! Yes, I'm very proud of this GOTO.
    2359         [ -  + ]:          80 :  if (gqk%pert_ppsum_bsum_comm%me /= 0) goto 10 ! Yes, I'm very proud of this GOTO.
    2360                 :             :  ! SC: I commented out the above two GOTOs to avoid the deadlock issue on my desktop, lemaitre4 and lucia.
    2361                 :             :  ! Follow-up: The GOTOs were not the cause. The first access to the variables that were not prepared
    2362                 :             :  ! triggered a collective metadata read done by the writers only. All the variables are now prepared after
    2363                 :             :  ! the open (gstore_prepare_mpiio), so the GOTOs are restored. Only one proc of pert_ppsum_bsum_comm writes
    2364                 :             :  ! the data now.
    2365                 :             : 
    2366                 :             :  !iq_buf(:, iqbuf_cnt) = [my_iq, iq_bz]
    2367                 :          80 :  my_iq = iq_buf(1, 1)
    2368                 :          80 :  iq_glob = my_iq + gqk%my_qstart - 1
    2369                 :             : 
    2370                 :             :  !print *, "in dump_my_gbuf with start: ", [1, 1, 1, 1, gqk%my_kstart, iq_glob]
    2371                 :             :  !print *, "                  count; ", [2, gqk%nb_kq, gqk%nb_k, gqk%natom3, gqk%my_nk, iqbuf_cnt]
    2372                 :             :  !print *, "my_gbuf", my_gbuf(:,:,:,natom3,1,1)
    2373                 :             : 
    2374                 :             :  ! Output g^Sigma
    2375                 :             :  ! NB: this is an individual IO operation
    2376                 :             :  ncerr = nf90_put_var(spin_ncid, spin_vid("gvals"), my_gbuf, &
    2377                 :             :                       start=[1, 1, 1, 1, gqk%my_kstart, iq_glob], &
    2378   [ +  +  +  + ]:        1040 :                       count=[2, gqk%nb_kq, gqk%nb_k, gqk%natom3, gqk%my_nk, iqbuf_cnt])
    2379         [ -  + ]:          80 :  NCF_CHECK(ncerr)
    2380                 :             : 
    2381                 :             :  ! Output g^KS
    2382                 :             :  ncerr = nf90_put_var(spin_ncid, spin_vid("gvals_ks"), my_gbuf_ks, &
    2383                 :             :                       start=[1, 1, 1, 1, gqk%my_kstart, iq_glob], &
    2384   [ +  +  +  + ]:        1040 :                       count=[2, gqk%nb_kq, gqk%nb_k, gqk%natom3, gqk%my_nk, iqbuf_cnt])
    2385         [ -  + ]:          80 :  NCF_CHECK(ncerr)
    2386                 :             : 
    2387                 :             :  ncerr = nf90_put_var(root_ncid, root_vid("gstore_glob_state_kqs"), state_kq(:, 1:iqbuf_cnt), &
    2388                 :             :                       start=[gqk%my_kstart, iq_glob, spin], &
    2389   [ +  +  +  + ]:         560 :                       count=[gqk%my_nk, iqbuf_cnt, 1])
    2390         [ -  + ]:          80 :  NCF_CHECK(ncerr)
    2391                 :             : 
    2392                 :             :  ! Only one proc sets the entry in done_qbz_spin to 1 for all the q-points in the buffer.
    2393                 :             :  !if (all(gqk%coords_qkpb_sumbp(2:3) == [0, 0]))  then
    2394         [ +  + ]:         160 :    do ii=1,iqbuf_cnt
    2395                 :          80 :      iq_bz = iq_buf(2, ii)
    2396   [ +  +  -  +  :         320 :      NCF_CHECK(nf90_put_var(root_ncid, root_vid("gstore_done_qbz_spin"), 1, start=[iq_bz, spin]))
                   -  - ]
    2397                 :             :    end do
    2398                 :             :  !end if
    2399                 :             : 
    2400                 :             :  ! Zero the counter before returning, otherwise the flush after the my_iq loop dumps the last q-points again
    2401                 :             :  ! with state_kq already reset to MISSING (same logic as in m_gstore).
    2402                 :          80 : 10 iqbuf_cnt = 0
    2403   [ +  +  +  + ]:         320 :  iq_buf = 0
    2404   [ +  +  +  + ]:         256 :  state_kq = GSTORE_KQ_MISSING
    2405                 :             : 
    2406                 :             :  ! SC: these syncs can deadlock on lemaitre4; keep them disabled.
    2407                 :             :  ! SC: nf90_sync is collective on a file opened with comm (HDF5 flush of the metadata cache), so all the procs
    2408                 :             :  ! must call it the same number of times. dump_my_gbuf is called a number of times that depends on the proc
    2409                 :             :  ! (my_nq differs when nqbz is not a multiple of the number of q-blocks, q-points done in a previous run are
    2410                 :             :  ! skipped on restart), hence these syncs deadlock on the machine. The file is synced once by all the procs
    2411                 :             :  ! after the loops. The syncs are not needed for restart: the q-points written before a kill are in the file
    2412                 :             :  ! (checked with kill -9 followed by eph_restart 1).
    2413                 :             :  !NCF_CHECK(nf90_sync(spin_ncid))
    2414                 :             :  !NCF_CHECK(nf90_sync(root_ncid))
    2415                 :             : 
    2416                 :          80 : end subroutine dump_my_gbuf
    2417                 :             : 
    2418                 :         169 : integer function root_vid(var_name)
    2419                 :             :   character(len=*),intent(in) :: var_name
    2420         [ +  - ]:         169 :   root_vid = nctk_idname(root_ncid, var_name)
    2421                 :             : end function root_vid
    2422                 :             : 
    2423                 :         160 : integer function spin_vid(var_name)
    2424                 :             :   character(len=*),intent(in) :: var_name
    2425                 :         160 :   spin_vid = nctk_idname(spin_ncid, var_name)
    2426                 :             : end function spin_vid
    2427                 :             : 
    2428                 :             : end subroutine gwpt_run
    2429                 :             : !!***
    2430                 :             : 
    2431                 :             : end module m_gwpt
    2432                 :             : !!***
        

Generated by: LCOV version 2.3-1