LCOV - code coverage report
Current view: top level - src/78_eph - m_sigmaph.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.4 % 2216 1893
Test Date: 2026-09-19 15:24:51 Functions: 61.9 % 21 13

            Line data    Source code
       1              : !!****m* ABINIT/m_sigmaph
       2              : !! NAME
       3              : !!  m_sigmaph
       4              : !!
       5              : !! FUNCTION
       6              : !!  Compute the matrix elements of the Fan-Migdal Debye-Waller self-energy in the KS basis set.
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2008-2026 ABINIT group (MG, HM)
      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_sigmaph
      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_hide_blas
      32              :  use m_copy
      33              :  use m_ifc
      34              :  use m_ebands
      35              :  use m_ddk
      36              :  use m_dvdb,           only : dvdb_t
      37              :  use m_fft
      38              :  use m_hamiltonian,    only : gs_hamiltonian_type, rf_hamiltonian_type
      39              :  use m_pawcprj,        only : pawcprj_type, pawcprj_free
      40              :  use m_wfd,            only : wfd_t, u1_cache_t
      41              :  use m_wfk
      42              :  use m_skw
      43              :  use m_krank,           only : krank_t
      44              :  use m_lgroup
      45              :  use m_ephwg
      46              :  use m_sort
      47              :  use m_hdr
      48              :  use m_sigtk
      49              :  use m_ephtk
      50              :  use m_eph_double_grid
      51              :  use netcdf
      52              :  use m_nctk
      53              :  use m_rf2
      54              :  use m_clib
      55              :  use m_mkffnl
      56              : 
      57              :  use defs_abitypes,    only : mpi_type
      58              :  use m_dtfil,          only : datafiles_type
      59              :  use m_dtset,          only : dataset_type
      60              :  use defs_datatypes,   only : pseudopotential_type
      61              :  use m_time,           only : cwtime, cwtime_report, timab, sec2str
      62              :  use m_fstrings,       only : itoa, ftoa, sjoin, ktoa, ltoa, strcat
      63              :  use m_numeric_tools,  only : arth, c2r, get_diag, linfit, iseven, simpson_cplx, simpson, print_arr, inrange
      64              :  use m_io_tools,       only : iomode_from_fname, file_exists, is_open, open_file, flush_unit
      65              :  use m_special_funcs,  only : gaussian
      66              :  use m_fftcore,        only : ngfft_seq, sphereboundary, get_kg, kgindex
      67              :  use m_cgtk,           only : cgtk_rotate, cgtk_change_gsphere
      68              :  use m_cgtools,        only : cg_zdotc, cg_real_zdotc, cg_zgemm
      69              :  use m_crystal,        only : crystal_t
      70              :  use m_kpts,           only : kpts_ibz_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map
      71              :  use m_occ,            only : occ_fd, occ_be
      72              :  use m_kg,             only : getph, mkkpg
      73              :  use m_bz_mesh,        only : isamek
      74              :  use m_getgh1c,        only : getgh1c, rf_transgrid_and_pack
      75              :  use m_ioarr,          only : read_rhor
      76              :  use m_paw_sphharm,    only : ylm_angular_mesh
      77              :  use m_pawang,         only : pawang_type
      78              :  use m_pawrad,         only : pawrad_type
      79              :  use m_pawtab,         only : pawtab_type
      80              :  use m_pawrhoij,       only : pawrhoij_type
      81              :  use m_pawfgr,         only : pawfgr_type
      82              :  use m_dfpt_cgwf,      only : stern_t
      83              :  use m_phonons,        only : phstore_t
      84              :  use m_pstat,          only : pstat_proc
      85              : 
      86              :  implicit none
      87              : 
      88              :  private
      89              : !!***
      90              : 
      91              : #ifdef HAVE_MPI1
      92              :  include 'mpif.h'
      93              : #endif
      94              : 
      95              :  ! Store the weights in single or double precision
      96              :  integer,private,parameter :: DELTAW_KIND = dp
      97              :  !integer,private,parameter :: DELTAW_KIND = sp
      98              : 
      99              : !----------------------------------------------------------------------
     100              : 
     101              : !!****t* m_sigmaph/sigmaph_t
     102              : !! NAME
     103              : !! sigmaph_t
     104              : !!
     105              : !! FUNCTION
     106              : !! Container for the (diagonal) matrix elements of the electron-phonon self-energy
     107              : !! in the KS representation i.e. Sigma_eph(omega, T, band, k, spin).
     108              : !! Provides methods to compute QP corrections, spectral functions, QP linewidths and
     109              : !! save the results to netcdf file.
     110              : !!
     111              : !! SOURCE
     112              : 
     113              :  type,public :: sigmaph_t
     114              : 
     115              :   integer :: nkcalc
     116              :    ! Number of k-points computed (inside energy window)
     117              : 
     118              :   integer :: max_nbcalc
     119              :    ! Maximum number of bands computed (max over nkcalc and spin).
     120              : 
     121              :   integer :: nsppol
     122              :    ! Number of independent spin polarizations.
     123              : 
     124              :   integer :: nspinor
     125              :    ! Number of spinor components.
     126              : 
     127              :   integer :: nwr
     128              :    ! Number of frequency points along the real axis for Sigma(w) and spectral function A(w)
     129              :    ! Odd number so that the mesh is centered on the KS energy.
     130              :    ! The spectral function is computed only if nwr > 0 (taken from dtset%nfreqsp)
     131              : 
     132              :   integer :: ntemp
     133              :    ! Number of temperatures.
     134              : 
     135              :   integer :: symsigma
     136              :    ! 1 if matrix elements should be symmetrized.
     137              :    ! Required when the sum over q in the BZ is replaced by IBZ(k).
     138              : 
     139              :   integer :: timrev
     140              :    ! timrev = 1 if the use of time-reversal is allowed; 0 otherwise
     141              : 
     142              :   integer :: nbsum
     143              :    ! Total number of bands used in sum over states without taking into account MPI distribution.
     144              : 
     145              :   integer :: bsum_start, bsum_stop
     146              :    ! First and last band included in self-energy sum without taking into account MPI distribution inside bsum_comm
     147              :    ! nbsum = bsum_stop - bsum_start + 1
     148              : 
     149              :   integer :: my_bsum_start, my_bsum_stop
     150              :    ! Initial and final band index included in self-energy sum
     151              :    ! Processor-dependent if Re-Im calculation.
     152              :    ! Processor-independent and computed at runtime on the basis of the nk states in Sigma_{nk} if imag_only
     153              : 
     154              :   integer :: my_npert
     155              :    ! Number of atomic perturbations or phonon modes treated by this MPI rank.
     156              :    ! Note that natom3 are equally distributed. This allows us to use allgather instead of allgatherv
     157              : 
     158              :   type(xcomm_t) :: pert_comm
     159              :    ! MPI communicator for parallelism over atomic perturbations.
     160              : 
     161              :   type(xcomm_t) :: qb_comm
     162              :    ! MPI communicator used to distribute (band_sum, q-points)
     163              : 
     164              :   type(xcomm_t) :: qpt_comm
     165              :    ! MPI communicator for q-points
     166              : 
     167              :   type(xcomm_t) :: bsum_comm
     168              :    ! MPI communicator for bands in self-energy sum
     169              : 
     170              :   type(xcomm_t) :: kcalc_comm
     171              :    ! MPI communicator for parallelism over k-points (high-level)
     172              : 
     173              :   type(xcomm_t) :: spin_comm
     174              :    ! MPI communicator for parallelism over spins (high-level)
     175              : 
     176              :   type(xcomm_t) :: pqb_comm
     177              :     ! MPI communicator for the (perturbation, band_sum, qpoint_sum)
     178              : 
     179              :   type(xcomm_t) :: ncwrite_comm
     180              :    ! MPI communicator for parallel netcdf IO used to write results for the different k-points/spins
     181              : 
     182              :   integer :: coords_pqbks(5)
     183              :    ! Cartesian coordinates of this processor in the Cartesian grid.
     184              : 
     185              :   integer :: nqbz
     186              :    ! Number of q-points in the (dense) BZ for sigma integration
     187              : 
     188              :   integer :: nqibz
     189              :    ! Number of q-points in the (dense) IBZ for sigma integration
     190              : 
     191              :   integer :: nqibz_k
     192              :    ! Number of q-points in the IBZ(k). Depends on ikcalc.
     193              : 
     194              :   integer :: my_nqibz_k
     195              :    ! Number of q-points in the IBZ(k) treated by this MPI proc. Depends on ikcalc.
     196              :    ! Differs from nqibz_k only if imag with tetra because in this case we can introduce a cutoff on the weights
     197              : 
     198              :   integer :: lgk_nsym
     199              :    ! Number of symmetries in the little group of k. Depends on ikcalc.
     200              : 
     201              :   integer :: ncid = nctk_noid
     202              :    ! Netcdf file handle used to save results.
     203              : 
     204              :   integer :: mpw
     205              :    ! Maximum number of PWs for all possible k+q
     206              : 
     207              :   integer :: bcorr = 0
     208              :    ! 1 to include Blochl correction in the tetrahedron method else 0.
     209              : 
     210              :   integer :: zinv_opt = 1
     211              :    ! Defines the algorithm used to compute the tetrahedron weights for 1/z if re-im computation
     212              :    ! 1 for S. Kaprzyk routines,
     213              :    ! 2 for Lambin-Vigneron.
     214              : 
     215              :   integer :: ntheta = 0, nphi = 0
     216              :    ! Number of division for spherical integration of Frohlich term.
     217              : 
     218              :   integer :: angl_size = 0
     219              :    ! Dimension of angular mesh for spherical integration of the Frohlich self-energy
     220              :    ! angl_size = ntheta * nphi
     221              : 
     222              :   complex(dp) :: ieta
     223              :    ! Used to shift the poles in the complex plane (Ha units)
     224              :    ! Corresponds to `i eta` term in equations.
     225              : 
     226              :   real(dp) :: elow, ehigh
     227              :    ! min and Max KS energy treated in self-energy +- max phonon energy
     228              :    ! Used to select bands in self-energy sum if imag_only and select q-points in qpoints_oracle
     229              : 
     230              :   real(dp) :: phwinfact = four
     231              :    ! phwinfact * wmax is used to define the energy window for filtering electronic states
     232              :    ! in the computation of electron lifetimes.
     233              : 
     234              :   real(dp) :: wr_step
     235              :    ! Step of the linear mesh along the real axis (Ha units).
     236              : 
     237              :   real(dp) :: wmax
     238              :    ! Max phonon energy + buffer. Used to select the bands to sum for the imaginary part
     239              :    ! and filter q-points on the basis of electron energy difference.
     240              : 
     241              :   integer :: qint_method
     242              :    ! Defines the method used for the q-space integration
     243              :    ! 0 -> Standard quadrature (one point per micro zone).
     244              :    ! 1 -> Use tetrahedron method.
     245              : 
     246              :   integer :: frohl_model = 0
     247              :    ! > 0 to treat the q --> 0 divergence and accelerate convergence in polar semiconductors.
     248              :    !   1: Use spherical integration inside the micro zone around the Gamma point
     249              : 
     250              :   integer :: mrta = 0
     251              :    ! 0 to disable MRTA.
     252              :    ! > 0 if linewidths in the energy-momentum relaxation time approximation should be computed
     253              : 
     254              :   real(dp),allocatable :: scratew(:,:,:,:)
     255              :   ! (%phmesh_size, %ntemp, %max_nbcalc, 2)
     256              : 
     257              :   logical :: use_doublegrid = .False.
     258              :    ! whether to use double grid or not
     259              : 
     260              :   logical :: need_ftinterp = .False.
     261              :    ! whether DFPT potentials should be read from the DVDB or Fourier-interpolated on the fly.
     262              : 
     263              :   type(eph_double_grid_t) :: eph_doublegrid
     264              :    ! store the double grid related object
     265              : 
     266              :   logical :: imag_only
     267              :    ! True if only the imaginary part of the self-energy must be computed
     268              : 
     269              :   integer :: gmax(3)
     270              : 
     271              :   integer :: ngqpt(3)
     272              :    ! Number of divisions in the Q mesh in the BZ.
     273              : 
     274              :   integer,allocatable :: bstart_ks(:,:)
     275              :    ! bstart_ks(nkcalc, nsppol)
     276              :    ! Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
     277              :    ! Depends on spin because all degenerate states should be included when symmetries are used.
     278              : 
     279              :   integer,allocatable :: bstop_ks(:,:)
     280              :    ! bstop_ks(nkcalc, nsppol)
     281              : 
     282              :   integer,allocatable :: nbcalc_ks(:,:)
     283              :    ! nbcalc_ks(nkcalc, nsppol)
     284              :    ! Number of bands included in self-energy matrix elements for each k-point in kcalc.
     285              :    ! Depends on spin because all degenerate states should be included when symmetries are used.
     286              : 
     287              :   integer,allocatable :: kcalc2ibz(:,:)
     288              :    !kcalc2ibz(nkcalc, 6))
     289              :    ! Mapping ikcalc --> IBZ as reported by listkk.
     290              : 
     291              :   integer :: my_nspins
     292              :    ! Number of spins treated by this MPI rank
     293              : 
     294              :   integer,allocatable :: my_spins(:)
     295              :    ! my_spins(my_nspins)
     296              :    ! Indirect table giving the spin indices treated by this MPI rank.
     297              :    ! Used only in the collinear case with nsppol = 2 and nspinor == 1
     298              : 
     299              :   integer :: my_nkcalc
     300              :    ! Number of k-points treated by this MPI rank
     301              : 
     302              :   integer,allocatable :: my_ikcalc(:)
     303              :    ! my_ikcalc(my_nkcalc)
     304              :    ! List of ikcalc indices treated by this pool if k-point parallelism is activated.
     305              : 
     306              :   integer,allocatable :: myq2ibz_k(:)
     307              :    ! myq2ibz_k(my_nqibz_k)
     308              :    ! Mapping my q-point index --> index in nqibz_k arrays (IBZ_k)
     309              :    ! Differs from nqibz_k only if imag with tetra because in this case we can introduce a cutoff.
     310              : 
     311              :   integer(i1b),allocatable :: itreat_qibz(:)
     312              :    ! itreat_qibz(nqibz)
     313              :    ! Table used to distribute potentials over q-points in the IBZ.
     314              :    ! The loop over qpts in the IBZ(k) is MPI distributed inside qpt_comm according to this table.
     315              :    ! 0 if this IBZ point is not treated by this proc.
     316              :    ! 1 if this IBZ is treated.
     317              : 
     318              :   integer,allocatable :: my_pinfo(:,:)
     319              :    ! my_pinfo(3, my_npert)
     320              :    ! my_pinfo(1, ip) gives the `idir` index of the ip-th perturbation.
     321              :    ! my_pinfo(2, ip) gives the `ipert` index of the ip-th perturbation.
     322              :    ! my_pinfo(3, ip) gives `pertcase`=idir + (ipert-1)*3
     323              : 
     324              :   integer,allocatable :: pert_table(:,:)
     325              :    ! pert_table(2, natom3)
     326              :    ! pert_table(1, npert): rank of the processor treating this atomic perturbation.
     327              :    ! pert_table(2, npert): imyp index in my_pinfo table, -1 if this rank is not treating ipert.
     328              : 
     329              :   integer,allocatable :: phmodes_skip(:)
     330              :    ! (natom3)
     331              :    ! A mask to skip accumulating the contribution of certain phonon modes
     332              : 
     333              :   integer,allocatable:: ind_qbz2ibz(:,:)
     334              :    ! (6, %nqibz)
     335              :    ! Mapping qBZ to IBZ
     336              : 
     337              :   integer,allocatable:: indkk_kq(:, :)
     338              :    ! (6, %nqibz_k))
     339              :    ! Mapping k+q --> initial IBZ. Depends on ikcalc.
     340              :    ! These table used the conventions for the symmetrization of the wavefunctions expected by cgtk_rotate.
     341              :    ! In this case listkk has been called with symrel and use_symrec=False
     342              : 
     343              :   integer,allocatable :: ind_q2dvdb_k(:,:)
     344              :    ! (6, %nqibz_k))
     345              :    ! Mapping qibz_k --> IBZ found in DVDB file.
     346              :    ! Used when DFPT potentials are read from DVDB file so that we know how to access/symmetrize v1scf
     347              :    ! Depends on ikcalc.
     348              : 
     349              :   integer,allocatable :: ind_ibzk2ibz(:,:)
     350              :    ! (6, %nqibz_k))
     351              :    ! Mapping qibz_k --> IBZ defined by eph_ngqpt_fine.
     352              :    ! Depends on ikcalc.
     353              : 
     354              :   integer,allocatable :: qibz2dvdb(:)
     355              :    ! (%nqibz))
     356              :    ! Mapping dvdb%ibz --> %ibz
     357              : 
     358              :   integer, allocatable :: lgk_sym2glob(:, :)
     359              :    ! lgk_sym2glob(2, lgk_nsym)
     360              :    ! Mapping isym_lg --> [isym, itime]
     361              :    ! where isym is the index of the operation in the global array **crystal%symrec**
     362              :    ! and itim is 2 if time-reversal T must be included else 1. Depends on ikcalc
     363              : 
     364              :   integer,allocatable :: nbsum_rank(:,:)
     365              :    ! (%bsum_comm%nproc, 2)
     366              :    ! (rank+1, 1): Number of bands treated by rank in %bsum_comm.
     367              :    ! (rank+1, 2): bsum_start of MPI rank
     368              :    ! Available only if .not. imag_only
     369              : 
     370              :   real(dp),allocatable :: kcalc(:,:)
     371              :    ! kcalc(3, nkcalc)
     372              :    ! List of k-points where the self-energy is computed.
     373              : 
     374              :   real(dp),allocatable :: qbz(:,:)
     375              :    ! qbz(3, nqbz)
     376              :    ! Reduced coordinates of the q-points in the full BZ.
     377              : 
     378              :   real(dp),allocatable :: qibz(:,:)
     379              :    ! qibz(3, nqibz)
     380              :    ! Reduced coordinates of the q-points in the IBZ (full symmetry of the system).
     381              : 
     382              :   real(dp),allocatable :: wtq(:)
     383              :    ! wtq(nqibz)
     384              :    ! Weights of the q-points in the IBZ (normalized to one).
     385              : 
     386              :   real(dp),allocatable :: qibz_k(:,:)
     387              :    ! qibz(3, nqibz_k)
     388              :    ! Reduced coordinates of the q-points in the IBZ(k). Depends on ikcalc.
     389              : 
     390              :   real(dp),allocatable :: wtq_k(:)
     391              :    ! wtq(nqibz_k)
     392              :    ! Weights of the q-points in the IBZ(k) (normalized to one). Depends on ikcalc.
     393              : 
     394              :   real(dp),allocatable :: srate(:,:,:,:)
     395              :   ! (%bsum_start:%bsum_stop, %nbcalc_ks(ikcalc, spin), %ntemp, %my_nqibz_k))
     396              :   ! This array is initialized inside the (ikcalc, spin) loop
     397              : 
     398              :   real(dp),allocatable :: kTmesh(:)
     399              :    ! kTmesh(ntemp)
     400              :    ! List of temperatures (kT units).
     401              : 
     402              :   real(dp),allocatable :: mu_e(:)
     403              :    ! mu_e(ntemp)
     404              :    ! chemical potential of electrons for the different temperatures.
     405              : 
     406              :   real(dp),allocatable :: e0vals(:)
     407              :    ! (nbcalc_ks)
     408              :    ! KS energies where QP corrections are wantend
     409              :    ! This array is initialized inside the (ikcalc, spin) loop
     410              : 
     411              :   real(dp),allocatable :: vcar_calc(:,:,:,:)
     412              :    ! (3, max_nbcalc, nkcalc, nsppol))
     413              :    ! Diagonal elements of velocity operator in cartesian coordinates for all states in Sigma_nk.
     414              : 
     415              :   real(dp),allocatable :: linewidth_mrta(:,:)
     416              :    ! linewidth_mrta(ntemp, max_nbcalc)
     417              :    ! Linewidths computed within the momentum relaxation time approximation
     418              :    ! for given (ikcalc, spin). Only if imag_only
     419              : 
     420              :   complex(dp),allocatable :: cweights(:,:,:,:,:,:,:)
     421              :    ! (nz, 2, nbcalc_ks, my_npert, my_bsum_start:my_bsum_stop, my_nqibz_k, ndiv))
     422              :    ! Weights for the q-integration of 1 / (e1 - e2 \pm w_{q, nu} + i.eta)
     423              :    ! This array is initialized inside the (ikcalc, spin) loop
     424              : 
     425              :   real(kind=DELTAW_KIND),allocatable :: deltaw_pm(:,:,:,:,:,:)
     426              :    ! (2, nbcalc_ks, my_npert, bsum_start:bsum_stop, my_nqibz_k, ndiv))
     427              :    ! Weights for the q-integration of the two delta (abs/emission) if imag_only
     428              :    ! This array is initialized inside the (ikcalc, spin) loop
     429              : 
     430              :   real(dp),allocatable :: wrmesh_b(:,:)
     431              :    ! wrmesh_b(nwr, max_nbcalc)
     432              :    ! Frequency mesh along the real axis (Ha units) used for the different bands
     433              :    ! Each mesh is **centered** on the corresponding KS energy.
     434              :    ! This array depends on (ikcalc, spin)
     435              : 
     436              :   real(dp), allocatable :: qvers_cart(:,:)
     437              :    ! qvers_cart(3, angl_size)
     438              :    ! For each point of the angular mesh, gives the Cartesian coordinates
     439              :    ! of the corresponding point on an unitary sphere (Frohlich self-energy)
     440              : 
     441              :   real(dp), allocatable :: angwgth(:)
     442              :    ! angwgth(angl_size)
     443              :    ! For each point of the angular mesh, gives the weight
     444              :    ! of the corresponding point on an unitary sphere (Frohlich self-energy)
     445              : 
     446              :   real(dp),allocatable :: frohl_deltas_sphcorr(:,:,:,:)
     447              :    ! (2, ntemp, max_nbcalc, natom3))
     448              :    ! Integration of the imaginary part inside the small sphere around Gamma
     449              :    ! computed numerically with the Frohlich model by Verdi and angular integration.
     450              :    ! The first dimension stores the contributions due to +/- omega_qn
     451              :    ! Used if frohl_model == 1 and imag_only. This array depend on (ikcalc, spin)
     452              :    ! TODO: Finalize implementation
     453              : 
     454              :   real(dp),allocatable :: E2(:)
     455              :    ! E2(ntemp)
     456              :    ! Second-order contribution to total energy
     457              : 
     458              :   integer, allocatable :: qp_done(:,:)
     459              :    ! qp_done(kcalc, spin)
     460              :    ! Keep track of the QP states already computed for restart of the calculation
     461              : 
     462              :   complex(dp),allocatable :: vals_e0ks(:,:)
     463              :    ! vals_e0ks(ntemp, max_nbcalc)
     464              :    ! Sigma_eph(omega=eKS, kT, band) for given (ikcalc, spin).
     465              :    ! Fan-Migdal + Debye-Waller
     466              : 
     467              :   complex(dp),allocatable :: fan_vals(:,:)
     468              :    ! fan_vals(ntemp, max_nbcalc)
     469              :    ! Fan-Migdal
     470              : 
     471              :   complex(dp),allocatable :: E4_vals(:,:)
     472              :    ! E4_vals(ntemp, max_nbcalc)
     473              :    ! nk resolved 4th order contribution to total energy
     474              : 
     475              :   complex(dp),allocatable :: E4_vals2(:,:)
     476              :    ! E4_vals2(ntemp, max_nbcalc)
     477              :    ! nk resolved 4th order contribution to total energy, alternative derivation with g^2
     478              : 
     479              :   complex(dp),allocatable :: fan_stern_vals(:,:)
     480              :    ! fan_stern_vals(ntemp, max_nbcalc)
     481              :    ! Fan-Migdal adiabatic Sternheimer part
     482              : 
     483              :   complex(dp),allocatable :: dvals_de0ks(:,:)
     484              :    ! dvals_de0ks(ntemp, max_nbcalc) for given (ikcalc, spin)
     485              :    ! d Re Sigma_eph(omega, kT, band, kcalc, spin) / d omega (omega=eKS)
     486              : 
     487              :   complex(dp),allocatable :: frohl_dvals_de0ks(:,:)
     488              :    ! frohl_dvals_de0ks(ntemp, max_nbcalc) for given (ikcalc, spin)
     489              :    ! d Re Sigma_frohl(omega, kT, band, kcalc, spin) / d omega (omega=eKS)
     490              : 
     491              :   real(dp),allocatable :: dw_vals(:,:)
     492              :    ! dw_vals(ntemp, max_nbcalc) for given (ikcalc, spin)
     493              :    ! Debye-Waller term (static).
     494              : 
     495              :   real(dp),allocatable :: dw_stern_vals(:,:)
     496              :    !  dw_stern_vals(ntemp, max_nbcalc) for given (ikcalc, spin)
     497              :    !  Debye-Waller Sternheimer term (static) .
     498              : 
     499              :   complex(dp),allocatable :: vals_wr(:,:,:)
     500              :    ! vals_wr(nwr, ntemp, max_nbcalc)
     501              :    ! Sigma_eph(omega, kT, band) for given (ikcalc, spin).
     502              :    ! enk_KS corresponds to nwr/2 + 1.
     503              :    ! This array depends on (ikcalc, spin)
     504              : 
     505              :   integer :: phmesh_size
     506              :    ! Number of phonon frequencies in phonon mesh used for Eliashberg functions and
     507              :    ! and other omega-resolved quantities.
     508              : 
     509              :   real(dp),allocatable :: phmesh(:)
     510              :    ! phmesh(phmesh_size)
     511              :    ! phonon mesh in Ha.
     512              : 
     513              :   real(dp),allocatable :: gf_nnuq(:,:,:,:)
     514              :    ! (nbcalc_ks, natom3, %nqibz_k, 3)
     515              :    ! Quantities needed to compute the generalized Eliashberg functions (gkq2/Fan-Migdal/DW terms)
     516              :    ! This array depends on (ikcalc, spin)
     517              :    ! NB: q-weights for integration are not included.
     518              : 
     519              :   real(dp),allocatable :: gfw_vals(:,:,:)
     520              :    ! gfw_vals(phmesh_size, 3, max_nbcalc)
     521              :    ! Generalized Eliashberg function a2F_{n,k,spin}(w)
     522              :    !     1: |g(k,q)|^2 with delta(e_\nk - e_{m\kq})
     523              :    !     2: Fan-Migdal in the adiabatic approximation
     524              :    !     3: DW contribution in the adiabatic approximation.
     525              :    ! This array depends on (ikcalc, spin)
     526              : 
     527              :   integer :: a2f_ne = 0
     528              :    ! Number of points in a2f_emesh
     529              : 
     530              :   real(dp),allocatable :: a2f_emesh(:)
     531              :    ! a2f_emesh(a2f_ne)
     532              :    ! Energy mesh for electrons
     533              : 
     534              :   real(dp),allocatable :: a2few(:,:,:)
     535              :    ! a2few(a2f_ne, phmesh_size, max_nbcalc)
     536              :    ! FM Eliashberg function a2f_\nk(e, w) = \sum_{mq} |g(k,q)|^2 delta(e - e_{m\kq}) delta(w - w_\qnu}
     537              :    ! This array depends on (ikcalc, spin) and is computed only if prteliash == 3
     538              : 
     539              :   type(ephwg_t) :: ephwg
     540              :    ! This object computes the weights for the BZ integration in q-space if qint_method > 0
     541              : 
     542              :   type(degtab_t),allocatable :: degtab(:,:)
     543              :    ! (nkcalc, nsppol)
     544              :    ! Table used to average QP results in the degenerate subspace if symsigma == 1
     545              : 
     546              :   contains
     547              : 
     548              :     procedure :: write => sigmaph_write
     549              :      ! Write main dimensions and header of sigmaph on a netcdf file.
     550              : 
     551              :     procedure :: compare => sigmaph_compare
     552              :      ! Compare two instances of sigmaph raise error if different
     553              : 
     554              :     procedure :: setup_kcalc => sigmaph_setup_kcalc
     555              :      ! Return tables used to perform the sum over q-points for given k-point.
     556              : 
     557              :     procedure :: gather_and_write => sigmaph_gather_and_write
     558              :      ! Compute the QP corrections.
     559              : 
     560              :     procedure :: print => sigmaph_print
     561              :      ! Print results to main output file.
     562              : 
     563              :     procedure :: free => sigmaph_free
     564              :       ! Free sigmaph object
     565              : 
     566              :     procedure :: get_ebands => sigmaph_get_ebands
     567              :       ! Fill in values in ebands from the sigmaph structure and netcdf file
     568              : 
     569              :     !procedure :: skip_phmode => sigmaph_skip_phmode
     570              :       ! Ignore contribution of phonon mode depending on phonon frequency value or mode index.
     571              : 
     572              :  end type sigmaph_t
     573              : !!***
     574              : 
     575              :  public :: sigmaph        ! Main entry point to compute self-energy matrix elements
     576              :  public :: sigmaph_read   ! Read main dimensions and header of sigmaph from a netcdf file.
     577              :  private :: sigmaph_new   ! Creation method (allocates memory, initialize data from input vars).
     578              : 
     579              :  real(dp),private,parameter :: TOL_EDIFF = 0.001_dp * eV_Ha
     580              : 
     581              :  type frohl_integrator_t
     582              :    integer :: ntheta = 0, nphi = 0
     583              :      ! Number of division for spherical integration of Frohlich term.
     584              : 
     585              :   integer :: angl_size = 0
     586              :    ! Dimension of angular mesh for spherical integration of the Frohlich self-energy
     587              :    ! angl_size = ntheta * nphi
     588              : 
     589              :   real(dp), allocatable :: qvers_cart(:,:)
     590              :    ! qvers_cart(3, angl_size)
     591              :    ! For each point of the angular mesh, gives the Cartesian coordinates
     592              :    ! of the corresponding point on an unitary sphere (Frohlich self-energy)
     593              : 
     594              :   real(dp), allocatable :: angwgth(:)
     595              :    ! angwgth(angl_size)
     596              :    ! For each point of the angular mesh, gives the weight
     597              :    ! of the corresponding point on an unitary sphere (Frohlich self-energy)
     598              : 
     599              :   real(dp), allocatable :: phfrq(:,:)
     600              :   real(dp), allocatable :: displ_cart(:,:,:,:,:)
     601              : 
     602              :  contains
     603              :     procedure :: init => frohl_integrator_init
     604              :     procedure :: free =>  frohl_integrator_free
     605              :     !procedure :: eval => frohl_integrator_eval
     606              :     procedure :: eval_isotropic_avg => frohl_integrator_eval_isotropic_avg
     607              :  end type frohl_integrator_t
     608              : 
     609              : !----------------------------------------------------------------------
     610              : 
     611              : contains  !=====================================================
     612              : !!***
     613              : 
     614              : !----------------------------------------------------------------------
     615              : 
     616              : !!****f* m_sigmaph/sigmaph
     617              : !! NAME
     618              : !!  sigmaph
     619              : !!
     620              : !! FUNCTION
     621              : !!  Compute phonon-contribution to the electron self-energy.
     622              : !!
     623              : !! INPUTS
     624              : !! wfk0_path=String with the path to the GS unperturbed WFK file.
     625              : !! dtfil<datafiles_type>=Variables related to files.
     626              : !! ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
     627              : !! dtset<dataset_type>=All input variables for this dataset.
     628              : !! cryst: Crystalline structure
     629              : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     630              : !! dvdb<dbdb_type>=Database with the DFPT SCF potentials.
     631              : !! ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
     632              : !! wfk_hdr=Header of the WFK file.
     633              : !! pawfgr <type(pawfgr_type)>=fine grid parameters and related data
     634              : !! pawang<pawang_type)>=PAW angular mesh and related data.
     635              : !! pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
     636              : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
     637              : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
     638              : !! comm=MPI communicator.
     639              : !!
     640              : !! OUTPUT
     641              : !!
     642              : !! SOURCE
     643              : 
     644           58 : subroutine sigmaph(wfk0_path, dtfil, ngfft, ngfftf, dtset, cryst, ebands, dvdb, ifc, wfk_hdr, &
     645           58 :                    pawfgr, pawang, pawrad, pawtab, psps, mpi_enreg, comm)
     646              : 
     647              : !Arguments ------------------------------------
     648              : !scalars
     649              :  character(len=*),intent(in) :: wfk0_path
     650              :  integer,intent(in) :: comm
     651              :  type(datafiles_type),intent(in) :: dtfil
     652              :  type(dataset_type),intent(in) :: dtset
     653              :  type(crystal_t),intent(in) :: cryst
     654              :  type(ebands_t),intent(in) :: ebands
     655              :  type(dvdb_t),intent(inout) :: dvdb
     656              :  type(pawang_type),intent(in) :: pawang
     657              :  type(pseudopotential_type),intent(in) :: psps
     658              :  type(pawfgr_type),intent(in) :: pawfgr
     659              :  type(ifc_type),intent(in) :: ifc
     660              :  type(hdr_type),intent(in) :: wfk_hdr
     661              :  type(mpi_type),intent(inout) :: mpi_enreg
     662              : !arrays
     663              :  integer,intent(in) :: ngfft(18),ngfftf(18)
     664              :  type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
     665              :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
     666              : 
     667              : !Local variables ------------------------------
     668              : !scalars
     669              :  integer,parameter :: tim_getgh1c1 = 1, berryopt0 = 0, ider0 = 0, idir0 = 0, istwfk_1 = 1
     670              :  integer,parameter :: useylmgr0 = 0, master = 0, ndat1 = 1, cplex1 = 1, pawread0 = 0, optder0 = 0
     671              :  integer :: band_me, nband_me
     672              :  integer :: my_rank,nsppol,nkpt,iq_ibz,iq_ibz_k,my_npert ! iq_ibz_frohl,iq_bz_frohl,
     673              :  integer :: cplex,db_iqpt,natom,natom3,ipc,nspinor,nprocs, qptopt ! = 1
     674              :  integer :: ibsum_kq, ib_k, u1c_ib_k, band_ks, u1_band, ibsum, ii, jj, iw !ib_kq,
     675              :  integer :: u1_master, ip, sfact
     676              :  integer :: ig, ispinor, ifft !nband_kq,
     677              :  integer :: idir,ipert,ip1,ip2 !,idir1,ipert1,idir2,ipert2
     678              :  integer :: ik_ibz,ikq_ibz,isym_k,isym_kq,trev_k,trev_kq, isym_q, trev_q
     679              :  integer :: iq_ibz_fine,ikq_ibz_fine,ikq_bz_fine
     680              :  integer :: my_spin, spin, istwf_k, istwf_kq, istwf_kqirr, npw_k, npw_kq, npw_kqirr
     681              :  integer :: mpw,ierr,it,imyq,band, ignore_kq, ignore_ibsum_kq
     682              :  integer :: n1,n2,n3,n4,n5,n6,nspden,nu, iang
     683              :  integer :: sij_opt,usecprj,usevnl,optlocal,optnl,opt_gvnlx1
     684              :  integer :: nfft,nfftf,mgfft,mgfftf,nkpg,nkpg_kq,nq,cnt,imyp, q_start, q_stop, restart, enough_stern
     685              :  integer :: nbcalc_ks,nbsum,bsum_start, bsum_stop, bstart_ks,my_ikcalc,ikcalc,bstart,bstop,iatom, sendcount
     686              :  integer :: comm_rpt, osc_npw, stern_comm !, ntheta
     687              :  integer :: nelem, cgq_request ! ffnl_k_request, ffnl_kq_request,
     688              :  real(dp) :: cpu,wall,gflops,cpu_all,wall_all,gflops_all,cpu_ks,wall_ks,gflops_ks,cpu_dw,wall_dw,gflops_dw
     689              :  real(dp) :: cpu_setk, wall_setk, gflops_setk, cpu_qloop, wall_qloop, gflops_qloop, gf_val
     690              :  real(dp) :: ecut,eshift,weight_q,rfact,gmod2,hmod2,ediff,weight, inv_qepsq, simag, q0rad
     691              :  real(dp) :: vkk_norm, vkq_norm, osc_ecut, bz_vol
     692              :  complex(dp) :: cfact,cnum, sig_cplx, cfact2 ! dka,dkap,dkpa,dkpap,
     693              :  logical :: isirr_k, isirr_kq, gen_eigenpb, q_is_gamma, isirr_q, use_ifc_fourq, stern_use_cache, intra_band, same_band
     694              :  logical :: zpr_frohl_sphcorr_done, stern_has_band_para
     695           58 :  type(wfd_t) :: wfd
     696           58 :  type(gs_hamiltonian_type) :: gs_ham_kq
     697           58 :  type(rf_hamiltonian_type) :: rf_ham_kq
     698           58 :  type(sigmaph_t) :: sigma, sigma_restart
     699          580 :  type(ddkop_t) :: ddkop
     700         3016 :  type(crystal_t) :: pot_cryst
     701           58 :  type(hdr_type) :: pot_hdr
     702           58 :  type(phstore_t) :: phstore
     703           58 :  type(u1_cache_t) :: u1c
     704           58 :  type(stern_t) :: stern
     705              :  !type(frohl_integrator_t) :: frohl
     706              :  character(len=5000) :: msg
     707              :  character(len=fnlen) :: sigeph_filepath
     708              : !arrays
     709              :  integer :: g0_k(3),g0_kq(3), units(2), work_ngfft(18), gmax(3)
     710           58 :  integer(i1b),allocatable :: itreatq_dvdb(:)
     711          116 :  integer,allocatable :: kg_k(:,:),kg_kq(:,:),nband(:,:), qselect(:), wfd_istwfk(:)
     712          116 :  integer,allocatable :: gbound_kq(:,:), osc_gbound_q(:,:), osc_gvecq(:,:), osc_indpw(:), root_bcalc(:)
     713           58 :  integer,allocatable :: ibzspin_2ikcalc(:,:)
     714          116 :  integer, allocatable :: recvcounts(:), displs(:)
     715          116 :  real(dp) :: kk(3),kq(3),kk_ibz(3),kq_ibz(3),qpt(3),qpt_cart(3),phfrq(3*cryst%natom), dotri(2),qq_ibz(3)
     716              :  real(dp) :: vk(3), vkq(3), tsec(2), eminmax(2), etot
     717          174 :  real(dp) :: zpr_frohl_sphcorr(3*cryst%natom), vec_natom3(2, 3*cryst%natom)
     718              :  real(dp) :: wqnu,nqnu,gkq2,gkq2_pf,eig0nk,eig0mk,eig0mkq,f_mkq,f_nk, gdw2, gdw2_stern, rtmp
     719          116 :  real(dp) :: fermie1_idir_ipert(3,cryst%natom)
     720           58 :  real(dp),allocatable :: displ_cart(:,:,:,:),displ_red(:,:,:,:)
     721           58 :  real(dp),allocatable :: grad_berry(:,:),kinpw_k(:), kinpw_kq(:),kpg_kq(:,:),kpg_k(:,:)
     722          116 :  real(dp),allocatable :: ffnl_k(:,:,:,:),ffnl_kq(:,:,:,:),ph3d_k(:,:,:),ph3d_kq(:,:,:),v1scf(:,:,:,:)
     723           58 :  real(dp),allocatable :: gkq_atm(:,:,:),gkq_nu(:,:,:),gkq0_atm(:,:,:,:), gaussw_qnu(:)
     724          116 :  real(dp),allocatable :: cg1s_kq(:,:,:,:), h1kets_kq_allperts(:,:,:,:)
     725           58 :  real(dp),allocatable :: stern_ppb(:,:,:,:), stern_dw(:,:,:,:)
     726          116 :  logical,allocatable :: ihave_ikibz_spin(:,:), bks_mask(:,:,:),keep_ur(:,:,:), osc_mask(:)
     727           58 :  real(dp),allocatable :: E4stern_nk(:,:,:,:)
     728          116 :  real(dp),allocatable :: bra_kq(:,:),kets_k(:,:,:),h1kets_kq(:,:,:,:),cgwork(:,:)
     729          116 :  real(dp),allocatable :: ph1d(:,:),vlocal(:,:,:,:),vlocal1(:,:,:,:,:)
     730          116 :  real(dp),allocatable :: vtrial(:,:),gvnlx1(:,:),work(:,:,:,:), vcar_ibz(:,:,:,:)
     731          116 :  real(dp),allocatable :: gs1c(:,:),nqnu_tlist(:),dtw_weights(:,:),dt_tetra_weights(:,:,:),dwargs(:),alpha_mrta(:)
     732           58 :  real(dp),allocatable :: delta_e_minus_emkq(:), gkq_allgather(:,:,:),f_tlist_b(:,:)
     733              :  !real(dp),allocatable :: phfreqs_qibz(:,:), pheigvec_qibz(:,:,:,:), eigvec_qpt(:,:,:)
     734           58 :  real(dp),allocatable :: gkq2_lr(:,:,:), E4(:)
     735              :  complex(dp) :: cp3(3)
     736           58 :  complex(dp),allocatable :: osc_ks(:,:), fmw_frohl_sphcorr(:,:,:,:), cfact_wr(:), tpp_red(:,:)
     737           58 :  complex(gwp),allocatable :: ur_k(:,:), ur_kq(:), work_ur(:), workq_ug(:)
     738           58 :  type(pawcprj_type),allocatable :: cwaveprj0(:,:), cwaveprj(:,:)
     739           58 :  type(pawrhoij_type),allocatable :: pot_pawrhoij(:)
     740              : #if defined HAVE_MPI && !defined HAVE_MPI2_INPLACE
     741              :  integer :: me
     742              :  real(dp),allocatable :: cgq_buf(:)
     743              :  real(dp),pointer :: cgq_ptr(:)
     744              : #endif
     745              : !************************************************************************
     746              : 
     747           58 :  if (psps%usepaw == 1) then
     748            0 :    ABI_ERROR("PAW not implemented")
     749              :    ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/))
     750              :  end if
     751              : 
     752           58 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
     753           58 :  call cwtime(cpu_all, wall_all, gflops_all, "start")
     754              : 
     755          174 :  units = [std_out, ab_out]
     756              : 
     757           58 :  call pstat_proc%print(_PSTAT_ARGS_)
     758              : 
     759              :  ! Copy important dimensions
     760           58 :  natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands%nsppol; nspinor = ebands%nspinor
     761           58 :  nspden = dtset%nspden; nkpt = ebands%nkpt
     762              : 
     763          518 :  stern_has_band_para = .False.; fermie1_idir_ipert = zero
     764              : 
     765              :  ! FFT meshes from input file, not necessarily equal to the ones found in the external files.
     766          232 :  nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3))
     767          406 :  nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3))
     768           58 :  n1 = ngfft(1); n2 = ngfft(2); n3 = ngfft(3)
     769           58 :  n4 = ngfft(4); n5 = ngfft(5); n6 = ngfft(6)
     770              : 
     771              :  ! Get one-dimensional structure factor information on the coarse grid.
     772          174 :  ABI_MALLOC(ph1d, (2,3*(2*mgfft+1)*natom))
     773           58 :  call getph(cryst%atindx, natom, n1, n2, n3, ph1d, cryst%xred)
     774              : 
     775           58 :  ecut = dtset%ecut ! dtset%dilatmx
     776              : 
     777              :  ! Check if a previous netcdf file is present and restart the calculation
     778              :  ! Here we try to read an existing SIGEPH file if eph_restart == 1.
     779              :  ! and we compare the variables with the state of the code (i.e. new sigmaph generated in sigmaph_new)
     780           58 :  restart = 0; ierr = 1; sigeph_filepath = strcat(dtfil%filnam_ds(4), "_SIGEPH.nc")
     781           58 :  if (my_rank == master .and. dtset%eph_restart == 1) then
     782           58 :    sigma_restart = sigmaph_read(sigeph_filepath, dtset, xmpi_comm_self, msg, ierr)
     783              :  end if
     784              : 
     785              :  ! Construct object to store final results.
     786           58 :  sigma = sigmaph_new(dtset, ecut, cryst, ebands, ifc, dtfil, comm)
     787              : 
     788           58 :  if (my_rank == master .and. dtset%eph_restart == 1) then
     789           58 :    if (ierr == 0) then
     790            0 :      if (any(sigma_restart%qp_done /= 1)) then
     791            0 :        call sigma%compare(sigma_restart)
     792              :        ! Get list of QP states that have been computed.
     793            0 :        sigma%qp_done = sigma_restart%qp_done
     794            0 :        restart = 1
     795            0 :        call wrtout(units, "- Restarting from previous SIGEPH.nc file")
     796            0 :        call wrtout(units, sjoin("- Number of k-points completed:", itoa(count(sigma%qp_done == 1)), "/", itoa(sigma%nkcalc)))
     797              :      else
     798              :        ! Previous computation completed, keep a backup of the file and start from scratch.
     799            0 :        restart = 0; sigma%qp_done = 0
     800              :        msg = sjoin("Found SIGEPH.nc file with all QP entries already computed.", ch10, &
     801              :                    "Will overwrite:", sigeph_filepath, ch10, &
     802            0 :                    "Keeping backup copy in:", strcat(sigeph_filepath, ".bkp"))
     803            0 :        call wrtout(ab_out, sjoin("WARNING: ", msg))
     804            0 :        ABI_WARNING(msg)
     805              :        ! Keep backup copy
     806            0 :        ABI_CHECK(clib_rename(sigeph_filepath, strcat(sigeph_filepath, ".bkp")) == 0, "Failed to rename SIGPEPH file.")
     807              :      end if
     808              :    end if
     809           58 :    call sigma_restart%free()
     810              :  end if
     811              : 
     812           58 :  call xmpi_bcast(restart, master, comm, ierr)
     813           58 :  call xmpi_bcast(sigma%qp_done, master, comm, ierr)
     814              : 
     815           58 :  if (restart == 0) then
     816           58 :    call sigma%write(dtset, cryst, ebands, wfk_hdr, dtfil, comm)
     817              :  else
     818              :    ! Open file inside ncwrite_comm to perform parallel IO if kpt parallelism.
     819            0 :    if (sigma%ncwrite_comm%value /= xmpi_comm_null) then
     820            0 :      NCF_CHECK(nctk_open_modify(sigma%ncid, sigeph_filepath, sigma%ncwrite_comm%value))
     821            0 :      NCF_CHECK(nctk_set_datamode(sigma%ncid))
     822              :    end if
     823              :  end if
     824              : 
     825           58 :  if (.not. sigma%imag_only .and. sigma%frohl_model /= 0 .and. .not. dvdb%has_zeff) sigma%frohl_model = 0
     826              : 
     827           58 :  if (my_rank == master) then
     828           58 :    call sigma%print(dtset, ab_out)
     829           58 :    call sigma%print(dtset, std_out)
     830              :  end if
     831           58 :  my_npert = sigma%my_npert
     832              : 
     833              :  ! This is the maximum number of PWs for all possible k+q treated.
     834          232 :  mpw = sigma%mpw; gmax = sigma%gmax
     835              : 
     836              :  ! Init work_ngfft
     837          232 :  gmax = gmax + 4 ! FIXME: this is to account for umklapp, should also consider Gamma-only and istwfk
     838          232 :  gmax = 2*gmax + 1
     839           58 :  call ngfft_seq(work_ngfft, gmax)
     840              :  !write(std_out,*)"work_ngfft(1:3): ",work_ngfft(1:3)
     841          290 :  ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6)))
     842              : 
     843              :  ! Initialize the wave function descriptor.
     844              :  ! Each node has all k-points and spins and bands between my_bsum_start and my_bsum_stop
     845          232 :  ABI_MALLOC(nband, (nkpt, nsppol))
     846          290 :  ABI_MALLOC(bks_mask, (dtset%mband, nkpt, nsppol))
     847          232 :  ABI_MALLOC(keep_ur, (dtset%mband, nkpt ,nsppol))
     848              : 
     849        95990 :  nband = dtset%mband; bks_mask = .False.; keep_ur = .False.
     850              : 
     851              :  ! Mapping Sigma_{k,s} states to IBZ. -1 if not computed
     852          174 :  ABI_MALLOC(ibzspin_2ikcalc, (nkpt, nsppol))
     853         4186 :  ibzspin_2ikcalc = -1
     854              : 
     855              :  ! Each node needs the wavefunctions for Sigma_{nk}
     856              :  ! TODO: kcalc should depend on the spin!
     857              : 
     858          116 :  do spin=1,sigma%nsppol
     859          298 :    do ikcalc=1,sigma%nkcalc
     860          182 :      ik_ibz = sigma%kcalc2ibz(ikcalc, 1)
     861          182 :      bstart = sigma%bstart_ks(ikcalc, spin)
     862          182 :      bstop = bstart + sigma%nbcalc_ks(ikcalc, spin) - 1
     863          966 :      bks_mask(bstart:bstop, ik_ibz, spin) = .True.
     864          240 :      ibzspin_2ikcalc(ik_ibz, spin) = ikcalc
     865              :    end do
     866              :  end do
     867              : 
     868              :  ! For the imaginay part, add bands outside the energy window to account for ph absorption/emission
     869           58 :  if (sigma%imag_only .and. sigma%qint_method == 1) then
     870           16 :    call wrtout(std_out, " Including restricted set of states within energy window around relevant states.", newlines=1)
     871           32 :    do spin=1,sigma%nsppol
     872         3558 :      do ik_ibz=1,ebands%nkpt
     873         7411 :        do band=sigma%my_bsum_start, sigma%my_bsum_stop
     874         3869 :          eig0mk = ebands%eig(band, ik_ibz, spin)
     875         3869 :          if (eig0mk >= sigma%elow  - sigma%phwinfact * sigma%wmax .and. &
     876         3526 :              eig0mk <= sigma%ehigh + sigma%phwinfact * sigma%wmax) then
     877          317 :             bks_mask(band, ik_ibz ,spin) = .True.
     878              :          end if
     879              :        end do
     880              :      end do
     881              :    end do
     882              :    ! Uncomment these lines to disable energy window trick and allocate all bands.
     883              :    !if (dtset%userie == 123) then
     884              :    !  call wrtout(std_out, " Storing all bands between my_bsum_start and my_bsum_stop.")
     885              :    !  bks_mask(sigma%my_bsum_start:sigma%my_bsum_stop, : ,:) = .True.
     886              :    !end if
     887              :  else
     888        11836 :    bks_mask(sigma%my_bsum_start:sigma%my_bsum_stop, : ,:) = .True.
     889              :  endif
     890              : 
     891              :  !if (dtset%userie == 124) then
     892              :  !  ! Uncomment this line to have all states on each MPI rank.
     893              :  !  bks_mask = .True.; call wrtout(std_out, " Storing all bands for debugging purposes.")
     894              :  !end if
     895              : 
     896              :  ! This table is needed when computing the imaginary part:
     897              :  ! k+q states outside the energy window are not read hence their contribution won't be included.
     898              :  ! Error is small provided calculation is close to convergence.
     899              :  ! To reduce the error one should increase the value of phwinfact
     900          232 :  ABI_MALLOC(ihave_ikibz_spin, (nkpt, nsppol))
     901         4186 :  ihave_ikibz_spin = .False.
     902          116 :  do spin=1,sigma%nsppol
     903         4186 :    do ik_ibz=1,ebands%nkpt
     904        33448 :      if (any(bks_mask(:, ik_ibz, spin))) ihave_ikibz_spin(ik_ibz, spin) = .True.
     905              :    end do
     906              :  end do
     907              : 
     908              :  ! Impose istwfk=1 for all k points. This is also done in respfn (see inkpts)
     909              :  ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
     910          174 :  ABI_MALLOC(wfd_istwfk, (nkpt))
     911         4128 :  wfd_istwfk = 1
     912              : 
     913              :  call wfd%init(cryst, pawtab, psps, keep_ur, dtset%mband, nband, nkpt, nsppol, bks_mask,&
     914              :                nspden, nspinor, ecut, dtset%ecutsm, dtset%dilatmx, wfd_istwfk, ebands%kptns, ngfft,&
     915           58 :                dtset%nloalg, dtset%prtvol, dtset%pawprtvol, comm)
     916              : 
     917          116 :  call wfd%print([std_out], header="Wavefunctions for self-energy calculation.")
     918              : 
     919           58 :  ABI_FREE(nband)
     920           58 :  ABI_FREE(bks_mask)
     921           58 :  ABI_FREE(keep_ur)
     922           58 :  ABI_FREE(wfd_istwfk)
     923              : 
     924              :  ! Read wavefunctions.
     925           58 :  call wfd%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
     926              : 
     927              :  ! if PAW, one has to solve a generalized eigenproblem
     928           58 :  usecprj = 0; gen_eigenpb = psps%usepaw == 1; sij_opt = 0; if (gen_eigenpb) sij_opt = 1
     929              : 
     930          116 :  ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj))
     931          116 :  ABI_MALLOC(cwaveprj, (natom, nspinor*usecprj))
     932          232 :  ABI_MALLOC(displ_cart, (2, 3, cryst%natom, natom3))
     933          174 :  ABI_MALLOC(displ_red, (2, 3, cryst%natom, natom3))
     934          232 :  ABI_MALLOC(tpp_red, (natom3, natom3))
     935          232 :  ABI_MALLOC(gbound_kq, (2*wfd%mgfft+8, 2))
     936          116 :  ABI_MALLOC(osc_gbound_q, (2*wfd%mgfft+8, 2))
     937              : 
     938           58 :  osc_ecut = dtset%eph_ecutosc
     939           58 :  if (osc_ecut > zero) then
     940            0 :    call wrtout(std_out, sjoin("Computing oscillator matrix elements with ecut.", ftoa(osc_ecut)))
     941            0 :    ABI_CHECK(osc_ecut <= wfd%ecut, "osc_ecut cannot be greater than dtset%ecut")
     942           58 :  else if (osc_ecut < zero) then
     943            0 :    call wrtout(std_out, sjoin("Including G vectors inside a sphere with ecut.", ftoa(osc_ecut)))
     944              :  end if
     945              : 
     946              :  ! ============================
     947              :  ! Compute vnk matrix elements
     948              :  ! ============================
     949          174 :  ABI_MALLOC(cgwork, (2, mpw*wfd%nspinor))
     950         4010 :  ABI_CALLOC(sigma%vcar_calc, (3, sigma%max_nbcalc, sigma%nkcalc, nsppol))
     951              : 
     952           58 :  call ddkop%init(dtset, cryst, pawtab, psps, wfd%mpi_enreg, mpw, wfd%ngfft)
     953              : 
     954           58 :  if (sigma%mrta == 0) then
     955           33 :    call cwtime(cpu_ks, wall_ks, gflops_ks, "start", msg=" Computing v_nk matrix elements for all states in Sigma_nk...")
     956              :    ! Consider only the nk states in Sigma_nk
     957              :    ! All sigma_nk states are available on each node so MPI parallelization is easy.
     958           33 :    cnt = 0
     959           66 :    do spin=1,nsppol
     960          136 :      do ikcalc=1,sigma%nkcalc
     961          280 :        kk = sigma%kcalc(:, ikcalc)
     962           70 :        bstart_ks = sigma%bstart_ks(ikcalc, spin)
     963           70 :        ik_ibz = sigma%kcalc2ibz(ikcalc, 1)
     964           70 :        npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz)
     965           70 :        call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kk, istwf_k, npw_k, wfd%kdata(ik_ibz)%kg_k)
     966              : 
     967          462 :        do ib_k=1,sigma%nbcalc_ks(ikcalc, spin)
     968          359 :          cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism.
     969          359 :          band_ks = ib_k + bstart_ks - 1
     970          359 :          call wfd%copy_cg(band_ks, ik_ibz, spin, cgwork)
     971          359 :          eig0nk = ebands%eig(band_ks, ik_ibz, spin)
     972         1506 :          sigma%vcar_calc(:, ib_k, ikcalc, spin) = ddkop%get_vdiag(eig0nk, istwf_k, npw_k, wfd%nspinor, cgwork, cwaveprj0)
     973              :        end do
     974              : 
     975              :      end do
     976              :    end do
     977           33 :    call xmpi_sum(sigma%vcar_calc, comm, ierr)
     978              : 
     979              :  else
     980           25 :    call cwtime(cpu_ks, wall_ks, gflops_ks, "start", msg=" Computing v_nk matrix elements for all states in the IBZ...")
     981              : 
     982              :    ! Imaginary part with MRTA. Here we need v_kq as well.
     983              :    ! Usually kq is one of the kcalc points except when nk is close to the edge of the sigma_erange window.
     984              :    ! due to ph absorption/emission.
     985              :    ! In this case, indeed, we may need a kq state that is not in the initial kcalc set.
     986              :    !
     987              :    ! Solution:
     988              :    !   1) precompute group velocities in the IBZ and the ihave_ikibz_spin file (common to all procs)
     989              :    !   2) Fill sigma%vcar_calc needed by the transport driver from the vcar_ibz array
     990              :    !   3) Use symmetries to reconstruct v_kq from vcar_ibz
     991              :    !
     992              :    ! NB: All procs store in memory the same set of Bloch states.
     993              : 
     994        21528 :    ABI_CALLOC(vcar_ibz, (3, sigma%bsum_start:sigma%bsum_stop, nkpt, nsppol))
     995              : 
     996           25 :    cnt = 0
     997           50 :    do spin=1,nsppol
     998         3648 :      do ik_ibz=1,ebands%nkpt
     999        14392 :        kk = ebands%kptns(:, ik_ibz)
    1000         3598 :        npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz)
    1001         3598 :        ikcalc = ibzspin_2ikcalc(ik_ibz, spin)
    1002         3598 :        if (.not. ihave_ikibz_spin(ik_ibz, spin)) cycle
    1003          195 :        if (npw_k == 1) cycle
    1004          195 :        cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism.
    1005              : 
    1006          195 :        call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kk, istwf_k, npw_k, wfd%kdata(ik_ibz)%kg_k)
    1007              : 
    1008         1199 :        do band_ks=sigma%bsum_start,sigma%bsum_stop
    1009          979 :          if (.not. wfd%ihave_ug(band_ks, ik_ibz, spin)) cycle
    1010          893 :          call wfd%copy_cg(band_ks, ik_ibz, spin, cgwork)
    1011          893 :          eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    1012          893 :          vk = ddkop%get_vdiag(eig0nk, istwf_k, npw_k, wfd%nspinor, cgwork, cwaveprj0)
    1013         3572 :          vcar_ibz(:, band_ks, ik_ibz, spin) = vk
    1014         4491 :          if (ikcalc /= -1) then
    1015              :            ! This IBZ k-point is in the kcalc set --> Store vk in vcar_calc
    1016          522 :            bstart_ks = sigma%bstart_ks(ikcalc, spin)
    1017          522 :            bstop = bstart_ks + sigma%nbcalc_ks(ikcalc, spin) - 1
    1018          522 :            if (band_ks >= bstart_ks .and. band_ks <= bstop) then
    1019          425 :              ib_k = band_ks - bstart_ks + 1
    1020         1700 :              sigma%vcar_calc(:, ib_k, ikcalc, spin) = vk
    1021              :            end if
    1022              :          end if
    1023              :        end do
    1024              :      end do
    1025              :    end do
    1026           25 :    call xmpi_sum(sigma%vcar_calc, comm, ierr)
    1027           50 :    call xmpi_sum(vcar_ibz, comm, ierr)
    1028              :  endif
    1029              : 
    1030              :  ! Write v_nk to disk.
    1031           58 :  if (my_rank == master) then
    1032           58 :    NCF_CHECK(nf90_put_var(sigma%ncid, nctk_idname(sigma%ncid, "vcar_calc"), sigma%vcar_calc))
    1033              :  end if
    1034              : 
    1035           58 :  ABI_FREE(cgwork)
    1036           58 :  call ddkop%free()
    1037           58 :  call cwtime_report(" Velocities", cpu_ks, wall_ks, gflops_ks)
    1038              : 
    1039              :  ! Precompute phonon frequencies and eigenvectors in the IBZ.
    1040              :  ! These quantities are then used to symmetrize quantities for q in the IBZ(k) in order
    1041              :  ! to reduce the number of calls to ifc%fourq (expensive if dipdip == 1).
    1042              : 
    1043           58 :  use_ifc_fourq = .False. !use_ifc_fourq = .True. !use_ifc_fourq = dtset%userib == 123
    1044           58 :  call phstore%init(cryst, ifc, sigma%nqibz, sigma%qibz, use_ifc_fourq, sigma%pert_comm%value)
    1045           58 :  call cwtime_report(" phonons in the IBZ", cpu_ks, wall_ks, gflops_ks)
    1046              : 
    1047              :  ! Radius of sphere with volume equivalent to the micro zone.
    1048           58 :  q0rad = two_pi * (three / (four_pi * cryst%ucvol * sigma%nqbz)) ** third
    1049           58 :  bz_vol = two_pi**3 / cryst%ucvol
    1050              : 
    1051              :  ! Prepare call to getgh1c
    1052           58 :  usevnl = 0
    1053           58 :  optlocal = 1   ! local part of H^(1) is computed in gh1c=<G|H^(1)|C>
    1054           58 :  optnl = 2      ! non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
    1055           58 :  opt_gvnlx1 = 0 ! gvnlx1 is output
    1056              : 
    1057           58 :  ABI_MALLOC(grad_berry, (2, nspinor*(berryopt0/4)))
    1058              : 
    1059              :  ! This part is taken from dfpt_vtorho
    1060              :  !==== Initialize most of the Hamiltonian (and derivative) ====
    1061              :  ! 1) Allocate all arrays and initialize quantities that do not depend on k and spin.
    1062              :  ! 2) Perform the setup needed for the non-local factors:
    1063              :  !
    1064              :  ! Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk.
    1065              :  ! PAW: Initialize the overlap coefficients and allocate the Dij coefficients.
    1066              : 
    1067              :  call gs_ham_kq%init(psps, pawtab, nspinor, nsppol, nspden, natom,&
    1068              :   dtset%typat, cryst%xred, nfft, mgfft, ngfft, cryst%rprimd, dtset%nloalg,&
    1069              :   comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab, mpi_spintab=mpi_enreg%my_isppoltab,&
    1070           58 :   usecprj=usecprj, ph1d=ph1d, nucdipmom=dtset%nucdipmom, gpu_option=dtset%gpu_option)
    1071              : 
    1072              :  ! Allocate work space arrays.
    1073              :  ! vtrial and vlocal are required for Sternheimer (H0). DFPT routines do not need it.
    1074              :  ! Note nvloc in vlocal (we will select one/four spin components afterwards)
    1075       786301 :  ABI_CALLOC(vtrial, (nfftf, nspden))
    1076       874419 :  ABI_CALLOC(vlocal, (n4, n5, n6, gs_ham_kq%nvloc))
    1077              : 
    1078              :  ! DBSP
    1079           58 :  etot = zero
    1080           58 :  if (dtset%eph_stern /= 0) then
    1081              :    ! Read the GS potential (vtrial) from input POT file.
    1082              :    ! In principle one may store vtrial in the DVDB but getpot_filepath is simpler to implement.
    1083           17 :    call wrtout(units, sjoin(" Reading GS KS potential for Sternheimer from: ", dtfil%filpotin))
    1084              :    call read_rhor(dtfil%filpotin, cplex1, nspden, nfftf, ngfftf, pawread0, mpi_enreg, vtrial, pot_hdr, pot_pawrhoij, comm, &
    1085           17 :                   allow_interp=.True., want_varname="vtrial")
    1086           17 :    pot_cryst = pot_hdr%get_crystal()
    1087           17 :    if (cryst%compare(pot_cryst, header=" Comparing input crystal with POT crystal") /= 0) then
    1088            0 :      ABI_ERROR("Crystal structure from WFK and POT do not agree! Check messages above!")
    1089              :    end if
    1090           17 :    etot = pot_hdr%etot
    1091           17 :    call pot_cryst%free(); call pot_hdr%free()
    1092              :  end if
    1093              : 
    1094           58 :  if (sigma%nwr > 0) then
    1095           63 :    ABI_MALLOC(cfact_wr, (sigma%nwr))
    1096              :  end if
    1097          174 :  ABI_MALLOC(nqnu_tlist, (sigma%ntemp))
    1098              : 
    1099              :  ! Allocate workspace arrays for Eliashberg functions
    1100           58 :  if (dtset%prteliash /= 0) then
    1101           63 :    ABI_MALLOC(dtw_weights, (sigma%phmesh_size, 2))
    1102           63 :    ABI_MALLOC(dwargs, (sigma%phmesh_size))
    1103           21 :    if (sigma%a2f_ne > 0) then
    1104            0 :      ABI_MALLOC(delta_e_minus_emkq, (sigma%a2f_ne))
    1105              :    end if
    1106              :  end if
    1107              : 
    1108              :  ! Array used to store delta(w - w_{q\nu}) with delta replaced by gaussian.
    1109          174 :  ABI_MALLOC(gaussw_qnu, (sigma%phmesh_size))
    1110              : 
    1111           58 :  if (dtset%eph_prtscratew == 1) then
    1112            6 :    ABI_MALLOC(sigma%scratew, (sigma%phmesh_size, sigma%ntemp, sigma%max_nbcalc, 2))
    1113              :  end if
    1114              : 
    1115              :  ! Open the DVDB file
    1116           58 :  call dvdb%open_read(ngfftf, xmpi_comm_self)
    1117           58 :  ABI_CHECK(dvdb%has_fields("pot1", msg), msg)
    1118              : 
    1119           58 :  if (sigma%pert_comm%nproc > 1) then
    1120              :    !  Activate parallelism over perturbations
    1121            0 :    call dvdb%set_pert_distrib(sigma%my_npert, natom3, sigma%my_pinfo, sigma%pert_table, sigma%pert_comm%value)
    1122              :  end if
    1123              : 
    1124              :  ! Find correspondence IBZ --> set of q-points in DVDB.
    1125              :  ! Activate FT interpolation automatically if required q-points in the IBZ are not found in the DVDB.
    1126           58 :  sigma%need_ftinterp = .False.
    1127          174 :  ABI_MALLOC(sigma%qibz2dvdb, (sigma%nqibz))
    1128           58 :  if (dvdb%find_qpts(sigma%nqibz, sigma%qibz, sigma%qibz2dvdb, comm) /= 0) then
    1129           23 :    call wrtout(units, " Cannot find eph_ngqpt_fine q-points in DVDB --> Activating Fourier interpolation.")
    1130           23 :    sigma%need_ftinterp = .True.
    1131              :  else
    1132           35 :    call wrtout(units, " DVDB file contains all q-points in the IBZ --> Reading DFPT potentials from file.")
    1133           35 :    sigma%need_ftinterp = .False.
    1134              :  end if
    1135              : 
    1136           58 :  if (.not. sigma%need_ftinterp .and. dtset%eph_use_ftinterp /= 0) then
    1137            0 :    ABI_WARNING("Enforcing FT interpolation for q-points even if it's not strictly needed.")
    1138            0 :    sigma%need_ftinterp = .True.
    1139              :  end if
    1140              : 
    1141           58 :  if (sigma%need_ftinterp) then
    1142              :    ! Use ddb_ngqpt q-mesh to compute the real-space representation of DFPT v1scf potentials to prepare Fourier interpolation.
    1143              :    ! R-points are distributed inside comm_rpt
    1144              :    ! Note that when R-points are distributed inside qpt_comm we cannot interpolate potentials on-the-fly
    1145              :    ! inside the loop over q-points.
    1146              :    ! In this case, indeed, the interpolation must be done in sigma_setup_qloop once we know the q-points contributing
    1147              :    ! to the integral and the potentials must be cached.
    1148              :    !FIXME: qpt_comm is buggy.
    1149              :    !if (sigma%imag_only) comm_rpt = xmpi_comm_self
    1150              :    !comm_rpt = sigma%bsum_comm%value
    1151           23 :    comm_rpt = xmpi_comm_self
    1152           23 :    qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt
    1153           23 :    call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt)
    1154              : 
    1155              :    ! Build q-cache in the *dense* IBZ using the global mask qselect and itreat_qibz.
    1156           69 :    ABI_MALLOC(qselect, (sigma%nqibz))
    1157         3797 :    qselect = 1
    1158           23 :    if (sigma%imag_only .and. sigma%qint_method == 1) then
    1159           10 :      call qpoints_oracle(sigma, dtset, cryst, ebands, sigma%qibz, sigma%nqibz, sigma%nqbz, sigma%qbz, qselect, comm)
    1160              :    end if
    1161              : 
    1162              :  else
    1163          105 :    ABI_MALLOC(qselect, (dvdb%nqpt))
    1164          251 :    qselect = 1
    1165              :    ! Try to predict the q-points required to compute tau.
    1166           35 :    if (sigma%imag_only .and. sigma%qint_method == 1) then
    1167            6 :      call qpoints_oracle(sigma, dtset, cryst, ebands, dvdb%qpts, dvdb%nqpt, sigma%nqbz, sigma%qbz, qselect, comm)
    1168              :    end if
    1169              :  end if
    1170              : 
    1171          116 :  call dvdb%print([std_out], "", dtset%prtvol)
    1172              : 
    1173           58 :  if (.not. sigma%need_ftinterp) then
    1174              :    ! Need to translate itreat_qibz into itreatq_dvdb.
    1175          321 :    ABI_ICALLOC(itreatq_dvdb, (dvdb%nqpt))
    1176          251 :    do iq_ibz=1,sigma%nqibz
    1177          216 :      if (sigma%itreat_qibz(iq_ibz) == 0) cycle
    1178          216 :      db_iqpt = sigma%qibz2dvdb(iq_ibz)
    1179          216 :      ABI_CHECK(db_iqpt /= -1, sjoin("Could not find IBZ q-point:", ktoa(sigma%qibz(:, iq_ibz)), "in the DVDB file."))
    1180          251 :      itreatq_dvdb(db_iqpt) = 1
    1181              :    end do
    1182           35 :    ABI_FREE(itreatq_dvdb)
    1183              :  end if
    1184              : 
    1185           58 :  ABI_FREE(qselect)
    1186          403 :  zpr_frohl_sphcorr = zero; zpr_frohl_sphcorr_done = .False.
    1187              : 
    1188           58 :  call pstat_proc%print(_PSTAT_ARGS_)
    1189              : 
    1190              :  !if (sigma%frohl_model == 1 .and. .not. sigma%imag_only) then
    1191              :  !  call frohl_integrator_find_mesh(cryst, ifc, ntheta, comm)
    1192              :  !  call frohl%init(cryst, ifc, ntheta, comm)
    1193              :  !  call frohl%eval_isotropic_avg(cryst, ifc, comm, zpr_frohl_sphcorr)
    1194              :  !  call frohl%free()
    1195              :  !end if
    1196              :  !stop
    1197              : 
    1198              :  ! Temperature resolved 4th order contribution to total energy
    1199          406 :  ABI_CALLOC(E4, (sigma%ntemp))
    1200              :  !
    1201              :  ! Loop over k-points in Sigma_nk. Loop over spin is internal as we operate on nspden components at once.
    1202          240 :  do my_ikcalc=1,sigma%my_nkcalc
    1203              :    !if (my_ikcalc > 1) exit
    1204          182 :    ikcalc = sigma%my_ikcalc(my_ikcalc)
    1205              : 
    1206              :    ! Check if this (kpoint, spin) was already calculated
    1207          182 :    if (all(sigma%qp_done(ikcalc, :) == 1)) cycle
    1208          182 :    call cwtime(cpu_ks, wall_ks, gflops_ks, "start")
    1209              : 
    1210              :    ! Find IBZ(k) for q-point integration.
    1211          182 :    call cwtime(cpu_setk, wall_setk, gflops_setk, "start")
    1212              :    ! FIXME invert spin but checks shape of the different arrays!
    1213          182 :    call sigma%setup_kcalc(dtset, cryst, ebands, ikcalc, dtset%prtvol, sigma%pqb_comm%value)
    1214              : 
    1215              :    ! Symmetry indices for kk.
    1216          728 :    kk = sigma%kcalc(:, ikcalc)
    1217          182 :    ik_ibz = sigma%kcalc2ibz(ikcalc, 1); isym_k = sigma%kcalc2ibz(ikcalc, 2)
    1218          728 :    trev_k = sigma%kcalc2ibz(ikcalc, 6); g0_k = sigma%kcalc2ibz(ikcalc, 3:5)
    1219          728 :    isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
    1220            0 :    ABI_CHECK(isirr_k, "For the time being the k-point in Sigma_{nk} must be in the IBZ")
    1221          182 :    kk_ibz = ebands%kptns(:,ik_ibz)
    1222          182 :    npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz)
    1223              : 
    1224              :    ! Allocate PW-arrays. Note mpw in kg_kq
    1225          546 :    ABI_MALLOC(kg_k, (3, npw_k))
    1226       479600 :    kg_k = wfd%kdata(ik_ibz)%kg_k
    1227          546 :    ABI_MALLOC(kg_kq, (3, mpw))
    1228              : 
    1229              :    call gs_ham_kq%eph_setup_k("k", kk, istwfk_1, npw_k, kg_k, dtset, cryst, psps, &
    1230          182 :                               nkpg, kpg_k, ffnl_k, kinpw_k, ph3d_k, sigma%pert_comm%value)
    1231              : 
    1232          182 :    call cwtime_report(" Setup kcalc", cpu_setk, wall_setk, gflops_setk)
    1233              : 
    1234              :    ! TODO: Spin should be treated in a more flexible and scalable way --> kcalc and bdgw should depend on spin.
    1235              :    ! Introduce other comm and cartesian dimension for spin
    1236          364 :    do my_spin=1,sigma%my_nspins
    1237          182 :      spin = sigma%my_spins(my_spin)
    1238              : 
    1239              :      ! Check if this kpoint and spin was already calculated
    1240          182 :      if (sigma%qp_done(ikcalc, spin) == 1) cycle
    1241              : 
    1242              :      !call timab(1900, 1, tsec)
    1243              :      ! Bands in Sigma_nk to compute and number of bands in sum over states.
    1244          182 :      bstart_ks = sigma%bstart_ks(ikcalc, spin)
    1245          182 :      nbcalc_ks = sigma%nbcalc_ks(ikcalc, spin)
    1246          182 :      bsum_start = sigma%bsum_start; bsum_stop = sigma%bsum_stop
    1247          182 :      nbsum = sigma%nbsum
    1248          546 :      ABI_MALLOC(root_bcalc, (nbcalc_ks))
    1249              : 
    1250              :      ! Zero self-energy matrix elements. Build frequency mesh for nk states.
    1251        10556 :      sigma%vals_e0ks = zero; sigma%dvals_de0ks = zero; sigma%dw_vals = zero
    1252        10556 :      sigma%fan_vals = zero; sigma%fan_stern_vals = zero; sigma%dw_stern_vals = zero
    1253          767 :      sigma%E2 = zero
    1254         3640 :      sigma%E4_vals = zero
    1255         3640 :      sigma%E4_vals2 = zero
    1256          182 :      if (sigma%mrta > 0) then
    1257         1939 :        sigma%linewidth_mrta = zero
    1258          336 :        ABI_MALLOC(alpha_mrta, (nbcalc_ks))
    1259              :      end if
    1260              : 
    1261          182 :      if (sigma%nwr > 0) then
    1262              :        ! Prepare computation of Sigma_{nk}(w) and spectral function.
    1263              :        ! Build linear mesh **centered** around the KS energy.
    1264       116184 :        sigma%vals_wr = zero
    1265          336 :        do ib_k=1,nbcalc_ks
    1266          284 :          band_ks = ib_k + bstart_ks - 1
    1267          284 :          eig0nk = ebands%eig(band_ks, ik_ibz, spin) - sigma%wr_step * (sigma%nwr / 2)
    1268        35668 :          sigma%wrmesh_b(:,ib_k) = arth(eig0nk, sigma%wr_step, sigma%nwr)
    1269              :        end do
    1270              :      end if
    1271              : 
    1272              :      ! Prepare Eliasberg functions.
    1273          182 :      if (dtset%prteliash /= 0) then
    1274           58 :        ABI_SFREE(sigma%gf_nnuq)
    1275       102789 :        ABI_CALLOC(sigma%gf_nnuq, (nbcalc_ks, natom3, sigma%nqibz_k, 3))
    1276           58 :        if (dtset%prteliash == 3) sigma%a2few = zero
    1277              :      end if
    1278              : 
    1279              :      ! Zeroing array used to compute spectral decomposition of 1/tau as a function of ph omega.
    1280        91178 :      if (dtset%eph_prtscratew == 1) sigma%scratew = zero
    1281              : 
    1282              :      ! Allocate eph matrix elements.
    1283          728 :      ABI_MALLOC(gkq_atm, (2, nbcalc_ks, natom3))
    1284          546 :      ABI_MALLOC(gkq_nu, (2, nbcalc_ks, natom3))
    1285          728 :      ABI_MALLOC(gkq_allgather, (2, nbcalc_ks * natom3, 2))
    1286              : 
    1287              :      ! Allocate arrays for Debye-Waller
    1288          182 :      if (.not. sigma%imag_only) then
    1289       154766 :        ABI_CALLOC_OR_DIE(gkq0_atm, (2, nbcalc_ks, sigma%my_bsum_start:sigma%my_bsum_stop, natom3), ierr)
    1290           70 :        if (dtset%eph_stern /= 0) then
    1291        17995 :          ABI_CALLOC(stern_dw, (2, natom3, natom3, nbcalc_ks))
    1292              :          enough_stern = 0
    1293              :        end if
    1294              :      end if
    1295              : 
    1296          182 :      if (sigma%frohl_model == 1 .and. .not. sigma%imag_only) then
    1297            0 :        call wrtout(std_out, " Computing spherical average to treat Frohlich divergence in Sigma^{FM}")
    1298            0 :        ABI_MALLOC(f_tlist_b, (sigma%ntemp, nbcalc_ks))
    1299              : 
    1300            0 :        if (sigma%nwr > 0) then
    1301            0 :          do ib_k=1,nbcalc_ks
    1302            0 :            band_ks = ib_k + bstart_ks - 1; eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    1303            0 :            do it=1,sigma%ntemp
    1304            0 :              f_tlist_b(it,ib_k) = occ_fd(eig0nk, sigma%kTmesh(it), sigma%mu_e(it))
    1305              :            end do
    1306              :          end do
    1307              :          ! This integral depends on the (n, k) state
    1308            0 :          ABI_CALLOC(fmw_frohl_sphcorr, (sigma%nwr, natom3, sigma%ntemp, nbcalc_ks))
    1309              :        end if
    1310              : 
    1311              :        ! Angular integration.
    1312            0 :        if (.not. zpr_frohl_sphcorr_done) zpr_frohl_sphcorr = zero
    1313              : 
    1314            0 :        do iang=1,sigma%angl_size
    1315            0 :          if (sigma%kcalc_comm%skip(iang)) cycle ! MPI parallelism inside kcalc_comm
    1316            0 :          qpt_cart = sigma%qvers_cart(:, iang); inv_qepsq = one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart))
    1317            0 :          call ifc%fourq(cryst, qpt_cart, phfrq, displ_cart, nanaqdir="cart")
    1318              : 
    1319              :          ! Acoustic modes are ignored here.
    1320            0 :          do nu=4,natom3
    1321            0 :            wqnu = phfrq(nu); if (ephtk_skip_phmode(nu, wqnu, sigma%phmodes_skip, dtset%eph_phrange_w)) cycle
    1322              :            ! Get phonon occupation for all temperatures.
    1323            0 :            nqnu_tlist = occ_be(wqnu, sigma%kTmesh(:), zero)
    1324              : 
    1325              :            ! cnum = q.\sum_k Z_k.d_k(q,nu)
    1326            0 :            cp3 = czero
    1327            0 :            do iatom=1, natom
    1328            0 :              cp3 = cp3 + matmul(ifc%zeff(:, :, iatom), cmplx(displ_cart(1,:,iatom, nu), displ_cart(2,:,iatom, nu), kind=dp))
    1329              :            end do
    1330            0 :            cnum = dot_product(qpt_cart, cp3); if (abs(cnum) < tol12) cycle
    1331              : 
    1332              :            ! Compute spherical average for ZPR
    1333            0 :            if (.not. zpr_frohl_sphcorr_done) then
    1334            0 :              zpr_frohl_sphcorr(nu) = zpr_frohl_sphcorr(nu) + sigma%angwgth(iang) * abs(cnum) ** 2 * inv_qepsq ** 2 / wqnu ** 2
    1335              :            end if
    1336              : 
    1337            0 :            if (sigma%nwr > 0) then
    1338              :              ! NB: summing over f * angwgth gives the spherical average 1/(4pi) \int domega f(omega)
    1339            0 :              weight = four_pi * sigma%angwgth(iang) * abs(cnum) ** 2 * inv_qepsq ** 2 / wqnu
    1340            0 :              do ib_k=1,nbcalc_ks
    1341            0 :                band_ks = ib_k + bstart_ks - 1; eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    1342            0 :                do it=1,sigma%ntemp
    1343            0 :                  f_nk = f_tlist_b(it,ib_k)
    1344            0 :                  nqnu = nqnu_tlist(it)
    1345              :                  fmw_frohl_sphcorr(:,nu,it,ib_k) = fmw_frohl_sphcorr(:,nu,it,ib_k) + &
    1346              :                    ((nqnu + f_nk      ) / (sigma%wrmesh_b(:,ib_k) - eig0nk + wqnu + sigma%ieta) + &
    1347            0 :                     (nqnu - f_nk + one) / (sigma%wrmesh_b(:,ib_k) - eig0nk - wqnu + sigma%ieta) ) * weight
    1348              :                end do ! it
    1349              :              end do ! ib_k
    1350              :            end if
    1351              :          end do ! nu
    1352              :        end do ! iang
    1353            0 :        ABI_FREE(f_tlist_b)
    1354              : 
    1355            0 :        if (.not. zpr_frohl_sphcorr_done) then
    1356            0 :          call xmpi_sum(zpr_frohl_sphcorr, sigma%kcalc_comm%value, ierr)
    1357              :          zpr_frohl_sphcorr = zpr_frohl_sphcorr * eight * pi / cryst%ucvol * &
    1358            0 :                              (three / (four_pi * cryst%ucvol * sigma%nqbz)) ** third
    1359              :          !zpr_frohl_sphcorr = zpr_frohl_sphcorr * q0rad  / (pi * cryst%ucvol)
    1360              :          zpr_frohl_sphcorr_done = .True.
    1361              :        end if
    1362              : 
    1363            0 :        if (sigma%nwr > 0) then
    1364            0 :          call xmpi_sum(fmw_frohl_sphcorr, sigma%kcalc_comm%value, ierr)
    1365            0 :          fmw_frohl_sphcorr = fmw_frohl_sphcorr * (four_pi/cryst%ucvol)**2 * q0rad * half / bz_vol
    1366              :        end if
    1367              : 
    1368            0 :        if (my_rank == master .and. is_open(ab_out)) then
    1369            0 :          write(ab_out, "(/,a)")" Frohlich model integrated inside the small q-sphere around Gamma."
    1370            0 :          write(ab_out,"(2(a,i0,1x),/)")" Angular mesh with ntheta: ", sigma%ntheta, ", nphi: ", sigma%nphi
    1371            0 :          write(ab_out, "(2a)")" Phonon-resolved contributions to Sigma^{FM}(w=e_KS):", ch10
    1372            0 :          do nu=1,natom3
    1373            0 :            if (abs(zpr_frohl_sphcorr(nu)) < tol12) cycle
    1374            0 :            write(ab_out, "(1x,f8.1,a,i0)")zpr_frohl_sphcorr(nu) * Ha_meV, " (meV) for ph-mode: ", nu
    1375              :          end do
    1376            0 :          write(ab_out, "(a)")ch10
    1377              :        end if
    1378              :      end if
    1379              : 
    1380              :      ! Load ground-state wavefunctions for which corrections are wanted (available on each node)
    1381              :      ! and save KS energies in sigma%e0vals
    1382              :      ! Note: One should rotate the wavefunctions if kk is not in the IBZ (not implemented)
    1383          728 :      ABI_MALLOC(kets_k, (2, npw_k*nspinor, nbcalc_ks))
    1384          546 :      ABI_MALLOC(sigma%e0vals, (nbcalc_ks))
    1385              : 
    1386          182 :      if (osc_ecut /= zero) then
    1387            0 :        ABI_MALLOC(ur_k, (wfd%nfft*nspinor, nbcalc_ks))
    1388            0 :        ABI_MALLOC(ur_kq, (wfd%nfft*nspinor))
    1389            0 :        ABI_MALLOC(work_ur, (wfd%nfft*nspinor))
    1390            0 :        ABI_MALLOC(gkq2_lr, (sigma%eph_doublegrid%ndiv, nbcalc_ks, sigma%my_npert))
    1391              :      end if
    1392              : 
    1393          966 :      do ib_k=1,nbcalc_ks
    1394          784 :        band_ks = ib_k + bstart_ks - 1
    1395          784 :        call wfd%copy_cg(band_ks, ik_ibz, spin, kets_k(1, 1, ib_k))
    1396          784 :        sigma%e0vals(ib_k) = ebands%eig(band_ks, ik_ibz, spin)
    1397          966 :        if (osc_ecut > zero) call wfd%get_ur(band_ks, ik_ibz, spin, ur_k(1, ib_k))
    1398              :      end do
    1399              : 
    1400              :      ! Distribute q-points, compute tetra weights.
    1401          182 :      call sigmaph_setup_qloop(sigma, dtset, cryst, ebands, dvdb, spin, ikcalc, sigma%pqb_comm%value)
    1402              :      !call timab(1900, 2, tsec)
    1403              : 
    1404              :      ! ==========================================
    1405              :      ! Integration over my q-points in the IBZ(k)
    1406              :      ! ==========================================
    1407          182 :      call cwtime(cpu_qloop, wall_qloop, gflops_qloop, "start")
    1408          182 :      ignore_kq = 0; ignore_ibsum_kq = 0
    1409              : 
    1410        14654 :      do imyq=1,sigma%my_nqibz_k
    1411        14472 :        call cwtime(cpu, wall, gflops, "start")
    1412        14472 :        iq_ibz_k = sigma%myq2ibz_k(imyq)
    1413        57888 :        qpt = sigma%qibz_k(:, iq_ibz_k)
    1414        57888 :        q_is_gamma = sum(qpt**2) < tol14
    1415              : 
    1416        14472 :        iq_ibz = sigma%ind_ibzk2ibz(1, iq_ibz_k)
    1417        14472 :        isym_q = sigma%ind_ibzk2ibz(2, iq_ibz_k)
    1418        14472 :        trev_q = sigma%ind_ibzk2ibz(6, iq_ibz_k)
    1419              :        ! Don't test if umklapp == 0 because we use the periodic gauge: phfreq(q+G) = phfreq(q) and eigvec(q) = eigvec(q+G)
    1420        14472 :        isirr_q = (isym_q == 1 .and. trev_q == 0)
    1421              :        !qq_ibz = sigma%qibz(:, iq_ibz)
    1422              : 
    1423              :        ! Find k + q in the extended zone and extract symmetry info.
    1424              :        ! Be careful here because there are two umklapp vectors to be considered as:
    1425              :        !
    1426              :        !   k + q = k_bz + g0_bz = IS(k_ibz) + g0_ibz + g0_bz
    1427              :        !
    1428        57888 :        kq = kk + qpt
    1429        14472 :        ikq_ibz = sigma%indkk_kq(1, iq_ibz_k); isym_kq = sigma%indkk_kq(2, iq_ibz_k)
    1430        57888 :        trev_kq = sigma%indkk_kq(6, iq_ibz_k); g0_kq = sigma%indkk_kq(3:5, iq_ibz_k)
    1431        34778 :        isirr_kq = (isym_kq == 1 .and. trev_kq == 0 .and. all(g0_kq == 0))
    1432        57888 :        kq_ibz = ebands%kptns(:, ikq_ibz)
    1433              :        !nband_kq = ebands%nband(ikq_ibz + (spin-1) * ebands%nkpt)
    1434              : 
    1435              :        ! This can happen if we have loaded the wavefunctions inside the energy range.
    1436        14472 :        if (sigma%imag_only .and. .not. ihave_ikibz_spin(ikq_ibz, spin)) then
    1437        10620 :          ignore_kq = ignore_kq + 1; cycle
    1438              :        end if
    1439              : 
    1440              :        ! ====================================
    1441              :        ! Get DFPT potentials for this q-point
    1442              :        ! ====================================
    1443              :        ! After this branch we have allocated v1scf(cplex, nfftf, nspden, my_npert))
    1444         3852 :        if (sigma%need_ftinterp) then
    1445              :          ! Use Fourier interpolation to get DFPT potentials for this qpt (hopefully in cache).
    1446         2818 :          db_iqpt = sigma%ind_ibzk2ibz(1, iq_ibz_k)
    1447              :          qq_ibz = sigma%qibz(:, db_iqpt)
    1448         2818 :          call dvdb%get_ftqbz(qpt, cplex, nfftf, ngfftf, v1scf, sigma%pert_comm%value)
    1449              :        else
    1450              :          ! Read and reconstruct the dvscf potentials for qpt and my_npert perturbations.
    1451         1034 :          db_iqpt = sigma%ind_q2dvdb_k(1, iq_ibz_k)
    1452         1034 :          ABI_CHECK(db_iqpt /= -1, sjoin("Could not find symmetric of q-point:", ktoa(qpt), "in DVDB file."))
    1453         1034 :          call dvdb%readsym_qbz(cryst, qpt, sigma%ind_q2dvdb_k(:,iq_ibz_k), cplex, nfftf, ngfftf, v1scf, sigma%pert_comm%value)
    1454              :        end if
    1455              : 
    1456              :        ! Rotate phonon frequencies and displacements for q in BZ. Non-blocking operation inside pert_comm
    1457              :        !call timab(1901, 1, tsec)
    1458              : 
    1459         3852 :        call phstore%async_rotate(cryst, ifc, iq_ibz, sigma%qibz(:, iq_ibz), qpt, isym_q, trev_q)
    1460              : 
    1461              :        ! Double grid stuff
    1462         3852 :        if (sigma%use_doublegrid) then
    1463          238 :          call sigma%eph_doublegrid%get_mapping(kk, kq, qpt)
    1464              :          !iq_bz_frohl = sigma%eph_doublegrid%get_index(qpt, 2)
    1465              :          !iq_ibz_frohl = sigma%eph_doublegrid%bz2ibz_dense(iq_bz_frohl)
    1466              :        end if
    1467              : 
    1468              :        ! Map q to qibz for tetrahedron
    1469         3852 :        if (sigma%qint_method > 0) then
    1470         2718 :          if (.not. sigma%use_doublegrid) then
    1471         2554 :            iq_ibz_fine = iq_ibz_k
    1472         2554 :            if (sigma%symsigma == 0) iq_ibz_fine = sigma%ephwg%lgk%find_ibzimage(qpt)
    1473         2554 :            ABI_CHECK(iq_ibz_fine /= -1, sjoin("Cannot find q-point in IBZ(k):", ktoa(qpt)))
    1474         2554 :            if (abs(sigma%symsigma) == 1) then
    1475        10216 :               if (.not. all(abs(sigma%qibz_k(:, iq_ibz_fine) - sigma%ephwg%lgk%ibz(:, iq_ibz_fine)) < tol12)) then
    1476            0 :                 ABI_ERROR("Mismatch in qpoints.")
    1477              :               end if
    1478              :            end if
    1479              :          endif
    1480              :        end if
    1481              : 
    1482              :        ! Get istwf_kq, npw_kq, kg_kq for k+q.
    1483              :        call wfd%get_gvec_gbound(cryst%gmet, ecut, kq, ikq_ibz, isirr_kq, dtset%nloalg, & ! in
    1484         3852 :                                 istwf_kq, npw_kq, kg_kq, nkpg_kq, kpg_kq, gbound_kq)     ! out
    1485              : 
    1486              :        !call timab(1901, 2, tsec)
    1487              :        !call timab(1902, 1, tsec)
    1488              : 
    1489         3852 :        istwf_kqirr = wfd%istwfk(ikq_ibz); npw_kqirr = wfd%npwarr(ikq_ibz)
    1490        11556 :        ABI_MALLOC(bra_kq, (2, npw_kq*nspinor))
    1491        11556 :        ABI_MALLOC(cgwork, (2, npw_kqirr*nspinor))
    1492              : 
    1493         3852 :        if (osc_ecut /= zero) then
    1494              :          ! Compute "small" G-sphere centered on qpt and gbound for zero-padded FFT for oscillators.
    1495            0 :          call get_kg(qpt, istwfk_1, abs(osc_ecut), cryst%gmet, osc_npw, osc_gvecq)
    1496            0 :          call sphereboundary(osc_gbound_q, istwfk_1, osc_gvecq, wfd%mgfft, osc_npw)
    1497              : 
    1498              :          ! Compute correspondence G-sphere --> FFT mesh.
    1499            0 :          ABI_MALLOC(osc_indpw, (osc_npw))
    1500            0 :          ABI_MALLOC(osc_mask, (osc_npw))
    1501            0 :          call kgindex(osc_indpw, osc_gvecq, osc_mask, wfd%mpi_enreg, ngfft, osc_npw)
    1502            0 :          ABI_FREE(osc_mask)
    1503              : 
    1504            0 :          ABI_MALLOC(workq_ug, (npw_kq*nspinor))
    1505            0 :          ABI_MALLOC(osc_ks, (osc_npw*nspinor, nbcalc_ks))
    1506              :        end if
    1507              : 
    1508              :        ! Allocate array to store H1 |psi_nk> for all 3*natom perturbations
    1509        19260 :        ABI_MALLOC_OR_DIE(h1kets_kq, (2, npw_kq*nspinor, my_npert, nbcalc_ks), ierr)
    1510              : 
    1511              :        ! Allocate vlocal1 with correct cplex. Note nvloc
    1512        26964 :        ABI_MALLOC_OR_DIE(vlocal1, (cplex*n4, n5, n6, gs_ham_kq%nvloc, my_npert), ierr)
    1513              : 
    1514        11556 :        ABI_MALLOC(gs1c, (2, npw_kq*nspinor*((sij_opt+1)/2)))
    1515        11556 :        ABI_MALLOC(gvnlx1, (2, npw_kq*nspinor))
    1516              : 
    1517              :        call gs_ham_kq%eph_setup_k("kq", kq, istwfk_1, npw_kq, kg_kq, dtset, cryst, psps, &
    1518         3852 :                                   nkpg, kpg_kq, ffnl_kq, kinpw_kq, ph3d_kq, sigma%pert_comm%value)
    1519              : 
    1520         3852 :        if (dtset%eph_stern /= 0 .and. .not. sigma%imag_only) then
    1521              :          ! Build global array with GS wavefunctions cg_kq at k+q to prepare call to dfpt_cgwf.
    1522              :          ! NB: bsum_range is not compatible with Sternheimer.
    1523              :          ! There's a check at the level of the parser in chkinp.
    1524              : 
    1525              :          ! The static correction to FM_nk is:
    1526              :          !    \sum_{qnu} (2n_qnu + 1) <H^1_{qnu} psi_nk| psi^1_{nk; qnu}>
    1527              : 
    1528          579 :          call timab(1908, 1, tsec)
    1529     38669334 :          ABI_CALLOC(cg1s_kq, (2, npw_kq*nspinor, natom3, nbcalc_ks))
    1530              : 
    1531              :          ! NOTE: in the present version, we need to gather all nbsum bands on each core before calling dfpt_cgwf.
    1532              :          ! In principle one can call dfpt_cgwf in band-para mode but then
    1533              :          ! we are obliged to call the sternheimer solver with one psi1 and all procs in bsum_comm
    1534              :          ! just to to be able to apply the projector operator.
    1535              :          ! The present version is not memory efficient and leads to a big load imbalance if
    1536              :          ! bsum%comm%nproc > nband_calc_ks
    1537              : 
    1538              :          if (stern_has_band_para) then
    1539              :            nband_me = sigma%my_bsum_stop - sigma%my_bsum_start + 1
    1540              :            stern_comm = sigma%bsum_comm%value
    1541              :          else
    1542          579 :            nband_me = nbsum
    1543          579 :            stern_comm = xmpi_comm_self
    1544              :          end if
    1545              : 
    1546          579 :          stern_use_cache = merge(.True., .False., dtset%eph_stern == 1)
    1547              :          call stern%init(dtset, npw_k, npw_kq, nspinor, nbsum, nband_me, fermie1_idir_ipert, &
    1548          579 :                          stern_use_cache, work_ngfft, mpi_enreg, stern_comm)
    1549              : 
    1550         9335 :          do ibsum_kq=sigma%my_bsum_start, sigma%my_bsum_stop
    1551              : 
    1552              :             ! Reconstruct u_kq(G) from the IBZ image.
    1553              :             call wfd%rotate_cg(ibsum_kq, ndat1, spin, kq_ibz, npw_kq, kg_kq, istwf_kq, &
    1554         8756 :                                cryst, sigma%indkk_kq(:,iq_ibz_k), gbound_kq, work_ngfft, work, bra_kq)
    1555              : 
    1556         9335 :             if (stern%has_band_para) then
    1557            0 :               ii = ibsum_kq - sigma%my_bsum_start + 1
    1558            0 :               stern%cgq(:,:,ii) = bra_kq
    1559              :             else
    1560     37029800 :               stern%cgq(:, :, ibsum_kq) = bra_kq
    1561              :             end if
    1562              :          end do ! ibsum_kq
    1563              : 
    1564          579 :          cgq_request = xmpi_request_null
    1565              : 
    1566          579 : if (.not. stern%has_band_para) then
    1567          579 :          if (sigma%bsum_comm%nproc > 1) then
    1568              :            ! If band parallelism, need to gather all bands nbsum bands.
    1569              :            ! FIXME: This part is network intensive, one can avoid it by calling dfpt_cgwf in band-para mode.
    1570              :            !call xmpi_sum(stern%cgq, sigma%bsum_comm%value, ierr)
    1571              :            !call xmpi_isum_ip(stern%cgq, sigma%bsum_comm%value, cgq_request, ierr)
    1572              : 
    1573            0 :            nelem = 2 * npw_kq * nspinor
    1574            0 :            call sigma%bsum_comm%prep_gatherv(nelem, sigma%nbsum_rank(:,1), sendcount, recvcounts, displs)
    1575              : #ifdef HAVE_MPI
    1576              :            !call MPI_ALLGATHERV(MPI_IN_PLACE, sendcount, MPI_DOUBLE_PRECISION, stern%cgq, recvcounts, displs, &
    1577              :            !                    MPI_DOUBLE_PRECISION, sigma%bsum_comm%value, ierr)
    1578              : 
    1579              : #if defined HAVE_MPI2_INPLACE
    1580              :            call MPI_IALLGATHERV(MPI_IN_PLACE, sendcount, MPI_DOUBLE_PRECISION, stern%cgq, recvcounts, displs, &
    1581            0 :                                 MPI_DOUBLE_PRECISION, sigma%bsum_comm%value, cgq_request, ierr)
    1582              : #else
    1583              :            ABI_MALLOC(cgq_buf,(sendcount))
    1584              :            me=1+xmpi_comm_rank(sigma%bsum_comm%value)
    1585              :            cgq_buf(1:sendcount)=cgq_ptr(displs(me)+1:displs(me)+sendcount)
    1586              :            call c_f_pointer(c_loc(stern%cgq), cgq_ptr, [2*npw_kq*nspinor*nband_me])
    1587              :            call MPI_IALLGATHERV(cgq_buf, sendcount, MPI_DOUBLE_PRECISION, cgq_ptr, recvcounts, displs, &
    1588              :                                 MPI_DOUBLE_PRECISION, sigma%bsum_comm%value, cgq_request, ierr)
    1589              :            ABI_FREE(cgq_buf)
    1590              : #endif
    1591            0 :            call xmpi_requests_add(+1)
    1592              : #endif
    1593              : 
    1594            0 :            ABI_FREE(recvcounts)
    1595            0 :            ABI_FREE(displs)
    1596              :          end if
    1597              : end if
    1598          579 :          call timab(1908, 2, tsec)
    1599              :        end if ! eph_stern
    1600              : 
    1601              :        ! Loop over all 3*natom perturbations (Each core prepares its own potentials)
    1602              :        ! In the inner loop, we calculate H1 * psi_k, stored in h1kets_kq on the k+q sphere.
    1603        24408 :        do imyp=1,my_npert
    1604        20556 :          idir = sigma%my_pinfo(1, imyp); ipert = sigma%my_pinfo(2, imyp); ipc = sigma%my_pinfo(3, imyp)
    1605              : 
    1606              :          ! Set up local potential vlocal1 with proper dimensioning, from vtrial1 taking into account the spin.
    1607              :          ! Each CPU prepares its own potentials.
    1608              :          call rf_transgrid_and_pack(spin, nspden, psps%usepaw, cplex, nfftf, nfft, ngfft, gs_ham_kq%nvloc, &
    1609        20556 :            pawfgr, mpi_enreg, vtrial, v1scf(:,:,:,imyp), vlocal, vlocal1(:,:,:,:,imyp))
    1610              : 
    1611              :          ! Continue to initialize the Hamiltonian (call it here to support dfpt_cgwf Sternheimer).
    1612        20556 :          call gs_ham_kq%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.)
    1613              : 
    1614              :          ! Prepare application of the NL part.
    1615        20556 :          call rf_ham_kq%init(cplex, gs_ham_kq, ipert, has_e1kbsc=.true.)
    1616        20556 :          call rf_ham_kq%load_spin(spin, vlocal1=vlocal1(:,:,:,:,imyp), with_nonlocal=.true.)
    1617              : 
    1618              :          ! Compute H(1) applied to GS wavefunction Psi_nk(0)
    1619        74646 :          do ib_k=1,nbcalc_ks
    1620        54090 :            if (sigma%bsum_comm%skip(ib_k, root=root_bcalc(ib_k))) cycle ! MPI parallelism inside bsum_comm
    1621              :                                                                         ! Store rank treating ib_k in root_bcalc
    1622        54090 :            band_ks = ib_k + bstart_ks - 1
    1623        54090 :            eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    1624              :            ! Use scissor shift on 0-order eigenvalue
    1625        54090 :            eshift = eig0nk - dtset%dfpt_sciss
    1626              : 
    1627              :            call getgh1c(berryopt0, kets_k(:,:,ib_k), cwaveprj0, h1kets_kq(:,:,imyp, ib_k), &
    1628              :              grad_berry, gs1c, gs_ham_kq, gvnlx1, idir, ipert, (/eshift/), mpi_enreg, 1, optlocal, &
    1629       128736 :              optnl, opt_gvnlx1, rf_ham_kq, sij_opt, tim_getgh1c1, usevnl)
    1630              :          end do
    1631              : 
    1632        74646 :          do ib_k=1,nbcalc_ks
    1633        74646 :            call xmpi_bcast(h1kets_kq(:,:,imyp,ib_k), root_bcalc(ib_k), sigma%bsum_comm%value, ierr)
    1634              :          end do
    1635              : 
    1636        20556 :          if (dtset%eph_stern /= 0 .and. .not. sigma%imag_only) then
    1637         3474 :            call timab(1909, 1, tsec)
    1638              :            ! Activate Sternheimer. Note that we are still inside the MPI loop over my_npert.
    1639              :            ! NB: Assume adiabatic AHC expression to compute the contribution of states above nbsum.
    1640              : 
    1641              :            ! Wait for gatherv operation
    1642         3474 :            if (.not. stern%has_band_para .and. cgq_request /= xmpi_request_null) call xmpi_wait(cgq_request, ierr)
    1643              : 
    1644        17676 :            do ib_k=1,nbcalc_ks
    1645        14202 :              band_ks = ib_k + bstart_ks - 1
    1646       229410 :              stern%bands_treated_now(:) = 0; stern%bands_treated_now(band_ks) = 1
    1647              : 
    1648        14202 :              if (stern%has_band_para) then
    1649              :                ! Init rank_band and band_me from nbsum_rank.
    1650            0 :                stern%rank_band = -1; band_me = 1
    1651            0 :                do ip=1,sigma%bsum_comm%nproc
    1652            0 :                  ii = sigma%nbsum_rank(ip,2)
    1653            0 :                  jj = sigma%nbsum_rank(ip,2) + sigma%nbsum_rank(ip,1) -1
    1654            0 :                  stern%rank_band(ii:jj) = ip - 1
    1655            0 :                  if (inrange(band_ks, [ii, jj])) u1_master = ip - 1
    1656              :                end do
    1657            0 :                if (inrange(band_ks, [sigma%my_bsum_start, sigma%my_bsum_stop])) then
    1658            0 :                  band_me = band_ks - sigma%my_bsum_start + 1
    1659            0 :                  u1_band = band_ks
    1660              :                else
    1661            0 :                  band_me = 1
    1662            0 :                  u1_band = -band_ks
    1663              :                end if
    1664              :              else
    1665       229410 :                stern%rank_band = 0; u1_band = band_ks; band_me = band_ks
    1666        14202 :                if (sigma%bsum_comm%skip(ib_k)) cycle ! MPI parallelism inside bsum_comm
    1667              :              end if
    1668              : 
    1669              :              ! Init entry in cg1s_kq, either from cache or with zeros.
    1670        14202 :              if (stern%use_cache) then
    1671        14202 :                u1c_ib_k = u1c%find_band(band_ks)
    1672        14202 :                if (u1c_ib_k /= -1) then
    1673              :                  call cgtk_change_gsphere(nspinor, &
    1674              :                                           u1c%prev_npw_kq, istwfk_1, u1c%prev_kg_kq, u1c%prev_cg1s_kq(1,1,ipc,u1c_ib_k), &
    1675        13698 :                                           npw_kq, istwfk_1, kg_kq, cg1s_kq(1,1,ipc,ib_k), work_ngfft, work)
    1676              :                else
    1677      1532232 :                  cg1s_kq(:,:,ipc,ib_k) = zero
    1678              :                end if
    1679              : 
    1680              :              else
    1681            0 :                cg1s_kq(:,:,ipc,ib_k) = zero
    1682              :              end if
    1683              : 
    1684        14202 :              call timab(1909, 2, tsec)
    1685              : 
    1686              :              call stern%solve(u1_band, band_me, idir, ipert, qpt, gs_ham_kq, rf_ham_kq, &
    1687              :                               ebands%eig(:,ik_ibz,spin), ebands%eig(:,ikq_ibz,spin), &
    1688        14202 :                               kets_k(:,:,ib_k), cwaveprj0, cg1s_kq(:,:,ipc,ib_k), cwaveprj, msg, ierr)
    1689        14202 :              ABI_CHECK(ierr == 0, msg)
    1690        17676 :              if (stern%has_band_para) call xmpi_bcast(cg1s_kq(:,:,ipc,ib_k), u1_master, sigma%bsum_comm%value, ierr)
    1691              :            end do ! ib_k
    1692              : 
    1693              :            !call timab(1909, 2, tsec)
    1694              :          end if ! sternheimer
    1695              : 
    1696        24408 :          call rf_ham_kq%free()
    1697              :        end do ! imyp  (loop over perturbations)
    1698              : 
    1699              :        !call timab(1902, 2, tsec)
    1700         3852 :        ABI_FREE(gs1c)
    1701         3852 :        ABI_FREE(gvnlx1)
    1702         3852 :        ABI_FREE(vlocal1)
    1703         3852 :        ABI_FREE(v1scf)
    1704         3852 :        call stern%free()
    1705              : 
    1706              :        ! Wait from phonon frequencies and displacements inside pert_comm
    1707         3852 :        call phstore%wait(cryst, phfrq, displ_cart, displ_red)
    1708              : 
    1709         3852 :        if (dtset%eph_stern /= 0 .and. .not. sigma%imag_only) then
    1710          579 :          call timab(1910, 1, tsec)
    1711              :          ! Add contribution to Fan-Migdal self-energy coming from Sternheimer.
    1712              :          ! NB: All procs inside (bsum_comm x pert_comm) enter here!
    1713              : 
    1714              :          ! Store |Psi_1> to init Sternheimer solver for the next q-point.
    1715          579 :          call u1c%store(qpt, npw_kq, nspinor, natom3, bstart_ks, nbcalc_ks, kg_kq, cg1s_kq)
    1716              : 
    1717              :          ! h1kets_kq are MPI distributed inside pert_comm but we need off-diagonal pp' terms --> collect results.
    1718     38669334 :          ABI_CALLOC(h1kets_kq_allperts, (2, npw_kq*nspinor, natom3, nbcalc_ks))
    1719              : 
    1720              :          ! Compute S_pp' = <D_{qp} vscf u_nk|u'_{nk+q p'}>
    1721       275100 :          ABI_CALLOC(stern_ppb, (2, natom3, natom3, nbcalc_ks))
    1722              : 
    1723              :          ! Compute <Psi_1|Psi_1>
    1724       274521 :          ABI_CALLOC(E4stern_nk, (2, natom3, natom3, nbcalc_ks))
    1725              : 
    1726         2946 :          do ib_k=1,nbcalc_ks
    1727         2367 :            if (sigma%bsum_comm%skip(ib_k)) cycle ! MPI parallelism inside bsum_comm
    1728              : 
    1729         2367 :            call xmpi_sum(cg1s_kq(:,:,:,ib_k), sigma%pert_comm%value, ierr)
    1730              : 
    1731              :            ! TODO
    1732              :            !nelem = 2*npw_kq*nspinor*sigma%my_npert
    1733              :            !call MPI_ALLGATHER(MPI_IN_PLACE, nelem, MPI_DOUBLE_PRECISION, cg1s_kq(:,:,:,ib_k), nelem, &
    1734              :            !                   MPI_DOUBLE_PRECISION, sigma%pert_comm%value, ierr)
    1735              : 
    1736              :            call xmpi_allgather(h1kets_kq(:,:,:,ib_k), 2*npw_kq*nspinor*sigma%my_npert, &
    1737         2367 :                                h1kets_kq_allperts(:,:,:,ib_k), sigma%pert_comm%value, ierr)
    1738              : 
    1739              :            call cg_zgemm("C", "N", npw_kq*nspinor, natom3, natom3, &
    1740         2367 :              h1kets_kq_allperts(:,:,:,ib_k), cg1s_kq(:,:,:,ib_k), stern_ppb(:,:,:,ib_k))
    1741              :            !
    1742              :            ! We now compute <Psi_1|Psi_1>
    1743              :            call cg_zgemm("C", "N", npw_kq*nspinor, natom3, natom3, &
    1744         2367 :              cg1s_kq(:,:,:,ib_k), cg1s_kq(:,:,:,ib_k), E4stern_nk(:,:,:,ib_k))
    1745              : 
    1746              :            ! Save data for Debye-Waller that is performed outside the q-loop.
    1747        20616 :            if (q_is_gamma) stern_dw(:,:,:,ib_k) = stern_ppb(:,:,:,ib_k)
    1748              :          end do ! ib_k
    1749              : 
    1750          579 :          ABI_FREE(cg1s_kq)
    1751          579 :          ABI_FREE(h1kets_kq_allperts)
    1752              : 
    1753          579 :          if (q_is_gamma) call xmpi_sum(stern_dw, sigma%bsum_comm%value, ierr)
    1754              : 
    1755              :          ! Compute contribution to Fan-Migdal for M > sigma%nbsum
    1756         4053 :          do imyp=1,my_npert
    1757         3474 :            nu = sigma%my_pinfo(3, imyp)
    1758         3474 :            wqnu = phfrq(nu); if (ephtk_skip_phmode(nu, wqnu, sigma%phmodes_skip, dtset%eph_phrange_w)) cycle
    1759              : 
    1760              :            ! Get phonon occupation for all temperatures.
    1761        15816 :            nqnu_tlist = occ_be(wqnu, sigma%kTmesh(:), zero)
    1762              : 
    1763        16339 :            do ib_k=1,nbcalc_ks
    1764        13121 :              if (sigma%bsum_comm%skip(ib_k)) cycle ! MPI parallelism inside bsum_comm
    1765              : 
    1766              :              ! sum_{pp'} d_p* Stern_{pp'} d_p' with d = displ_red(:,:,:,nu) and S = stern_ppb(:,:,:,ib_k)
    1767       249299 :              vec_natom3 = zero
    1768        13121 :              call cg_zgemm("N", "N", natom3, natom3, 1, stern_ppb(:,:,:,ib_k), displ_red(:,:,:,nu), vec_natom3)
    1769        13121 :              dotri = cg_zdotc(natom3, displ_red(:,:,:,nu), vec_natom3)
    1770              :              !write(std_out, *)"dotri:", dotri
    1771        13121 :              rfact = dotri(1)
    1772              :              !rfact = cg_real_zdotc(natom3, displ_red(:,:,:,nu), vec_natom3)
    1773        13121 :              rfact = rfact * sigma%wtq_k(iq_ibz_k) / (two * wqnu)
    1774              : 
    1775        58090 :              do it=1,sigma%ntemp
    1776        44969 :                rtmp = (two * nqnu_tlist(it) + one) * rfact
    1777        44969 :                sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + rtmp
    1778        44969 :                sigma%fan_vals(it, ib_k) = sigma%fan_vals(it, ib_k) + rtmp
    1779        44969 :                sigma%fan_stern_vals(it, ib_k) = sigma%fan_stern_vals(it, ib_k) + rtmp
    1780              :                ! Add static term from Sternheimer to Sigma(w) as well.
    1781      3627409 :                if (sigma%nwr > 0) sigma%vals_wr(:, it, ib_k) = sigma%vals_wr(:, it, ib_k) + rtmp
    1782              :              end do
    1783              : 
    1784              :              ! Calculation of the 4th-order contribution to total energy due to electron-phonon interaction
    1785              :              ! SP - For E4 we multipy with eigendiplacement vectors
    1786       249299 :              vec_natom3 = zero
    1787        13121 :              call cg_zgemm("N", "N", natom3, natom3, 1, E4stern_nk(:,:,:,ib_k), displ_red(:,:,:,nu), vec_natom3)
    1788        13121 :              dotri = cg_zdotc(natom3, displ_red(:,:,:,nu), vec_natom3)
    1789        13121 :              rfact = dotri(1)
    1790        13121 :              rfact = rfact * sigma%wtq_k(iq_ibz_k) / two
    1791              :              !
    1792        61308 :              do it=1, sigma%ntemp
    1793        44969 :                rtmp = (two * nqnu_tlist(it) + one) * rfact
    1794        58090 :                sigma%E4_vals(it, ib_k) = sigma%E4_vals(it, ib_k) + rtmp
    1795              :              end do
    1796              : 
    1797              :              ! TODO Eliashberg functions with Sternheimer
    1798              :              !if (dtset%prteliash /= 0) then
    1799              :              !end if
    1800              :            end do
    1801              :            !
    1802              :            ! Second-order contribution to the total energy.
    1803              :            ! This is he phonon contribution (\hbar\omega/2)
    1804        13177 :            do it=1, sigma%ntemp
    1805         9380 :              rtmp = (two * nqnu_tlist(it) + one) * wqnu * sigma%wtq_k(iq_ibz_k) / two
    1806        12598 :              sigma%E2(it) = sigma%E2(it) + rtmp
    1807              :            enddo
    1808              :          end do  ! imyp
    1809              : 
    1810          579 :          ABI_FREE(stern_ppb)
    1811          579 :          ABI_FREE(E4stern_nk)
    1812          579 :          call timab(1910, 2, tsec)
    1813              :        end if ! eph_stern /= 0
    1814              : 
    1815              :        ! ==============================================
    1816              :        ! Sum over m bands parallelized inside bsum_comm
    1817              :        ! ==============================================
    1818         3852 :        call timab(1903, 1, tsec)
    1819              : 
    1820        29770 :        do ibsum_kq=sigma%my_bsum_start, sigma%my_bsum_stop
    1821        25918 :          call timab(1904, 1, tsec)
    1822              :          ! This can happen if we have loaded the wavefunctions inside the energy range.
    1823        25918 :          if (sigma%imag_only .and. sigma%qint_method == 1) then
    1824         5360 :            if (.not. wfd%ihave_ug(ibsum_kq, ikq_ibz, spin)) then
    1825         1248 :              ignore_ibsum_kq = ignore_ibsum_kq + 1; cycle
    1826              :            end if
    1827              :          end if
    1828              : 
    1829              :          ! Reconstruct u_kq(G) from the IBZ image.
    1830              :          call wfd%rotate_cg(ibsum_kq, ndat1, spin, kq_ibz, npw_kq, kg_kq, istwf_kq, &
    1831        24670 :                             cryst, sigma%indkk_kq(:,iq_ibz_k), gbound_kq, work_ngfft, work, bra_kq)
    1832              : 
    1833              :          ! Get gkk(kcalc, q, idir_ipert) in the atomic representation.
    1834              :          ! No need to handle istwf_kq because it's always 1.
    1835      2071114 :          gkq_atm = zero; cnt = 0
    1836       170134 :          do imyp=1,my_npert
    1837       145464 :            ipc = sigma%my_pinfo(3, imyp)
    1838              :            ! Calculate <u_(band,k+q)^(0)|H_(k+q,k)^(1)|u_(band,k)^(0)> for this pert (NC psps) istwf_k always 1
    1839       803794 :            do ib_k=1,nbcalc_ks
    1840       633660 :              gkq_atm(:, ib_k, ipc) = cg_zdotc(npw_kq*nspinor, bra_kq, h1kets_kq(:,:,imyp,ib_k))
    1841       633660 :              cnt = cnt + 1
    1842      2046444 :              gkq_allgather(:,cnt, 1) = gkq_atm(:, ib_k, ipc)
    1843              :            end do
    1844              :            !call cg_zgemv("C", npw_kq*nspinor, nbcalc_ks, h1kets_kq(:,:,:,imyp), bra_kq, gkq_atm(:,:,ipc))
    1845              :          end do
    1846        24670 :          call timab(1904, 2, tsec)
    1847        24670 :          call timab(1905, 1, tsec)
    1848              :          !ii = nbcalc_ks * my_npert
    1849              :          !call cg_zgemm("H", "N", npw_kq*nspinor, ii, ii, h1kets_kq, bra_kq, gkq_atm)
    1850              :          !call cg_zgemm("H", "N", npw_kq*nspinor, ii, ii, bra_kq, h1kets_kq, gkq_atm)
    1851              : 
    1852              :          ! Get gkk(kcalc, q, nu) in the phonon representation.
    1853              :          ! Need to gather all perts distributed in pert_comm
    1854        24670 :          if (sigma%pert_comm%nproc > 1) then
    1855              :            call xmpi_allgather(gkq_allgather(:,:,1), 2 * nbcalc_ks * my_npert, gkq_allgather(:,:,2), &
    1856            0 :                                sigma%pert_comm%value, ierr)
    1857            0 :            do cnt=1,nbcalc_ks*natom3
    1858            0 :              ipc = 1 + (cnt - 1) / nbcalc_ks
    1859            0 :              ib_k = 1 + mod(cnt - 1, nbcalc_ks)
    1860            0 :              gkq_atm(:, ib_k, ipc) = gkq_allgather(:, cnt, 2)
    1861              :            end  do
    1862              :          end if
    1863              : 
    1864        24670 :          call ephtk_gkknu_from_atm(1, nbcalc_ks, 1, natom, gkq_atm, phfrq, displ_red, gkq_nu)
    1865              : 
    1866              :          ! bsum_2 and bsum_3 are hotspots.
    1867        24670 :          call timab(1905, 2, tsec)
    1868        24670 :          call timab(1906, 1, tsec)
    1869              : 
    1870              :          ! Save e-ph matrix elements for Debye-Waller computation that will be performed outside the q-loop.
    1871              :          ! gkq0_atm(2, nbcalc_ks, bsum_start:bsum_stop, natom3)
    1872       178666 :          if (q_is_gamma .and. .not. sigma%imag_only) gkq0_atm(:, :, ibsum_kq, :) = gkq_atm
    1873              : 
    1874        24670 :          if (osc_ecut > zero) then
    1875            0 :            workq_ug = cmplx(bra_kq(1, :), bra_kq(2, :), kind=gwp)
    1876              :            call fft_ug(npw_kq, wfd%nfft, nspinor, ndat1, wfd%mgfft, wfd%ngfft, &
    1877            0 :                        istwf_kq, kg_kq, gbound_kq, workq_ug, ur_kq)
    1878              : 
    1879              :            ! We need <k+q| e^{iq+G}|k> --> compute <k| e^{-i(q+G)}|k+q> with FFT and take CC.
    1880            0 :            do ib_k=1,nbcalc_ks
    1881            0 :              work_ur = ur_kq * conjg(ur_k(:, ib_k))
    1882              :              ! Call zero-padded FFT routine.
    1883            0 :              call fftpad(work_ur, ngfft, n1, n2, n3, n1, n2, n3, nspinor, wfd%mgfft, -1, osc_gbound_q)
    1884              : 
    1885              :              ! Need results on the G-sphere --> Transfer data from FFT to G-sphere.
    1886            0 :              do ispinor=1,nspinor
    1887            0 :                do ig=1,osc_npw
    1888            0 :                  ifft = osc_indpw(ig) + (ispinor-1) * wfd%nfft
    1889            0 :                  osc_ks(ig + (ispinor -1) * osc_npw, ib_k) = conjg(work_ur(ifft))
    1890              :                end do
    1891              :              end do
    1892              : 
    1893              :              !band_ks = ib_k + bstart_ks - 1
    1894              :              !if (ibsum_kq == band_ks) then
    1895              :              !if (ibsum_kq == band_ks .and. all(abs(qpt) < tol12)) then
    1896              :              !  write(std_out,"(a,i0,2a)")" Ene and Oscillator for band: ", band_ks, ", and q-point: ", trim(ktoa(qpt))
    1897              :              !  write(std_out,*)ebands%eig(band_ks, ik_ibz, spin) * Ha_eV, osc_ks(:2,ib_k)
    1898              :              !end if
    1899              :            end do
    1900              :          end if
    1901              : 
    1902        24670 :          eig0mkq = ebands%eig(ibsum_kq, ikq_ibz, spin)
    1903              : 
    1904              :          ! q-weight for naive integration
    1905        24670 :          weight_q = sigma%wtq_k(iq_ibz_k)
    1906              : 
    1907        24670 :          if (sigma%mrta > 0) then
    1908              :            ! Compute v_kq
    1909              :            ! If k+q is not in the IBZ, we need to recostruct the value by symmetry using v(Sq) = S v(q).
    1910              :            ! Use transpose(R) because we are using the tables for the wavefunctions
    1911              :            ! In this case listkk has been called with symrel and use_symrec=False
    1912              :            ! so q_bz = S^T q_ibz where S is the isym_kq symmetry
    1913        22240 :            vkq = vcar_ibz(:, ibsum_kq, ikq_ibz, spin)
    1914         5560 :            if (.not. isirr_kq) then
    1915         4334 :              vkq = matmul(transpose(cryst%symrel_cart(:,:,isym_kq)), vkq)
    1916         5108 :              if (trev_kq /= 0) vkq = -vkq
    1917              :              vkq_norm = sqrt(dot_product(vk, vk))
    1918              :            end if
    1919              : 
    1920              :            ! Precompute alpha MRTA coefficients for all nk states.
    1921        25338 :            do ib_k=1,nbcalc_ks
    1922        79112 :              vk = sigma%vcar_calc(:, ib_k, ikcalc, spin)
    1923        79112 :              vkk_norm = sqrt(dot_product(vk, vk))
    1924        19778 :              alpha_mrta(ib_k) = one ! zero
    1925        61785 :              if (vkk_norm > tol6) alpha_mrta(ib_k) = one - dot_product(vkq, vk) / vkk_norm ** 2
    1926              :              !if (vkk_norm > tol6 .and. vkq_norm > tol6) then
    1927              :              !  alpha_mrta(ib_k) = one - dot_product(vkq, vk) / (vkk_norm * vk_norm)
    1928              :              !end if
    1929              :            end do
    1930              :          end if
    1931        24670 :          call timab(1906, 2, tsec)
    1932        24670 :          call timab(1907, 1, tsec)
    1933              : 
    1934              :          ! Accumulate contribution to the FM self-energy
    1935       170134 :          do imyp=1,my_npert
    1936       145464 :            nu = sigma%my_pinfo(3, imyp)
    1937              :            ! Ignore unstable modes or modes that should be skipped.
    1938       145464 :            wqnu = phfrq(nu); if (ephtk_skip_phmode(nu, wqnu, sigma%phmodes_skip, dtset%eph_phrange_w)) cycle
    1939              : 
    1940       137610 :            if (dtset%eph_prtscratew == 1) then
    1941              :              ! Precompute delta(w-w_qnu)
    1942      1383363 :              gaussw_qnu = gaussian(sigma%phmesh - wqnu, dtset%ph_smear)
    1943              :            end if
    1944              : 
    1945              :            ! For each band in Sigma_{nk}
    1946       759808 :            do ib_k=1,nbcalc_ks
    1947       597528 :              band_ks = ib_k + bstart_ks - 1
    1948       597528 :              eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    1949       597528 :              gkq2 = weight_q * (gkq_nu(1,ib_k,nu) ** 2 + gkq_nu(2,ib_k,nu) ** 2)
    1950       597528 :              ediff = eig0nk - eig0mkq
    1951       597528 :              intra_band = q_is_gamma .and. ediff <= TOL_EDIFF
    1952       597528 :              same_band = ibsum_kq == band_ks
    1953              : 
    1954              :              ! Optionally, accumulate contribution to Eliashberg functions
    1955       597528 :              if (dtset%prteliash /= 0) then
    1956              :                ! EPH strength with delta(e_{nk} - e_{m\kq})
    1957       325314 :                rfact = gaussian(eig0nk - eig0mkq, dtset%tsmear)
    1958              :                sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 1) = sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 1) + &
    1959       325314 :                     rfact * (gkq_nu(1, ib_k, nu) ** 2 + gkq_nu(2, ib_k, nu) ** 2)
    1960              : 
    1961              :                ! Treat contribution to Eliashberg function due to Fan term.
    1962       325314 :                if (ediff > wqnu) then
    1963        55493 :                   rfact = one / ediff
    1964              :                else
    1965              :                  ! Non adiabatic regime --> Add complex shift.
    1966              :                  ! Note however that the expression for this flavor of Eliashberg function relies on adiabaticity.
    1967       269821 :                  rfact = real(one / (ediff + sigma%ieta))
    1968              :                end if
    1969              : 
    1970       325314 :                gf_val = gkq_nu(1, ib_k, nu) ** 2 + gkq_nu(2, ib_k, nu) ** 2
    1971       325314 :                if (intra_band .and. sigma%frohl_model == 1) then
    1972            0 :                  gf_val = zero; if (same_band) gf_val = zpr_frohl_sphcorr(nu) * (four_pi / three * q0rad ** 3)
    1973              :                end if
    1974              : 
    1975       325314 :                sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 2) = sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 2) + gf_val * rfact
    1976              :                ! TODO: Add Sternheimer contribution
    1977              : 
    1978       325314 :                if (dtset%prteliash == 3) then
    1979              :                  ! Accumulate: |g(k,q)|^2 delta(e - e_{m\kq}) delta(w - w_\qnu}
    1980            0 :                  delta_e_minus_emkq = gaussian(sigma%a2f_emesh - eig0mkq, dtset%tsmear)
    1981            0 :                  dwargs = sigma%phmesh - phfrq(nu)
    1982            0 :                  dtw_weights(:, 1) = gaussian(dwargs, dtset%ph_smear)
    1983            0 :                  do iw=1,sigma%phmesh_size
    1984              :                    sigma%a2few(:, iw, ib_k) = sigma%a2few(:, iw, ib_k) + &
    1985            0 :                       delta_e_minus_emkq(:) * dtw_weights(iw, 1) * gf_val * sigma%wtq_k(iq_ibz_k)
    1986              :                  end do
    1987              :                end if
    1988              :              end if  ! prteliash /= 0
    1989              : 
    1990      3104074 :              do it = 1, sigma%ntemp
    1991              :                ! Compute electronic occ for this T (note mu_e(it) Fermi level)
    1992      2368936 :                nqnu = occ_be(wqnu, sigma%kTmesh(it), zero)
    1993      2368936 :                f_nk = occ_fd(eig0nk, sigma%kTmesh(it), sigma%mu_e(it))
    1994              :                ! SP - the + 1E-6 is needed because eig0mkq is not perfectly degenerate at \Gamma
    1995      2368936 :                f_mkq = occ_fd(eig0mkq, sigma%kTmesh(it), sigma%mu_e(it) + 1E-6)
    1996              :                !
    1997              :                ! Here we have to handle 3 different logical values leading to 9 different cases:
    1998              :                !
    1999              :                ! qint_method         0      1
    2000              :                !   use_doublegrid   .true. .false.
    2001              :                !     imag_only      .true. .false.
    2002              :                !
    2003              :                ! We will write this with nested conditionals using the order above
    2004              : 
    2005      2368936 :                if (sigma%qint_method == 0) then
    2006              :                  ! =========
    2007              :                  ! zcut mode
    2008              :                  ! =========
    2009              : 
    2010      1670612 :                  if (sigma%use_doublegrid) then
    2011        51744 :                    cfact = zero
    2012      1448832 :                    do jj=1,sigma%eph_doublegrid%ndiv
    2013              :                      ! Double Grid shared points weights
    2014      1397088 :                      ikq_bz_fine  = sigma%eph_doublegrid%mapping(2, jj)
    2015      1397088 :                      weight = sigma%eph_doublegrid%weights_dense(ikq_bz_fine)
    2016              : 
    2017              :                      ! Electronic eigenvalue
    2018      1397088 :                      ikq_ibz_fine = sigma%eph_doublegrid%mapping(5, jj)
    2019      1397088 :                      eig0mkq = sigma%eph_doublegrid%ebands_dense%eig(ibsum_kq, ikq_ibz_fine, spin)
    2020      1397088 :                      f_mkq = occ_fd(eig0mkq, sigma%kTmesh(it), sigma%mu_e(it))
    2021              : 
    2022              :                      ! Phonon frequency
    2023      1397088 :                      iq_ibz_fine = sigma%eph_doublegrid%mapping(6, jj)
    2024      1397088 :                      wqnu = sigma%ephwg%phfrq_ibz(iq_ibz_fine, nu)
    2025      1397088 :                      nqnu = occ_be(wqnu, sigma%kTmesh(it), zero)
    2026              : 
    2027      1448832 :                      if (dtset%eph_ahc_type == 1) then
    2028              :                         cfact = cfact + &
    2029              :                                ((nqnu + f_mkq      ) / (eig0nk - eig0mkq + wqnu + sigma%ieta) + &
    2030      1397088 :                                 (nqnu - f_mkq + one) / (eig0nk - eig0mkq - wqnu + sigma%ieta) ) * weight
    2031              :                      else
    2032            0 :                         cfact = cfact + ((two * nqnu + one) / (eig0nk - eig0mkq + sigma%ieta)) * weight
    2033              :                      end if
    2034              :                    end do
    2035              :                  else
    2036              :                    ! No double-grid.
    2037      1618868 :                    if (dtset%eph_ahc_type == 1) then
    2038              :                       cfact =  (nqnu + f_mkq      ) / (eig0nk - eig0mkq + wqnu + sigma%ieta) + &
    2039      1491732 :                                (nqnu - f_mkq + one) / (eig0nk - eig0mkq - wqnu + sigma%ieta)
    2040              :                    else
    2041       127136 :                       cfact =  (two * nqnu + one) / (eig0nk - eig0mkq + sigma%ieta)
    2042              :                    end if
    2043              :                  endif
    2044              : 
    2045      1670612 :                  if (sigma%imag_only) then
    2046       117936 :                    simag = gkq2 * aimag(cfact)
    2047       117936 :                    sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + j_dpc * simag
    2048       117936 :                    if (sigma%mrta > 0) then
    2049       117936 :                      sigma%linewidth_mrta(it, ib_k) = sigma%linewidth_mrta(it, ib_k) + simag * alpha_mrta(ib_k)
    2050              :                    end if
    2051              : 
    2052       117936 :                    if (dtset%eph_prtscratew == 1) then
    2053            0 :                      sigma%scratew(:, it, ib_k, 1) = sigma%scratew(:, it, ib_k, 1) + simag * gaussw_qnu
    2054            0 :                      sigma%scratew(:, it, ib_k, 2) = sigma%scratew(:, it, ib_k, 2) + simag * gaussw_qnu * alpha_mrta(ib_k)
    2055              :                    end if
    2056              : 
    2057              :                  else
    2058              :                    ! Re + Im self-energy
    2059      1552676 :                    sig_cplx = gkq2 * cfact
    2060      1552676 :                    if (intra_band .and. sigma%frohl_model == 1) then
    2061              :                      ! Treat Frohlich divergence with spherical integration around the Gamma point.
    2062              :                      ! In principle one should rescale by the number of degenerate states but it's
    2063              :                      ! easier to move all the weight to a single band.
    2064            0 :                      sig_cplx = czero; if (same_band) sig_cplx = zpr_frohl_sphcorr(nu) * (two * f_mkq - one)
    2065              :                    end if
    2066              : 
    2067      1552676 :                    sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + sig_cplx
    2068      1552676 :                    sigma%fan_vals(it, ib_k) = sigma%fan_vals(it, ib_k) + sig_cplx
    2069              :                    !
    2070              :                    ! SP - Dec 2025
    2071              :                    ! Alternative way to compute E4 with sum-over-state.
    2072              :                    ! Note that the temperature factor (two * nqnu + one) is the logical extension but only the 0 K expression has
    2073              :                    ! been derived explicitely in https://arxiv.org/abs/2512.04897
    2074              :                    ! No eta is needed since we compute it for n=occ and m=unocc (on active space)
    2075      1552676 :                    if (f_nk > 1E-6 .and. f_mkq < 1E-6) then
    2076              :                      sigma%E4_vals2(it, ib_k) = sigma%E4_vals2(it, ib_k) + &
    2077       718668 :                                  0.5d0 * gkq2 * (two * nqnu + one) * two * wqnu / (eig0mkq - eig0nk)**2
    2078              :                    end if
    2079              :                  end if
    2080              :                  !
    2081              :                else
    2082              : 
    2083              :                  ! ===================
    2084              :                  ! Tetrahedron method
    2085              :                  ! ===================
    2086       698324 :                  if (sigma%use_doublegrid) then
    2087              :                    ! Tetra + double grid
    2088              : 
    2089       704088 :                    do jj=1,sigma%eph_doublegrid%ndiv
    2090              :                      ! Double Grid shared points weights
    2091       678942 :                      ikq_bz_fine  = sigma%eph_doublegrid%mapping(2, jj)
    2092       678942 :                      weight = sigma%eph_doublegrid%weights_dense(ikq_bz_fine)
    2093              : 
    2094              :                      ! Electronic eigenvalue
    2095       678942 :                      ikq_ibz_fine = sigma%eph_doublegrid%mapping(5, jj)
    2096       678942 :                      eig0mkq = sigma%eph_doublegrid%ebands_dense%eig(ibsum_kq, ikq_ibz_fine, spin)
    2097       678942 :                      f_mkq = occ_fd(eig0mkq, sigma%kTmesh(it), sigma%mu_e(it))
    2098              : 
    2099              :                      ! Phonon frequency
    2100       678942 :                      iq_ibz_fine = sigma%eph_doublegrid%mapping(6, jj)
    2101       678942 :                      wqnu = sigma%ephwg%phfrq_ibz(iq_ibz_fine,nu)
    2102       678942 :                      nqnu = occ_be(wqnu, sigma%kTmesh(it), zero)
    2103              : 
    2104              :                      ! Add Frohlich contribution
    2105       678942 :                      gkq2_pf = gkq2
    2106       678942 :                      if (osc_ecut /= zero) gkq2_pf = gkq2_pf + weight_q * gkq2_lr(jj,ib_k,imyp)
    2107              : 
    2108       704088 :                      if (sigma%imag_only) then
    2109              :                        ! Note pi factor from Sokhotski-Plemelj theorem.
    2110              :                        simag = gkq2_pf * pi * ( &
    2111              :                          (nqnu + f_mkq      ) * sigma%deltaw_pm(1, ib_k, imyp, ibsum_kq, imyq, jj) +  &
    2112       678942 :                          (nqnu - f_mkq + one) * sigma%deltaw_pm(2, ib_k, imyp, ibsum_kq, imyq, jj) ) * weight
    2113       678942 :                        sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + j_dpc * simag
    2114       678942 :                        if (sigma%mrta > 0) then
    2115       678942 :                          sigma%linewidth_mrta(it, ib_k) = sigma%linewidth_mrta(it, ib_k) + simag * alpha_mrta(ib_k)
    2116              :                        end if
    2117              : 
    2118       678942 :                        if (dtset%eph_prtscratew == 1) then
    2119            0 :                          sigma%scratew(:, it, ib_k, 1) = sigma%scratew(:, it, ib_k, 1) + simag * gaussw_qnu
    2120            0 :                          sigma%scratew(:, it, ib_k, 2) = sigma%scratew(:, it, ib_k, 2) + simag * gaussw_qnu * alpha_mrta(ib_k)
    2121              :                        end if
    2122              : 
    2123              :                      else
    2124              :                        ! Re + Sigma with tetra and double grid
    2125              :                        sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + gkq2_pf * ( &
    2126              :                          (nqnu + f_mkq      ) * sigma%cweights(1, 1, ib_k, imyp, ibsum_kq, imyq, jj) +  &
    2127            0 :                          (nqnu - f_mkq + one) * sigma%cweights(1, 2, ib_k, imyp, ibsum_kq, imyq, jj) ) * weight
    2128              :                      end if
    2129              :                    end do
    2130              : 
    2131              :                  else
    2132              : 
    2133              :                    ! Tetrahedron method WITHOUT double grid.
    2134       673178 :                    if (sigma%imag_only) then
    2135              :                      ! Imag part
    2136              :                      simag = gkq2 * pi * ( &
    2137              :                        (nqnu + f_mkq      ) * sigma%deltaw_pm(1, ib_k, imyp, ibsum_kq, imyq, 1) +  &
    2138       131738 :                        (nqnu - f_mkq + one) * sigma%deltaw_pm(2, ib_k, imyp, ibsum_kq, imyq, 1) )
    2139              : 
    2140       131738 :                      if (intra_band .and. sigma%frohl_model == 1) then
    2141              :                        ! Treat Frohlich divergence with spherical integration of deltas around the Gamma point.
    2142              :                        ! In principle one should rescale by the number of degenerate states but it's
    2143              :                        ! easier to move all the weight to a single band
    2144              :                        ! TODO: Check the sign, use convention for retarded function
    2145            0 :                        simag = zero
    2146            0 :                        if (same_band) simag = -pi * sum(sigma%frohl_deltas_sphcorr(1:2, it, ib_k, nu), dim=1)
    2147              :                      end if
    2148              : 
    2149       131738 :                      sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + j_dpc * simag
    2150       131738 :                      if (sigma%mrta > 0) then
    2151       131738 :                        sigma%linewidth_mrta(it, ib_k) = sigma%linewidth_mrta(it, ib_k) + simag * alpha_mrta(ib_k)
    2152              :                      end if
    2153              : 
    2154       131738 :                      if (dtset%eph_prtscratew == 1) then
    2155     23173524 :                        sigma%scratew(:, it, ib_k, 1) = sigma%scratew(:, it, ib_k, 1) + simag * gaussw_qnu
    2156     23173524 :                        sigma%scratew(:, it, ib_k, 2) = sigma%scratew(:, it, ib_k, 2) + simag * gaussw_qnu * alpha_mrta(ib_k)
    2157              :                      end if
    2158              : 
    2159       131738 :                      if (dtset%ibte_prep > 0) then
    2160              :                        ! Save scattering rates.
    2161              :                        sigma%srate(ibsum_kq, ib_k, it, imyq) = sigma%srate(ibsum_kq, ib_k, it, imyq) + &
    2162              :                          gkq2 * two_pi * ( &
    2163              :                          (nqnu - f_nk  + one) * sigma%deltaw_pm(1, ib_k, imyp, ibsum_kq, imyq, 1) +  &
    2164         2540 :                          (nqnu + f_nk       ) * sigma%deltaw_pm(2, ib_k, imyp, ibsum_kq, imyq, 1) )
    2165              :                      end if
    2166              : 
    2167              :                    else
    2168              :                      ! Re + Sigma with tetra and WITHOUT double grid
    2169              :                      sig_cplx = gkq2 * ( &
    2170              :                        (nqnu + f_mkq      ) * sigma%cweights(1, 1, ib_k, imyp, ibsum_kq, imyq, 1) +  &
    2171       541440 :                        (nqnu - f_mkq + one) * sigma%cweights(1, 2, ib_k, imyp, ibsum_kq, imyq, 1) )
    2172              : 
    2173       541440 :                      if (intra_band .and. sigma%frohl_model == 1) then
    2174              :                        ! Treat Frohlich divergence with spherical integration around the Gamma point.
    2175              :                        ! In principle one should rescale by the number of degenerate states but it's
    2176              :                        ! easier to move all the weight to a single band
    2177            0 :                        sig_cplx = czero; if (same_band) sig_cplx = zpr_frohl_sphcorr(nu) * (two * f_mkq - one)
    2178              :                      end if
    2179              : 
    2180       541440 :                      sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + sig_cplx
    2181              :                    endif
    2182              :                  end if
    2183              :                end if
    2184              : 
    2185              :                ! Derivative of sigma
    2186              :                ! TODO: should calculate this with the double grid as well
    2187      2966464 :                if (.not. sigma%imag_only) then
    2188              :                  ! Accumulate d(Re Sigma) / dw(w=eKS) for state ib_k
    2189              :                  !cfact(x) =  (nqnu + f_mkq      ) / (x - eig0mkq + wqnu + sigma%ieta) + &
    2190              :                  !            (nqnu - f_mkq + one) / (x - eig0mkq - wqnu + sigma%ieta)
    2191      2094116 :                  gmod2 = (eig0nk - eig0mkq + wqnu) ** 2
    2192      2094116 :                  hmod2 = (eig0nk - eig0mkq - wqnu) ** 2
    2193              :                  rfact = (nqnu + f_mkq      ) * (-gmod2 + aimag(sigma%ieta)**2) / (gmod2 + aimag(sigma%ieta)**2) ** 2 + &
    2194      2094116 :                          (nqnu - f_mkq + one) * (-hmod2 + aimag(sigma%ieta)**2) / (hmod2 + aimag(sigma%ieta)**2) ** 2
    2195      2094116 :                  sigma%dvals_de0ks(it, ib_k) = sigma%dvals_de0ks(it, ib_k) + gkq2 * rfact
    2196              :                  !cfact =  (nqnu + f_mkq      ) / (eig0nk - eig0mkq + wqnu + sigma%ieta) + &
    2197              :                  !         (nqnu - f_mkq + one) / (eig0nk - eig0mkq - wqnu + sigma%ieta)
    2198              :                  !sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + gkq2 * cfact
    2199              : 
    2200              :                  !cfact = (eig0nk - eig0mkq + wqnu + sigma%ieta)
    2201              :                  !gmod2 = cfact * dconjg(cfact)
    2202              :                  !cfact = (eig0nk - eig0mkq - wqnu + sigma%ieta)
    2203              :                  !hmod2 = cfact * dconjg(cfact)
    2204              :                  !sigma%dvals_de0ks(it, ib_k) = sigma%dvals_de0ks(it, ib_k) + gkq2 * ( &
    2205              :                  !  (nqnu + f_mkq)        * (gmod2 - two * (eig0nk - eig0mkq + wqnu) ** 2) / gmod2 ** 2 + &
    2206              :                  !  (nqnu - f_mkq + one)  * (hmod2 - two * (eig0nk - eig0mkq - wqnu) ** 2) / hmod2 ** 2   &
    2207              :                  !)
    2208              : 
    2209              :                  ! Accumulate Sigma(w) for state ib_k if spectral function is wanted.
    2210      2094116 :                  if (sigma%nwr > 0) then
    2211      1377252 :                    if (sigma%qint_method == 1) then
    2212              :                      ! Tetra
    2213              :                      cfact_wr(:) = (nqnu + f_mkq      ) * sigma%cweights(2:, 1, ib_k, imyp, ibsum_kq, imyq, 1) + &
    2214     23500800 :                                    (nqnu - f_mkq + one) * sigma%cweights(2:, 2, ib_k, imyp, ibsum_kq, imyq, 1)
    2215              :                    else
    2216              :                      ! Zcut
    2217              :                      cfact_wr(:) = (nqnu + f_mkq      ) / (sigma%wrmesh_b(:,ib_k) - eig0mkq + wqnu + sigma%ieta) + &
    2218    148104864 :                                    (nqnu - f_mkq + one) / (sigma%wrmesh_b(:,ib_k) - eig0mkq - wqnu + sigma%ieta)
    2219              :                    end if
    2220    171605664 :                    cfact_wr(:) = gkq2 * cfact_wr(:)
    2221              : 
    2222      1377252 :                    if (intra_band .and. sigma%frohl_model == 1)  then
    2223              :                      ! Add Frohlich correction to Sigma_nk(w)
    2224            0 :                      cfact_wr(:) = zero; if (same_band) cfact_wr(:) = fmw_frohl_sphcorr(:,nu,it,ib_k)
    2225              :                    end if
    2226              : 
    2227    171605664 :                    sigma%vals_wr(:,it,ib_k) = sigma%vals_wr(:,it,ib_k) + cfact_wr(:)
    2228              :                  end if ! nwr > 0
    2229              :                end if
    2230              : 
    2231              :              end do ! it
    2232              :            end do ! ib_k
    2233              :          end do ! imyp
    2234        28522 :          call timab(1907, 2, tsec)
    2235              : 
    2236              :        end do ! ibsum_kq (sum over bands at k+q)
    2237         3852 :        call timab(1903, 2, tsec)
    2238              : 
    2239         3852 :        ABI_FREE(bra_kq)
    2240         3852 :        ABI_FREE(cgwork)
    2241         3852 :        ABI_FREE(h1kets_kq)
    2242         3852 :        ABI_FREE(kpg_kq)
    2243         3852 :        ABI_FREE(ffnl_kq)
    2244         3852 :        ABI_FREE(kinpw_kq)
    2245         3852 :        ABI_FREE(ph3d_kq)
    2246              : 
    2247         3852 :        if (osc_ecut /= zero) then
    2248            0 :          ABI_FREE(osc_gvecq)
    2249            0 :          ABI_FREE(osc_indpw)
    2250            0 :          ABI_FREE(osc_ks)
    2251            0 :          ABI_FREE(workq_ug)
    2252              :        end if
    2253              : 
    2254        18506 :        if (imyq <= 10 .or. mod(imyq, 100) == 0) then
    2255         1269 :          write(msg,'(4(a,i0),a)') " k-point [",my_ikcalc,"/",sigma%my_nkcalc, "] q-point [",imyq,"/",sigma%my_nqibz_k,"]"
    2256         1269 :          call cwtime_report(msg, cpu, wall, gflops)
    2257              :        end if
    2258              :      end do ! imyq (sum over q-points in IBZ_k)
    2259              : 
    2260          182 :      call cwtime_report(" Fan-Migdal q-loop", cpu_qloop, wall_qloop, gflops_qloop)
    2261              : 
    2262          182 :      ABI_FREE(sigma%e0vals)
    2263          182 :      ABI_FREE(kets_k)
    2264          182 :      ABI_FREE(gkq_atm)
    2265          182 :      ABI_FREE(gkq_nu)
    2266          182 :      ABI_FREE(gkq_allgather)
    2267          182 :      ABI_SFREE(fmw_frohl_sphcorr)
    2268              : 
    2269          182 :      if (osc_ecut /= zero) then
    2270            0 :        ABI_FREE(ur_k)
    2271            0 :        ABI_FREE(ur_kq)
    2272            0 :        ABI_FREE(work_ur)
    2273            0 :        ABI_FREE(gkq2_lr)
    2274              :      end if
    2275              : 
    2276              :      ! =========================
    2277              :      ! Compute Debye-Waller term
    2278              :      ! =========================
    2279          182 :      if (.not. sigma%imag_only) then
    2280           70 :        call cwtime(cpu_dw, wall_dw, gflops_dw, "start", msg=" Computing Debye-Waller within the rigid ion approximation...")
    2281              :        ! Collect gkq0_atm inside qpt_comm
    2282              :        ! FIXME: In principle it's sufficient to broadcast from itreated_q0 inside qpt_comm
    2283              :        ! Yet, q-points are not equally distributed so this synch is detrimental.
    2284              : 
    2285           70 :        call cwtime(cpu, wall, gflops, "start")
    2286           70 :        call xmpi_sum(gkq0_atm, sigma%qpt_comm%value, ierr)
    2287           70 :        if (dtset%eph_stern /= 0) call xmpi_sum(stern_dw, sigma%qpt_comm%value, ierr)
    2288           70 :        call cwtime_report(" DW MPI synch before q-loop", cpu, wall, gflops)
    2289              : 
    2290              :        ! Integral over IBZ(k) distributed inside qpt_comm
    2291           70 :        nq = sigma%nqibz; if (sigma%symsigma == 0) nq = sigma%nqbz
    2292           70 :        if (abs(sigma%symsigma) == +1) nq = sigma%nqibz_k
    2293           70 :        call xmpi_split_work(nq, sigma%qpt_comm%value, q_start, q_stop)
    2294              : 
    2295         1086 :        do iq_ibz_k=q_start,q_stop
    2296         1016 :          call cwtime(cpu, wall, gflops, "start")
    2297              : 
    2298         1016 :          if (abs(sigma%symsigma) == 1) then
    2299              :            ! Sum over IBZ_k
    2300         4000 :            qpt = sigma%qibz_k(:, iq_ibz_k); weight_q = sigma%wtq_k(iq_ibz_k)
    2301         1000 :            iq_ibz = sigma%ind_ibzk2ibz(1, iq_ibz_k)
    2302         1000 :            isym_q = sigma%ind_ibzk2ibz(2, iq_ibz_k)
    2303         1000 :            trev_q = sigma%ind_ibzk2ibz(6, iq_ibz_k)
    2304              :            ! Don't test if umklapp == 0 because we use the periodic gauge: phfreq(q+G) = phfreq(q) and eigvec(q) = eigvec(q+G)
    2305         1000 :            isirr_q = (isym_q == 1 .and. trev_q == 0)
    2306              : 
    2307              :            ! Sum over IBZ
    2308              :            ! TODO: This should be much faster but it should be tested.
    2309              :            !qpt = sigma%qibz(:,iq_ibz_k); weight_q = sigma%wtq(iq_ibz_k)
    2310              : 
    2311         1000 :            call phstore%async_rotate(cryst, ifc, iq_ibz, sigma%qibz(:, iq_ibz), qpt, isym_q, trev_q)
    2312         1000 :            call phstore%wait(cryst, phfrq, displ_cart,  displ_red)
    2313              : 
    2314              :            ! Get phonons for this q-point.
    2315              :            !call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red, comm=sigma%pert_comm%value)
    2316              : 
    2317              :          else
    2318              :            ! Sum over full BZ
    2319           64 :            qpt = sigma%qbz(:, iq_ibz_k); weight_q = one / sigma%nqbz
    2320              : 
    2321              :            ! Get phonons for this q-point.
    2322           16 :            call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red, comm=sigma%pert_comm%value)
    2323              :          end if
    2324              : 
    2325              :          ! Sum over my phonon modes for this q-point.
    2326         7112 :          do imyp=1,my_npert
    2327         6096 :            nu = sigma%my_pinfo(3, imyp)
    2328              :            ! Ignore acoustic or unstable modes.
    2329         6096 :            wqnu = phfrq(nu); if (ephtk_skip_phmode(nu, wqnu, sigma%phmodes_skip, dtset%eph_phrange_w)) cycle
    2330              : 
    2331              :            ! Get phonon occupation for all temperatures.
    2332        27462 :            nqnu_tlist = occ_be(wqnu, sigma%kTmesh(:), zero)
    2333              : 
    2334              :            ! Compute T_pp'(q,nu) matrix in reduced coordinates.
    2335         5732 :            call sigtk_dw_tpp_red(natom, displ_red(:,:,:,nu), tpp_red)
    2336              : 
    2337              :            ! Sum over my bands and add (static) DW contribution for the different temperatures.
    2338       116388 :            do ibsum=sigma%my_bsum_start, sigma%my_bsum_stop
    2339       109640 :              eig0mk = ebands%eig(ibsum, ik_ibz, spin)
    2340              : 
    2341              :              ! For each n in Sigma_nk
    2342       606258 :              do ib_k=1,nbcalc_ks
    2343       490886 :                band_ks = ib_k + bstart_ks - 1
    2344       490886 :                eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    2345              :                !
    2346              :                ! Compute DW term following XG paper. Check prefactor.
    2347              :                ! gkq0_atm(2, nbcalc_ks, bsum_start:bsum_stop, natom3)
    2348       490886 :                gdw2 = zero
    2349      3436202 :                do ip2=1,natom3
    2350     21108098 :                  do ip1=1,natom3
    2351              :                    cfact = ( &
    2352              :                      + gkq0_atm(1, ib_k, ibsum, ip1) * gkq0_atm(1, ib_k, ibsum, ip2) &
    2353              :                      + gkq0_atm(2, ib_k, ibsum, ip1) * gkq0_atm(2, ib_k, ibsum, ip2) &
    2354              :                      + gkq0_atm(1, ib_k, ibsum, ip2) * gkq0_atm(1, ib_k, ibsum, ip1) &
    2355              :                      + gkq0_atm(2, ib_k, ibsum, ip2) * gkq0_atm(2, ib_k, ibsum, ip1) &
    2356     17671896 :                    )
    2357              :                    !
    2358     20617212 :                    gdw2 = gdw2 + real(tpp_red(ip1,ip2) * cfact)
    2359              :                  end do
    2360              :                end do
    2361       490886 :                gdw2 = gdw2 / (four * two * wqnu)
    2362              :                !
    2363       490886 :                if (dtset%eph_stern /= 0 .and. ibsum == bsum_stop) then
    2364              :                  ! Compute DW term for m > nband
    2365              :                  cfact = zero
    2366        91847 :                  do ip2=1,natom3
    2367       564203 :                    do ip1=1,natom3
    2368       551082 :                      cfact = cfact + tpp_red(ip1, ip2) * cmplx(stern_dw(1,ip1,ip2,ib_k), stern_dw(2,ip1,ip2,ib_k), kind=dp)
    2369              :                    end do
    2370              :                  end do
    2371              :                  ! There's no 1/two here because I don't symmetrize the expression.
    2372              :                  ! TODO: Test symmetrization, real quantity? add support for the different Eliashberg functions with Stern
    2373        13121 :                  gdw2_stern = real(cfact) / (four * wqnu)
    2374              :                end if
    2375              :                !
    2376              :                ! Handle n == m and degenerate states.
    2377       490886 :                ediff = eig0nk - eig0mk ! SP: one cannot cycle here because the Sternheimer contribution needs to be computed
    2378              :                !
    2379              :                ! Optionally, accumulate DW contribution to Eliashberg functions.
    2380       490886 :                if (dtset%prteliash /= 0) then
    2381       306222 :                  if (abs(ediff) > EPHTK_WTOL) then
    2382       284361 :                    sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 3) = sigma%gf_nnuq(ib_k, nu, iq_ibz_k, 3) - gdw2 / ediff
    2383              :                  end if
    2384              :                end if
    2385              :                !
    2386              :                ! Accumulate DW for each T, add it to Sigma(e0) and Sigma(w) as well
    2387              :                ! - (2 n_{q\nu} + 1) * gdw2 / (e_nk - e_mk)
    2388      2694642 :                do it = 1, sigma%ntemp
    2389      2094116 :                  if (abs(ediff) > EPHTK_WTOL) then
    2390      1929272 :                    cfact = - weight_q * gdw2 * (two * nqnu_tlist(it) + one)  / (ediff + sigma%ieta)
    2391              :                  else
    2392              :                    cfact = zero
    2393              :                  endif
    2394      2094116 :                  if (dtset%eph_stern /= 0 .and. ibsum == bsum_stop) then
    2395              :                    ! Add contribution due to the Sternheimer. ediff is absorbed in Sternheimer.
    2396        44969 :                    cfact = cfact - weight_q * gdw2_stern * (two * nqnu_tlist(it) + one)
    2397        44969 :                    cfact2 = - weight_q * gdw2_stern * (two * nqnu_tlist(it) + one)
    2398        44969 :                    rfact = real(cfact2)
    2399        44969 :                    sigma%dw_stern_vals(it, ib_k) = sigma%dw_stern_vals(it, ib_k) + rfact
    2400              :                  end if
    2401      2094116 :                  rfact = real(cfact)
    2402      2094116 :                  sigma%dw_vals(it, ib_k) = sigma%dw_vals(it, ib_k) + rfact
    2403      2094116 :                  sigma%vals_e0ks(it, ib_k) = sigma%vals_e0ks(it, ib_k) + rfact
    2404    172813414 :                  if (sigma%nwr > 0) sigma%vals_wr(:, it, ib_k) = sigma%vals_wr(:, it, ib_k) + rfact
    2405              :                end do
    2406              : 
    2407              :              end do ! ib_k
    2408              :            end do ! ibsum
    2409              : 
    2410              :          end do ! nu
    2411              : 
    2412              :          !if (nq < 1000 .or. (nq > 1000 .and. mod(iq_ibz_k, 200) == 0) .or. iq_ibz_k <= nprocs) then
    2413         1016 :          ii = iq_ibz_k - q_start
    2414         2102 :          if (ii <= 5 .or. mod(ii, 100) == 0) then
    2415          393 :            write(msg,'(4(a,i0),a,f8.2)') " k-point [",my_ikcalc,"/",sigma%my_nkcalc, "] q-point [",iq_ibz_k,"/",nq,"]"
    2416          393 :            call cwtime_report(msg, cpu, wall, gflops)
    2417              :          end if
    2418              :        end do ! iq_ibz_k
    2419              : 
    2420           70 :        ABI_FREE(gkq0_atm)
    2421           70 :        ABI_SFREE(stern_dw)
    2422           70 :        call cwtime_report(" Debye-Waller", cpu_dw, wall_dw, gflops_dw, end_str=ch10)
    2423              :      end if ! not %imag_only
    2424              : 
    2425          182 :      if (dtset%prteliash /= 0) then
    2426              :        ! Compute Eliashberg function.
    2427              :        call cwtime(cpu, wall, gflops, "start", msg=sjoin(" Computing Eliashberg function with nomega: ", &
    2428           58 :            itoa(sigma%phmesh_size)))
    2429              : 
    2430           58 :        if (dtset%prteliash == 3) call xmpi_sum(sigma%a2few, sigma%pqb_comm%value, ierr)
    2431              : 
    2432              :        ! Collect all terms on each node so that we can MPI-parallelize easily inside pqb_comm
    2433              :        ! Note that: gf_nnuq does not include the q-weights from the integration.
    2434           58 :        call xmpi_sum(sigma%gf_nnuq, sigma%pqb_comm%value, ierr)
    2435      1204710 :        sigma%gfw_vals = zero
    2436              : 
    2437           58 :        if (sigma%qint_method == 0 .or. sigma%symsigma == 0) then
    2438              :          ! Compute Eliashberg function with gaussian method and ph_smear smearing.
    2439          498 :          do iq_ibz_k=1,sigma%nqibz_k
    2440          459 :            if (sigma%pqb_comm%skip(iq_ibz_k)) cycle ! MPI parallelism inside pqb_comm
    2441              : 
    2442              :            ! Recompute phonons (cannot use sigma%ephwg in this case)
    2443          459 :            call ifc%fourq(cryst, sigma%qibz_k(:,iq_ibz_k), phfrq, displ_cart)
    2444         3252 :            do nu=1,natom3
    2445      2680950 :              dwargs = sigma%phmesh - phfrq(nu)
    2446      2678196 :              dtw_weights(:, 1) = gaussian(dwargs, dtset%ph_smear)
    2447        14451 :              do ib_k=1,nbcalc_ks
    2448        47706 :                do ii=1,3
    2449              :                  sigma%gfw_vals(:, ii, ib_k) = sigma%gfw_vals(:, ii, ib_k) +  &
    2450     37416102 :                    sigma%gf_nnuq(ib_k, nu, iq_ibz_k, ii) * dtw_weights(:, 1) * sigma%wtq_k(iq_ibz_k)
    2451              :                end do
    2452              :              end do
    2453              :            end do
    2454              :          end do
    2455              : 
    2456              :        else
    2457              :          ! Compute Eliashberg function with tetrahedron method.
    2458           57 :          eminmax = [sigma%phmesh(1), sigma%phmesh(sigma%phmesh_size)]
    2459           95 :          ABI_MALLOC(dt_tetra_weights, (sigma%phmesh_size, sigma%nqibz_k, 2))
    2460          133 :          do nu=1,natom3
    2461              :            ! All procs compute weights.
    2462              :            call sigma%ephwg%get_deltas_qibzk(nu, sigma%phmesh_size, eminmax, sigma%bcorr, dt_tetra_weights, &
    2463          114 :                                              sigma%pqb_comm%value, with_qweights=.True.)
    2464              : 
    2465         5893 :            do iq_ibz_k=1,sigma%nqibz_k
    2466         5760 :              if (sigma%pqb_comm%skip(iq_ibz_k)) cycle ! MPI parallelism inside pqb_comm
    2467        18792 :              do ib_k=1,nbcalc_ks
    2468        57432 :                do ii=1,3
    2469              :                  sigma%gfw_vals(:, ii, ib_k) = sigma%gfw_vals(:, ii, ib_k) +  &
    2470     40881162 :                    sigma%gf_nnuq(ib_k, nu, iq_ibz_k, ii) * dt_tetra_weights(:, iq_ibz_k, 1)
    2471              :                end do
    2472              :              end do
    2473              :            end do
    2474              :          end do
    2475           19 :          ABI_FREE(dt_tetra_weights)
    2476              :        end if
    2477              : 
    2478              :        ! Collect final results.
    2479           58 :        call xmpi_sum(sigma%gfw_vals, sigma%pqb_comm%value, ierr)
    2480           58 :        call cwtime_report(" Eliashberg function", cpu, wall, gflops)
    2481              :      end if
    2482              : 
    2483              :      !ivals2 = [ignore_ks, ignore_ibsum_kq]
    2484              :      !call xmpi_sum_master(ivals, master, sigma%pqb_comm%value)
    2485          182 :      if (my_rank == master) then
    2486          182 :        if (ignore_kq /= 0) write(std_out, "(a, 1x, i0)")" Number of ignored k+q points:", ignore_kq
    2487          182 :        if (ignore_ibsum_kq /= 0) write(std_out, "(a, 1x, i0)")" Number of ignored (k+q, m) states:", ignore_ibsum_kq
    2488              :      end if
    2489              : 
    2490              :      ! Reduce E2 over perturbations and q-points only (E2 does not depend on bands)
    2491          182 :      call xmpi_sum(sigma%E2, sigma%pert_comm%value, ierr)
    2492          182 :      call xmpi_sum(sigma%E2, sigma%qpt_comm%value, ierr)
    2493              :      ! Collect results inside pqb_comm and write results for this (k-point, spin) to NETCDF file.
    2494          182 :      call sigma%gather_and_write(dtset, ebands, ikcalc, spin, sigma%pqb_comm%value)
    2495              : 
    2496          182 :      ABI_SFREE(alpha_mrta)
    2497          910 :      ABI_SFREE(root_bcalc)
    2498              :    end do ! spin
    2499              : 
    2500              :    ! Gather total energies
    2501          182 :    ikcalc = sigma%my_ikcalc(my_ikcalc)
    2502          182 :    ik_ibz = sigma%kcalc2ibz(ikcalc, 1)
    2503          364 :    do spin=1,sigma%nsppol
    2504         1148 :      do ib_k=1,nbcalc_ks
    2505         3414 :        do it = 1, sigma%ntemp
    2506         3232 :          E4(it) = E4(it) + sigma%E4_vals(it, ib_k) * ebands%wtk(ik_ibz)
    2507              :        end do
    2508              :      end do
    2509              :    end do
    2510              : 
    2511          182 :    ABI_FREE(kg_k)
    2512          182 :    ABI_FREE(kg_kq)
    2513          182 :    ABI_SFREE(kpg_kq)
    2514          182 :    ABI_FREE(kpg_k)
    2515          182 :    ABI_FREE(ffnl_k)
    2516          182 :    ABI_FREE(kinpw_k)
    2517          182 :    ABI_FREE(ph3d_k)
    2518              : 
    2519          182 :    call cwtime_report(" One ikcalc k-point", cpu_ks, wall_ks, gflops_ks)
    2520          604 :    call pstat_proc%print(_PSTAT_ARGS_)
    2521              :  end do ! my_ikcalc
    2522              : 
    2523              :  ! --------------------
    2524              :  ! Print total energies
    2525              :  ! SP - 01/26 - Note that this way of computing total energies requires computing E4 on a k-point grid that is
    2526              :  !              the same as the interpolated q-point grid. This might not always be the best.
    2527              :  !              In that case, it is recommended to read E4 from the _SIGEPH.nc file and perform the k-integral
    2528              :  !              with a post-processing script.
    2529              :  ! --------------------
    2530           58 :  call xmpi_sum_master(E4, master, comm, ierr)
    2531           58 :  if (my_rank == master .and. dtset%eph_task == 4 .and. dtset%eph_stern /= 0 .and. .not. sigma%imag_only ) then
    2532              :    ! Spin factor
    2533           17 :    if (dtset%nsppol == 1 .and. dtset%nspinor == 1) then
    2534              :      sfact = two
    2535              :    else
    2536            0 :      sfact = one
    2537              :    endif
    2538              :    !
    2539           17 :    write(ab_out,"(a)")" "
    2540           17 :    write(ab_out,"(a)")" ========================================================= "
    2541           17 :    write(ab_out,"(a)")" Contributions to total energies (in meV)                  "
    2542           17 :    write(ab_out,"(a)")"   See Table II of S. Ponce and X. Gonze, arXiv:2512.04897 "
    2543           17 :    write(ab_out,"(a)")"   for additional information.                             "
    2544           17 :    write(ab_out,"(a)")" ========================================================= "
    2545           17 :    write(ab_out,"(a)")" "
    2546           78 :    do it = 1, sigma%ntemp
    2547           61 :      write(ab_out, "(2(a,f12.6),a)")" Temperature =  ", sigma%kTmesh(it) / kb_HaK, " K"
    2548           61 :      write(ab_out, "(2(a,f20.6),a)")" E^(BO)   = ",   etot * Ha_eV * 1000
    2549           61 :      write(ab_out, "(2(a,f20.6),a)")" E^(ph)   = ",   sigma%E2(it) * Ha_eV * 1000
    2550              :      ! We need the spin factor.
    2551           78 :      write(ab_out, "(2(a,f20.6),a)")" E^(elph) = ", sfact * E4(it) * Ha_eV * 1000
    2552              :    end do
    2553              :  end if
    2554              : 
    2555           58 :  call cwtime_report(" Sigma_eph full calculation", cpu_all, wall_all, gflops_all, end_str=ch10)
    2556              : 
    2557              :  ! Free memory
    2558           58 :  ABI_FREE(E4)
    2559           58 :  ABI_FREE(ihave_ikibz_spin)
    2560           58 :  ABI_FREE(grad_berry)
    2561           58 :  ABI_FREE(vtrial)
    2562           58 :  ABI_FREE(work)
    2563           58 :  ABI_FREE(ph1d)
    2564           58 :  ABI_FREE(vlocal)
    2565           58 :  ABI_FREE(nqnu_tlist)
    2566           58 :  ABI_FREE(displ_cart)
    2567           58 :  ABI_FREE(displ_red)
    2568           58 :  ABI_FREE(tpp_red)
    2569           58 :  ABI_SFREE(cfact_wr)
    2570           58 :  ABI_SFREE(dwargs)
    2571           58 :  ABI_SFREE(dtw_weights)
    2572           58 :  ABI_SFREE(delta_e_minus_emkq)
    2573           58 :  ABI_FREE(gbound_kq)
    2574           58 :  ABI_FREE(osc_gbound_q)
    2575           58 :  ABI_FREE(ibzspin_2ikcalc)
    2576           58 :  ABI_FREE(gaussw_qnu)
    2577           58 :  ABI_SFREE(vcar_ibz)
    2578              : 
    2579           58 :  call gs_ham_kq%free(); call wfd%free(); call phstore%free(); call u1c%free(); call sigma%free()
    2580           58 :  call pawcprj_free(cwaveprj0)
    2581           58 :  ABI_FREE(cwaveprj0)
    2582           58 :  call pawcprj_free(cwaveprj)
    2583           58 :  ABI_FREE(cwaveprj)
    2584              : 
    2585              :  ! This to make sure that the parallel output of SIGEPH is completed
    2586           58 :  call xmpi_barrier(comm)
    2587           58 :  call cwtime_report(" sigmaph: MPI barrier before returning.", cpu_all, wall_all, gflops_all, end_str=ch10, comm=comm)
    2588              : 
    2589          870 : end subroutine sigmaph
    2590              : !!***
    2591              : 
    2592              : !----------------------------------------------------------------------
    2593              : 
    2594              : !!****f* m_sigmaph/sigmaph_new
    2595              : !! NAME
    2596              : !!  sigmaph_new
    2597              : !!
    2598              : !! FUNCTION
    2599              : !!  Creation method (allocates memory, initialize data from input vars).
    2600              : !!
    2601              : !! INPUTS
    2602              : !!  dtset<dataset_type>=All input variables for this dataset.
    2603              : !!  ecut=Cutoff energy for wavefunctions.
    2604              : !!  cryst<crystal_t>=Crystalline structure
    2605              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    2606              : !!  ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
    2607              : !!  dtfil<datafiles_type>=variables related to files.
    2608              : !!  comm=MPI communicator
    2609              : !!
    2610              : !! SOURCE
    2611              : 
    2612           58 : type(sigmaph_t) function sigmaph_new(dtset, ecut, cryst, ebands, ifc, dtfil, comm) result(new)
    2613              : 
    2614              : !Arguments ------------------------------------
    2615              :  integer,intent(in) :: comm
    2616              :  real(dp),intent(in) :: ecut
    2617              :  type(crystal_t),intent(in) :: cryst
    2618              :  type(dataset_type),intent(in) :: dtset
    2619              :  type(ebands_t),intent(in) :: ebands
    2620              :  type(ifc_type),intent(in) :: ifc
    2621              :  type(datafiles_type),intent(in) :: dtfil
    2622              : 
    2623              : !Local variables ------------------------------
    2624              : !scalars
    2625              :  integer,parameter :: master = 0, istwfk_1 = 1
    2626              :  integer :: my_rank,my_nshiftq,cnt,nprocs,ik_ibz,ndeg, iq_ibz, qptopt, qtimrev
    2627              :  integer :: ii, ierr, spin, gap_err, ikcalc, qprange_, bstop !it,
    2628              :  integer :: jj, bstart, natom, natom3 !, ip, iatom, idir, pertcase,
    2629              :  integer :: isym_k, trev_k, mband, nrest, color, kptopt
    2630              :  logical :: downsample
    2631              :  character(len=fnlen) :: wfk_fname_dense
    2632              :  character(len=5000) :: msg
    2633              :  real(dp) :: estep, cpu_all, wall_all, gflops_all, cpu, wall, gflops
    2634              :  logical :: changed, isirr_k
    2635           58 :  type(ebands_t) :: tmp_ebands, ebands_dense
    2636           58 :  type(gaps_t) :: gaps
    2637           58 :  type(krank_t) :: krank, qrank
    2638              : !arrays
    2639              :  integer :: intp_nshiftk
    2640              :  integer :: intp_kptrlatt(3,3), g0_k(3), units(2), indkk_k(6,1), band_block(2), qptrlatt(3,3)
    2641           58 :  integer,allocatable :: temp(:,:), degblock(:,:), degblock_all(:,:,:,:), ndeg_all(:,:), iperm(:)
    2642              :  real(dp):: params(4), my_shiftq(3,1), kk(3), intp_shiftk(3)
    2643              : #ifdef HAVE_MPI
    2644              :  integer,parameter :: ndims = 5
    2645              :  integer :: comm_cart, me_cart
    2646              :  logical :: reorder
    2647              :  integer :: dims(ndims)
    2648              :  logical :: periods(ndims), keepdim(ndims)
    2649              : #endif
    2650              : ! *************************************************************************
    2651              : 
    2652           58 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    2653              : 
    2654           58 :  call cwtime(cpu_all, wall_all, gflops_all, "start")
    2655           58 :  call cwtime(cpu, wall, gflops, "start")
    2656              : 
    2657          174 :  units = [std_out, ab_out]
    2658              : 
    2659              :  ! Copy important dimensions.
    2660           58 :  new%nsppol = ebands%nsppol; new%nspinor = ebands%nspinor; mband = dtset%mband
    2661           58 :  natom = cryst%natom; natom3 = cryst%natom * 3
    2662              : 
    2663              :  ! Re-Im or Im only?
    2664           58 :  new%imag_only = .False.
    2665           58 :  if (dtset%eph_task == -4) then
    2666           25 :    new%imag_only = .True.
    2667           25 :    new%mrta = 1 ! Compute lifetimes in the MRTA approximation? Default is yes
    2668              :    !if (dtset%userie == 1) new%mrta = 0
    2669              :  end if
    2670              : 
    2671              :  ! TODO: Remove qint_method, use eph_intmeth or perhaps dtset%qint_method dtset%kint_method
    2672              :  ! FIXME: Tetra gives positive SIGE2 while zcut gives negative (retarded)
    2673              :  ! Decide default behaviour for Re-Im/Im
    2674           58 :  new%qint_method = dtset%eph_intmeth - 1
    2675           58 :  new%phwinfact = dtset%eph_phwinfact
    2676              : 
    2677              :  ! Define option for integration of 1/z with tetrahedron method.
    2678           58 :  new%zinv_opt = 1; if (dtset%userie /= 0) new%zinv_opt = dtset%userie
    2679              : 
    2680              :  ! Broadening parameter from zcut
    2681           58 :  new%ieta = + j_dpc * dtset%zcut
    2682              : 
    2683              :  ! Define q-mesh for integration of the self-energy.
    2684              :  ! Either q-mesh from DVDB (no interpolation) or eph_ngqpt_fine (Fourier interpolation if q not in DDB)
    2685          406 :  new%ngqpt = dtset%ddb_ngqpt; my_nshiftq = 1; my_shiftq(:,1) = dtset%ddb_shiftq
    2686          154 :  if (all(dtset%eph_ngqpt_fine /= 0)) then
    2687          128 :    new%ngqpt = dtset%eph_ngqpt_fine; my_shiftq = 0
    2688              :  end if
    2689              : 
    2690              :  ! Setup IBZ, weights and BZ.
    2691              :  ! Assume qptopt == kptopt unless value is specified in input
    2692           58 :  qptrlatt = 0; qptrlatt(1, 1) = new%ngqpt(1); qptrlatt(2, 2) = new%ngqpt(2); qptrlatt(3, 3) = new%ngqpt(3)
    2693              :  !my_shiftq(:,1) = [0.1, 0, 0]
    2694           58 :  qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt
    2695              :  qtimrev = kpts_timrev_from_kptopt(qptopt)
    2696              :  call kpts_ibz_from_kptrlatt(cryst, qptrlatt, qptopt, my_nshiftq, my_shiftq, &
    2697           58 :                              new%nqibz, new%qibz, new%wtq, new%nqbz, new%qbz, bz2ibz=new%ind_qbz2ibz)
    2698              : 
    2699              :  ! HM: the bz2ibz produced above is incomplete, I do it here using listkk
    2700          174 :  ABI_MALLOC(temp, (6, new%nqbz))
    2701              : 
    2702           58 :  call qrank%from_kptrlatt(new%nqibz, new%qibz, qptrlatt, compute_invrank=.False.)
    2703           58 :  if (kpts_map("symrec", qptopt, cryst, qrank, new%nqbz, new%qbz, temp) /= 0) then
    2704            0 :    ABI_ERROR("Cannot map qBZ to qIBZ!")
    2705              :  end if
    2706              : 
    2707           58 :  call qrank%free()
    2708              : 
    2709       122762 :  new%ind_qbz2ibz(1,:) = temp(1,:)
    2710       122762 :  new%ind_qbz2ibz(2,:) = temp(2,:)
    2711       122762 :  new%ind_qbz2ibz(3,:) = temp(6,:)
    2712       122762 :  new%ind_qbz2ibz(4,:) = temp(3,:)
    2713       122762 :  new%ind_qbz2ibz(5,:) = temp(4,:)
    2714       122762 :  new%ind_qbz2ibz(6,:) = temp(5,:)
    2715           58 :  ABI_FREE(temp)
    2716              : !END DEBUG
    2717              : 
    2718              :  ! Build (linear) mesh of K * temperatures. tsmesh(1:3) = [start, step, num]
    2719           58 :  call dtset%get_ktmesh(new%ntemp, new%kTmesh)
    2720              : 
    2721           58 :  gaps = ebands%get_gaps(gap_err)
    2722              : 
    2723              :  ! Frequency mesh for sigma(w) and spectral functions.
    2724           58 :  call dtset%get_wrmesh_for_sigeph(new%nwr, new%wr_step)
    2725              : 
    2726              :  ! ======================================================
    2727              :  ! Select k-point and bands where corrections are wanted
    2728              :  ! ======================================================
    2729              :  !
    2730              :  ! if symsigma == +1, we have to include all degenerate states in the set
    2731              :  ! because the final QP corrections will be obtained by averaging the results in the degenerate subspace.
    2732              :  ! We initialize IBZ(k) here so that we have all the basic dimensions of the run and it's possible
    2733              :  ! to distribute the calculations among processors.
    2734           58 :  new%symsigma = dtset%symsigma; new%timrev = kpts_timrev_from_kptopt(ebands%kptopt)
    2735              : 
    2736           58 :  call cwtime_report(" sigmaph_new: k-points", cpu, wall, gflops)
    2737              : 
    2738              :  ! TODO: nkcalc should be spin dependent (similar piece of code in m_gwr).
    2739           58 :  if (dtset%nkptgw /= 0) then
    2740              :    ! Treat the k-points and bands specified in the input file via kptgw and bdgw.
    2741           27 :    call sigtk_kcalc_from_nkptgw(dtset, mband, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks)
    2742              : 
    2743              :  else
    2744           74 :    if (any(abs(dtset%sigma_erange) > zero)) then
    2745              :      ! Use sigma_erange and (optionally) sigma_ngkpt
    2746           14 :      call sigtk_kcalc_from_erange(dtset, cryst, ebands, gaps, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks, comm)
    2747              : 
    2748              :    else
    2749              :      ! Use qp_range to select the interesting k-points and the corresponding bands.
    2750              :      !
    2751              :      !    0 --> Compute the QP corrections only for the fundamental and the direct gap.
    2752              :      ! +num --> Compute the QP corrections for all the k-points in the irreducible zone and include `num`
    2753              :      !          bands above and below the Fermi level.
    2754              :      ! -num --> Compute the QP corrections for all the k-points in the irreducible zone.
    2755              :      !          Include all occupied states and `num` empty states.
    2756              : 
    2757           17 :      qprange_ = dtset%gw_qprange
    2758           17 :      if (gap_err /= 0 .and. qprange_ == 0) then
    2759            0 :        ABI_WARNING("Cannot compute fundamental and direct gap (likely metal). Will replace qprange 0 with qprange 1")
    2760            0 :        qprange_ = 1
    2761              :      end if
    2762              : 
    2763           17 :      if (qprange_ /= 0) then
    2764           11 :        call sigtk_kcalc_from_qprange(dtset, cryst, ebands, qprange_, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks)
    2765              :      else
    2766              :        ! qprange is not specified in the input.
    2767              :        ! Include direct and fundamental KS gap or include states depending on the position wrt band edges.
    2768            6 :        call sigtk_kcalc_from_gaps(dtset, ebands, gaps, new%nkcalc, new%kcalc, new%bstart_ks, new%nbcalc_ks)
    2769              :      end if
    2770              :    end if
    2771              : 
    2772              :  end if ! nkptgw /= 0
    2773              : 
    2774              :  ! The k-point and the symmetries connecting the BZ k-point to the IBZ.
    2775          174 :  ABI_MALLOC(new%kcalc2ibz, (new%nkcalc, 6))
    2776           58 :  if (abs(new%symsigma) == 1) then
    2777          452 :    ABI_MALLOC(new%degtab, (new%nkcalc, new%nsppol))
    2778              :  end if
    2779              : 
    2780              :  ! Workspace arrays used to compute degeneracy tables.
    2781         8432 :  ABI_ICALLOC(degblock_all, (2, mband, new%nkcalc, new%nsppol))
    2782          472 :  ABI_ICALLOC(ndeg_all, (new%nkcalc, new%nsppol))
    2783              : 
    2784           58 :  call krank%from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.)
    2785           58 :  ierr = 0
    2786              : 
    2787          240 :  do ikcalc=1,new%nkcalc
    2788          182 :    if (mod(ikcalc, nprocs) /= my_rank) then
    2789            0 :      new%kcalc2ibz(ikcalc, :) = 0
    2790            0 :      new%bstart_ks(ikcalc, :) = 0
    2791            0 :      new%nbcalc_ks(ikcalc, :) = 0
    2792              :      cycle ! MPI parallelism inside comm
    2793              :    end if
    2794              : 
    2795              :    ! Note symrel and use_symrel.
    2796              :    ! These are the conventions for the symmetrization of the wavefunctions used in cgtk_rotate.
    2797          728 :    kk = new%kcalc(:, ikcalc)
    2798          182 :    if (new%timrev == 1) then
    2799          182 :      kptopt=1
    2800              :    else
    2801            0 :      kptopt=4
    2802              :    end if
    2803          182 :    if (kpts_map("symrel", kptopt, cryst, krank, 1, kk, indkk_k) /= 0) then
    2804              :       write(msg, '(11a)' )&
    2805            0 :        "The WFK file cannot be used to compute self-energy corrections at k-point: ",trim(ktoa(kk)),ch10,&
    2806            0 :        "The k-point cannot be generated from a symmetrical one.", ch10,&
    2807            0 :        "q-mesh: ",trim(ltoa(new%ngqpt)),", k-mesh (from kptrlatt): ",trim(ltoa(get_diag(dtset%kptrlatt))),ch10, &
    2808            0 :        'Action: check your WFK file and the (k, q) point input variables.'
    2809            0 :       ABI_ERROR(msg)
    2810              :    end if
    2811              : 
    2812              :    ! TODO: Invert dims and update abipy
    2813         1274 :    new%kcalc2ibz(ikcalc, :) = indkk_k(:, 1)
    2814              : 
    2815          182 :    ik_ibz = indkk_k(1,1); isym_k = indkk_k(2,1)
    2816          728 :    trev_k = indkk_k(6, 1); g0_k = indkk_k(3:5,1)
    2817          728 :    isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
    2818              :    !kk_ibz = ebands%kptns(:,ik_ibz)
    2819              :    if (.not. isirr_k) then
    2820            0 :      ABI_WARNING(sjoin("The k-point in Sigma_{nk} must be in the IBZ but got:", ktoa(kk)))
    2821            0 :      ierr = ierr + 1
    2822              :    end if
    2823              : 
    2824              :    ! We will have to average the QP corrections over degenerate states if symsigma=1 is used.
    2825              :    ! Here we make sure that all the degenerate states are included.
    2826              :    ! Store also band indices of the degenerate sets, used to average final results.
    2827          240 :    if (abs(new%symsigma) == 1) then
    2828          172 :      cnt = 0
    2829          344 :      do spin=1,new%nsppol
    2830          172 :        bstop = new%bstart_ks(ikcalc, spin) + new%nbcalc_ks(ikcalc, spin) - 1
    2831              :        call ebands%enclose_degbands(ik_ibz, spin, new%bstart_ks(ikcalc, spin), bstop, changed, dtset%symsigma_de, &
    2832          172 :                                     degblock=degblock)
    2833          172 :        if (changed) then
    2834           35 :          new%nbcalc_ks(ikcalc, spin) = bstop - new%bstart_ks(ikcalc, spin) + 1
    2835           35 :          cnt = cnt + 1
    2836           35 :          if (cnt < 5) then
    2837              :            write(msg,'(2(a,i0),2a,2(1x,i0))') &
    2838           35 :              "Not all the degenerate states for ikcalc: ",ikcalc,", spin: ",spin,ch10, &
    2839           70 :              "were included in the bdgw set. bdgw has been automatically changed to: ",new%bstart_ks(ikcalc, spin), bstop
    2840           35 :            ABI_COMMENT(msg)
    2841              :          end if
    2842              :          write(msg,'(2(a,i0),2a)') &
    2843           35 :            "The number of included states: ", bstop, &
    2844           35 :            " is larger than the number of bands in the input ",dtset%nband(ik_ibz + (spin-1)*ebands%nkpt),ch10,&
    2845           70 :            "Action: Increase nband."
    2846           35 :          ABI_CHECK(bstop <= dtset%nband(ik_ibz + (spin-1)*ebands%nkpt), msg)
    2847              :        end if
    2848              : 
    2849              :        ! Store band indices used for averaging (shifted by bstart_ks)
    2850          172 :        ndeg = size(degblock, dim=2)
    2851          172 :        ndeg_all(ikcalc, spin) = ndeg
    2852         1546 :        degblock_all(:, 1:ndeg, ikcalc, spin) = degblock(:, 1:ndeg)
    2853              : 
    2854          344 :        ABI_FREE(degblock)
    2855              :      end do
    2856              :    end if ! symsigma
    2857              :  end do ! ikcalc
    2858              : 
    2859           58 :  call krank%free()
    2860           58 :  ABI_CHECK(ierr == 0, "kptgw wavevectors must be in the IBZ read from the WFK file.")
    2861              : 
    2862              :  ! Collect data
    2863           58 :  call xmpi_sum(new%kcalc2ibz, comm, ierr)
    2864           58 :  call xmpi_sum(new%bstart_ks, comm, ierr)
    2865           58 :  call xmpi_sum(new%nbcalc_ks, comm, ierr)
    2866              : 
    2867              :  ! Build degtab tables.
    2868           58 :  if (abs(new%symsigma) == 1) then
    2869           56 :    call xmpi_sum(ndeg_all, comm, ierr)
    2870           56 :    call xmpi_sum(degblock_all, comm, ierr)
    2871          228 :    do ikcalc=1,new%nkcalc
    2872          400 :      do spin=1,new%nsppol
    2873          172 :        ndeg = ndeg_all(ikcalc, spin)
    2874          974 :        ABI_MALLOC(new%degtab(ikcalc, spin)%bids, (ndeg))
    2875          802 :        do ii=1,ndeg
    2876          458 :          cnt = degblock_all(2, ii, ikcalc, spin) - degblock_all(1, ii, ikcalc, spin) + 1
    2877         1374 :          ABI_MALLOC(new%degtab(ikcalc, spin)%bids(ii)%vals, (cnt))
    2878              :          new%degtab(ikcalc, spin)%bids(ii)%vals = [(jj, jj= &
    2879              :            degblock_all(1, ii, ikcalc, spin) - new%bstart_ks(ikcalc, spin) + 1, &
    2880         3272 :            degblock_all(2, ii, ikcalc, spin) - new%bstart_ks(ikcalc, spin) + 1)]
    2881              :        end do
    2882              :      end do
    2883              :    end do
    2884              :  end if
    2885           58 :  ABI_FREE(degblock_all)
    2886           58 :  ABI_FREE(ndeg_all)
    2887              : 
    2888           58 :  call cwtime_report(" sigmaph_new: kptgw", cpu, wall, gflops)
    2889              : 
    2890              :  ! Now we can finally compute max_nbcalc
    2891          298 :  new%max_nbcalc = maxval(new%nbcalc_ks)
    2892              : 
    2893          232 :  ABI_MALLOC(new%bstop_ks, (new%nkcalc, new%nsppol))
    2894          356 :  new%bstop_ks = new%bstart_ks + new%nbcalc_ks - 1
    2895              : 
    2896              :  ! Compute mpw and gmax
    2897           58 :  call ephtk_get_mpw_gmax(new%nkcalc, new%kcalc, ecut, cryst%gmet, new%mpw, new%gmax, comm)
    2898           58 :  call wrtout(std_out, sjoin(' Optimal value of mpw:', itoa(new%mpw), "gmax:", ltoa(new%gmax)))
    2899           58 :  call cwtime_report(" sigmaph_new: mpw", cpu, wall, gflops)
    2900              : 
    2901              :  ! Define number of bands included in self-energy summation as well as the band range.
    2902              :  ! This value depends on the kind of calculation as imag_only can take advantage of
    2903              :  ! the energy window around the band edges.
    2904              :  !
    2905              :  ! Notes about MPI version.
    2906              :  ! If eph_task == -4:
    2907              :  !    Loops are MPI parallelized over bands so that we can distribute memory for wavefunctions over nband.
    2908              :  !    perturbations and q-points in the IBZ can also be distributed.
    2909              :  !
    2910              :  ! If eph_task == -4:
    2911              :  !    Loops are MPI parallelized over q-points
    2912              :  !    wavefunctions are NOT distributed but only states between my_bsum_start and my_bsum_stop
    2913              :  !    are allocated and read from file.
    2914              :  !    perturbations and q-points in the IBZ can also be distributed.
    2915              : 
    2916           58 :  new%wmax = 1.1_dp * abs(ifc%omega_minmax(2))
    2917           58 :  if (new%qint_method == 0) new%wmax = new%wmax + five * dtset%zcut
    2918              :  ! TODO: One should be consistent with tolerances when using tetra + q-point filtering.
    2919              :  !if (new%qint_method == 1) new%wmax = new%wmax + five * dtset%zcut
    2920              :  !new%wmax = new%wmax + five * dtset%zcut
    2921              :  !write(std_out,*)"wmax:", new%wmax * Ha_eV, " (eV)"
    2922              : 
    2923           58 :  new%elow = huge(one); new%ehigh = - huge(one)
    2924          116 :  do spin=1,new%nsppol
    2925          298 :    do ikcalc=1,new%nkcalc
    2926          182 :      ik_ibz = new%kcalc2ibz(ikcalc, 1)
    2927          182 :      bstart = new%bstart_ks(ikcalc, spin)
    2928          182 :      bstop = new%bstart_ks(ikcalc, spin) + new%nbcalc_ks(ikcalc, spin) - 1
    2929         1148 :      new%ehigh = max(new%ehigh, maxval(ebands%eig(bstart:bstop, ik_ibz, spin)) + new%wmax)
    2930         1206 :      new%elow = min(new%elow, minval(ebands%eig(bstart:bstop, ik_ibz, spin)) - new%wmax)
    2931              :    end do
    2932              :  end do
    2933              :  !call wrtout(std_out, sjoin("elow:", ftoa(elow), "ehigh:", ftoa(ehigh), "[Ha]"))
    2934              : 
    2935           58 :  if (new%imag_only) then
    2936              : 
    2937           25 :    if (all(dtset%sigma_bsum_range /= 0)) then
    2938            0 :      new%bsum_start = max(dtset%sigma_bsum_range(1), 1)
    2939            0 :      new%bsum_stop = min(dtset%sigma_bsum_range(2), mband)
    2940            0 :      new%nbsum = new%bsum_stop - new%bsum_start + 1
    2941            0 :      new%my_bsum_start = new%bsum_start; new%my_bsum_stop = new%bsum_stop
    2942              :    else
    2943              :      ! Compute the min/max KS energy to be included in the imaginary part.
    2944              :      ! ifc%omega_minmax(2) comes from the coarse Q-mesh of the DDB so increase it by 10%.
    2945              :      ! Also take into account the Lorentzian function if zcut is used.
    2946              :      ! In principle this should be large enough but it seems that the linewidths in v8[160] are slightly affected.
    2947              :      ! Select indices for energy window.
    2948              : 
    2949           25 :      call ebands%get_bands_from_erange(new%elow, new%ehigh, new%bsum_start, new%bsum_stop)
    2950           25 :      new%bsum_stop = min(new%bsum_stop, mband)
    2951           25 :      ABI_CHECK(new%bsum_start <= new%bsum_stop, "bsum_start > bsum_bstop")
    2952           25 :      new%nbsum = new%bsum_stop - new%bsum_start + 1
    2953           25 :      new%my_bsum_start = new%bsum_start; new%my_bsum_stop = new%bsum_stop
    2954              :    end if
    2955              : 
    2956              :    !if (dtset%useria == 567) then
    2957              :    !  ! Uncomment this part to use all states to debug.
    2958              :    !  call wrtout(units, "- Setting bstart to 1 and bstop to nband for debugging purposes")
    2959              :    !  new%nbsum = mband; new%bsum_start = 1; new%bsum_stop = new%bsum_start + new%nbsum - 1
    2960              :    !  new%my_bsum_start = new%bsum_start; new%my_bsum_stop = new%bsum_stop
    2961              :    !end if
    2962              : 
    2963              :  else
    2964              :    ! Re + Im
    2965           33 :    new%bsum_start = 1; new%bsum_stop = mband
    2966           37 :    if (all(dtset%sigma_bsum_range /= 0)) then
    2967            2 :      new%bsum_start = max(dtset%sigma_bsum_range(1), 1)
    2968            2 :      new%bsum_stop = min(dtset%sigma_bsum_range(2), mband)
    2969              :    end if
    2970           33 :    new%nbsum = new%bsum_stop - new%bsum_start + 1
    2971              :  end if
    2972              : 
    2973              :  ! ========================
    2974              :  ! === MPI DISTRIBUTION ===
    2975              :  ! ========================
    2976              :  ! Init for sequential execution.
    2977           58 :  new%my_npert = natom3
    2978              : 
    2979          348 :  if (any(dtset%eph_np_pqbks /= 0)) then
    2980              :    ! Use parameters from input file.
    2981            0 :    new%pert_comm%nproc = dtset%eph_np_pqbks(1)
    2982            0 :    new%qpt_comm%nproc  = dtset%eph_np_pqbks(2)
    2983            0 :    new%bsum_comm%nproc = dtset%eph_np_pqbks(3)
    2984            0 :    new%kcalc_comm%nproc = dtset%eph_np_pqbks(4)
    2985            0 :    new%spin_comm%nproc = dtset%eph_np_pqbks(5)
    2986            0 :    new%my_npert = natom3 / new%pert_comm%nproc
    2987            0 :    ABI_CHECK(new%my_npert > 0, "pert_comm_nproc cannot be greater than 3 * natom.")
    2988            0 :    ABI_CHECK(mod(natom3, new%pert_comm%nproc) == 0, "pert_comm_nproc must divide 3 * natom.")
    2989            0 :    if (new%imag_only .and. new%bsum_comm%nproc /= 1) then
    2990            0 :      ABI_ERROR("Nprocs in bsum_comm should be 1 when computing Imag(Sigma)")
    2991              :    end if
    2992              :  else
    2993              :    ! Automatic grid generation.
    2994              : 
    2995              :    ! TODO: Spin
    2996              :    ! Automatic grid generation over q-points and spins.
    2997              :    !if (new%nsppol == 2 .and. mod(nprocs, 2) == 0) then
    2998              :    !  spin_comm%nproc = 2
    2999              :    !  new%qpt_comm%nproc = nprocs / 2
    3000              :    !else
    3001              :    !  new%qpt_comm%nproc = nprocs
    3002              :    !end if
    3003              : 
    3004              :    ! Handle parallelism over perturbations first.
    3005              :    ! Use MPI communicator to distribute the 3 * natom perturbations to reduce memory requirements for DFPT potentials.
    3006              :    ! Ideally, perturbations are equally distributed --> total number of CPUs should be divisible by 3 * natom.
    3007              :    ! or at least, divisible by one integer i for i in [2, 3 * natom - 1].
    3008              : 
    3009              :    ! Try to have 3 perts per proc first because the q-point parallelism is more efficient.
    3010              :    ! The memory for W(R,r,ipert) will increase though.
    3011              :    !do cnt=natom,2,-1
    3012              :    !  if (mod(nprocs, cnt) == 0 .and. mod(natom3, cnt) == 0) then
    3013              :    !    new%pert_comm%nproc = cnt; new%my_npert = natom3 / cnt; exit
    3014              :    !  end if
    3015              :    !end do
    3016              : 
    3017           58 :    if (new%pert_comm%nproc == 1) then
    3018              :      ! Try again with more procs.
    3019          345 :      do cnt=natom3,2,-1
    3020          345 :        if (mod(nprocs, cnt) == 0 .and. mod(natom3, cnt) == 0) then
    3021            0 :          new%pert_comm%nproc = cnt; new%my_npert = natom3 / cnt; exit
    3022              :        end if
    3023              :      end do
    3024              :    end if
    3025              : 
    3026           58 :    if (new%my_npert == natom3 .and. nprocs > 1) then
    3027            0 :      ABI_WARNING("The number of MPI procs should be divisible by 3*natom to reduce memory requirements!")
    3028              :    end if
    3029              : 
    3030              :    ! Define number of procs for q-points and bands. nprocs is divisible by pert_comm%nproc.
    3031           58 :    if (new%imag_only) then
    3032              :      ! Just one extra MPI level for q-points.
    3033           25 :      new%qpt_comm%nproc = nprocs / new%pert_comm%nproc
    3034              :    else
    3035              :      ! Try to distribute equally nbsum first.
    3036           33 :      nrest = nprocs / new%pert_comm%nproc
    3037           33 :      do bstop=nrest,1,-1
    3038           33 :        if (mod(new%nbsum, bstop) == 0 .and. mod(nprocs, new%pert_comm%nproc * bstop) == 0) then
    3039           33 :          new%bsum_comm%nproc = bstop; new%qpt_comm%nproc = nrest / new%bsum_comm%nproc
    3040           33 :          exit
    3041              :        end if
    3042              :      end do
    3043              :    end if
    3044              :  end if
    3045              : 
    3046              :  ! Consistency check.
    3047           58 :  if (new%pert_comm%nproc * new%qpt_comm%nproc * new%bsum_comm%nproc * new%kcalc_comm%nproc * new%spin_comm%nproc /= nprocs) then
    3048              :    write(msg, "(a,i0,3a, 6(a,1x,i0))") &
    3049            0 :      "Cannot create 5d Cartesian grid with total nprocs: ", nprocs, ch10, &
    3050            0 :      "Idle processes are not supported. The product of the `nprocs_*` vars should be equal to nprocs.", ch10, &
    3051            0 :      "pert_nproc (", new%pert_comm%nproc, ") x qpt_nproc (", new%qpt_comm%nproc, ") x bsum_nproc (", new%bsum_comm%nproc, &
    3052            0 :      ") x kcalc_nproc (", new%kcalc_comm%nproc, ") x spin_nproc (", new%spin_comm%nproc, ") != ", nprocs
    3053            0 :    ABI_ERROR(msg)
    3054              :  end if
    3055              : 
    3056          348 :  new%coords_pqbks = 0
    3057              : #ifdef HAVE_MPI
    3058              :  ! Create 5d cartesian communicator: 3*natom perturbations, q-points in IBZ, bands in Sigma sum, kpoints in Sigma_k, spins
    3059              :  ! FIXME: Fix spin
    3060           58 :  periods(:) = .False.; reorder = .False.
    3061          348 :  dims = [new%pert_comm%nproc, new%qpt_comm%nproc, new%bsum_comm%nproc, new%kcalc_comm%nproc, new%spin_comm%nproc]
    3062              :  ! Try New distrib ?
    3063              :  !dims = [new%pert_comm%nproc, new%bsum_comm%nproc, new%qpt_comm%nproc, new%kcalc_comm%nproc, new%spin_comm%nproc]
    3064              : 
    3065           58 :  call MPI_CART_CREATE(comm, ndims, dims, periods, reorder, comm_cart, ierr)
    3066              :  ! Find the index and coordinates of the current processor
    3067           58 :  call MPI_COMM_RANK(comm_cart, me_cart, ierr)
    3068           58 :  call MPI_CART_COORDS(comm_cart, me_cart, ndims, new%coords_pqbks, ierr)
    3069              : 
    3070              :  ! Create communicator to distribute natom3 perturbations.
    3071           58 :  keepdim = .False.; keepdim(1) = .True.; call new%pert_comm%from_cart_sub(comm_cart, keepdim)
    3072              :  ! Create communicator for qpoints in self-energy integration.
    3073           58 :  keepdim = .False.; keepdim(2) = .True.; call new%qpt_comm%from_cart_sub(comm_cart, keepdim)
    3074              :  ! Create communicator for bands for self-energy summation
    3075           58 :  keepdim = .False.; keepdim(3) = .True.; call new%bsum_comm%from_cart_sub(comm_cart, keepdim)
    3076              :  ! Create communicator for kpoints.
    3077           58 :  keepdim = .False.; keepdim(4) = .True.; call new%kcalc_comm%from_cart_sub(comm_cart, keepdim)
    3078              :  ! Create communicator for spins.
    3079           58 :  keepdim = .False.; keepdim(5) = .True.; call new%spin_comm%from_cart_sub(comm_cart, keepdim)
    3080              :  ! Create communicator for the (band_sum, qpoint_sum) loops
    3081          174 :  keepdim = .False.; keepdim(2:3) = .True.; call new%qb_comm%from_cart_sub(comm_cart, keepdim)
    3082              :  ! Create communicator for the (perturbation, band_sum, qpoint_sum)
    3083          232 :  keepdim = .False.; keepdim(1:3) = .True.; call new%pqb_comm%from_cart_sub(comm_cart, keepdim)
    3084              : 
    3085           58 :  call xmpi_comm_free(comm_cart)
    3086              : #endif
    3087              : 
    3088              :  ! Distribute k-points and create mapping to ikcalc index.
    3089           58 :  call xmpi_split_cyclic(new%nkcalc, new%kcalc_comm%value, new%my_nkcalc, new%my_ikcalc)
    3090           58 :  ABI_CHECK(new%my_nkcalc > 0, sjoin("nkcalc (", itoa(new%nkcalc), ") < kcalc_comm_nproc (", itoa(new%kcalc_comm%nproc), ")"))
    3091              : 
    3092              :  ! Distribute spins and create mapping to spin index.
    3093           58 :  if (new%nsppol == 2) then
    3094            0 :    call xmpi_split_block(new%nsppol, new%spin_comm%value, new%my_nspins, new%my_spins)
    3095            0 :    ABI_CHECK(new%my_nspins > 0, sjoin("nsppol (", itoa(new%nsppol), ") < spin_comm_nproc (", itoa(new%spin_comm%nproc), ")"))
    3096              :  else
    3097              :    ! No nsppol parallelism DOH!
    3098           58 :    new%my_nspins = 1
    3099           58 :    ABI_MALLOC(new%my_spins, (new%my_nspins))
    3100          116 :    new%my_spins = 1
    3101              :  end if
    3102              : 
    3103              :  ! Create MPI communicator for parallel netcdf IO used to write results for the different k-points.
    3104              :  ! This communicator is defined only on the processes that will perform IO.
    3105           58 :  call new%ncwrite_comm%set_to_null()
    3106              : 
    3107           58 :  if (new%kcalc_comm%nproc == 1 .and. new%spin_comm%nproc == 1) then
    3108              :    ! Easy-peasy: only master in comm_world performs IO.
    3109           58 :    if (my_rank == master) call new%ncwrite_comm%set_to_self()
    3110              :  else
    3111              :     ! Create subcommunicator by selecting one proc per kpoint-spin subgrid.
    3112              :     ! Since we write to ab_out in sigmaph_gather_and_write, make sure that ab_out is connected!
    3113              :     ! This means Sigma_nk results will be spread among multiple ab_out files.
    3114              :     ! Only SIGPEPH.nc will contain all the results.
    3115              :     ! Remember that now all nc define operations must be done inside ncwrite_comm
    3116              :     ! Obviously I'm assuming HDF5 + MPI-IO
    3117              :     !
    3118              :     ! NB: If MPI_UNDEFINED is passed as the colour value, the subgroup in which the calling
    3119              :     ! MPI process will be placed is MPI_COMM_NULL
    3120              : 
    3121            0 :     color = xmpi_undefined; if (all(new%coords_pqbks(1:3) == 0)) color = 1
    3122            0 :     call xmpi_comm_split(comm, color, my_rank, new%ncwrite_comm%value, ierr)
    3123            0 :     if (color == 1) then
    3124            0 :       new%ncwrite_comm%me = xmpi_comm_rank(new%ncwrite_comm%value)
    3125            0 :       new%ncwrite_comm%nproc = xmpi_comm_size(new%ncwrite_comm%value)
    3126            0 :       if (my_rank == master) then
    3127              :         call wrtout(units, &
    3128              :           sjoin("- Using parallelism over k-points/spins. Cannot write full results to main output", ch10, &
    3129            0 :                 "- All procs except master will write to dev_null. Use SIGEPH.nc to analyze results."))
    3130              :         !write(std_out, *)"ncwrite_comm_me:", new%ncwrite_comm%me, "ncwrite_comm%nproc:", new%ncwrite_comm%nproc
    3131              :       end if
    3132            0 :       if (.not. is_open(ab_out)) then
    3133              :         !if (open_file(strcat(dtfil%filnam_ds(2), "_rank_", itoa(new%ncwrite_comm%me)), msg, unit=ab_out, &
    3134            0 :         if (open_file(NULL_FILE, msg, unit=ab_out, form="formatted", action="write", status='unknown') /= 0) then
    3135            0 :           ABI_ERROR(msg)
    3136              :         end if
    3137              :       end if
    3138              :     else
    3139            0 :       call new%ncwrite_comm%set_to_null()
    3140              :     end if
    3141              :  end if
    3142              : 
    3143              :  ! Build table with list of perturbations treated by this CPU inside pert_comm
    3144           58 :  call ephtk_set_pertables(cryst%natom, new%my_npert, new%pert_table, new%my_pinfo, new%pert_comm%value)
    3145              : 
    3146              :  ! Setup a mask to skip accumulating the contribution of certain phonon modes.
    3147           58 :  call ephtk_set_phmodes_skip(dtset%natom, dtset%eph_phrange, new%phmodes_skip)
    3148              : 
    3149           58 :  if (.not. new%imag_only) then
    3150              :    ! Split bands among the procs inside bsum_comm using block distribution.
    3151           33 :    call xmpi_split_work(new%nbsum, new%bsum_comm%value, new%my_bsum_start, new%my_bsum_stop)
    3152           33 :    if (new%my_bsum_start == new%nbsum + 1) then
    3153            0 :      ABI_ERROR("sigmaph code does not support idle processes! Decrease ncpus or increase nband or use eph_np_pqbks input var.")
    3154              :    end if
    3155           33 :    new%my_bsum_start = new%bsum_start + new%my_bsum_start - 1
    3156           33 :    new%my_bsum_stop = new%bsum_start + new%my_bsum_stop - 1
    3157           99 :    ABI_MALLOC(new%nbsum_rank, (new%bsum_comm%nproc, 3))
    3158           33 :    ii = new%my_bsum_stop - new%my_bsum_start + 1
    3159           33 :    call xmpi_allgather(ii, new%nbsum_rank(:,1), new%bsum_comm%value, ierr)
    3160           33 :    ii = new%my_bsum_start
    3161           33 :    call xmpi_allgather(ii, new%nbsum_rank(:,2), new%bsum_comm%value, ierr)
    3162              :  end if
    3163              : 
    3164              :  call wrtout(std_out, sjoin(" Global bands for self-energy sum, bsum_start: ", itoa(new%bsum_start), &
    3165           58 :    " bsum_bstop:", itoa(new%bsum_stop)))
    3166              :  call wrtout(std_out, sjoin(" Allocating and treating bands from my_bsum_start: ", itoa(new%my_bsum_start), &
    3167           58 :    " up to my_bsum_stop:", itoa(new%my_bsum_stop)))
    3168              : 
    3169              :  ! Distribute DFPT potentials (IBZ q-points) inside qpt_comm.
    3170              :  ! Note that we distribute IBZ instead of the full BZ or the IBZ_k inside the loop over ikcalc.
    3171              :  ! This means that the load won't be equally distributed but memory will scale with qpt_comm%nproc.
    3172              :  ! To reduce load imbalance, we sort the qibz points by norm and use cyclic distribution inside qpt_comm
    3173         4164 :  ABI_ICALLOC(new%itreat_qibz, (new%nqibz))
    3174           58 :  call sort_rpts(new%nqibz, new%qibz, cryst%gmet, iperm)
    3175         4048 :  do ii=1,new%nqibz
    3176         3990 :    iq_ibz = iperm(ii)
    3177         4048 :    if (mod(ii, new%qpt_comm%nproc) == new%qpt_comm%me) new%itreat_qibz(iq_ibz) = 1
    3178              :  end do
    3179           58 :  ABI_FREE(iperm)
    3180              : 
    3181         4048 :  call wrtout(std_out, sjoin("P Number of q-points in the IBZ treated by this proc: " ,itoa(count(new%itreat_qibz == 1))))
    3182              : 
    3183              :  ! ================================================================
    3184              :  ! Allocate arrays used to store final results and set them to zero
    3185              :  ! ================================================================
    3186          472 :  ABI_ICALLOC(new%qp_done, (new%nkcalc, new%nsppol))
    3187         1730 :  ABI_CALLOC(new%vals_e0ks, (new%ntemp, new%max_nbcalc))
    3188         1672 :  ABI_CALLOC(new%fan_vals, (new%ntemp, new%max_nbcalc))
    3189          406 :  ABI_CALLOC(new%E2, (new%ntemp))
    3190         1672 :  ABI_CALLOC(new%E4_vals, (new%ntemp, new%max_nbcalc))
    3191         1672 :  ABI_CALLOC(new%E4_vals2, (new%ntemp, new%max_nbcalc))
    3192         1672 :  ABI_CALLOC(new%fan_stern_vals, (new%ntemp, new%max_nbcalc))
    3193         1672 :  ABI_CALLOC(new%dvals_de0ks, (new%ntemp, new%max_nbcalc))
    3194         1730 :  ABI_CALLOC(new%dw_vals, (new%ntemp, new%max_nbcalc))
    3195         1672 :  ABI_CALLOC(new%dw_stern_vals, (new%ntemp, new%max_nbcalc))
    3196              : 
    3197              :  ! Frequency dependent stuff
    3198           58 :  if (new%nwr > 0) then
    3199        54575 :    ABI_CALLOC(new%vals_wr, (new%nwr, new%ntemp, new%max_nbcalc))
    3200        17068 :    ABI_CALLOC(new%wrmesh_b, (new%nwr, new%max_nbcalc))
    3201              :  end if
    3202              : 
    3203              :  ! Compute phonon frequency mesh.
    3204           58 :  call ifc%get_phmesh(dtset%ph_wstep, new%phmesh_size, new%phmesh)
    3205              : 
    3206              :  ! Prepare calculation of generalized Eliashberg functions
    3207              :  ! prteliash == 0 deactivates computation (default).
    3208           58 :  if (dtset%prteliash /= 0) then
    3209           84 :    ABI_MALLOC(new%gfw_vals, (new%phmesh_size, 3, new%max_nbcalc))
    3210              :  end if
    3211              : 
    3212           58 :  new%a2f_ne = 0
    3213           58 :  if (dtset%prteliash == 3) then
    3214              :    ! TODO: dosdeltae should have a default value.
    3215              :    ! TODO: Use logmesh/double mesh for electrons?
    3216            0 :    estep = dtset%dosdeltae; if (estep <= zero) estep = 0.05 * eV_Ha
    3217            0 :    new%a2f_ne = nint((maxval(ebands%eig) - minval(ebands%eig)) / estep) + 1
    3218            0 :    if (my_rank == master) then
    3219            0 :      write(std_out, *)" Computing a2f with ", new%a2f_ne, " points for electrons and ", new%phmesh_size, " points for phonons."
    3220            0 :      write(std_out, *)" doseltae:", estep, ", tsmear:", dtset%tsmear
    3221              :    end if
    3222            0 :    ABI_MALLOC(new%a2f_emesh, (new%a2f_ne))
    3223            0 :    new%a2f_emesh = arth(minval(ebands%eig), estep, new%a2f_ne)
    3224            0 :    ABI_CALLOC(new%a2few, (new%a2f_ne, new%phmesh_size, new%max_nbcalc))
    3225              :  end if
    3226              : 
    3227           58 :  call cwtime_report(" MPI setup", cpu, wall, gflops)
    3228              : 
    3229              :  ! Initialize object for the computation of integration weights (integration in q-space).
    3230              :  ! Weights can be obtained in different ways:
    3231              :  !
    3232              :  !  1. Computed from eigens on the same coarse q-mesh as the one used for the self-energy.
    3233              :  !  2. Obtained from eigens on a denser q-mesh and then transferred to the coarse q-mesh.
    3234              :  !     In this case the eigens on the dense mesh are either read from an external file (ab-initio)
    3235              :  !     or interpolated on the fly with star-functions.
    3236              :  !
    3237              :  !  NB: The routines assume that the k-mesh for electrons and the q-mesh for phonons are the same.
    3238              :  !  Thus we need to downsample the k-mesh if it's denser that the q-mesh.
    3239              : 
    3240           58 :  new%use_doublegrid = .False.
    3241              : 
    3242              :  ! ================================================================================================
    3243              :  ! Here we construct ebands_dense for the double grid either from WFK file or via SKW interpolation
    3244              :  ! ================================================================================================
    3245              : 
    3246           58 :  if (dtset%getwfkfine /= 0 .or. dtset%irdwfkfine /= 0 .or. dtset%getwfkfine_filepath /= ABI_NOFILE) then
    3247              : 
    3248              :    ! In principle only getwfkfine_filepath is used
    3249            5 :    wfk_fname_dense = trim(dtfil%fnameabi_wfkfine)
    3250            5 :    ABI_CHECK(nctk_try_fort_or_ncfile(wfk_fname_dense, msg) == 0, msg)
    3251            5 :    call wrtout(units, "- EPH double grid interpolation: will read energies from: "//trim(wfk_fname_dense), newlines=1)
    3252              : 
    3253            5 :    ebands_dense = wfk_read_ebands(wfk_fname_dense, comm)
    3254              : 
    3255              :    ! TODO add consistency check: number of bands and kpoints (commensurability)
    3256              :    !if (ebands_dense%is_commensurate(msg) /= 0)
    3257            5 :    ABI_CHECK_IEQ(ebands_dense%mband, ebands%mband, "Inconsistent number of bands for the fine and dense grid:")
    3258            5 :    new%use_doublegrid = .True.
    3259              : 
    3260          206 :  else if (any(dtset%bs_interp_kmult /= 0)) then
    3261              : 
    3262              :    ! Read bs_interpmult
    3263            2 :    call wrtout(units, " EPH interpolation: will use star functions interpolation.", newlines=1)
    3264              :    ! Interpolate band energies with star-functions
    3265            2 :    params = 0; params(1) = 1; params(2) = 5
    3266            2 :    if (nint(dtset%einterp(1)) == 1) params = dtset%einterp
    3267              :    !write(std_out, "(a, 4(f5.2, 2x))")" SKW parameters for double-grid:", params
    3268              : 
    3269              :    !TODO: mband should be min of nband
    3270            6 :    band_block = [1, ebands%mband]
    3271              :    ! TODO: Now we should use this band range.
    3272              :    ! Note that we start from 1 because we are gonna use ebands_dense to compute the Fermi level.
    3273              :    !band_block = [1, new%bsum_stop]
    3274            8 :    intp_kptrlatt(:,1) = [ebands%kptrlatt(1,1)*dtset%bs_interp_kmult(1), 0, 0]
    3275            8 :    intp_kptrlatt(:,2) = [0, ebands%kptrlatt(2,2)*dtset%bs_interp_kmult(2), 0]
    3276            8 :    intp_kptrlatt(:,3) = [0, 0, ebands%kptrlatt(3,3)*dtset%bs_interp_kmult(3)]
    3277              : 
    3278            2 :    intp_nshiftk = 1; intp_shiftk = zero
    3279              :    ebands_dense = ebands%interp_kmesh(cryst, params, intp_kptrlatt, &
    3280            2 :                                       intp_nshiftk, intp_shiftk, band_block, comm)
    3281            2 :    new%use_doublegrid = .True.
    3282              :  end if
    3283              : 
    3284           58 :  if (new%use_doublegrid) then
    3285              :    ! Note that we don't recompute %fermie and %occ in ebands_dense, only %nelect must be consistent with the
    3286              :    ! input ebands to handle possible doping
    3287            7 :    ebands_dense%nelect = ebands%nelect
    3288            7 :    ebands_dense%fermie = ebands%fermie
    3289            7 :    if (abs(dtset%mbpt_sciss) > tol6) then
    3290              :      ! Apply the scissor operator to the dense mesh
    3291            0 :      call wrtout(std_out, sjoin(" Apply the scissor operator to the dense CB with:",ftoa(dtset%mbpt_sciss)))
    3292            0 :      call ebands_dense%apply_scissors(dtset%mbpt_sciss)
    3293              :    end if
    3294              :  end if
    3295              : 
    3296              :  ! Build object used to compute integration weights taking into account double-grid.
    3297              :  ! Note that we compute the weights only for the states included in the sum
    3298              :  ! bstart and new%bsum_comm select the band range.
    3299              :  ! TODO:
    3300              :  !  1) Should recheck the case bstart > 1 with star functions as I got weird results.
    3301              :  !  2) Should refactor ephwg so that only my_npert phonons are stored in the datatype.
    3302           58 :  bstart = new%bsum_start
    3303              : 
    3304           58 :  if (new%qint_method > 0) then
    3305              :    ! Tetra
    3306           19 :    if (new%use_doublegrid) then
    3307              :      ! Double-grid technique from ab-initio energies or star-function interpolation.
    3308            3 :      new%ephwg = ephwg_from_ebands(cryst, ifc, ebands_dense, bstart, new%nbsum, comm)
    3309            3 :      new%eph_doublegrid = eph_double_grid_new(cryst, ebands_dense, ebands%kptrlatt, ebands_dense%kptrlatt)
    3310              :    else
    3311          208 :      downsample = any(ebands%kptrlatt /= qptrlatt) .or. ebands%nshiftk /= my_nshiftq
    3312           80 :      if (ebands%nshiftk == my_nshiftq) downsample = downsample .or. any(ebands%shiftk /= my_shiftq)
    3313           16 :      if (downsample) then
    3314            0 :        ABI_COMMENT("K-mesh != Q-mesh for self-energy. Will downsample electron energies.")
    3315            0 :        tmp_ebands = ebands%downsample(cryst, qptrlatt, my_nshiftq, my_shiftq)
    3316            0 :        new%ephwg = ephwg_from_ebands(cryst, ifc, tmp_ebands, bstart, new%nbsum, comm)
    3317            0 :        call tmp_ebands%free()
    3318              :      else
    3319           16 :        new%ephwg = ephwg_from_ebands(cryst, ifc, ebands, bstart, new%nbsum, comm)
    3320              :      end if
    3321              :    end if
    3322              : 
    3323              :  else
    3324              :    ! Standard quadrature.
    3325           39 :    if (new%use_doublegrid) then
    3326            4 :      new%eph_doublegrid = eph_double_grid_new(cryst, ebands_dense, ebands%kptrlatt, ebands_dense%kptrlatt)
    3327            4 :      new%ephwg = ephwg_from_ebands(cryst, ifc, ebands_dense, bstart, new%nbsum, comm)
    3328              :    endif
    3329              :  end if
    3330              : 
    3331           58 :  call cwtime_report(" sigmaph_new: after doublegrid", cpu, wall, gflops)
    3332              : 
    3333              :  ! Compute the chemical potential at the different physical temperatures with Fermi-Dirac.
    3334          174 :  ABI_MALLOC(new%mu_e, (new%ntemp))
    3335          290 :  new%mu_e(:) = ebands%fermie
    3336              : 
    3337           58 :  if (dtset%eph_fermie == zero) then
    3338           57 :    if (new%use_doublegrid) then
    3339            7 :      call ebands_dense%get_muT_with_fd(new%ntemp, new%ktmesh, dtset%spinmagntarget, dtset%prtvol, new%mu_e, comm)
    3340              :    else
    3341           50 :      call ebands%get_muT_with_fd(new%ntemp, new%ktmesh, dtset%spinmagntarget, dtset%prtvol, new%mu_e, comm)
    3342              :    end if
    3343              :  endif
    3344              : 
    3345           58 :  call ebands_dense%free()
    3346              : 
    3347           58 :  if (my_rank == master) then
    3348           58 :    call gaps%print(units, kTmesh=new%ktmesh, mu_e=new%mu_e, header="Gaps, band edges and relative position wrt Fermi level")
    3349              :  end if
    3350           58 :  call gaps%free()
    3351              : 
    3352              :  ! Prepare computation of Frohlich self-energy
    3353              :  ! TODO: Reintegrate at least frohl_model 1 for the full self-energy
    3354           58 :  new%frohl_model = 0
    3355           58 :  new%ntheta = abs(dtset%eph_frohl_ntheta)
    3356           58 :  if (.not. new%imag_only .and. new%ntheta > 0) then
    3357            0 :    new%frohl_model = 1
    3358              :    !if (.not. dvdb%has_zeff) new%frohl_model = 0
    3359              :  end if
    3360              : 
    3361           58 :  if (new%frohl_model /= 0) then
    3362              :    ! Set angular mesh for numerical integration inside micro BZ around Gamma.
    3363            0 :    new%nphi = 2 * new%ntheta
    3364            0 :    if (my_rank == master) then
    3365            0 :      write(std_out,"(a)")" Activating computation the of Frohlich self-energy:"
    3366            0 :      write(std_out,"(2(a,i0,1x))")" ntheta: ", new%ntheta, "nphi: ", new%nphi
    3367              :    end if
    3368              : 
    3369              :    ! Initialize angular mesh qvers_cart and angwgth
    3370              :    ! NB: summing over f * angwgth gives the spherical average 1/(4pi) \int domega f(omega)
    3371            0 :    call ylm_angular_mesh(new%ntheta, new%nphi, new%angl_size, new%qvers_cart, new%angwgth)
    3372              :  end if
    3373              : 
    3374           58 :  if (new%mrta > 0) then
    3375          745 :    ABI_CALLOC(new%linewidth_mrta, (new%ntemp, new%max_nbcalc))
    3376              :  end if
    3377              : 
    3378           58 :  call cwtime_report(" sigmaph_new: all", cpu_all, wall_all, gflops_all)
    3379              : 
    3380          522 : end function sigmaph_new
    3381              : !!***
    3382              : 
    3383              : !----------------------------------------------------------------------
    3384              : 
    3385              : !!****f* m_sigmaph/sigmaph_write
    3386              : !! NAME
    3387              : !!  sigmaph_write
    3388              : !!
    3389              : !! FUNCTION
    3390              : !!  Define dimensions and netcdf arrays in SIGEPH file.
    3391              : !!
    3392              : !! INPUTS
    3393              : !!  dtset<dataset_type>=All input variables for this dataset.
    3394              : !!  cryst<crystal_t>=Crystalline structure
    3395              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    3396              : !!  wfk_hdr=Header of the WFK file.
    3397              : !!  ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
    3398              : !!  dtfil<datafiles_type>=variables related to files.
    3399              : !!  comm=MPI communicator
    3400              : !!
    3401              : !! SOURCE
    3402              : 
    3403           58 : subroutine sigmaph_write(self, dtset, cryst, ebands, wfk_hdr, dtfil, comm)
    3404              : 
    3405              : !Arguments ------------------------------------
    3406              :  integer,intent(in) :: comm
    3407              :  class(sigmaph_t),intent(inout) :: self
    3408              :  type(crystal_t),intent(in) :: cryst
    3409              :  type(dataset_type),intent(in) :: dtset
    3410              :  type(ebands_t),intent(in) :: ebands
    3411              :  type(hdr_type),intent(in) :: wfk_hdr
    3412              :  type(datafiles_type),intent(in) :: dtfil
    3413              : 
    3414              : !Local variables ------------------------------
    3415              : !scalars
    3416              :  integer,parameter :: master = 0
    3417              :  integer :: my_rank, ii, edos_intmeth, spin, ikcalc
    3418              :  integer :: ncid, ncerr, grp_ncid
    3419              :  !character(len=5000) :: msg
    3420              :  real(dp) :: edos_broad, edos_step,  cpu_all, wall_all, gflops_all, cpu, wall, gflops
    3421              :  character(len=fnlen) :: path
    3422           58 :  type(edos_t) :: edos
    3423              : ! *************************************************************************
    3424              : 
    3425           58 :  my_rank = xmpi_comm_rank(comm)
    3426              : 
    3427           58 :  call cwtime(cpu_all, wall_all, gflops_all, "start")
    3428              : 
    3429           58 :  if (dtset%prtdos /= 0) then
    3430            0 :    call cwtime(cpu, wall, gflops, "start")
    3431              :    ! Compute electron DOS.
    3432            0 :    edos_intmeth = 2; if (self%bcorr == 1) edos_intmeth = -2
    3433            0 :    if (dtset%prtdos == 1) edos_intmeth = 1
    3434            0 :    edos_step = dtset%dosdeltae; edos_broad = dtset%tsmear
    3435            0 :    call wrtout(std_out, " Computing electron dos. Use prtdos 0 to disable this part...", do_flush=.True.)
    3436            0 :    edos = ebands%get_edos(cryst, edos_intmeth, edos_step, edos_broad, comm)
    3437            0 :    if (my_rank == master) then
    3438            0 :      path = strcat(dtfil%filnam_ds(4), "_EDOS")
    3439            0 :      call wrtout(ab_out, sjoin("- Writing electron DOS to file:", path))
    3440            0 :      call edos%write(path)
    3441            0 :      call edos%print([std_out])
    3442              :    end if
    3443            0 :    call cwtime_report(" sigmaph_new: ebands", cpu, wall, gflops)
    3444              :  end if
    3445              : 
    3446              :  ! Create netcdf file (only master works, HDF5 + MPI-IO is handled afterwards by reopening the file inside ncwrite_comm)
    3447           58 :  path = strcat(dtfil%filnam_ds(4), "_SIGEPH.nc")
    3448           58 :  if (my_rank == master) then
    3449              :    ! Master creates the netcdf file used to store the results of the calculation.
    3450           58 :    NCF_CHECK(nctk_open_create(self%ncid, path, xmpi_comm_self))
    3451           58 :    ncid = self%ncid
    3452           58 :    NCF_CHECK(wfk_hdr%ncwrite(ncid, fform_from_ext("SIGEPH.nc"), nc_define=.True.))
    3453           58 :    NCF_CHECK(cryst%ncwrite(ncid))
    3454           58 :    NCF_CHECK(ebands%ncwrite(ncid))
    3455           58 :    if (dtset%prtdos /= 0) then
    3456            0 :      NCF_CHECK(edos%ncwrite(ncid))
    3457              :    end if
    3458              : 
    3459              :    ! Add dimensions.
    3460              :    ncerr = nctk_def_dims(ncid, [ &
    3461              :      nctkdim_t("nkcalc", self%nkcalc), nctkdim_t("max_nbcalc", self%max_nbcalc), &
    3462              :      nctkdim_t("nsppol", self%nsppol), nctkdim_t("ntemp", self%ntemp), nctkdim_t("natom3", 3 * cryst%natom), &
    3463              :      nctkdim_t("phmesh_size", self%phmesh_size), &
    3464              :      nctkdim_t("nqibz", self%nqibz), nctkdim_t("nqbz", self%nqbz)], &
    3465          522 :      defmode=.True.)
    3466           58 :    NCF_CHECK(ncerr)
    3467              : 
    3468           58 :    if (self%nwr > 0) then
    3469           42 :      NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("nwr", self%nwr)]))
    3470              :    end if
    3471           58 :    if (dtset%prteliash == 3) then
    3472            0 :      NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("a2f_ne", self%a2f_ne)]))
    3473              :    end if
    3474              : 
    3475              :    ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: &
    3476              :      "eph_task", "symsigma", "nbsum", "bsum_start", "bsum_stop", "symdynmat", &
    3477              :      "ph_intmeth", "eph_intmeth", "qint_method", "eph_transport", &
    3478         1044 :      "imag_only", "symv1scf", "dvdb_add_lr", "mrta", "ibte_prep", "eph_prtscratew", "eph_ahc_type"])
    3479           58 :    NCF_CHECK(ncerr)
    3480              :    ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: &
    3481              :      "eta", "wr_step", "eph_fsewin", "eph_fsmear", "eph_extrael", "eph_fermie", &
    3482          580 :      "ph_wstep", "ph_smear", "eph_phwinfact"])
    3483           58 :    NCF_CHECK(ncerr)
    3484              : 
    3485              :    ! Define arrays with results.
    3486              :    ncerr = nctk_def_arrays(ncid, [ &
    3487              :      nctkarr_t("ngqpt", "int", "three"), &
    3488              :      nctkarr_t("eph_ngqpt_fine", "int", "three"), &
    3489              :      nctkarr_t("eph_phrange", "int", "two"), &
    3490              :      nctkarr_t("eph_phrange_w", "dp", "two"), &
    3491              :      nctkarr_t("ddb_ngqpt", "int", "three"), &
    3492              :      nctkarr_t("ph_ngqpt", "int", "three"), &
    3493              :      nctkarr_t("sigma_ngkpt", "int", "three"), &
    3494              :      nctkarr_t("sigma_erange", "dp", "two"), &
    3495              :      !nctkarr_t("frohl_params", "dp", "four"), &
    3496              :      nctkarr_t("bstart_ks", "int", "nkcalc, nsppol"), &
    3497              :      nctkarr_t("nbcalc_ks", "int", "nkcalc, nsppol"), &
    3498              :      nctkarr_t("kcalc", "dp", "three, nkcalc"), &
    3499              :      nctkarr_t("kcalc2ibz", "int", "nkcalc, six"), &
    3500              :      nctkarr_t("kTmesh", "dp", "ntemp"), &
    3501              :      nctkarr_t("mu_e", "dp", "ntemp"), &
    3502              :      nctkarr_t("qp_done", "int", "nkcalc, nsppol"), &
    3503              :      nctkarr_t("vals_e0ks", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3504              :      nctkarr_t("fan_vals", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3505              :      nctkarr_t("E2", "dp", "ntemp"), &
    3506              :      nctkarr_t("E4_vals", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3507              :      nctkarr_t("E4_vals2", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3508              :      nctkarr_t("fan_stern_vals", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3509              :      nctkarr_t("dvals_de0ks", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3510              :      nctkarr_t("dw_vals", "dp", "ntemp, max_nbcalc, nkcalc, nsppol"), &
    3511              :      nctkarr_t("dw_stern_vals", "dp", "ntemp, max_nbcalc, nkcalc, nsppol"), &
    3512              :      nctkarr_t("qpoms_enes", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3513              :      nctkarr_t("qp_enes", "dp", "two, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3514              :      nctkarr_t("ze0_vals", "dp", "ntemp, max_nbcalc, nkcalc, nsppol"), &
    3515              :      nctkarr_t("ks_enes", "dp", "max_nbcalc, nkcalc, nsppol"), &
    3516              :      nctkarr_t("ks_gaps", "dp", "nkcalc, nsppol"), &
    3517              :      nctkarr_t("qpoms_gaps", "dp", "ntemp, nkcalc, nsppol"), &
    3518              :      nctkarr_t("qp_gaps", "dp", "ntemp, nkcalc, nsppol"), &
    3519              :      nctkarr_t("phmesh", "dp", "phmesh_size"), &
    3520              :      nctkarr_t("vcar_calc", "dp", "three, max_nbcalc, nkcalc, nsppol") &
    3521         1972 :    ])
    3522           58 :    NCF_CHECK(ncerr)
    3523              : 
    3524           58 :    if (self%mrta > 0) then
    3525              :      ncerr = nctk_def_arrays(ncid, [ &
    3526              :        nctkarr_t("linewidth_mrta", "dp", "ntemp, max_nbcalc, nkcalc, nsppol") &
    3527           50 :      ])
    3528           25 :      NCF_CHECK(ncerr)
    3529              :    end if
    3530              : 
    3531           58 :    if (dtset%eph_prtscratew == 1) then
    3532              :      ncerr = nctk_def_arrays(ncid, [ &
    3533              :        nctkarr_t("scratew", "dp", "phmesh_size, ntemp, max_nbcalc, two, nkcalc, nsppol") &
    3534            2 :      ])
    3535            1 :      NCF_CHECK(ncerr)
    3536              :    end if
    3537              : 
    3538              :    !if (self%frohl_model == 1) then
    3539              :    !  if (self%imag_only) then
    3540              :    !    ncerr = nctk_def_arrays(ncid, [ &
    3541              :    !      nctkarr_t("frohl_deltas_sphcorr", "dp", "two, ntemp, max_nbcalc, natom3, nkcalc, nsppol") &
    3542              :    !    ])
    3543              :    !    NCF_CHECK(ncerr)
    3544              :    !  end if
    3545              :    !end if
    3546              : 
    3547           58 :    if (self%nwr > 0) then
    3548              :      ! Make room for the spectral function. These arrays get two extra dimensions on file (nkcalc, nsppol).
    3549              :      ncerr = nctk_def_arrays(ncid, [ &
    3550              :        nctkarr_t("wrmesh_b", "dp", "nwr, max_nbcalc, nkcalc, nsppol"), &
    3551              :        nctkarr_t("vals_wr", "dp", "two, nwr, ntemp, max_nbcalc, nkcalc, nsppol"), &
    3552              :        nctkarr_t("spfunc_wr", "dp", "nwr, ntemp, max_nbcalc, nkcalc, nsppol") &
    3553           84 :      ])
    3554           21 :      NCF_CHECK(ncerr)
    3555              :    end if
    3556              : 
    3557           58 :    if (dtset%prteliash /= 0) then
    3558              :      ncerr = nctk_def_arrays(ncid, [ &
    3559              :        nctkarr_t("gfw_vals", "dp", "phmesh_size, three, max_nbcalc, nkcalc, nsppol") &
    3560           42 :      ])
    3561           21 :      NCF_CHECK(ncerr)
    3562           21 :      if (dtset%prteliash == 3) then
    3563              :        ncerr = nctk_def_arrays(ncid, [ &
    3564              :          nctkarr_t("a2f_emesh", "dp", "a2f_ne"), &
    3565              :          nctkarr_t("a2few", "dp", "a2f_ne, phmesh_size, max_nbcalc, nkcalc, nsppol") &
    3566            0 :        ])
    3567            0 :        NCF_CHECK(ncerr)
    3568              :      end if
    3569              :    end if
    3570              : 
    3571           58 :    if (dtset%ibte_prep > 0) then
    3572              :       ! Create groups to store scattering rates (ragged array).
    3573            2 :       do spin=1,self%nsppol
    3574            8 :         do ikcalc=1,self%nkcalc
    3575            7 :           NCF_CHECK(nf90_def_grp(ncid, strcat("srate_k", itoa(ikcalc), "_s", itoa(spin)), grp_ncid))
    3576              :         end do
    3577              :       end do
    3578              :    end if
    3579              : 
    3580              :    ! ======================================================
    3581              :    ! Write data that do not depend on the (kpt, spin) loop.
    3582              :    ! ======================================================
    3583           58 :    NCF_CHECK(nctk_set_datamode(ncid))
    3584           58 :    ii = 0; if (self%imag_only) ii = 1
    3585              :    ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: &
    3586              :      "eph_task", "symsigma", "nbsum", "bsum_start", "bsum_stop", &
    3587              :      "symdynmat", "ph_intmeth", "eph_intmeth", "qint_method", &
    3588              :      "eph_transport", "imag_only", "symv1scf", "dvdb_add_lr", "mrta", "ibte_prep", "eph_prtscratew", "eph_ahc_type"], &
    3589              :      [dtset%eph_task, self%symsigma, self%nbsum, self%bsum_start, self%bsum_stop, &
    3590              :      dtset%symdynmat, dtset%ph_intmeth, dtset%eph_intmeth, self%qint_method, dtset%eph_transport, ii, &
    3591         2030 :      dtset%symv1scf, dtset%dvdb_add_lr, self%mrta, dtset%ibte_prep, dtset%eph_prtscratew, dtset%eph_ahc_type])
    3592           58 :    NCF_CHECK(ncerr)
    3593              :    ncerr = nctk_write_dpscalars(ncid, [character(len=nctk_slen) :: &
    3594              :      "eta", "wr_step", "eph_fsewin", "eph_fsmear", "eph_extrael", "eph_fermie", "ph_wstep", "ph_smear", "eph_phwinfact"], &
    3595              :      [aimag(self%ieta), self%wr_step, dtset%eph_fsewin, dtset%eph_fsmear, dtset%eph_extrael, dtset%eph_fermie, &
    3596         1102 :      dtset%ph_wstep, dtset%ph_smear, dtset%eph_phwinfact])
    3597           58 :    NCF_CHECK(ncerr)
    3598              : 
    3599           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ngqpt"), self%ngqpt))
    3600           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_ngqpt_fine"), dtset%eph_ngqpt_fine))
    3601           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ddb_ngqpt"), dtset%ddb_ngqpt))
    3602           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ph_ngqpt"), dtset%ph_ngqpt))
    3603           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_ngkpt"), dtset%sigma_ngkpt))
    3604           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_erange"), dtset%sigma_erange))
    3605              :    !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "frohl_params"), dtset%frohl_params))
    3606           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_phrange"), dtset%eph_phrange))
    3607           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_phrange_w"), dtset%eph_phrange_w))
    3608           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "bstart_ks"), self%bstart_ks))
    3609           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nbcalc_ks"), self%nbcalc_ks))
    3610           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc"), self%kcalc))
    3611           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc2ibz"), self%kcalc2ibz))
    3612           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kTmesh"), self%kTmesh))
    3613           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "mu_e"), self%mu_e))
    3614           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eta"), aimag(self%ieta)))
    3615           58 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phmesh"), self%phmesh))
    3616           58 :    if (dtset%prteliash == 3) then
    3617            0 :      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "a2f_emesh"), self%a2f_emesh))
    3618              :    end if
    3619           58 :    NCF_CHECK(nf90_close(ncid))
    3620              :  end if ! master
    3621              : 
    3622           58 :  call xmpi_barrier(comm)
    3623              : 
    3624              :  ! Now reopen the file inside ncwrite_comm to perform parallel-IO (required for k-point parallelism).
    3625           58 :  if (self%ncwrite_comm%value /= xmpi_comm_null) then
    3626           58 :    NCF_CHECK(nctk_open_modify(self%ncid, path, self%ncwrite_comm%value))
    3627           58 :    NCF_CHECK(nctk_set_datamode(self%ncid))
    3628              :  end if
    3629              : 
    3630           58 :  call edos%free()
    3631           58 :  call cwtime_report(" sigmaph_new: netcdf", cpu_all, wall_all, gflops_all)
    3632              : 
    3633           58 : end subroutine sigmaph_write
    3634              : !!***
    3635              : 
    3636              : !----------------------------------------------------------------------
    3637              : 
    3638              : !!****f* m_sigmaph/sigmaph_read
    3639              : !! NAME
    3640              : !!  sigmaph_read
    3641              : !!
    3642              : !! FUNCTION
    3643              : !!  Start an (incomplete) sigmaph instance from a netcdf file.
    3644              : !!  This routine serves only to read some basic dimensions and parameters from the SIGEPH.nc file to
    3645              : !!
    3646              : !!     1. Verify whether a restart in sigmaph is possible when eph_restart == 1
    3647              : !!     2. Use these metadata in the RTA module to prepare the calculation of transport properties.
    3648              : !!
    3649              : !! INPUTS
    3650              : !!  path= SIGEPH Filename.
    3651              : !!  dtset<dataset_type>=All input variables for this dataset.
    3652              : !!  comm=MPI communicator
    3653              : !!  msg=Error message if ierr /= 0
    3654              : !!  ierr = Exit status
    3655              : !!  [keep_open]=True to keep the Nc file handle open for further reading. Default: False.
    3656              : !!  [extrael_fermie]: Return the value of (eph_extrael, eph_fermie) read from file.
    3657              : !!  [sigma_ngkpt] =  Value read from the ncfile (used in m_rta)
    3658              : !!  [sigma_erange] = Value read from the ncfile (used in m_rta)
    3659              : !!
    3660              : !! SOURCE
    3661              : 
    3662           73 : type(sigmaph_t) function sigmaph_read(path, dtset, comm, msg, ierr, keep_open, &
    3663              :                                       extrael_fermie, sigma_ngkpt, sigma_erange) result(new)
    3664              : 
    3665              : !Arguments ------------------------------------
    3666              :  integer,intent(in) :: comm
    3667              :  integer,intent(out) :: ierr
    3668              :  type(dataset_type),intent(in) :: dtset
    3669              :  character(len=500),intent(out) :: msg
    3670              :  real(dp), optional, intent(out) :: extrael_fermie(2)
    3671              :  logical,optional,intent(in) :: keep_open
    3672              :  integer,optional, intent(out) :: sigma_ngkpt(3)
    3673              :  real(dp),optional,intent(out) :: sigma_erange(2)
    3674              : 
    3675              : !Local variables ------------------------------
    3676              : !scalars
    3677              :  integer :: imag_only, eph_task, symdynmat, ph_intmeth, eph_intmeth, eph_transport
    3678              :  integer :: ncid !, varid !, ncerr
    3679              :  real(dp) :: eph_fermie, eph_fsewin, ph_wstep, ph_smear, eta, eph_extrael, eph_fsmear, cpu, wall, gflops
    3680              :  character(len=fnlen) :: path
    3681              : !arrays
    3682              :  integer :: eph_ngqpt_fine(3), ddb_ngqpt(3), ph_ngqpt(3), my_sigma_ngkpt(3)
    3683              :  real(dp) :: my_sigma_erange(2)
    3684              : ! *************************************************************************
    3685              : 
    3686           73 :  call cwtime(cpu, wall, gflops, "start")
    3687              : 
    3688           73 :  msg = ""; ierr = 0
    3689           73 :  if (.not. file_exists(path)) then
    3690           58 :    msg = sjoin("Cannot find file", path); ierr = 1; return
    3691              :  end if
    3692              : 
    3693              :  ! Open netcdf file
    3694           15 :  NCF_CHECK(nctk_open_read(ncid, path, comm))
    3695              : 
    3696              :  !TODO?
    3697              :  !NCF_CHECK(cryst%ncread(ncid))
    3698              :  !NCF_CHECK(ebands_ncread(ebands, ncid))
    3699              : 
    3700              :  ! Read sigma_eph dimensions.
    3701           15 :  NCF_CHECK(nctk_get_dim(ncid, "nkcalc", new%nkcalc))
    3702           15 :  NCF_CHECK(nctk_get_dim(ncid, "max_nbcalc", new%max_nbcalc))
    3703           15 :  NCF_CHECK(nctk_get_dim(ncid, "nsppol", new%nsppol))
    3704           15 :  NCF_CHECK(nctk_get_dim(ncid, "ntemp", new%ntemp))
    3705           15 :  NCF_CHECK(nctk_get_dim(ncid, "nqibz", new%nqibz))
    3706           15 :  NCF_CHECK(nctk_get_dim(ncid, "nqbz", new%nqbz))
    3707              :  !NCF_CHECK(nctk_get_dim(ncid, "nwr", new%nwr))
    3708              :  !NCF_CHECK(nctk_get_dim(ncid, "phmesh_size", new%phmesh_size))
    3709              : 
    3710              :  ! ======================================================
    3711              :  ! Read data that does not depend on the (kpt, spin) loop.
    3712              :  ! ======================================================
    3713           15 :  NCF_CHECK(nf90_get_var(ncid, vid("symsigma"), new%symsigma))
    3714           15 :  NCF_CHECK(nf90_get_var(ncid, vid("nbsum"), new%nbsum))
    3715           15 :  NCF_CHECK(nf90_get_var(ncid, vid("bsum_start"), new%bsum_start))
    3716           15 :  NCF_CHECK(nf90_get_var(ncid, vid("bsum_stop"), new%bsum_stop))
    3717              : 
    3718           15 :  NCF_CHECK(nf90_get_var(ncid, vid("qint_method"), new%qint_method))
    3719              :  !NCF_CHECK(nf90_get_var(ncid, vid("frohl_model"), new%frohl_model))
    3720           15 :  NCF_CHECK(nf90_get_var(ncid, vid("imag_only"), imag_only))
    3721           15 :  new%imag_only = (imag_only == 1)
    3722           15 :  NCF_CHECK(nf90_get_var(ncid, vid("mrta"), new%mrta))
    3723              : 
    3724           45 :  ABI_MALLOC(new%kcalc, (3, new%nkcalc))
    3725           60 :  ABI_MALLOC(new%bstart_ks, (new%nkcalc, new%nsppol))
    3726           45 :  ABI_MALLOC(new%bstop_ks, (new%nkcalc, new%nsppol))
    3727           45 :  ABI_MALLOC(new%nbcalc_ks, (new%nkcalc, new%nsppol))
    3728           45 :  ABI_MALLOC(new%mu_e, (new%ntemp))
    3729           30 :  ABI_MALLOC(new%kTmesh, (new%ntemp))
    3730           45 :  ABI_MALLOC(new%kcalc2ibz, (new%nkcalc, 6))
    3731              : 
    3732           15 :  NCF_CHECK(nf90_get_var(ncid, vid("ngqpt"), new%ngqpt))
    3733           15 :  NCF_CHECK(nf90_get_var(ncid, vid("bstart_ks"), new%bstart_ks))
    3734           15 :  NCF_CHECK(nf90_get_var(ncid, vid("nbcalc_ks"), new%nbcalc_ks))
    3735          108 :  new%bstop_ks = new%bstart_ks + new%nbcalc_ks - 1
    3736              : 
    3737           15 :  NCF_CHECK(nf90_get_var(ncid, vid("kcalc"), new%kcalc))
    3738           15 :  NCF_CHECK(nf90_get_var(ncid, vid("kcalc2ibz"), new%kcalc2ibz))
    3739           15 :  NCF_CHECK(nf90_get_var(ncid, vid("kTmesh"), new%kTmesh))
    3740           15 :  NCF_CHECK(nf90_get_var(ncid, vid("wr_step"), new%wr_step))
    3741           15 :  NCF_CHECK(nf90_get_var(ncid, vid("mu_e"), new%mu_e))
    3742           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eta"), eta))
    3743           15 :  new%ieta = j_dpc * eta
    3744              : 
    3745              :  ! Read the done array used to implement restart capabilities.
    3746          138 :  ABI_ICALLOC(new%qp_done, (new%nkcalc, new%nsppol))
    3747           15 :  NCF_CHECK(nf90_get_var(ncid, vid("qp_done"), new%qp_done))
    3748              : 
    3749              :  ! ============================================================
    3750              :  ! Read and check consistency against dtset
    3751              :  ! ============================================================
    3752           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_fsewin"), eph_fsewin))
    3753           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_fsmear"), eph_fsmear))
    3754           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_extrael"), eph_extrael))
    3755           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_fermie"), eph_fermie))
    3756           15 :  NCF_CHECK(nf90_get_var(ncid, vid("ph_wstep"), ph_wstep))
    3757           15 :  NCF_CHECK(nf90_get_var(ncid, vid("ph_smear"), ph_smear))
    3758           15 :  ABI_CHECK(eph_fsewin == dtset%eph_fsewin, "netcdf eph_fsewin != input file")
    3759           15 :  ABI_CHECK(eph_fsmear == dtset%eph_fsmear, "netcdf eph_fsmear != input file")
    3760           15 :  ABI_CHECK(ph_wstep   == dtset%ph_wstep, "netcdf ph_wstep != input file")
    3761           15 :  ABI_CHECK(ph_smear   == dtset%ph_smear, "netcdf ph_smear != input file")
    3762              : 
    3763           15 :  if (present(extrael_fermie)) then
    3764           45 :    extrael_fermie = [eph_extrael, eph_fermie]
    3765              :  else
    3766            0 :    ABI_CHECK_DEQ(eph_extrael, dtset%eph_extrael, "netcdf eph_extrael != input file")
    3767            0 :    ABI_CHECK_DEQ(eph_fermie, dtset%eph_fermie, "netcdf eph_feremie != input file")
    3768              :  end if
    3769              : 
    3770           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_task"), eph_task))
    3771           15 :  NCF_CHECK(nf90_get_var(ncid, vid("symdynmat"), symdynmat))
    3772           15 :  NCF_CHECK(nf90_get_var(ncid, vid("ph_intmeth"), ph_intmeth))
    3773           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_intmeth"), eph_intmeth))
    3774           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_transport"), eph_transport))
    3775              : 
    3776           15 :  if (dtset%eph_task==-4 .or. dtset%eph_task==4) then
    3777           12 :    ABI_CHECK_IEQ(symdynmat, dtset%symdynmat, "netcdf symdynmat != input file")
    3778           12 :    ABI_CHECK_IEQ(ph_intmeth, dtset%ph_intmeth, "netcdf ph_intmeth != input file")
    3779           12 :    ABI_CHECK_IEQ(eph_intmeth, dtset%eph_intmeth, "netcdf eph_intmeth != input file")
    3780           12 :    ABI_CHECK_IEQ(eph_transport, dtset%eph_transport, "netcdf eph_transport != input file")
    3781              :  endif
    3782              : 
    3783              :  !NCF_CHECK(nf90_get_var(ncid, vid("frohl_params"), frohl_params))
    3784           15 :  NCF_CHECK(nf90_get_var(ncid, vid("eph_ngqpt_fine"), eph_ngqpt_fine))
    3785           15 :  NCF_CHECK(nf90_get_var(ncid, vid("ddb_ngqpt"), ddb_ngqpt))
    3786           15 :  NCF_CHECK(nf90_get_var(ncid, vid("ph_ngqpt"), ph_ngqpt))
    3787           15 :  NCF_CHECK(nf90_get_var(ncid, vid("sigma_ngkpt"), my_sigma_ngkpt))
    3788           15 :  if (present(sigma_ngkpt)) then
    3789           15 :    sigma_ngkpt = my_sigma_ngkpt
    3790              :  else
    3791            0 :    ABI_CHECK(all(dtset%sigma_ngkpt == my_sigma_ngkpt), "netcdf sigma_ngkpt != input file")
    3792              :  end if
    3793              : 
    3794           15 :  NCF_CHECK(nf90_get_var(ncid, vid("sigma_erange"), my_sigma_erange))
    3795           15 :  if (present(sigma_erange)) then
    3796           15 :    sigma_erange = my_sigma_erange
    3797              :  else
    3798            0 :    ABI_CHECK(all(dtset%sigma_erange == my_sigma_erange), "netcdf sigma_erange != input file")
    3799              :  end if
    3800              : 
    3801           15 :  if (present(keep_open)) then
    3802           15 :    new%ncid = ncid
    3803              :  else
    3804            0 :    NCF_CHECK(nf90_close(ncid))
    3805              :    ! so that the structure is properly freed
    3806            0 :    new%ncid = nctk_noid
    3807              :  end if
    3808              : 
    3809           60 :  ABI_CHECK(all(dtset%eph_ngqpt_fine == eph_ngqpt_fine),"netcdf eph_ngqpt_fine != input file")
    3810           60 :  ABI_CHECK(all(dtset%ddb_ngqpt      == ddb_ngqpt), "netcdf ddb_ngqpt != input file")
    3811           60 :  ABI_CHECK(all(dtset%ph_ngqpt       == ph_ngqpt), "netcdf ph_ngqpt != input file")
    3812              :  !ABI_CHECK(all(abs(dtset%frohl_params - frohl_params) < tol6), "netcdf frohl_params != input file")
    3813              : 
    3814           88 :  call cwtime_report(" sigmaph_read", cpu, wall, gflops)
    3815              : 
    3816              : contains
    3817          495 :  integer function vid(var_name)
    3818              :    character(len=*),intent(in) :: var_name
    3819          495 :    vid = nctk_idname(ncid, var_name)
    3820              : end function vid
    3821              : 
    3822              : end function sigmaph_read
    3823              : !!***
    3824              : 
    3825              : !----------------------------------------------------------------------
    3826              : 
    3827              : !!****f* m_sigmaph/sigmaph_get_ebands
    3828              : !! NAME
    3829              : !!  sigmaph_get_ebands
    3830              : !!
    3831              : !! FUNCTION
    3832              : !!  Read quantities from the sigmaph to an ebands_t structure and return mapping
    3833              : !!
    3834              : !! INPUTS
    3835              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    3836              : !!  opt=integer option selecting what to read on the ebands object. 1-only mapping, 10+n-read n temperature linewidths
    3837              : !!
    3838              : !! SOURCE
    3839              : 
    3840           15 : type(ebands_t) function sigmaph_get_ebands(self, cryst, ebands, brange, kcalc2ebands, linewidths, velocity, comm) result(new)
    3841              : 
    3842              : !Arguments -----------------------------------------------
    3843              :  integer,intent(in) :: comm
    3844              :  class(sigmaph_t),intent(in) :: self
    3845              :  type(crystal_t),intent(in) :: cryst
    3846              :  type(ebands_t),intent(in) :: ebands
    3847              :  integer,intent(in) :: brange(2)
    3848              :  integer, allocatable, intent(out) :: kcalc2ebands(:,:)
    3849              :  real(dp), allocatable, intent(out) :: linewidths(:,:,:,:,:), velocity(:,:,:,:)
    3850              : 
    3851              : !Local variables -----------------------------------------
    3852              : !scalars
    3853              :  integer,parameter :: master = 0
    3854              :  integer :: spin, ikpt, ikcalc, iband, itemp, nsppol, nkpt, band_ks, bstart_ks, nbcalc_ks, mband
    3855              :  integer :: bmin, bmax, my_rank, ierr, ncerr
    3856           15 :  type(krank_t) :: krank
    3857              :  character(len=5000) :: msg
    3858              : !arrays
    3859              :  !integer,allocatable :: kcalc2ebands(:,:)
    3860              : ! *************************************************************************
    3861              : 
    3862           30 :  my_rank = xmpi_comm_rank(comm)
    3863              : 
    3864              :  ! copy useful dimensions
    3865           15 :  nsppol = self%nsppol; nkpt = ebands%nkpt
    3866              : 
    3867              :  ! Map input ebands kpoints to kcalc k-points stored in sigmaph file.
    3868           45 :  ABI_MALLOC(kcalc2ebands, (6, self%nkcalc))
    3869              : 
    3870           15 :  call krank%from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.)
    3871              : 
    3872           15 :  if (kpts_map("symrec", ebands%kptopt, cryst, krank, self%nkcalc, self%kcalc, kcalc2ebands) /= 0) then
    3873              :     write(msg, '(3a)' ) &
    3874            0 :      "Error mapping input ebands%kptns to sigmaph kcalc",ch10,&
    3875            0 :      "the k-point could not be generated from a symmetrical one"
    3876            0 :     ABI_ERROR(msg)
    3877              :  end if
    3878           15 :  call krank%free()
    3879              : 
    3880              :  ! store mapping to return
    3881              :  !if (present(kcalc2ebands)) then
    3882              :  !  ABI_MALLOC(kcalc2ebands, (self%nkcalc))
    3883              :  !  kcalc2ebands(:) = indkk(1, :)
    3884              :  !end if
    3885              : 
    3886              :  ! Allocate using only the relevant bands for transport
    3887              :  ! including valence states to allow to compute different doping
    3888              :  ! MG: TODO: Do we really need this!
    3889           93 :  mband = maxval(self%bstop_ks)
    3890           15 :  new = ebands%chop(1, mband)
    3891              :  !mband = ebands%mband
    3892              :  !call ebands_copy(ebands, new)
    3893              :  !bmin = 1; bmax = mband
    3894           15 :  bmin = brange(1); bmax = brange(2)
    3895              : 
    3896              :  ! Read linewidths from sigmaph file.
    3897              :  ! Use global array (mband, nkpt, nsppol) but keep in mind that results in SIGPEPH are packed
    3898              :  ! so that only the relevant k-points are stored on file.
    3899              : 
    3900        20203 :  ABI_CALLOC(velocity, (3, bmin:bmax, nkpt, nsppol))
    3901        61931 :  ABI_CALLOC(linewidths, (self%ntemp, bmin:bmax, nkpt, nsppol, 2))
    3902              : 
    3903           15 :  if (my_rank == master) then
    3904           30 :    do spin=1,nsppol
    3905           93 :      do ikcalc=1,self%nkcalc
    3906           63 :        bstart_ks = self%bstart_ks(ikcalc, spin)
    3907           63 :        nbcalc_ks = self%nbcalc_ks(ikcalc, spin)
    3908          163 :        do iband=1,nbcalc_ks
    3909              :          ! band index in global array.
    3910           85 :          band_ks = iband + bstart_ks - 1
    3911              :          ! kcalc --> ibz index
    3912           85 :          ikpt = kcalc2ebands(1, ikcalc)
    3913              : 
    3914          375 :          do itemp=1,self%ntemp
    3915              :            ! Read SERTA lifetimes
    3916              :            ncerr = nf90_get_var(self%ncid, nctk_idname(self%ncid, "vals_e0ks"), &
    3917         1740 :                    linewidths(itemp, band_ks, ikpt, spin, 1), start=[2, itemp, iband, ikcalc, spin])
    3918          290 :            NCF_CHECK(ncerr)
    3919              : 
    3920              :            ! Read MRTA lifetimes
    3921              :            ! TODO: This should be called half_linewidth_mrta since
    3922              :            ! in m_rta we multiply by two to get tau = 1/(2 Imag(sigma))
    3923          375 :            if (self%mrta > 0) then
    3924              :              ncerr = nf90_get_var(self%ncid, nctk_idname(self%ncid, "linewidth_mrta"), &
    3925         1350 :                                   linewidths(itemp, band_ks, ikpt, spin, 2), start=[itemp, iband, ikcalc, spin])
    3926          270 :              NCF_CHECK(ncerr)
    3927              :            end if
    3928              :          end do
    3929              : 
    3930              :          ! Read band velocities computed only of the kcalc k-points.
    3931              :          ncerr = nf90_get_var(self%ncid, nctk_idname(self%ncid, "vcar_calc"), &
    3932          425 :                               velocity(:, band_ks, ikpt, spin), start=[1, iband, ikcalc, spin])
    3933          148 :          NCF_CHECK(ncerr)
    3934              :        end do
    3935              :      end do
    3936              :    end do
    3937              :  end if
    3938              : 
    3939              :  !ABI_FREE(indkk)
    3940              : 
    3941              :  ! This so that output linewidths are always positive independently
    3942              :  ! of the kind of self-energy used (retarded or advanced)
    3943        61841 :  linewidths = abs(linewidths)
    3944              : 
    3945           15 :  call xmpi_bcast(linewidths, master, comm, ierr)
    3946           15 :  call xmpi_bcast(velocity, master, comm, ierr)
    3947              : 
    3948           30 : end function sigmaph_get_ebands
    3949              : !!***
    3950              : 
    3951              : !----------------------------------------------------------------------
    3952              : 
    3953              : !!****f* m_sigmaph/sigmaph_compare
    3954              : !! NAME
    3955              : !!  sigmaph_compare
    3956              : !!
    3957              : !! FUNCTION
    3958              : !!  Compare the headers of two sigmaph_t instances
    3959              : !!
    3960              : !! SOURCE
    3961              : 
    3962            0 : subroutine sigmaph_compare(self, other)
    3963              : 
    3964              : !Arguments ------------------------------------
    3965              :  class(sigmaph_t),intent(in) :: self, other
    3966              : 
    3967              : !Local variables-------------------------------
    3968              :  integer :: ierr
    3969              : ! *************************************************************************
    3970            0 :  ierr = 0
    3971              : 
    3972            0 :  ABI_CHECK_NOSTOP(self%nkcalc == other%nkcalc, "Difference found in nkcalc.", ierr)
    3973            0 :  ABI_CHECK_NOSTOP(self%max_nbcalc == other%max_nbcalc, "Difference found in max_nbcalc.", ierr)
    3974            0 :  ABI_CHECK_NOSTOP(self%nsppol == other%nsppol, "Difference found in nsppol.", ierr)
    3975            0 :  ABI_CHECK_NOSTOP(self%ntemp == other%ntemp, "Difference found in ntemp.", ierr)
    3976            0 :  ABI_CHECK_NOSTOP(self%nqibz == other%nqibz, "Difference found in nqibz.", ierr)
    3977            0 :  ABI_CHECK_NOSTOP(self%nqbz == other%nqbz, "Difference found in nqbz.", ierr)
    3978              : 
    3979              :  ! ======================================================
    3980              :  ! Read data that does not depend on the (kpt, spin) loop.
    3981              :  ! ======================================================
    3982            0 :  ABI_CHECK_NOSTOP(self%symsigma == other%symsigma, "Different value found for symsigma.", ierr)
    3983            0 :  ABI_CHECK_NOSTOP(self%nbsum == other%nbsum, "Different value found for nbsum.", ierr)
    3984            0 :  ABI_CHECK_NOSTOP(self%bsum_start == other%bsum_start, "Different value found for bsum_start.", ierr)
    3985            0 :  ABI_CHECK_NOSTOP(self%bsum_stop == other%bsum_stop, "Different value found for bsum_stop.", ierr)
    3986            0 :  ABI_CHECK_NOSTOP(self%qint_method == other%qint_method, "Different value found for qint_method", ierr)
    3987              :  !ABI_CHECK_NOSTOP(self%frohl_model == other%frohl_model, "Different value found for frohl_model.", ierr)
    3988            0 :  ABI_CHECK_NOSTOP(self%imag_only .eqv. other%imag_only, "Difference found in imag_only", ierr)
    3989            0 :  ABI_CHECK_NOSTOP(self%wr_step == other%wr_step, "Different value found for wr_step", ierr)
    3990            0 :  ABI_CHECK_NOSTOP(self%ieta == other%ieta, "Different value found for zcut.", ierr)
    3991              : 
    3992            0 :  ABI_CHECK_NOSTOP(all(self%ngqpt == other%ngqpt), "Different value found for ngqpt", ierr)
    3993            0 :  ABI_CHECK_NOSTOP(all(self%bstart_ks == other%bstart_ks), "Different value found for bstart_ks", ierr)
    3994            0 :  ABI_CHECK_NOSTOP(all(self%nbcalc_ks == other%nbcalc_ks), "Different value found for bstop_ks", ierr)
    3995            0 :  ABI_CHECK_NOSTOP(all(self%kcalc == other%kcalc), "Different value found for kcalc", ierr)
    3996            0 :  ABI_CHECK_NOSTOP(all(self%kcalc2ibz == other%kcalc2ibz), "Different value found for kcalc2ibz", ierr)
    3997            0 :  ABI_CHECK_NOSTOP(all(self%kTmesh == other%kTmesh), "Different value found for kTmesh", ierr)
    3998            0 :  ABI_CHECK_NOSTOP(all(self%mu_e == other%mu_e), "Different value found for mu_e", ierr)
    3999              : 
    4000            0 :  ABI_CHECK(ierr == 0, "Fatal error in sigmaph_compare, see previous messages!")
    4001              : 
    4002            0 : end subroutine sigmaph_compare
    4003              : !!***
    4004              : 
    4005              : !!****f* m_sigmaph/sigmaph_free
    4006              : !! NAME
    4007              : !!  sigmaph_free
    4008              : !!
    4009              : !! FUNCTION
    4010              : !!  Deallocate dynamic memory
    4011              : !!
    4012              : !! SOURCE
    4013              : 
    4014          131 : subroutine sigmaph_free(self)
    4015              : 
    4016              : !Arguments ------------------------------------
    4017              :  class(sigmaph_t),intent(inout) :: self
    4018              : ! *************************************************************************
    4019              : 
    4020              :  ! integer
    4021          131 :  ABI_SFREE(self%bstart_ks)
    4022          131 :  ABI_SFREE(self%bstop_ks)
    4023          131 :  ABI_SFREE(self%nbcalc_ks)
    4024          131 :  ABI_SFREE(self%kcalc2ibz)
    4025          131 :  ABI_SFREE(self%my_ikcalc)
    4026          131 :  ABI_SFREE(self%my_spins)
    4027          131 :  ABI_SFREE(self%myq2ibz_k)
    4028          131 :  ABI_SFREE(self%itreat_qibz)
    4029          131 :  ABI_SFREE(self%my_pinfo)
    4030          131 :  ABI_SFREE(self%pert_table)
    4031          131 :  ABI_SFREE(self%phmodes_skip)
    4032          131 :  ABI_SFREE(self%ind_qbz2ibz)
    4033          131 :  ABI_SFREE(self%indkk_kq)
    4034          131 :  ABI_SFREE(self%ind_q2dvdb_k)
    4035          131 :  ABI_SFREE(self%ind_ibzk2ibz)
    4036          131 :  ABI_SFREE(self%qibz2dvdb)
    4037          131 :  ABI_SFREE(self%lgk_sym2glob)
    4038          131 :  ABI_SFREE(self%nbsum_rank)
    4039              : 
    4040              :  ! real
    4041          131 :  ABI_SFREE(self%kcalc)
    4042          131 :  ABI_SFREE(self%kTmesh)
    4043          131 :  ABI_SFREE(self%mu_e)
    4044          131 :  ABI_SFREE(self%e0vals)
    4045          131 :  ABI_SFREE(self%vcar_calc)
    4046          131 :  ABI_SFREE(self%linewidth_mrta)
    4047          131 :  ABI_SFREE(self%cweights)
    4048          131 :  ABI_SFREE(self%deltaw_pm)
    4049          131 :  ABI_SFREE(self%wrmesh_b)
    4050          131 :  ABI_SFREE(self%qvers_cart)
    4051          131 :  ABI_SFREE(self%angwgth)
    4052          131 :  ABI_SFREE(self%frohl_deltas_sphcorr)
    4053          131 :  ABI_SFREE(self%qp_done)
    4054          131 :  ABI_SFREE(self%qbz)
    4055          131 :  ABI_SFREE(self%qibz)
    4056          131 :  ABI_SFREE(self%wtq)
    4057          131 :  ABI_SFREE(self%qibz_k)
    4058          131 :  ABI_SFREE(self%wtq_k)
    4059          131 :  ABI_SFREE(self%srate)
    4060          131 :  ABI_SFREE(self%phmesh)
    4061          131 :  ABI_SFREE(self%gf_nnuq)
    4062          131 :  ABI_SFREE(self%scratew)
    4063          131 :  ABI_SFREE(self%E2)
    4064              : 
    4065              :  ! complex
    4066          131 :  ABI_SFREE(self%vals_e0ks)
    4067          131 :  ABI_SFREE(self%fan_vals)
    4068          131 :  ABI_SFREE(self%E4_vals)
    4069          131 :  ABI_SFREE(self%E4_vals2)
    4070          131 :  ABI_SFREE(self%fan_stern_vals)
    4071          131 :  ABI_SFREE(self%dvals_de0ks)
    4072          131 :  ABI_SFREE(self%dw_vals)
    4073          131 :  ABI_SFREE(self%dw_stern_vals)
    4074          131 :  ABI_SFREE(self%vals_wr)
    4075          131 :  ABI_SFREE(self%gfw_vals)
    4076          131 :  ABI_SFREE(self%a2f_emesh)
    4077          131 :  ABI_SFREE(self%a2few)
    4078              : 
    4079              :  ! datatypes.
    4080          131 :  if (allocated(self%degtab)) then
    4081           56 :    call degtab_array_free(self%degtab)
    4082          228 :    ABI_FREE(self%degtab)
    4083              :  end if
    4084              : 
    4085          131 :  call self%ephwg%free()
    4086          131 :  call self%eph_doublegrid%free()
    4087              : 
    4088              :  ! Deallocate MPI communicators
    4089          131 :  call self%pert_comm%free(); call self%qpt_comm%free(); call self%bsum_comm%free()
    4090          131 :  call self%qb_comm%free(); call self%kcalc_comm%free(); call self%spin_comm%free()
    4091          131 :  call self%pqb_comm%free(); call self%ncwrite_comm%free()
    4092              : 
    4093              :  ! Close netcdf file.
    4094          131 :  if (self%ncid /= nctk_noid) then
    4095           60 :    NCF_CHECK(nf90_close(self%ncid))
    4096              :  end if
    4097              : 
    4098          131 : end subroutine sigmaph_free
    4099              : !!***
    4100              : 
    4101              : !!****f* m_sigmaph/sigmaph_setup_kcalc
    4102              : !! NAME
    4103              : !!  sigmaph_setup_kcalc
    4104              : !!
    4105              : !! FUNCTION
    4106              : !!  Prepare calculations of self-energy matrix elements for ikcalc index.
    4107              : !!
    4108              : !! INPUTS
    4109              : !!  dtset<dataset_type>=All input variables for this dataset.
    4110              : !!  cryst<crystal_t> = Crystal structure.
    4111              : !!  dvdb<dbdb_type>=Database with the DFPT SCF potentials.
    4112              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    4113              : !!  ikcalc=Index of the k-point to compute.
    4114              : !!  prtvol= Verbosity level
    4115              : !!  comm= MPI communicator
    4116              : !!
    4117              : !! SOURCE
    4118              : 
    4119          182 : subroutine sigmaph_setup_kcalc(self, dtset, cryst, ebands, ikcalc, prtvol, comm)
    4120              : 
    4121              : !Arguments ------------------------------------
    4122              :  integer,intent(in) :: ikcalc, prtvol, comm
    4123              :  type(dataset_type),intent(in) :: dtset
    4124              :  type(crystal_t),intent(in) :: cryst
    4125              :  class(sigmaph_t),target,intent(inout) :: self
    4126              :  type(ebands_t),intent(in) :: ebands
    4127              : 
    4128              : !Local variables-------------------------------
    4129              :  integer,parameter :: master = 0
    4130              :  integer :: spin, my_rank, iq_ibz, nprocs, qptopt, kptopt !, nbcalc_ks !, bstart_ks
    4131              :  integer :: ikpt, ibz_k, isym_k, itim_k !isym_lgk,
    4132              :  real(dp) :: cpu, wall, gflops
    4133              :  character(len=5000) :: msg
    4134              :  logical :: compute_lgk
    4135          182 :  type(lgroup_t),target :: lgk
    4136              :  type(lgroup_t),pointer :: lgk_ptr
    4137          182 :  type(krank_t) :: krank, qrank
    4138              : !arrays
    4139              :  integer :: qptrlatt(3,3)
    4140          182 :  integer,allocatable :: iqk2dvdb(:,:)
    4141              :  real(dp) :: kk(3)
    4142          182 :  real(dp),allocatable :: kq_list(:,:)
    4143              : ! *************************************************************************
    4144              : 
    4145          182 :  ABI_SFREE(self%qibz_k)
    4146          182 :  ABI_SFREE(self%wtq_k)
    4147              : 
    4148          182 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    4149          728 :  kk = self%kcalc(:, ikcalc)
    4150              : 
    4151          182 :  call wrtout(std_out, sjoin(ch10, repeat("=", 92)))
    4152          182 :  msg = sjoin("[", itoa(ikcalc), "/", itoa(self%nkcalc), "]")
    4153          182 :  call wrtout(std_out, sjoin(" Computing self-energy matrix elements for k-point:", ktoa(kk), msg))
    4154              :  ! TODO Integrate with spin parallelism.
    4155          182 :  spin = 1
    4156          182 :  write(msg, "(3(a, i0))")" Treating ", self%nbcalc_ks(ikcalc, spin), " band(s) in Sigma_nk between: ", &
    4157          364 :    self%bstart_ks(ikcalc, spin)," and: ", self%bstart_ks(ikcalc, spin) + self%nbcalc_ks(ikcalc, spin) - 1
    4158          182 :  call wrtout(std_out, msg)
    4159          182 :  write(msg, "(2(a,i0))")"P Allocating and summing bands from my_bsum_start: ", self%my_bsum_start, &
    4160          364 :      " up to my_bsum_stop: ", self%my_bsum_stop
    4161          182 :  call wrtout(std_out, msg)
    4162          182 :  if (.not. self%imag_only .and. dtset%eph_stern /= 0) then
    4163           34 :    if (dtset%eph_stern ==  1) call wrtout(std_out, " Sternheimer method activated with cache for u1_nk")
    4164           34 :    if (dtset%eph_stern == -1) call wrtout(std_out, " Sternheimer method activated WITHOUT cache for u1_nk!")
    4165              :  end if
    4166              : 
    4167              :  ! Prepare weights for BZ(k) integration
    4168          182 :  if (self%qint_method > 0) then
    4169           81 :    if (self%use_doublegrid) then
    4170           19 :      call self%ephwg%double_grid_setup_kpoint(self%eph_doublegrid, kk, prtvol, comm)
    4171              :    else
    4172           62 :      call self%ephwg%setup_kpoint(kk, prtvol, comm, skip_mapping=.true.)
    4173              :    end if
    4174           81 :    call self%ephwg%report_stats()
    4175              :  endif
    4176              : 
    4177          182 :  call cwtime(cpu, wall, gflops, "start")
    4178              : 
    4179          182 :  if (self%symsigma == 0) then
    4180              :    ! Do not use symmetries in BZ sum_q --> nqibz_k == nqbz
    4181           10 :    self%nqibz_k = self%nqbz
    4182           30 :    ABI_MALLOC(self%qibz_k, (3, self%nqibz_k))
    4183           30 :    ABI_MALLOC(self%wtq_k, (self%nqibz_k))
    4184          420 :    self%qibz_k = self%qbz; self%wtq_k = one / self%nqbz
    4185           10 :    call wrtout(std_out, sjoin(" symsigma = 0 --> Integration done over full BZ with nqbz:", itoa(self%nqibz_k)))
    4186              : 
    4187              :    ! Store little group symmetries (well, just 1)
    4188           10 :    self%lgk_nsym = 1
    4189           30 :    ABI_REMALLOC(self%lgk_sym2glob, (2, self%lgk_nsym))
    4190           30 :    self%lgk_sym2glob(:, 1) = [1, 1]
    4191              : 
    4192          172 :  else if (abs(self%symsigma) == 1) then
    4193              :    ! Use the symmetries of the little group of the k-point
    4194              :    ! Pack points in *shells* to minimise cache misses.
    4195          172 :    compute_lgk = .not. (self%qint_method > 0 .and. .not. self%use_doublegrid)
    4196              :    if (compute_lgk) then
    4197          110 :      call lgk%init(cryst, kk, self%timrev, self%nqbz, self%qbz, self%nqibz, self%qibz, comm)
    4198          110 :      lgk_ptr => lgk
    4199              :    else
    4200              :      ! Avoid this call to lgroup new. Use lgk already computed in self%ephwg
    4201           62 :      lgk_ptr => self%ephwg%lgk
    4202              :    end if
    4203              : 
    4204              :    ! Store little group symmetries.
    4205          172 :    self%lgk_nsym = lgk_ptr%nsym_lg
    4206          516 :    ABI_REMALLOC(self%lgk_sym2glob, (2, self%lgk_nsym))
    4207        37676 :    self%lgk_sym2glob = lgk_ptr%lgsym2glob
    4208              : 
    4209              :    call wrtout(std_out, sjoin(" Number of operations in little group(k):", itoa(lgk_ptr%nsym_lg), &
    4210          172 :      "(including time-reversal symmetry)"))
    4211          172 :    call wrtout(std_out, sjoin(" Number of q-points in the IBZ(k):", itoa(lgk_ptr%nibz)))
    4212              : 
    4213          200 :    if (dtset%prtvol > 0) call lgk_ptr%print([std_out], prtvol=dtset%prtvol)
    4214              : 
    4215              :    ! TODO: Pointers instead of copies to save space?
    4216          172 :    self%nqibz_k = lgk_ptr%nibz
    4217          516 :    ABI_MALLOC(self%qibz_k, (3, self%nqibz_k))
    4218          516 :    ABI_MALLOC(self%wtq_k, (self%nqibz_k))
    4219      1338236 :    self%qibz_k = lgk_ptr%ibz; self%wtq_k = lgk_ptr%weights
    4220              :    !if (compute_lgk) call lgk%free()
    4221              :  else
    4222            0 :    ABI_ERROR(sjoin("Wrong symsigma:", itoa(self%symsigma)))
    4223              :  end if
    4224              : 
    4225          182 :  call cwtime_report(" lgroup_symsigma", cpu, wall, gflops)
    4226              : 
    4227              :  ! TODO: Cleanup
    4228              : 
    4229          182 :  if (self%symsigma == 0) then
    4230              :    ! Find correspondence IBZ_k --> IBZ
    4231           30 :    ABI_MALLOC(iqk2dvdb, (6, self%nqibz_k))
    4232              : 
    4233              :    ! Assume qptopt == kptopt unless value is specified in input
    4234           10 :    qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt
    4235           10 :    qptrlatt = 0; qptrlatt(1,1) = self%ngqpt(1); qptrlatt(2,2) = self%ngqpt(2); qptrlatt(3,3) = self%ngqpt(3)
    4236           10 :    call qrank%from_kptrlatt(self%nqibz, self%qibz, qptrlatt, compute_invrank=.False.)
    4237              : 
    4238           10 :    if (kpts_map("symrec", qptopt, cryst, qrank, self%nqibz_k, self%qibz_k, iqk2dvdb) /= 0) then
    4239              :      write(msg, '(3a)' )&
    4240            0 :        "At least one of the q points in the IBZ_k could not be generated from one in the IBZ.", ch10,&
    4241            0 :        "Action: check your DVDB file and use eph_task to interpolate the potentials on a denser q-mesh."
    4242            0 :      ABI_ERROR(msg)
    4243              :    end if
    4244           10 :    call qrank%free()
    4245              : 
    4246           30 :    ABI_REMALLOC(self%ind_ibzk2ibz, (6, self%nqibz_k))
    4247           90 :    do iq_ibz=1,self%nqibz_k
    4248          570 :      self%ind_ibzk2ibz(:, iq_ibz) = iqk2dvdb(:, iq_ibz)
    4249              :    end do
    4250           10 :    ABI_FREE(iqk2dvdb)
    4251              : 
    4252          172 :  else if (abs(self%symsigma) == 1) then
    4253              : 
    4254              :    ! IBZ_k --> BZ --> IBZ
    4255          516 :    ABI_REMALLOC(self%ind_ibzk2ibz, (6, self%nqibz_k))
    4256       936576 :    self%ind_ibzk2ibz = 0
    4257       480572 :    do ikpt=1,self%nqbz
    4258       480400 :      ibz_k    = lgk_ptr%bz2ibz_smap(1,ikpt)
    4259              :      !isym_lgk = lgk_ptr%bz2ibz_smap(2,ikpt)
    4260              :      !isym_k   = lgk_ptr%lgsym2glob(1,isym_lgk)
    4261              :      !itim_k   = lgk_ptr%lgsym2glob(2,isym_lgk)
    4262       480400 :      isym_k   = lgk_ptr%bz2ibz_smap(2,ikpt)
    4263       480400 :      itim_k   = lgk_ptr%bz2ibz_smap(3,ikpt)
    4264              :      ! I assume that isym=1 and itim_k=0 is identity but still verify the kpoint
    4265      1664913 :      if (isym_k /= 1 .or. itim_k /= 1 .or. any(lgk_ptr%bz2ibz_smap(4:,ikpt) /= 0)) cycle
    4266              :      ! check IBZ_k --> BZ
    4267       535088 :      ABI_CHECK(sum(abs(self%qbz(:,ikpt) - self%qibz_k(:,ibz_k))) < tol8, 'Wrong mapping')
    4268              :      ! IBZ_k --> IBZ
    4269              :      !self%ind_ibzk2ibz(:, ibz_k) = self%ind_qbz2ibz(:,ikpt)
    4270       133772 :      self%ind_ibzk2ibz(1, ibz_k) = self%ind_qbz2ibz(1, ikpt)
    4271       133772 :      self%ind_ibzk2ibz(2, ibz_k) = self%ind_qbz2ibz(2, ikpt)
    4272       133772 :      self%ind_ibzk2ibz(6, ibz_k) = self%ind_qbz2ibz(3, ikpt)
    4273       881888 :      self%ind_ibzk2ibz(3:5, ibz_k) = self%ind_qbz2ibz(4:6, ikpt)
    4274              :    end do
    4275       133944 :    do ikpt=1,self%nqibz_k
    4276       133944 :      ABI_CHECK(self%ind_ibzk2ibz(1, ikpt) /= 0, 'Did not find mapping')
    4277              :    end do
    4278          172 :    if (compute_lgk) call lgk%free()
    4279              :  else
    4280            0 :    ABI_ERROR(sjoin("Wrong symsigma:", itoa(self%symsigma)))
    4281              :  endif
    4282              : 
    4283          182 :  call cwtime_report(" IBZ_k --> IBZ", cpu, wall, gflops)
    4284              : 
    4285          182 :  if (.not. self%need_ftinterp) then
    4286              :    ! Find correspondence IBZ_k --> set of q-points in DVDB.
    4287              :    ! Need to handle q_bz = S q_ibz by symmetrizing the potentials already available in the DVDB.
    4288              :    !
    4289              :    ! Note:
    4290              :    !   q --> -q symmetry is always used for phonons.
    4291              :    !   we use symrec instead of symrel (see also m_dvdb)
    4292              :    ! IBZ_K -> BZ -> IBZ -> DVDB
    4293          315 :    ABI_REMALLOC(self%ind_q2dvdb_k, (6, self%nqibz_k))
    4294        10843 :    self%ind_q2dvdb_k = self%ind_ibzk2ibz
    4295         1624 :    do ikpt=1,self%nqibz_k
    4296         1624 :      self%ind_q2dvdb_k(1, ikpt) = self%qibz2dvdb(self%ind_ibzk2ibz(1, ikpt))
    4297              :    end do
    4298          105 :    call cwtime_report(" IBZ_k --> DVDB", cpu, wall, gflops)
    4299              :  end if
    4300              : 
    4301              :  ! Find k+q in the extended zone and extract symmetry info.
    4302              :  ! Be careful here because there are two umklapp vectors to be considered:
    4303              :  !
    4304              :  !   k + q = k_bz + g0_bz = IS(k_ibz) + g0_ibz + g0_bz
    4305              :  !
    4306              :  ! Note symrel and use_symrec=.False. in get_mapping.
    4307              :  ! This means that this table can be used to symmetrize wavefunctions in cgtk_rotate.
    4308              :  !
    4309          546 :  ABI_MALLOC(kq_list, (3, self%nqibz_k))
    4310       134034 :  do iq_ibz=1,self%nqibz_k
    4311       535590 :    kq_list(:, iq_ibz) = kk + self%qibz_k(:,iq_ibz)
    4312              :  end do
    4313              : 
    4314              :  ! Use iqk2dvdb as workspace array.
    4315          546 :  ABI_MALLOC(iqk2dvdb, (6, self%nqibz_k))
    4316              : 
    4317          182 :  call krank%from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.)
    4318              : 
    4319          182 :  if (self%timrev == 1) then
    4320          182 :    kptopt=1
    4321              :  else
    4322            0 :    kptopt=4
    4323              :  end if
    4324              : 
    4325          182 :  if (kpts_map("symrel", kptopt, cryst, krank, self%nqibz_k, kq_list, iqk2dvdb) /= 0) then
    4326              :    write(msg, '(11a)' )&
    4327            0 :     "The WFK file cannot be used to compute self-energy corrections at k: ", trim(ktoa(kk)), ch10,&
    4328            0 :     "At least one of the k+q points could not be generated from a symmetrical one.", ch10,&
    4329            0 :     "Q-mesh: ",trim(ltoa(self%ngqpt)),", K-mesh (from kptrlatt) ",trim(ltoa(get_diag(dtset%kptrlatt))),ch10, &
    4330            0 :     "Action: check your WFK file and the k/q point input variables."
    4331            0 :    ABI_ERROR(msg)
    4332              :  end if
    4333              : 
    4334          182 :  call krank%free()
    4335              : 
    4336          182 :  ABI_FREE(kq_list)
    4337              : 
    4338          546 :  ABI_REMALLOC(self%indkk_kq, (6, self%nqibz_k))
    4339       134034 :  do iq_ibz=1,self%nqibz_k
    4340       937146 :    self%indkk_kq(:, iq_ibz) = iqk2dvdb(:,iq_ibz)
    4341              :  end do
    4342          182 :  ABI_FREE(iqk2dvdb)
    4343              : 
    4344          182 :  call cwtime_report(" k+q --> ebands", cpu, wall, gflops)
    4345              : 
    4346          182 :  if (self%qint_method > 0 .and. .not. self%use_doublegrid) then
    4347          186 :    ABI_REMALLOC(self%ephwg%lgk2ibz, (self%nqibz_k))
    4348       122483 :    self%ephwg%lgk2ibz = self%ind_ibzk2ibz(1, :)
    4349          186 :    ABI_REMALLOC(self%ephwg%kq2ibz, (self%nqibz_k))
    4350       122483 :    self%ephwg%kq2ibz = self%indkk_kq(1, :)
    4351              :  end if
    4352              : 
    4353          910 : end subroutine sigmaph_setup_kcalc
    4354              : !!***
    4355              : 
    4356              : !!****f* m_sigmaph/sigmaph_setup_qloop
    4357              : !! NAME
    4358              : !!  sigmaph_setup_qloop
    4359              : !!
    4360              : !! FUNCTION
    4361              : !!  Prepare integration of self-energy matrix in q-space for given (spin, ikcalc)
    4362              : !!  Distribute q-points and precompute weights if tetrahedron method and imag_only
    4363              : !!
    4364              : !! INPUTS
    4365              : !!  dtset<dataset_type>=All input variables for this dataset.
    4366              : !!  cryst<crystal_t> = Crystal structure.
    4367              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    4368              : !!  dvdb<dbdb_type>=Database with the DFPT SCF potentials.
    4369              : !!  spin: spin index.
    4370              : !!  ikcalc=Index of the k-point to compute.
    4371              : !!  comm= MPI communicator
    4372              : !!
    4373              : !! SOURCE
    4374              : 
    4375          182 : subroutine sigmaph_setup_qloop(self, dtset, cryst, ebands, dvdb, spin, ikcalc, comm)
    4376              : 
    4377              : !Arguments ------------------------------------
    4378              :  integer,intent(in) :: spin, ikcalc, comm
    4379              :  type(dataset_type),intent(in) :: dtset
    4380              :  type(crystal_t),intent(in) :: cryst
    4381              :  class(sigmaph_t),intent(inout) :: self
    4382              :  type(ebands_t),intent(in) :: ebands
    4383              :  type(dvdb_t),intent(inout) :: dvdb
    4384              : 
    4385              : !Local variables-------------------------------
    4386              :  integer,parameter :: master = 0
    4387              :  integer :: my_rank, iq_ibz_k, iq_ibz, ierr, nprocs, imyq, iq_dvdb, ii, cnt, itreat, iq, nqeff, ndiv
    4388              :  integer :: min_nqibz_k, max_nqibz_k
    4389              :  real(dp) :: cpu, wall, gflops, efact_min, efact_max
    4390              :  logical :: qfilter
    4391              :  character(len=5000) :: msg
    4392              : !arrays
    4393          182 :  integer,allocatable :: mask_qibz_k(:), imask(:), qtab(:), ineed_qibz(:), ineed_qdvdb(:)
    4394              : ! *************************************************************************
    4395              : 
    4396          182 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    4397              : 
    4398          182 :  msg = "Standard quadrature"; if (self%qint_method == 1) msg = "tetrahedron method"
    4399          182 :  call wrtout(std_out, sjoin(" Preparing q-loop with integration method:", msg))
    4400          182 :  call cwtime(cpu, wall, gflops, "start")
    4401              : 
    4402          252 :  select case (dtset%eph_task)
    4403              :  case (4)
    4404              :    ! Computation of re-im
    4405           70 :    call distribute_nqibz_k_nofilter()
    4406           70 :    if (self%qint_method == 1) call sigmaph_get_all_qweights(self, cryst, ebands, spin, ikcalc, comm)
    4407              : 
    4408              :  case (-4)
    4409              :    ! Computation of imaginary part
    4410          112 :    if (self%qint_method == 0) then
    4411           37 :      call distribute_nqibz_k_nofilter()
    4412              : 
    4413           75 :    else if (self%qint_method == 1) then
    4414              :      ! Imag with tetra --> Precompute weights in IBZ_k.
    4415           75 :      call distribute_nqibz_k_nofilter()
    4416           75 :      call sigmaph_get_all_qweights(self, cryst, ebands, spin, ikcalc, comm)
    4417              : 
    4418           75 :      qfilter = any(dtset%eph_tols_idelta >= zero)
    4419              : 
    4420           75 :      if (qfilter) then
    4421              :        ! Two-pass algorithm:
    4422              :        ! Select q-points with significant contribution, recompute my_nqibz_k and myq2ibz_k.
    4423              :        ! Finally, recompute integration weights with new distribution.
    4424              :        ! NB: the two-pass algorithm could be replaced by a decimation algo and a single call to the tetrahedron routines
    4425              :        ! %deltaw_pm(2, nbcalc_ks, my_npert, bsum_start:bsum_stop, my_nqibz_k, ndiv)
    4426           75 :        ndiv = 1; if (self%use_doublegrid) ndiv = self%eph_doublegrid%ndiv
    4427       132880 :        ABI_ICALLOC(mask_qibz_k, (self%nqibz_k))
    4428       132730 :        do imyq=1,self%my_nqibz_k
    4429       132655 :          iq_ibz_k = self%myq2ibz_k(imyq)
    4430      5476061 :          if (any(abs(self%deltaw_pm(1,:,:,:,imyq,:)) >= dtset%eph_tols_idelta(1) / ndiv)) mask_qibz_k(iq_ibz_k) = 1
    4431      5521355 :          if (any(abs(self%deltaw_pm(2,:,:,:,imyq,:)) >= dtset%eph_tols_idelta(2) / ndiv)) mask_qibz_k(iq_ibz_k) = 1
    4432              :        end do
    4433              : 
    4434              :        ! Take max inside comm.
    4435           75 :        call alloc_copy(mask_qibz_k, imask)
    4436           75 :        call xmpi_max(imask, mask_qibz_k, comm, ierr)
    4437           75 :        ABI_FREE(imask)
    4438              : 
    4439              :        ! Find all qpts in the IBZ_k contributing to Im(Sigma).
    4440          225 :        ABI_MALLOC(qtab, (self%nqibz_k))
    4441           75 :        nqeff = 0
    4442       132730 :        do iq_ibz_k=1,self%nqibz_k
    4443       132730 :          if (mask_qibz_k(iq_ibz_k) == 1) then
    4444        13275 :            nqeff = nqeff + 1; qtab(nqeff) = iq_ibz_k
    4445              :          end if
    4446              :        end do
    4447           75 :        ABI_FREE(mask_qibz_k)
    4448              : 
    4449           75 :        if (my_rank == master) then
    4450              :          !write(std_out, "(a, 2(es16.6,1x))")" Removing q-points with integration weights < ", dtset%eph_tols_idelta / ndiv
    4451           75 :          write(std_out, "(a,i0,a,f5.1,a)")" Total number of q-points contributing to Im(Sigma(eKS)): ", nqeff, &
    4452          150 :            " (nqeff / nqibz_k): ", (100.0_dp * nqeff) / self%nqibz_k, " [%]"
    4453              :        end if
    4454              : 
    4455              :        ! Redistribute relevant q-points inside qpt_comm taking into account itreat_qibz
    4456              :        ! Must handle two cases: potentials from DVDB or Fourier-interpolated.
    4457           75 :        if (self%need_ftinterp) then
    4458        14222 :          ABI_ICALLOC(ineed_qibz, (self%nqibz))
    4459              :        else
    4460          431 :          ABI_ICALLOC(ineed_qdvdb, (dvdb%nqpt))
    4461              :        end if
    4462              : 
    4463           75 :        self%my_nqibz_k = 0
    4464          225 :        do ii=1,2
    4465          150 :          if (ii == 2) then
    4466          225 :            ABI_REMALLOC(self%myq2ibz_k, (self%my_nqibz_k))
    4467              :          end if
    4468          150 :          cnt = 0
    4469        26775 :          do iq=1,nqeff
    4470        26550 :            iq_ibz_k = qtab(iq)
    4471        26550 :            iq_ibz = self%ind_ibzk2ibz(1, iq_ibz_k)
    4472        26550 :            itreat = int(self%itreat_qibz(iq_ibz), kind=i4b)
    4473              :            if (.not. self%need_ftinterp) iq_dvdb = self%ind_q2dvdb_k(1, iq_ibz_k)
    4474        26700 :            if (itreat /= 0) then
    4475        26550 :              if (ii == 1) self%my_nqibz_k = self%my_nqibz_k + 1
    4476        26550 :              if (ii == 2) then
    4477        13275 :                cnt = cnt + 1
    4478        13275 :                self%myq2ibz_k(cnt) = qtab(iq)
    4479              :              end if
    4480              :            end if
    4481              :          end do
    4482              :        end do
    4483           75 :        ABI_FREE(qtab)
    4484              : 
    4485              :        ! Recompute weights with new q-point distribution.
    4486           75 :        call sigmaph_get_all_qweights(self, cryst, ebands, spin, ikcalc, comm)
    4487              : 
    4488           75 :        call xmpi_min(self%my_nqibz_k, min_nqibz_k, self%qpt_comm%value, ierr)
    4489           75 :        call xmpi_max(self%my_nqibz_k, max_nqibz_k, self%qpt_comm%value, ierr)
    4490              :        !efact = (one * self%my_nqibz_k * self%qpt_comm%nproc) / nqeff
    4491           75 :        efact_min = (one * min_nqibz_k * self%qpt_comm%nproc) / nqeff
    4492           75 :        efact_max = (one * max_nqibz_k * self%qpt_comm%nproc) / nqeff
    4493              :        write(msg, "(2(a,i0,a),a,2(f7.3,1x),a)") &
    4494           75 :         " Number of q-points in the IBZ(k) treated by this MPI proc: ", self%my_nqibz_k, ch10, &
    4495           75 :         " Number of MPI procs in qpt_comm: ", self%qpt_comm%nproc, ch10, &
    4496          150 :         " Load balance inside qpt_comm ranges between: [",  efact_min, efact_max, "] (should be ~1)"
    4497           75 :        call wrtout(std_out, msg)
    4498           75 :        ABI_WARNING_IF(self%my_nqibz_k == 0, "my_nqibz_k == 0")
    4499              : 
    4500           75 :        ABI_SFREE(ineed_qibz)
    4501          225 :        ABI_SFREE(ineed_qdvdb)
    4502              :      end if ! qfilter
    4503              : 
    4504              :    else
    4505            0 :      ABI_ERROR(sjoin("Invalid eph_intmeth:", itoa(self%qint_method)))
    4506              :    end if ! intmeth
    4507              : 
    4508          112 :    if (dtset%ibte_prep > 0) then
    4509              :      ! Allocate array with scattering rate for IBTE.
    4510        64303 :      ABI_RECALLOC(self%srate, (self%bsum_start:self%bsum_stop, self%nbcalc_ks(ikcalc, spin), self%ntemp, self%my_nqibz_k))
    4511        64273 :      self%srate = zero
    4512              :    end if
    4513              : 
    4514              :  case default
    4515          182 :    ABI_ERROR(sjoin("Invalid eph_task:", itoa(dtset%eph_task)))
    4516              :  end select
    4517              : 
    4518          182 :  call cwtime_report(" Setup qloop", cpu, wall, gflops)
    4519              : 
    4520              : contains
    4521              : 
    4522          182 : subroutine distribute_nqibz_k_nofilter()
    4523              :   ! Find number of q-points in IBZ(k) treated by this MPI rank
    4524              :   ! taking into account itreat_qibz and build redirection table myq2ibz_k.
    4525              :   ! The distribution must be consistent with the WF distribution done with bks_mask
    4526              : 
    4527          182 :   self%my_nqibz_k = 0
    4528          546 :   do ii=1,2
    4529          364 :     if (ii == 2) then
    4530          546 :       ABI_REMALLOC(self%myq2ibz_k, (self%my_nqibz_k))
    4531              :     end if
    4532          364 :     cnt = 0
    4533       268250 :     do iq_ibz_k=1,self%nqibz_k
    4534       267704 :       iq_ibz = self%ind_ibzk2ibz(1, iq_ibz_k)
    4535       267704 :       if (self%itreat_qibz(iq_ibz) == 0) cycle
    4536       267704 :       if (ii == 1) self%my_nqibz_k = self%my_nqibz_k + 1
    4537       268068 :       if (ii == 2) then
    4538       133852 :         cnt = cnt + 1
    4539       133852 :         self%myq2ibz_k(cnt) = iq_ibz_k
    4540              :       end if
    4541              :     end do
    4542              :   end do
    4543              : 
    4544          182 : end subroutine distribute_nqibz_k_nofilter
    4545              : 
    4546              : end subroutine sigmaph_setup_qloop
    4547              : !!***
    4548              : 
    4549              : !!****f* m_sigmaph/sigmaph_gather_and_write
    4550              : !! NAME
    4551              : !!  sigmaph_gather_and_write
    4552              : !!
    4553              : !! FUNCTION
    4554              : !!  Gather results from the MPI processes. Then master rank does:
    4555              : !!
    4556              : !!      1. Computes QP energies, Z factor and spectral function (if required).
    4557              : !!      2. Saves results to file.
    4558              : !!
    4559              : !! INPUTS
    4560              : !!  ebands<ebands_t>=KS band energies.
    4561              : !!  ikcalc=Index of the computed k-point
    4562              : !!  spin=Spin index.
    4563              : !!  comm=MPI communicator.
    4564              : !!
    4565              : !! SOURCE
    4566              : 
    4567          182 : subroutine sigmaph_gather_and_write(self, dtset, ebands, ikcalc, spin, comm)
    4568              : 
    4569              : !Arguments ------------------------------------
    4570              :  type(dataset_type),intent(in) :: dtset
    4571              :  integer,intent(in) :: ikcalc, spin, comm
    4572              :  class(sigmaph_t),target,intent(inout) :: self
    4573              :  type(ebands_t),intent(in) :: ebands
    4574              : 
    4575              : !Local variables-------------------------------
    4576              :  integer,parameter :: master = 0, max_ntemp = 50
    4577              :  integer :: ideg,ib,it,ii,iw,nstates,ierr,my_rank,band_ks,ik_ibz,ibc,ib_val,ib_cond,jj
    4578              :  integer :: nq_ibzk_eff, nelem, imyq, iq_ibz_k, sr_ncid
    4579              :  logical :: iwrite
    4580              :  real(dp) :: ravg,kse,kse_prev,dw,fan0,ks_gap,kse_val,kse_cond,qpe_oms,qpe_oms_val,qpe_oms_cond
    4581              :  real(dp) :: cpu, wall, gflops, invsig2fmts, tau, ravg2
    4582              :  complex(dp) :: sig0c,zc,qpe,qpe_prev,qpe_val,qpe_cond,cavg1,cavg2,cavg3,cavg4,cavg5,cavg6
    4583              :  !character(len=5000) :: msg
    4584              :  integer :: grp_ncid, ncerr
    4585              : !arrays
    4586          182 :  integer, allocatable :: recvcounts(:), displs(:), nq_rank(:), kq_symtab(:,:), my_kq_symtab(:,:)
    4587          182 :  integer, contiguous, pointer :: bids(:)
    4588          364 :  real(dp) :: qp_gaps(self%ntemp),qpoms_gaps(self%ntemp)
    4589          182 :  real(dp),allocatable :: aw(:,:,:), a2few_avg(:,:), gather_srate(:,:,:,:), grp_srate(:,:,:,:)
    4590          546 :  real(dp) :: ks_enes(self%max_nbcalc), ze0_vals(self%ntemp, self%max_nbcalc)
    4591          364 :  real(dp) :: gfw_avg(self%phmesh_size, 3)
    4592          364 :  complex(dp) :: qpoms_enes(self%ntemp, self%max_nbcalc),qp_enes(self%ntemp, self%max_nbcalc)
    4593              : ! *************************************************************************
    4594              : 
    4595              :  ! Could use non-blocking communications and double buffer technique to reduce synchronisation cost...
    4596          182 :  call cwtime(cpu, wall, gflops, "start", msg=" Gathering results. Waiting for other MPI processes...")
    4597              : 
    4598              :  ! Here comm corresponds to sigma%pqb_comm%value
    4599          182 :  my_rank = xmpi_comm_rank(comm)
    4600          182 :  iwrite = self%ncwrite_comm%value /= xmpi_comm_null
    4601          182 :  call xmpi_sum_master(self%vals_e0ks, master, comm, ierr)
    4602          182 :  call xmpi_sum_master(self%fan_vals, master, comm, ierr)
    4603          182 :  call xmpi_sum_master(self%E4_vals, master, comm, ierr)
    4604          182 :  call xmpi_sum_master(self%E4_vals2, master, comm, ierr)
    4605          182 :  call xmpi_sum_master(self%fan_stern_vals, master, comm, ierr)
    4606          182 :  call xmpi_sum_master(self%dvals_de0ks, master, comm, ierr)
    4607          182 :  call xmpi_sum_master(self%dw_vals, master, comm, ierr)
    4608          182 :  call xmpi_sum_master(self%dw_stern_vals, master, comm, ierr)
    4609          182 :  if (self%nwr > 0) call xmpi_sum_master(self%vals_wr, master, comm, ierr)
    4610          182 :  if (self%mrta > 0) call xmpi_sum_master(self%linewidth_mrta, master, comm, ierr)
    4611          182 :  if (dtset%eph_prtscratew == 1) then
    4612              :    ! Collect spectral decomposition of scattering rates, multiply by two since so far we have stored Imag(Sigma) (ph_w)
    4613            3 :    call xmpi_sum_master(self%scratew, master, comm, ierr)
    4614        90999 :    self%scratew = two * self%scratew
    4615              :  end if
    4616              : 
    4617          182 :  if (dtset%ibte_prep > 0) then
    4618              :    ! FIXME: Handle kpoint/spin parallelism.
    4619              :    ! (%bsum_start:%bsum_stop, %nbcalc_ks(ikcalc, spin), %ntemp, %nqibz_k))
    4620              :    ! Sum over phonon modes
    4621            6 :    call xmpi_sum(self%srate, self%pert_comm%value, ierr)
    4622              :    !call xmpi_sum(self%srate, self%pb_comm%value), ierr)
    4623              : 
    4624              :    ! Use gatherv to collect data and tables on the IO proc i.e. the master proc in qpt_comm.
    4625              :    ! Only the number of q-points changes across the qpt-procs and this is the last dimension.
    4626              :    ! nq_ibzk_eff is the total number of effective q-points in the IBZ(k).
    4627           24 :    ABI_CALLOC(nq_rank, (self%qpt_comm%nproc))
    4628            6 :    call xmpi_allgather(self%my_nqibz_k, nq_rank, self%qpt_comm%value, ierr)
    4629              : 
    4630           12 :    nq_ibzk_eff = sum(nq_rank)
    4631            6 :    nelem = self%nbsum * self%nbcalc_ks(ikcalc, spin) * self%ntemp
    4632              :    !call self%qpt_comm%prep_gatherv(nelem, nq_rank, recvcounts, displs)
    4633           18 :    ABI_MALLOC(recvcounts, (self%qpt_comm%nproc))
    4634           12 :    ABI_MALLOC(displs, (self%qpt_comm%nproc))
    4635              : 
    4636           18 :    recvcounts = nelem * nq_rank(:)
    4637            6 :    displs(1) = 0
    4638            6 :    do ii=2,self%qpt_comm%nproc
    4639            6 :      displs(ii) = sum(nq_rank(1:ii-1)) * nelem
    4640              :    end do
    4641              : 
    4642           36 :    ABI_MALLOC(gather_srate, (self%bsum_start:self%bsum_stop, self%nbcalc_ks(ikcalc, spin), self%ntemp, nq_ibzk_eff))
    4643              : 
    4644            6 :    call xmpi_gatherv(self%srate, nelem * self%my_nqibz_k, gather_srate, recvcounts, displs, master, self%qpt_comm%value, ierr)
    4645              :    !ABI_CHECK(all(abs(gather_srate - self%srate) < tol12), "This only if nproc == 1")
    4646              :    !ABI_CHECK(nq_ibzk_eff == self%my_nqibz_k, "This only if nproc == 1")
    4647              : 
    4648            6 :    if (.not. iwrite) then
    4649            0 :      ABI_FREE(gather_srate)
    4650              :    end if
    4651              : 
    4652           18 :    ABI_MALLOC(my_kq_symtab, (6, self%my_nqibz_k))
    4653         9187 :    do imyq=1,self%my_nqibz_k
    4654         9181 :      iq_ibz_k = self%myq2ibz_k(imyq)
    4655        64273 :      my_kq_symtab(:, imyq) = self%indkk_kq(:, iq_ibz_k)
    4656              :    end do
    4657              : 
    4658              :    !call self%qpt_comm%prep_gatherv(nelem, nq_rank, recvcounts, displs)
    4659            6 :    displs(1) = 0; nelem = 6
    4660            6 :    do ii=2,self%qpt_comm%nproc
    4661            6 :      displs(ii) = sum(nq_rank(1:ii-1)) * nelem
    4662              :    end do
    4663           18 :    recvcounts = nq_rank * nelem
    4664              : 
    4665           18 :    ABI_MALLOC(kq_symtab, (nelem, nq_ibzk_eff))
    4666            6 :    call xmpi_gatherv(my_kq_symtab, nelem * self%my_nqibz_k, kq_symtab, recvcounts, displs, master, self%qpt_comm%value, ierr)
    4667              :    !ABI_CHECK(all(abs(kq_symtab - my_kq_symtab) < tol12), "kq_symtab")
    4668              : 
    4669            6 :    if (.not. iwrite) then
    4670            0 :      ABI_FREE(kq_symtab)
    4671              :    end if
    4672              : 
    4673            6 :    ABI_FREE(nq_rank)
    4674            6 :    ABI_FREE(my_kq_symtab)
    4675            6 :    ABI_FREE(recvcounts)
    4676           18 :    ABI_FREE(displs)
    4677              :  end if
    4678              : 
    4679          182 :  call cwtime_report(" Sigma_nk gather", cpu, wall, gflops, comm=comm)
    4680              : 
    4681              :  ! Only procs inside ncwrite_comm perform IO (ab_out and ncid)
    4682          182 :  if (.not. iwrite) return
    4683              : 
    4684          182 :  ik_ibz = self%kcalc2ibz(ikcalc, 1)
    4685              : 
    4686          182 :  if (self%a2f_ne > 0) then
    4687            0 :    ABI_MALLOC(a2few_avg, (self%a2f_ne, self%phmesh_size))
    4688              :  end if
    4689              : 
    4690          182 :  if (self%symsigma == +1) then
    4691              :    ! Average self-energy matrix elements in the degenerate subspace.
    4692          630 :    do ideg=1,size(self%degtab(ikcalc, spin)%bids)
    4693          458 :      bids => self%degtab(ikcalc, spin)%bids(ideg)%vals
    4694          458 :      nstates = size(bids)
    4695              : 
    4696              :      ! Symmetrize Eliashberg function
    4697          458 :      if (dtset%prteliash > 0) then
    4698      1603855 :        gfw_avg = sum(self%gfw_vals(:, :, bids(:)), dim=3) / nstates
    4699          463 :        do ii=1,nstates
    4700       993697 :          self%gfw_vals(:, :, bids(ii)) = gfw_avg
    4701              :        end do
    4702          175 :        if (self%a2f_ne > 0) then
    4703            0 :           a2few_avg = sum(self%a2few(:, :, bids(:)), dim=3) / nstates
    4704            0 :           do ii=1,nstates
    4705            0 :             self%a2few(:, :, bids(ii)) = a2few_avg
    4706              :           end do
    4707              :        end if
    4708              :      end if
    4709              : 
    4710         2066 :      do it=1,self%ntemp
    4711              :        ! Average QP(T) and Z(T).
    4712         3708 :        cavg1 = sum(self%vals_e0ks(it, bids(:))) / nstates
    4713         3708 :        cavg2 = sum(self%dvals_de0ks(it, bids(:))) / nstates
    4714         3708 :        cavg3 = sum(self%fan_vals(it, bids(:))) / nstates
    4715         3708 :        cavg4 = sum(self%fan_stern_vals(it, bids(:))) / nstates
    4716         3708 :        cavg5 = sum(self%E4_vals(it, bids(:))) / nstates
    4717         3708 :        cavg6 = sum(self%E4_vals2(it, bids(:))) / nstates
    4718         3708 :        ravg = sum(self%dw_vals(it, bids(:))) / nstates
    4719         3708 :        ravg2 = sum(self%dw_stern_vals(it, bids(:))) / nstates
    4720         3708 :        do ii=1,nstates
    4721         2272 :          self%vals_e0ks(it, bids(ii)) = cavg1
    4722         2272 :          self%dvals_de0ks(it, bids(ii)) = cavg2
    4723         2272 :          self%fan_vals(it, bids(ii)) = cavg3
    4724         2272 :          self%fan_stern_vals(it, bids(ii)) = cavg4
    4725         2272 :          self%E4_vals(it, bids(ii)) = cavg5
    4726         2272 :          self%E4_vals2(it, bids(ii)) = cavg6
    4727         2272 :          self%dw_vals(it, bids(ii)) = ravg
    4728         3708 :          self%dw_stern_vals(it, bids(ii)) = ravg2
    4729              :        end do
    4730              : 
    4731              :        ! Average TAU_MRTA
    4732         1436 :        if (self%mrta > 0) then
    4733         1958 :          ravg = sum(self%linewidth_mrta(it, bids(:))) / nstates
    4734         1958 :          do ii=1,nstates
    4735         1958 :            self%linewidth_mrta(it, bids(ii)) = ravg
    4736              :          end do
    4737              :        end if
    4738              : 
    4739         1894 :        if (self%nwr > 0) then
    4740              :          ! Average Sigma(omega, T)
    4741        60964 :          do iw=1,self%nwr
    4742       158541 :            cavg1 = sum(self%vals_wr(iw, it, bids(:))) / nstates
    4743       159064 :            do ii=1,nstates
    4744       158541 :              self%vals_wr(iw, it, bids(ii)) = cavg1
    4745              :            end do
    4746              :          end do ! iw
    4747              :        end if
    4748              : 
    4749              :      end do ! it
    4750              :    end do ! ideg
    4751              :  end if ! symsigma == +1
    4752              : 
    4753          182 :  ABI_SFREE(a2few_avg)
    4754              : 
    4755              :  ! Compute QP energies and Gaps (Note that I'm assuming a non-magnetic semiconductor!)
    4756          182 :  ib_val = nint(ebands%nelect / (two / ebands%nspinor)); ib_cond = ib_val + 1
    4757          182 :  kse_val = huge(one) * tol6; kse_cond = huge(one) * tol6
    4758         7098 :  qp_enes = huge(one) * tol6; qpoms_enes = huge(one) * tol6
    4759         4510 :  ks_enes = huge(one) * tol6; ze0_vals = huge(one) * tol6
    4760         1352 :  ks_gap = -one; qpoms_gaps = -one; qp_gaps = -one
    4761              : 
    4762              :  ! Write legend.
    4763          182 :  if (ikcalc == 1 .and. spin == 1) then
    4764           58 :    write(ab_out,"(a)")repeat("=", 80)
    4765           58 :    write(ab_out,"(a)")" Final results in eV."
    4766           58 :    write(ab_out,"(a)")" Notations:"
    4767           58 :    write(ab_out,"(a)")"     eKS: Kohn-Sham energy. eQP: quasi-particle energy."
    4768           58 :    write(ab_out,"(a)")"     eQP - eKS: Difference between the QP and the KS energy."
    4769           58 :    write(ab_out,"(a)")"     SE1(eKS): Real part of the self-energy computed at the KS energy, SE2 for imaginary part."
    4770           58 :    write(ab_out,"(a)")"     Z(eKS): Renormalization factor."
    4771           58 :    write(ab_out,"(a)")"     FAN: Real part of the Fan term at eKS. DW: Debye-Waller term."
    4772           58 :    write(ab_out,"(a)")"     DeKS: KS energy difference between this band and band-1, DeQP same meaning but for eQP."
    4773           58 :    write(ab_out,"(a)")"     OTMS: On-the-mass-shell approximation with eQP ~= eKS + Sigma(omega=eKS)"
    4774           58 :    write(ab_out,"(a)")"     TAU(eKS): Lifetime in femtoseconds computed at the KS energy."
    4775           58 :    write(ab_out,"(a)")"     mu_e: Fermi level for given (T, nelect)"
    4776           58 :    write(ab_out,"(a)")" "
    4777           58 :    write(ab_out,"(a)")" "
    4778              :  end if
    4779              : 
    4780          767 :  do it=1,self%ntemp
    4781              : 
    4782              :    ! Write header.
    4783          585 :    if (it <= max_ntemp) then
    4784          585 :      if (self%nsppol == 1) then
    4785              :        write(ab_out,"(3a,f6.1,a,f8.3)") &
    4786          585 :          "K-point: ", trim(ktoa(self%kcalc(:,ikcalc))), ", T: ", self%kTmesh(it) / kb_HaK, &
    4787         1170 :          " [K], mu_e: ", self%mu_e(it) * Ha_eV
    4788              :      else
    4789              :        write(ab_out,"(3a,i1,a,f6.1,a,f8.3)") &
    4790            0 :          "K-point: ", trim(ktoa(self%kcalc(:,ikcalc))), ", spin: ", spin, ", T: ",self%kTmesh(it) / kb_HaK, &
    4791            0 :          " [K], mu_e: ", self%mu_e(it) * Ha_eV
    4792              :      end if
    4793          585 :      if (self%imag_only) then
    4794          387 :        write(ab_out,"(a)")"   B    eKS    SE2(eKS)  TAU(eKS)  DeKS"
    4795              :      else
    4796          198 :        write(ab_out,"(a)")"   B    eKS     eQP    eQP-eKS   SE1(eKS)  SE2(eKS)  Z(eKS)  FAN(eKS)   DW      DeKS     DeQP"
    4797              :      end if
    4798              :    end if
    4799              : 
    4800              :    ! Loop over bands for this k-point and spin
    4801         3033 :    do ibc=1,self%nbcalc_ks(ikcalc, spin)
    4802         2448 :      band_ks = self%bstart_ks(ikcalc, spin) + ibc - 1
    4803         2448 :      kse = ebands%eig(band_ks, ik_ibz, spin)
    4804         2448 :      ks_enes(ibc) = kse
    4805         2448 :      sig0c = self%vals_e0ks(it, ibc)
    4806         2448 :      dw = self%dw_vals(it, ibc)
    4807         2448 :      fan0 = real(sig0c) - dw
    4808              :      ! Compute QP energies with On-the-Mass-Shell approximation and first renormalization i.e. Z(eKS)
    4809              :      ! TODO: Note that here I use the full Sigma including the imaginary part
    4810              :      !zc = one / (one - self%dvals_de0ks(it, ibc))
    4811         2448 :      zc = one / (one - real(self%dvals_de0ks(it, ibc)))
    4812         2448 :      ze0_vals(it, ibc) = real(zc)
    4813         2448 :      qpe = kse + real(zc) * real(sig0c)
    4814         2448 :      qpe_oms = kse + real(sig0c)
    4815         2448 :      if (ibc == 1) then
    4816          585 :        kse_prev = kse; qpe_prev = qpe
    4817              :      end if
    4818         2448 :      if (band_ks == ib_val) then
    4819          389 :        kse_val = kse; qpe_val = qpe; qpe_oms_val = qpe_oms
    4820              :      end if
    4821         2448 :      if (band_ks == ib_cond) then
    4822          532 :        kse_cond = kse; qpe_cond = qpe; qpe_oms_cond = qpe_oms
    4823              :      end if
    4824              : 
    4825         2448 :      if (it <= max_ntemp) then
    4826         2448 :        if (self%imag_only) then
    4827              :          ! 1/tau  = 2 Imag(Sigma)
    4828         1258 :          invsig2fmts = Time_Sec * 1e+15 / two
    4829         1258 :          tau = 999999.0_dp
    4830         1258 :          if (abs(aimag(sig0c)) > tol16) tau = invsig2fmts / abs(aimag(sig0c))
    4831         1258 :          tau = min(tau, 999999.0_dp)
    4832              :          write(ab_out, "(i4,2(f8.3,1x),f8.1,1x,f8.3)") &
    4833         1258 :              band_ks, kse * Ha_eV, aimag(sig0c) * Ha_eV, tau, (kse - kse_prev) * Ha_eV
    4834              :        else
    4835              :          write(ab_out, "(i4, 10(f8.3,1x))") &
    4836         1190 :            band_ks, kse * Ha_eV, real(qpe) * Ha_eV, (real(qpe) - kse) * Ha_eV, &
    4837         3638 :            real(sig0c) * Ha_eV, aimag(sig0c) * Ha_eV, real(zc), &
    4838         2380 :            fan0 * Ha_eV, dw * Ha_eV, (kse - kse_prev) * Ha_eV, real(qpe - qpe_prev) * Ha_eV
    4839              :        end if
    4840              :      end if
    4841              : 
    4842         2448 :      if (ibc > 1) then
    4843         1863 :        kse_prev = kse; qpe_prev = qpe
    4844              :      end if
    4845         2448 :      qpoms_enes(it, ibc) = qpe_oms
    4846         2448 :      qp_enes(it, ibc) = qpe
    4847         3033 :      if (kse_val /= huge(one) * tol6 .and. kse_cond /= huge(one) * tol6) then
    4848              :        ! We have enough states to compute the gap.
    4849         1739 :        if (it == 1) ks_gap = kse_cond - kse_val
    4850         1739 :        qpoms_gaps(it) = qpe_oms_cond - qpe_oms_val
    4851         1739 :        qp_gaps(it) = real(qpe_cond - qpe_val)
    4852              :      end if
    4853              :    end do ! ibc
    4854              : 
    4855              :    ! Print KS and QP gaps.
    4856          767 :    if (it <= max_ntemp) then
    4857          585 :      if (.not. self%imag_only) then
    4858          198 :        if (kse_val /= huge(one) * tol6 .and. kse_cond /= huge(one) * tol6) then
    4859          167 :          write(ab_out, "(a)")" "
    4860          167 :          write(ab_out, "(a,f8.3,1x,2(a,i0),a)")" KS gap: ",ks_gap * Ha_eV, &
    4861          334 :            "(assuming bval:", ib_val, " ==> bcond:", ib_cond, ")"
    4862          167 :          write(ab_out, "(2(a,f8.3),a)")" QP gap: ",qp_gaps(it) * Ha_eV," (OTMS: ",qpoms_gaps(it) * Ha_eV, ")"
    4863          167 :          write(ab_out, "(2(a,f8.3),a)")" QP_gap - KS_gap: ",(qp_gaps(it) - ks_gap) * Ha_eV,&
    4864          334 :              " (OTMS: ",(qpoms_gaps(it) - ks_gap) * Ha_eV, ")"
    4865          167 :          write(ab_out, "(a)")" "
    4866              :        end if
    4867              :      else
    4868          387 :        if (kse_val /= huge(one) * tol6 .and. kse_cond /= huge(one) * tol6) then
    4869          169 :          write(ab_out, "(a)")" "
    4870          169 :          write(ab_out, "(a,f8.3,1x,2(a,i0),a)")" KS gap: ",ks_gap * Ha_eV, "(assuming bval:",ib_val," ==> bcond:",ib_cond,")"
    4871          169 :          write(ab_out, "(a)")" "
    4872              :        end if
    4873              :      end if
    4874              : 
    4875          585 :      write(ab_out, "(a)")repeat("=", 92)
    4876              :    end if
    4877              : 
    4878              :  end do ! it
    4879              : 
    4880          182 :  if (self%ntemp > max_ntemp .and. (ikcalc == 1 .and. spin == 1)) then
    4881            0 :    write(ab_out, "(a,i0,a)")" No more than ", max_ntemp, " temperatures are written to the main output file."
    4882            0 :    write(ab_out, "(2a)")" Please use SIGEPH.nc file and AbiPy to analyze the results.",ch10
    4883              :  end if
    4884              : 
    4885          182 :  if (dtset%prtvol > 0 .and. (ikcalc == 1 .and. spin == 1)) then
    4886           15 :    if (allocated(self%gfw_vals)) then
    4887           13 :      write(ab_out, "(2a)")" omega and Eliashberg function gf_{nk}(omega) for testing purposes:"
    4888           13 :      iw = (self%phmesh_size / 2)
    4889           73 :      do ib=1,min(self%nbcalc_ks(ikcalc, spin), 5)
    4890           60 :        band_ks = self%bstart_ks(ikcalc, spin) + ib - 1
    4891           60 :        write(ab_out, "(a, i0)")"For band:", band_ks
    4892          193 :        do jj=0,1
    4893          540 :          write(ab_out, "(4(f8.3,2x))")self%phmesh(iw+jj), (self%gfw_vals(iw+jj, ii, ib), ii=1,3)
    4894              :        end do
    4895              :      end do
    4896           13 :      write(ab_out, "(a)")ch10
    4897              :    end if
    4898              : 
    4899           15 :    if (self%nwr >= 3) then
    4900           14 :      write(ab_out, "(2a)")ch10," omega and Sigma_nk(omega, T=1) in eV for testing purposes:"
    4901           14 :      it = 1; iw = (self%nwr / 2)
    4902           77 :      do ib=1,min(self%nbcalc_ks(ikcalc, spin), 5)
    4903           63 :        band_ks = self%bstart_ks(ikcalc, spin) + ib - 1
    4904           63 :        write(ab_out, "(a, i0)")"For band:", band_ks
    4905          203 :        do ii=0,1
    4906          189 :          write(ab_out, "(3(f8.3,2x))")self%wrmesh_b(iw+ii, ib) * Ha_eV, self%vals_wr(iw+ii, it, ib) * Ha_eV
    4907              :        end do
    4908              :      end do
    4909           14 :      write(ab_out, "(a)")ch10
    4910              :    end if
    4911              :  end if
    4912              : 
    4913          182 :  call flush_unit(ab_out)
    4914              : 
    4915              :  ! Write self-energy matrix elements for this (kpt, spin). NB: Only master writes
    4916         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "vals_e0ks"), c2r(self%vals_e0ks), start=[1,1,1,ikcalc,spin]))
    4917         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "fan_vals"), c2r(self%fan_vals), start=[1,1,1,ikcalc,spin]))
    4918         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "E4_vals"), c2r(self%E4_vals), start=[1,1,1,ikcalc,spin]))
    4919         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "E4_vals2"), c2r(self%E4_vals2), start=[1,1,1,ikcalc,spin]))
    4920         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "fan_stern_vals"), c2r(self%fan_stern_vals), start=[1,1,1,ikcalc,spin]))
    4921         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "dvals_de0ks"), c2r(self%dvals_de0ks), start=[1,1,1,ikcalc,spin]))
    4922          910 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "dw_vals"), self%dw_vals, start=[1,1,ikcalc,spin]))
    4923          910 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "dw_stern_vals"), self%dw_stern_vals, start=[1,1,ikcalc,spin]))
    4924              :  ! Dump QP energies and gaps for this (kpt, spin)
    4925         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qpoms_enes"), c2r(qpoms_enes), start=[1,1,1,ikcalc,spin]))
    4926              : 
    4927          182 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "E2"), self%E2, start=[1]))
    4928         1092 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qp_enes"), c2r(qp_enes), start=[1,1,1,ikcalc,spin]))
    4929          910 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "ze0_vals"), ze0_vals, start=[1,1,ikcalc,spin]))
    4930          728 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "ks_enes"), ks_enes, start=[1,ikcalc,spin]))
    4931          546 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "ks_gaps"), ks_gap, start=[ikcalc,spin]))
    4932          728 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qpoms_gaps"), qpoms_gaps, start=[1,ikcalc,spin]))
    4933          728 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qp_gaps"), qp_gaps, start=[1,ikcalc,spin]))
    4934              : 
    4935          182 :  if (self%mrta > 0) then
    4936          560 :    NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "linewidth_mrta"), self%linewidth_mrta, start=[1,1,ikcalc,spin]))
    4937              :  end if
    4938              : 
    4939          182 :  if (dtset%eph_prtscratew == 1) then
    4940           21 :    NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "scratew"), self%scratew, start=[1,1,1,1,ikcalc,spin]))
    4941              :  end if
    4942              : 
    4943              :  !if (self%frohl_model == 1 .and. self%imag_only) then
    4944              :  !  ncerr = nf90_put_var(self%ncid, nctk_idname(self%ncid, "frohl_deltas_sphcorr"), &
    4945              :  !     self%frohl_deltas_sphcorr, start=[1,1,1,1, ikcalc, spin])
    4946              :  !  NCF_CHECK(ncerr)
    4947              :  !end if
    4948              : 
    4949              :  ! Write frequency dependent data.
    4950          182 :  if (self%nwr > 0) then
    4951          260 :    NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "wrmesh_b"), self%wrmesh_b, start=[1,1,ikcalc,spin]))
    4952          364 :    NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "vals_wr"), c2r(self%vals_wr), start=[1,1,1,1,ikcalc,spin]))
    4953              : 
    4954              :    ! Compute spectral function. A = -1/pi [Im Sigma(ww)] / ([ww - ee - Re Sigma(ww)] ** 2 + Im Sigma(ww) ** 2])
    4955          260 :    ABI_MALLOC(aw, (self%nwr, self%ntemp, self%max_nbcalc))
    4956          336 :    do ib=1,self%nbcalc_ks(ikcalc, spin)
    4957          284 :      band_ks = self%bstart_ks(ikcalc, spin) + ib - 1
    4958          284 :      kse = ebands%eig(band_ks, ik_ibz, spin)
    4959         1276 :      do it=1,self%ntemp
    4960              :        aw(:, it, ib) = -piinv * aimag(self%vals_wr(:, it, ib)) / &
    4961       109020 :          ((self%wrmesh_b(:, ib) - kse - real(self%vals_wr(:, it, ib))) ** 2 + aimag(self%vals_wr(:, it, ib)) ** 2)
    4962              :      end do
    4963              :    end do
    4964          312 :    NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "spfunc_wr"), aw, start=[1, 1, 1, ikcalc, spin]))
    4965           52 :    ABI_FREE(aw)
    4966              :  end if
    4967              : 
    4968              :  ! Write Eliashberg functions
    4969          182 :  if (allocated(self%gfw_vals)) then
    4970          348 :    NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "gfw_vals"), self%gfw_vals, start=[1, 1, 1, ikcalc, spin]))
    4971              :  end if
    4972          182 :  if (allocated(self%a2few)) then
    4973            0 :    NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "a2few"), self%a2few, start=[1, 1, 1, ikcalc, spin]))
    4974              :  end if
    4975              : 
    4976          182 :  if (dtset%ibte_prep > 0) then
    4977            6 :    call wrtout(std_out, " Writing scattering matrix elements to disk...")
    4978              :    ! Get ncid of group used to store scattering rate (ragged array implemented with netcdf groups).
    4979              :    ! FIXME: Unfortunately, this algo cannot be used if parallelism over kcalc/spin is on since
    4980              :    ! we have to change the metadata at runtime.
    4981            6 :    sr_ncid = self%ncid
    4982            6 :    NCF_CHECK(nf90_inq_ncid(sr_ncid, strcat("srate_k", itoa(ikcalc), "_s", itoa(spin)), grp_ncid))
    4983              : 
    4984              :    ! Define dimensions and arrays inside group at runtime
    4985              :    ncerr = nctk_def_dims(grp_ncid, [ &
    4986              :      nctkdim_t("lgk_nsym", self%lgk_nsym), &
    4987              :      nctkdim_t("nbcalc", self%nbcalc_ks(ikcalc, spin)), &
    4988              :      nctkdim_t("nbsum", self%bsum_stop - self%bsum_start + 1), &
    4989              :      nctkdim_t("nq_ibzk_eff", nq_ibzk_eff) &
    4990           30 :    ], defmode=.True.)
    4991            6 :    NCF_CHECK(ncerr)
    4992              : 
    4993              :    ncerr = nctk_def_arrays(grp_ncid, [ &
    4994              :      nctkarr_t("lgk_sym2glob", "int", "two, lgk_nsym"), &
    4995              :      nctkarr_t("kq_symtab", "int", "six, nq_ibzk_eff"), &
    4996              :      nctkarr_t("srate", "dp", "nq_ibzk_eff, nbsum, nbcalc, ntemp") &
    4997           24 :    ])
    4998            6 :    NCF_CHECK(ncerr)
    4999              : 
    5000              :    ! Write data.
    5001            6 :    NCF_CHECK(nctk_set_datamode(sr_ncid))
    5002            6 :    NCF_CHECK(nf90_put_var(grp_ncid, nctk_idname(grp_ncid, "lgk_sym2glob"), self%lgk_sym2glob))
    5003            6 :    NCF_CHECK(nf90_put_var(grp_ncid, nctk_idname(grp_ncid, "kq_symtab"), kq_symtab))
    5004            6 :    ABI_FREE(kq_symtab)
    5005              : 
    5006              :    ! Move q-points to first dimensions before writing.
    5007           36 :    ABI_MALLOC(grp_srate, (nq_ibzk_eff, self%bsum_start:self%bsum_stop, self%nbcalc_ks(ikcalc, spin), self%ntemp))
    5008         9187 :    do ii=1,nq_ibzk_eff
    5009        64273 :      grp_srate(ii,:,:,:) = gather_srate(:,:,:,ii)
    5010              :    end do
    5011            6 :    NCF_CHECK(nf90_put_var(grp_ncid, nctk_idname(grp_ncid, "srate"), grp_srate))
    5012            6 :    ABI_FREE(gather_srate)
    5013            6 :    ABI_FREE(grp_srate)
    5014              :  end if
    5015              : 
    5016              :  ! Write restart flag
    5017          182 :  self%qp_done(ikcalc, spin) = 1
    5018          546 :  NCF_CHECK(nf90_put_var(self%ncid, nctk_idname(self%ncid, "qp_done"), 1, start=[ikcalc, spin]))
    5019              : 
    5020              :  ! Dump the cache to file. This is necessary to ensure we can restart.
    5021          182 :  NCF_CHECK(nf90_sync(self%ncid))
    5022              : 
    5023          182 :  call cwtime_report(" Sigma_nk netcdf output", cpu, wall, gflops)
    5024              : 
    5025          364 : end subroutine sigmaph_gather_and_write
    5026              : !!***
    5027              : 
    5028              : !!****f* m_sigmaph/sigmaph_print
    5029              : !! NAME
    5030              : !!  sigmaph_print
    5031              : !!
    5032              : !! FUNCTION
    5033              : !!  Print self-energy and QP corrections for given (k-point, spin).
    5034              : !!
    5035              : !! INPUTS
    5036              : !!  dtset<dataset_type>=All input variables for this dataset.
    5037              : !!  unt=Fortran unit number
    5038              : !!
    5039              : !! SOURCE
    5040              : 
    5041          116 : subroutine sigmaph_print(self, dtset, unt)
    5042              : 
    5043              : !Arguments ------------------------------------
    5044              :  integer,intent(in) :: unt
    5045              :  type(dataset_type),intent(in) :: dtset
    5046              :  class(sigmaph_t),intent(in) :: self
    5047              : 
    5048              : !Local variables-------------------------------
    5049              :  integer :: ikc, is, ndiv
    5050              :  character(len=5000) :: msg
    5051              : ! *************************************************************************
    5052              : 
    5053          116 :  if (unt == dev_null) return
    5054              : 
    5055              :  ! Write dimensions
    5056          116 :  write(unt,"(/,a)")sjoin(" Number of bands in e-ph self-energy sum:", itoa(self%nbsum))
    5057          116 :  write(unt,"(a)")sjoin(" From bsum_start:", itoa(self%bsum_start), "to bsum_stop:", itoa(self%bsum_stop))
    5058          116 :  if (dtset%eph_stern /= 0 .and. .not. self%imag_only) then
    5059           34 :    write(unt, "(a)")" Treating high-energy bands with Sternheimer and static self-energy."
    5060           34 :    write(unt, "(a, es16.6, a, i0)")" Tolwfr:", dtset%tolwfr, ", nline: ", dtset%nline
    5061              :  end if
    5062          116 :  write(unt,"(a)")sjoin(" Symsigma: ",itoa(self%symsigma), "Timrev:", itoa(self%timrev))
    5063          116 :  if (.not. (self%qint_method == 1 .and. self%imag_only)) then
    5064           84 :    write(unt,"(a)")sjoin(" Imaginary shift in the denominator (zcut): ", ftoa(aimag(self%ieta) * Ha_eV, fmt="f5.3"), "[eV]")
    5065              :  end if
    5066          116 :  msg = " Standard quadrature"; if (self%qint_method == 1) msg = " Tetrahedron method"
    5067          116 :  write(unt, "(2a)")sjoin(" Method for q-space integration:", msg)
    5068          116 :  if (self%qint_method == 1) then
    5069           38 :    ndiv = 1; if (self%use_doublegrid) ndiv = self%eph_doublegrid%ndiv
    5070          114 :    write(unt, "(a, 2(es16.6,1x))")" Tolerance for integration weights < ", dtset%eph_tols_idelta(:) / ndiv
    5071           38 :    write(unt, "(a, (f5.2,1x))")" eph_phwinfact: ", self%phwinfact
    5072              :  end if
    5073          116 :  if (self%use_doublegrid) write(unt, "(a, i0)")" Using double grid technique with ndiv: ", self%eph_doublegrid%ndiv
    5074          116 :  if (self%imag_only) write(unt, "(a)")" Only the Imaginary part of Sigma will be computed."
    5075          116 :  if (.not. self%imag_only) write(unt, "(a)")" Both Real and Imaginary part of Sigma will be computed."
    5076              :  write(unt,"(a)")sjoin(" Number of frequencies along the real axis:", itoa(self%nwr), &
    5077          116 :     ", Step:", ftoa(self%wr_step * Ha_eV, fmt="f5.3"), "[eV]")
    5078          116 :  if (dtset%prteliash /= 0) then
    5079           42 :    write(unt, "(a)")sjoin(" Number of frequency in generalized Eliashberg functions:", itoa(self%phmesh_size))
    5080              :  else
    5081           74 :    write(unt, "(a)")" Number of frequency in generalized Eliashberg functions: 0"
    5082              :  end if
    5083              :  write(unt,"(a)")sjoin(" Number of temperatures:", itoa(self%ntemp), &
    5084          116 :    "From:", ftoa(self%kTmesh(1) / kb_HaK), "to", ftoa(self%kTmesh(self%ntemp) / kb_HaK), "[K]")
    5085          116 :  write(unt,"(a)")sjoin(" Ab-initio q-mesh from DDB file:", ltoa(dtset%ddb_ngqpt))
    5086          116 :  write(unt,"(a)")sjoin(" Q-mesh used for self-energy integration [ngqpt]:", ltoa(self%ngqpt))
    5087          116 :  write(unt,"(a)")sjoin(" Number of q-points in the IBZ:", itoa(self%nqibz))
    5088          116 :  write(unt,"(a)")sjoin(" asr:", itoa(dtset%asr), "chneut:", itoa(dtset%chneut))
    5089          116 :  write(unt,"(a)")sjoin(" dipdip:", itoa(dtset%dipdip), "symdynmat:", itoa(dtset%symdynmat))
    5090              : 
    5091          116 :  if (.not. self%imag_only) then
    5092           66 :    select case (self%frohl_model)
    5093              :    case (0)
    5094              :      !write(unt,"(a)")" No special treatment for the integration of the Frohlich divergence in the microzone around Gamma"
    5095              :    case (1)
    5096            0 :      write(unt,"(a)")" Integrating Frohlich model in small sphere around Gamma to accelerate qpt convergence"
    5097            0 :      write(unt,"(2(a,i0,1x))")" Spherical integration performed with: ntheta: ", self%ntheta, ", nphi: ", self%nphi
    5098              :    case default
    5099           66 :      ABI_ERROR(sjoin("Invalid value of frohl_mode:", itoa(self%frohl_model)))
    5100              :    end select
    5101              :  end if
    5102              : 
    5103          116 :  write(unt,"(a, i0)")" Number of k-points for self-energy corrections: ", self%nkcalc
    5104          310 :  if (any(abs(dtset%sigma_erange) /= zero)) then
    5105           84 :    write(unt, "(a, 2(f6.3, 1x), a)")" sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
    5106              :  end if
    5107          116 :  if (self%imag_only .and. self%qint_method == 1) then
    5108           32 :    write(unt,"(a, 2(f5.3, 1x), a)")" Including all final {mk+q} states inside energy window: [", &
    5109           64 :       self%elow * Ha_eV, self%ehigh * Ha_eV, "] [eV]"
    5110              :  end if
    5111          116 :  write(unt,"(a)")" List of k-points for self-energy corrections:"
    5112          480 :  do ikc=1,self%nkcalc
    5113          364 :    if (ikc > 10) then
    5114            0 :      write(unt, "(2a)")" nkcalc > 10. Stop printing more k-point information.",ch10
    5115            0 :      exit
    5116              :    end if
    5117          844 :    do is=1,self%nsppol
    5118          364 :      if (self%nsppol == 2) write(unt,"(a,i1,a)")" For spin: ",is, ", ikcalc, spin, kpt, bstart, bstop"
    5119              :      write(unt, "(2(i4,2x),a,2(i4,1x))") &
    5120          728 :        ikc, is, trim(ktoa(self%kcalc(:,ikc))), self%bstart_ks(ikc,is), self%bstart_ks(ikc,is) + self%nbcalc_ks(ikc,is) - 1
    5121              :      end do
    5122              :  end do
    5123              : 
    5124          116 :  write(unt, "(/,a)")" === MPI parallelism ==="
    5125          116 :  write(unt, "(2(a,i0))")"P Allocating and summing bands from my_bsum_start: ", self%my_bsum_start, &
    5126          232 :      " up to my_bsum_stop: ", self%my_bsum_stop
    5127          116 :  write(unt, "(a,i0)")"P Number of CPUs for parallelism over perturbations: ", self%pert_comm%nproc
    5128          116 :  write(unt, "(a,i0)")"P Number of perturbations treated by this CPU: ", self%my_npert
    5129          116 :  write(unt, "(a,i0)")"P Number of CPUs for parallelism over q-points: ", self%qpt_comm%nproc
    5130          116 :  write(unt, "(2(a,i0))")"P Number of q-points in the IBZ treated by this proc: " , &
    5131         8212 :      count(self%itreat_qibz == 1), " of ", self%nqibz
    5132          116 :  write(unt, "(a,i0)")"P Number of CPUs for parallelism over bands: ", self%bsum_comm%nproc
    5133          116 :  write(unt, "(a,i0)")"P Number of CPUs for parallelism over spins: ", self%spin_comm%nproc
    5134          116 :  write(unt, "(a,i0)")"P Number of CPUs for parallelism over k-points: ", self%kcalc_comm%nproc
    5135          116 :  write(unt, "(2(a,i0),/)")"P Number of k-point in Sigma_nk treated by this proc: ", self%my_nkcalc, " of ", self%nkcalc
    5136              : 
    5137              : end subroutine sigmaph_print
    5138              : !!***
    5139              : 
    5140              : !----------------------------------------------------------------------
    5141              : 
    5142              : !!****f* m_sigmaph/sigmaph_get_all_qweights
    5143              : !! NAME
    5144              : !!  sigmaph_get_all_qweights
    5145              : !!
    5146              : !! FUNCTION
    5147              : !!  Compute all the weights for q-space integration using the tetrahedron method
    5148              : !!
    5149              : !! INPUTS
    5150              : !!  cryst<crystal_t>=Crystalline structure
    5151              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    5152              : !!  spin: Spin index
    5153              : !!  ikcalc: Index of the self-energy k-point in the kcalc array.
    5154              : !!  comm: MPI communicator
    5155              : !!
    5156              : !! OUTPUT
    5157              : !!
    5158              : !! SOURCE
    5159              : 
    5160          156 : subroutine sigmaph_get_all_qweights(sigma, cryst, ebands, spin, ikcalc, comm)
    5161              : 
    5162              : !Arguments ------------------------------------
    5163              : !scalars
    5164              :  class(sigmaph_t),intent(inout) :: sigma
    5165              :  type(ebands_t),intent(in) :: ebands
    5166              :  type(crystal_t),intent(in) :: cryst
    5167              :  integer,intent(in) :: ikcalc, spin, comm
    5168              : 
    5169              : !Local variables ------------------------------
    5170              : !scalars
    5171              :  integer :: nu, ibsum_kq, ik_ibz, bstart_ks, nbcalc_ks, my_rank, natom3
    5172              :  integer :: nprocs, imyp, imyq, ndiv, bsum_start, bsum_stop, ib_k, band_ks
    5173              :  integer :: iq_ibz_fine,iq_bz_fine,iq_ibz,jj, nz
    5174              :  real(dp) :: weight, cpu,wall, gflops, eig0nk
    5175              : !arrays
    5176              :  real(dp) :: kk(3), kq(3), qpt(3), dpm(2)
    5177          156 :  real(dp),allocatable :: tmp_deltaw_pm(:,:,:)
    5178          156 :  complex(dp),allocatable :: zvals(:,:), tmp_cweights(:,:,:,:)
    5179              : ! *************************************************************************
    5180              : 
    5181          156 :  call cwtime(cpu, wall, gflops, "start")
    5182              : 
    5183          156 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    5184              : 
    5185          624 :  kk = sigma%kcalc(:, ikcalc)
    5186          156 :  ik_ibz = sigma%kcalc2ibz(ikcalc, 1)
    5187          156 :  nbcalc_ks = sigma%nbcalc_ks(ikcalc, spin)
    5188          156 :  bstart_ks = sigma%bstart_ks(ikcalc, spin)
    5189          156 :  bsum_start = sigma%bsum_start; bsum_stop = sigma%bsum_stop
    5190          156 :  natom3 = 3 * cryst%natom
    5191          156 :  ndiv = 1; if (sigma%use_doublegrid) ndiv = sigma%eph_doublegrid%ndiv
    5192              : 
    5193          156 :  ABI_CHECK(abs(sigma%symsigma) == 1, "symsigma 0 with tetra not implemented")
    5194              : 
    5195          156 :  if (sigma%imag_only) then
    5196              :    ! Weights for Im (tetrahedron, eta --> 0)
    5197         1050 :    ABI_REMALLOC(sigma%deltaw_pm, (2, nbcalc_ks, sigma%my_npert, bsum_start:bsum_stop, sigma%my_nqibz_k, ndiv))
    5198     13743622 :    sigma%deltaw_pm = zero
    5199              : 
    5200              :    ! Temporary weights (on the fine IBZ_k mesh if double grid is used)
    5201          450 :    ABI_MALLOC(tmp_deltaw_pm, (1, sigma%ephwg%nq_k, 2))
    5202              : 
    5203              :    ! Loop over bands to sum
    5204          696 :    do ibsum_kq=sigma%bsum_start, sigma%bsum_stop
    5205              :      ! Loop over my phonon modes
    5206         3936 :      do imyp=1,sigma%my_npert
    5207         3240 :        nu = sigma%my_pinfo(3, imyp)
    5208              : 
    5209              :        ! HM: This one should be faster but uses more memory, I compute for each ib instead
    5210              :        ! Compute weights inside qb_comm
    5211              :        !call sigma%ephwg%get_deltas_wvals(ibsum_kq, spin, nu, nbcalc_ks, &
    5212              :        !                                  ebands%eig(bstart_ks:bstart_ks+nbcalc_ks, ik_ibz, spin), &
    5213              :        !                                  sigma%bcorr, tmp_deltaw_pm, sigma%qb_comm%value)
    5214              : 
    5215              :        ! loop over bands in self-energy matrix elements.
    5216        18894 :        do ib_k=1,nbcalc_ks
    5217        15108 :          band_ks = ib_k + bstart_ks - 1
    5218        15108 :          eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    5219              : 
    5220              :          ! Compute weights inside qb_comm
    5221        30216 :          call sigma%ephwg%get_deltas_wvals(ibsum_kq, spin, nu, 1, [eig0nk], sigma%bcorr, tmp_deltaw_pm, sigma%qb_comm%value)
    5222              : 
    5223              :          ! For all the q-points that I am going to calculate
    5224       986229 :          do imyq=1,sigma%my_nqibz_k
    5225       967881 :            iq_ibz = sigma%myq2ibz_k(imyq)
    5226              : 
    5227       982989 :            if (sigma%use_doublegrid) then
    5228              :              ! For all the q-points in the microzone
    5229              :              ! This is done again in the main sigmaph routine
    5230       375480 :              qpt = sigma%qibz_k(:,iq_ibz)
    5231       375480 :              kq = kk + qpt
    5232        93870 :              call sigma%eph_doublegrid%get_mapping(kk, kq, qpt)
    5233      2628360 :              do jj=1,sigma%eph_doublegrid%ndiv
    5234      2534490 :                iq_bz_fine = sigma%eph_doublegrid%mapping(3,jj)
    5235      2534490 :                iq_ibz_fine = sigma%eph_doublegrid%bz2lgkibz(iq_bz_fine)
    5236      2534490 :                weight = sigma%ephwg%lgk%weights(iq_ibz_fine)
    5237              :                !dpm = tmp_deltaw_pm(ib_k, iq_ibz_fine, :)
    5238      7603470 :                dpm = tmp_deltaw_pm(1, iq_ibz_fine, :)
    5239      7697340 :                sigma%deltaw_pm(:, ib_k, imyp, ibsum_kq, imyq, jj) = dpm / weight
    5240              :              end do
    5241              :            else
    5242       874011 :              weight = sigma%ephwg%lgk%weights(iq_ibz)
    5243              :              !dpm = tmp_deltaw_pm(ib_k, iq_ibz, :)
    5244      2622033 :              dpm = tmp_deltaw_pm(1, iq_ibz, :)
    5245      2622033 :              sigma%deltaw_pm(:, ib_k, imyp, ibsum_kq, imyq, 1) = dpm / weight
    5246              :            end if
    5247              : 
    5248              :          end do
    5249              :        end do
    5250              :      end do
    5251              :    end do
    5252              : 
    5253          150 :    ABI_FREE(tmp_deltaw_pm)
    5254              : 
    5255              :  else
    5256              :    ! Both real and imag part --> compute \int 1/z with tetrahedron.
    5257              :    ! Note that we still need a finite i.eta in the expression (hopefully smaller than the default value).
    5258              :    ! Besides we have to take into account the case in which the spectral function is wanted.
    5259              :    ! Derivative wrt omega is still computed with finite i.eta, though.
    5260            6 :    ABI_CHECK(.not. sigma%use_doublegrid, "double grid for Re-Im not implemented")
    5261              : 
    5262              :    ! TODO: This part should be tested.
    5263            6 :    nz = 1; if (sigma%nwr > 0) nz = 1 + sigma%nwr
    5264           48 :    ABI_REMALLOC(sigma%cweights, (nz,2,nbcalc_ks,sigma%my_npert,sigma%my_bsum_start:sigma%my_bsum_stop,sigma%my_nqibz_k,ndiv))
    5265           30 :    ABI_MALLOC(tmp_cweights, (nz, 2, nbcalc_ks, sigma%nqibz_k))
    5266              : 
    5267              :    ! Initialize z-points for Sigma_{nk} for different n bands.
    5268           24 :    ABI_MALLOC(zvals, (nz, nbcalc_ks))
    5269           54 :    zvals(1, :) = sigma%e0vals + sigma%ieta
    5270         3270 :    if (sigma%nwr > 0) zvals(2:sigma%nwr+1, :) = sigma%wrmesh_b(:, 1:nbcalc_ks) + sigma%ieta
    5271              : 
    5272              :    ! Loop over my bands in self-energy sum.
    5273              :    ! TODO: Really slow if nz >> 1. Possible solutions:
    5274              :    ! 1) reduce the number of ibsum_kq bands for which tetra must be used.
    5275              :    ! 2) use spline with non-linear mesh
    5276              :    ! 3) use asyntotic expansion at "large" z
    5277          194 :    do ibsum_kq=sigma%my_bsum_start, sigma%my_bsum_stop
    5278              :      ! Loop over my phonon modes
    5279         1322 :      do imyp=1,sigma%my_npert
    5280         1128 :        nu = sigma%my_pinfo(3, imyp)
    5281              : 
    5282              :        ! cweights(nz, 2, nbsigma, self%nq_k)
    5283              :        call sigma%ephwg%get_zinv_weights(nz, nbcalc_ks, zvals, ibsum_kq, spin, nu, sigma%zinv_opt, tmp_cweights, &
    5284         1128 :                                          xmpi_comm_self)
    5285              :                                          !sigma%qpt_comm%value)
    5286              :                                          !erange=
    5287              :                                          !use_bzsum=sigma%symsigma == 0)
    5288              : 
    5289              :        ! Extract weights for all the q-points that I am going to calculate.
    5290        13160 :        do imyq=1,sigma%my_nqibz_k
    5291        11844 :          iq_ibz = sigma%myq2ibz_k(imyq)
    5292        11844 :          weight = sigma%ephwg%lgk%weights(iq_ibz)
    5293      8631372 :          sigma%cweights(:, :, :, imyp, ibsum_kq, imyq, 1) = tmp_cweights(:, :, :, iq_ibz) / weight
    5294              :        end do
    5295              :      end do
    5296              :    end do
    5297              : 
    5298            6 :    ABI_FREE(zvals)
    5299            6 :    ABI_FREE(tmp_cweights)
    5300              :  end if
    5301              : 
    5302          156 :  call cwtime_report(" get_all_qweights with tetrahedron", cpu, wall, gflops)
    5303              : 
    5304          156 : end subroutine sigmaph_get_all_qweights
    5305              : !!***
    5306              : 
    5307              : !!****f* m_sigmaph/qpoints_oracle
    5308              : !! NAME
    5309              : !!  qpoints_oracle
    5310              : !!
    5311              : !! FUNCTION
    5312              : !!  This function tries to predict the **full** list of q-points in the BZ needed to compute the lifetimes
    5313              : !!  once we know sigma%nkcalc.
    5314              : !!  It uses an energy window computed from the max phonon frequency multiplied by sigma%phwinfact.
    5315              : !!
    5316              : !! INPUT
    5317              : !! cryst=Crystalline structure
    5318              : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    5319              : !! qpts(3, nqpt)=
    5320              : !! nqpt= Number of points in qpts
    5321              : !! nqbz=Number of q-points in BZ.
    5322              : !! qbz(3, nbz) = full BZ
    5323              : !! comm=MPI communicator.
    5324              : !!
    5325              : !! OUTPUT
    5326              : !!  qselect(nqpt)
    5327              : !!
    5328              : !! SOURCE
    5329              : 
    5330           16 : subroutine qpoints_oracle(sigma, dtset, cryst, ebands, qpts, nqpt, nqbz, qbz, qselect, comm)
    5331              : 
    5332              : !Arguments ------------------------------------
    5333              : !scalars
    5334              :  class(sigmaph_t),intent(in) :: sigma
    5335              :  type(dataset_type),intent(in) :: dtset
    5336              :  type(crystal_t),intent(in) :: cryst
    5337              :  type(ebands_t),intent(in) :: ebands
    5338              :  integer,intent(in) :: nqpt, nqbz, comm
    5339              : !arrays
    5340              :  real(dp),intent(in) :: qpts(3,nqpt), qbz(3,nqbz)
    5341              :  integer,intent(out) :: qselect(nqpt)
    5342              : 
    5343              : !Local variables ------------------------------
    5344              : !scalars
    5345              :  integer,parameter :: master = 0
    5346              :  integer :: spin, ikcalc, ik_ibz, iq_bz, ierr, db_iqpt, ibsum_kq, ikq_ibz, ikq_bz
    5347              :  integer :: cnt, my_rank, nprocs, ib_k, band_ks, nkibz, nkbz, kq_rank, qptopt
    5348              :  real(dp) :: eig0nk, eig0mkq, ediff, cpu, wall, gflops
    5349              :  character(len=5000) :: msg
    5350           16 :  type(krank_t) :: krank, qrank
    5351              : !arrays
    5352              :  integer :: g0(3), qptrlatt(3,3)
    5353           16 :  integer,allocatable :: qbz_count(:), qbz2qpt(:,:), bz2ibz(:,:)
    5354              :  real(dp) :: kq(3), kk(3)
    5355           16 :  real(dp),allocatable :: wtk(:), kibz(:,:), kbz(:,:)
    5356              : ! *************************************************************************
    5357              : 
    5358           16 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    5359              : 
    5360           16 :  call cwtime(cpu, wall, gflops, "start")
    5361              :  call wrtout(std_out, &
    5362           16 :              sjoin(" qpoints_oracle: predicting number q-points for tau with eph_phwinfact:", ftoa(sigma%phwinfact)))
    5363              : 
    5364              :  ! Get full BZ associated to ebands
    5365              :  call kpts_ibz_from_kptrlatt(cryst, ebands%kptrlatt, ebands%kptopt, ebands%nshiftk, ebands%shiftk, &
    5366           16 :    nkibz, kibz, wtk, nkbz, kbz, bz2ibz=bz2ibz)
    5367           16 :  call cwtime_report(" kpts_ibz_from_kptrlatt", cpu, wall, gflops)
    5368              : 
    5369           16 :  ABI_FREE(wtk)
    5370           16 :  ABI_FREE(kibz)
    5371           16 :  ABI_CHECK(nkibz == ebands%nkpt, "nkibz != ebands%nkpt")
    5372              : 
    5373              :  ! Make full k-point rank arrays
    5374           16 :  call krank%init(nkbz, kbz)
    5375           16 :  call cwtime_report(" krank_new", cpu, wall, gflops)
    5376              : 
    5377              :  ! This loop is Expensive with a 288^3
    5378              :  ! qbz_count_loop completed. cpu: 03:16 [minutes] , wall: 03:16 [minutes] <<< TIME
    5379              :  ! qbz_count completed. cpu: 04:41 [minutes] , wall: 04:40 [minutes] <<< TIME
    5380       115520 :  ABI_ICALLOC(qbz_count, (nqbz))
    5381           16 :  cnt = 0
    5382           32 :  do spin=1,sigma%nsppol
    5383          107 :    do ikcalc=1,sigma%nkcalc
    5384           75 :      cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism inside comm
    5385          300 :      kk = sigma%kcalc(:, ikcalc)
    5386           75 :      ik_ibz = sigma%kcalc2ibz(ikcalc, 1)
    5387       471195 :      do iq_bz=1,nqbz
    5388       471104 :        if (qbz_count(iq_bz) /= 0) cycle ! No need to check this q-point again.
    5389      1869788 :        kq = kk + qbz(:, iq_bz)
    5390       467447 :        kq_rank = krank%get_rank(kq)
    5391       467447 :        ikq_bz = krank%invrank(kq_rank)
    5392       467447 :        ABI_CHECK(ikq_bz > 0, sjoin("Cannot find kq: ", ktoa(kq)))
    5393       467447 :        ABI_CHECK(isamek(kq, kbz(:, ikq_bz), g0), "Wrong invrank")
    5394              :        !ikq_ibz = bz2ibz(ikq_bz,1)
    5395       467447 :        ikq_ibz = bz2ibz(1, ikq_bz)
    5396       940445 :        do ib_k=1,sigma%nbcalc_ks(ikcalc, spin)
    5397       472923 :          band_ks = ib_k + sigma%bstart_ks(ikcalc, spin) - 1
    5398       472923 :          eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    5399      1452855 :          do ibsum_kq=sigma%bsum_start, sigma%bsum_stop
    5400       508828 :            eig0mkq = ebands%eig(ibsum_kq, ikq_ibz, spin)
    5401       508828 :            ediff = eig0nk - eig0mkq
    5402              :            ! Perform check on the energy difference to exclude this q-point.
    5403       981751 :            if (abs(ediff) <= sigma%phwinfact * sigma%wmax) qbz_count(iq_bz) = qbz_count(iq_bz) + 1
    5404              :          end do
    5405              :        end do
    5406              :      end do
    5407              :    end do
    5408              :  end do
    5409           16 :  call cwtime_report(" qbz_count_loop", cpu, wall, gflops)
    5410              : 
    5411           16 :  ABI_FREE(kbz)
    5412           16 :  ABI_FREE(bz2ibz)
    5413           16 :  call krank%free()
    5414              : 
    5415           16 :  call xmpi_sum(qbz_count, comm, ierr)
    5416           16 :  call cwtime_report(" qbz_count", cpu, wall, gflops)
    5417              : 
    5418              :  ! Get mapping QBZ --> List of q-points involved in e-ph scattering for e/h in pockets.
    5419              :  ! Assume qptopt == kptopt unless value is specified in input
    5420           48 :  ABI_MALLOC(qbz2qpt, (6, nqbz))
    5421              : 
    5422           16 :  qptrlatt = 0; qptrlatt(1,1) = sigma%ngqpt(1); qptrlatt(2,2) = sigma%ngqpt(2); qptrlatt(3,3) = sigma%ngqpt(3)
    5423           16 :  call qrank%from_kptrlatt(nqpt, qpts, qptrlatt, compute_invrank=.False.)
    5424           16 :  qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt
    5425              : 
    5426           16 :  if (kpts_map("symrec", qptopt, cryst, qrank, nqbz, qbz, qbz2qpt) /= 0) then
    5427              :    write(msg, '(3a)' )&
    5428            0 :      "At least one of the q-points could not be generated from a symmetrical one in the DVDB.", ch10, &
    5429            0 :      "Action: check your DVDB file and use eph_task to interpolate the potentials on a denser q-mesh."
    5430            0 :    ABI_ERROR(msg)
    5431              :  end if
    5432           16 :  call qrank%free()
    5433              : 
    5434           16 :  call cwtime_report(" oracle_listkk_qbz_qpts", cpu, wall, gflops)
    5435              : 
    5436              :  ! Compute qselect using qbz2qpt.
    5437         3532 :  qselect = 0
    5438       115488 :  do iq_bz=1,nqbz
    5439       115472 :    if (qbz_count(iq_bz) == 0) cycle
    5440         1477 :    db_iqpt = qbz2qpt(1, iq_bz)
    5441       115488 :    qselect(db_iqpt) = qselect(db_iqpt) + 1
    5442              :  end do
    5443              : 
    5444           16 :  ABI_FREE(qbz_count)
    5445           16 :  ABI_FREE(qbz2qpt)
    5446              : 
    5447           16 :  if (my_rank == master) then
    5448         3532 :    cnt = count(qselect /= 0)
    5449           16 :    write(std_out, "(a, i0, a, f5.1, a)")" qpoints_oracle: calculation of tau_nk will need: ", cnt, &
    5450           32 :      " q-points in the IBZ. (nqibz_eff / nqibz): ", (100.0_dp * cnt) / sigma%nqibz, " [%]"
    5451              :  end if
    5452              : 
    5453          112 : end subroutine qpoints_oracle
    5454              : !!***
    5455              : 
    5456              : !!****f* m_epthk/frohl_integrator_init
    5457              : !! FUNCTION
    5458              : !! Initialize the Frohlich integrator.
    5459              : !!
    5460              : !! INPUTS
    5461              : !!
    5462              : !! SOURCE
    5463              : 
    5464            0 : subroutine frohl_integrator_init(new, cryst, ifc, ntheta, comm)
    5465              : 
    5466              :  use m_lebedev, only : lebedev_t
    5467              : 
    5468              : !Arguments ------------------------------------
    5469              :  class(frohl_integrator_t),intent(out) :: new
    5470              :  type(crystal_t),intent(in) :: cryst
    5471              :  type(ifc_type),intent(in) :: ifc
    5472              :  integer,intent(in) :: ntheta, comm
    5473              : 
    5474              : !Local variables ------------------------------
    5475              :  integer :: iang, my_rank, nprocs
    5476              : !************************************************************************
    5477              : 
    5478              :  ! Set angular mesh for numerical integration inside micro BZ around Gamma.
    5479            0 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    5480            0 :  new%ntheta = ntheta; new%nphi = 2 * new%ntheta
    5481              :  !write(std_out,"(a)")" Activating computation of Frohlich self-energy:"
    5482              :  !write(std_out,"(2(a,i0,1x))")" ntheta: ", new%ntheta, "nphi: ", new%nphi
    5483              : 
    5484              :  ! Initialize angular mesh qvers_cart and angwgth
    5485              :  ! NB: summing over f * angwgth gives the spherical average 1/(4pi) \int domega f(omega)
    5486            0 :  call ylm_angular_mesh(new%ntheta, new%nphi, new%angl_size, new%qvers_cart, new%angwgth)
    5487            0 :  write(std_out, *) sum(new%angwgth) * four_pi, "should be one"
    5488            0 :  write(std_out, *) sum(new%angwgth), "should be one"
    5489            0 :  stop
    5490              : 
    5491              :  !call lebedev%from_npts(npts, ierr)
    5492              :  !ABI_CHECK(ierr = 0, "Error while initializing lebedev mesh.")
    5493              : 
    5494              :  ! Precompute ph frequencies and displacement including NAC terms.
    5495              :  ABI_MALLOC(new%phfrq, (cryst%natom * 3, new%angl_size))
    5496              :  ABI_MALLOC(new%displ_cart, (2, 3, cryst%natom, cryst%natom * 3, new%angl_size))
    5497              : 
    5498              :  do iang=1,new%angl_size
    5499              :    !if (mod(iang, nprocs) /= my_rank) cycle ! MPI parallelism
    5500              :    call ifc%fourq(cryst, new%qvers_cart(:, iang) , new%phfrq(:,iang), new%displ_cart(:,:,:,:,iang), nanaqdir="cart")
    5501              :  end do
    5502              : 
    5503              : end subroutine frohl_integrator_init
    5504              : !!***
    5505              : 
    5506            0 : subroutine frohl_integrator_eval_isotropic_avg(self, cryst, ifc, comm, avg_value)
    5507              :   class(frohl_integrator_t),intent(in) :: self
    5508              :   type(crystal_t),intent(in) :: cryst
    5509              :   type(ifc_type),intent(in) :: ifc
    5510              :   integer,intent(in) :: comm
    5511              :   real(dp),intent(out) :: avg_value(cryst%natom * 3)
    5512              : 
    5513              : !Local variables ------------------------------
    5514              :   integer :: iang, iatom, nu, natom3, my_rank, nprocs, ierr
    5515              :   real(dp) :: inv_qepsq2, wqnu, qzd2, inv_wqnu2
    5516              :   complex(dp) :: cnum, cp3(3)
    5517              : !************************************************************************
    5518              : 
    5519            0 :   my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    5520            0 :   natom3 = 3 * cryst%natom
    5521            0 :   avg_value = zero
    5522              : 
    5523            0 :   do iang=1,self%angl_size
    5524            0 :     if (mod(iang, nprocs) /= my_rank) cycle ! MPI parallelism
    5525            0 :     associate (qpt_cart => self%qvers_cart(:, iang), displ_cart => self%displ_cart(:,:,:,:,iang))
    5526            0 :     inv_qepsq2 = (one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart))) ** 2
    5527              : 
    5528              :     ! NB: Acoustic modes are ignored here
    5529            0 :     do nu=4,natom3
    5530            0 :       wqnu = self%phfrq(nu, iang); inv_wqnu2 = one / wqnu ** 2
    5531              :       ! cnum = q.\sum_k Z_k.d(q,nu)
    5532            0 :       cp3 = czero
    5533            0 :       do iatom=1, cryst%natom
    5534            0 :         cp3 = cp3 + matmul(ifc%zeff(:, :, iatom), cmplx(displ_cart(1,:,iatom, nu), displ_cart(2,:,iatom, nu), kind=dp))
    5535              :       end do
    5536            0 :       cnum = dot_product(qpt_cart, cp3); qzd2 = abs(cnum) ** 2
    5537            0 :       avg_value(nu) = avg_value(nu) + self%angwgth(iang) * qzd2 * inv_qepsq2 * inv_wqnu2
    5538              :     end do
    5539              :     end associate
    5540              :   end do ! iang
    5541            0 :   call xmpi_sum(avg_value, comm, ierr)
    5542              : 
    5543            0 : end subroutine frohl_integrator_eval_isotropic_avg
    5544              : !!***
    5545              : 
    5546              : !!****f* m_epthk/frohl_integrator_find_mesh
    5547              : !! NAME
    5548              : !!
    5549              : !! FUNCTION
    5550              : !!  Find mesh size needed to converge the angular integrals
    5551              : !!
    5552              : !! SOURCE
    5553              : 
    5554              : subroutine frohl_integrator_find_mesh(cryst, ifc, ntheta, comm)
    5555              : 
    5556              : !Arguments ------------------------------------
    5557              :  type(crystal_t),intent(in) :: cryst
    5558              :  type(ifc_type),intent(in) :: ifc
    5559              :  integer,intent(out) :: ntheta
    5560              :  integer,intent(in) :: comm
    5561              : 
    5562              : !Local variables ------------------------------
    5563              :  integer :: iter, my_rank, nprocs
    5564              :  integer, parameter :: max_iter = 20
    5565              :  type(frohl_integrator_t) :: frohl
    5566              :  real(dp) :: REL_TOL = 0.02_dp
    5567              :  real(dp) :: new_value, old_value, avg_value_ph(3*cryst%natom)
    5568              :  logical :: converged
    5569              : !************************************************************************
    5570              : 
    5571              :  ! Increment ntheta by 50 at each iteration. Stop when the value of the integral changes less than REL_TOL.
    5572              :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    5573              : 
    5574              :  if (my_rank == 0) then
    5575              :    call wrtout(std_out, " frohl_integrator_find_mesh: find angular mesh to converge spherical average of Frohlich divergence...")
    5576              :  end if
    5577              :  converged = .False.; iter = 0; old_value = huge(old_value)
    5578              : 
    5579              :  outer_loop: do while (.not. converged .and. iter < max_iter)
    5580              :    iter = iter + 1
    5581              :    ntheta = iter * 2
    5582              :    call frohl%init(cryst, ifc, ntheta, comm)
    5583              : 
    5584              :    call frohl%eval_isotropic_avg(cryst, ifc, comm, avg_value_ph)
    5585              :    new_value = sum(avg_value_ph)
    5586              : 
    5587              :    if (my_rank == 0) then
    5588              :      write(std_out, "(a,i0,a,i0,a,i0,a,es16.8)") &
    5589              :        " frohl_integrator_find_mesh: iter: ", iter, " ntheta: ", ntheta, " angl_size: ", frohl%angl_size, " value: ", new_value
    5590              :    end if
    5591              : 
    5592              :    if (iter > 1) then
    5593              :      converged = (abs(new_value - old_value) <= (old_value * REL_TOL))
    5594              :    end if
    5595              :    old_value = new_value
    5596              :    call frohl%free()
    5597              :  end do outer_loop
    5598              : 
    5599              :  call frohl%free()
    5600              : 
    5601              :  if (.not. converged) then
    5602              :    ABI_ERROR("frohl_integrator_find_mesh didn't converge")
    5603              :  end if
    5604              : 
    5605              : end subroutine frohl_integrator_find_mesh
    5606              : !!***
    5607              : 
    5608              : !!****f* m_epthk/frohl_integrator_eval
    5609              : !! NAME
    5610              : !!
    5611              : !! FUNCTION
    5612              : !!
    5613              : !! INPUTS
    5614              : !!
    5615              : !! OUTPUT
    5616              : !!
    5617              : !! SOURCE
    5618              : 
    5619              : !! subroutine frohl_integrator_eval(self, cryst, ifc, nqbz, nwr, ntemp, nk_size, e_nk, f_nk, kTmesh, sig0_nk, z0_nk, comm)
    5620              : !!
    5621              : !! !Arguments ------------------------------------
    5622              : !!  class(frohl_integrator_t),intent(in) :: self
    5623              : !!  type(crystal_t),intent(in) :: cryst
    5624              : !!  type(ifc_type),intent(in) :: ifc
    5625              : !!  integer,intent(in) :: nqbz, nwr, ntemp, nk_size
    5626              : !!  real(dp),intent(in) :: kTmesh(ntemp)
    5627              : !!  real(dp),intent(in) :: e_nk(nk_size), f_nk(nk_size, ntemp)
    5628              : !!  real(dp),intent(out) :: sig0_nk(nk_size, ntemp), z0_nk(nk_size, ntemp) !, fm(nwr, ntemp, nk_size)
    5629              : !!  integer,intent(in) :: comm
    5630              : !!
    5631              : !! !Local variables ------------------------------
    5632              : !! !scalars
    5633              : !!  integer,parameter :: master = 0
    5634              : !!  integer :: iang, nu, iatom, ierr, my_rank, nprocs, natom3, ink, itemp
    5635              : !!  real(dp) :: inv_qepsq2, q0rad,  wqnu, inv_wqnu2, qzd2
    5636              : !!  complex(dp) :: cnum
    5637              : !! !arrays
    5638              : !!  complex(dp) :: cp3(3)
    5639              : !! !************************************************************************
    5640              : !!
    5641              : !!  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    5642              : !!  natom3 = 3 * cryst%natom
    5643              : !!
    5644              : !!  ! Radius of sphere with volume equivalent to the micro zone.
    5645              : !!  q0rad = two_pi * (three / (four_pi * cryst%ucvol * nqbz)) ** third
    5646              : !!  !bz_vol = two_pi**3 / cryst%ucvol
    5647              : !!
    5648              : !!  sig0_nk = zero; z0_nk = zero
    5649              : !!
    5650              : !!  ! Angular integration
    5651              : !!  do iang=1,self%angl_size
    5652              : !!    if (mod(iang, nprocs) /= my_rank) cycle ! MPI parallelism
    5653              : !!    associate (qpt_cart => self%qvers_cart(:, iang), displ_cart => self%displ_cart(:,:,:,:,iang))
    5654              : !!    inv_qepsq2 = (one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart))) ** 2
    5655              : !!    !call ifc%fourq(cryst, qpt_cart, phfrq, displ_cart, nanaqdir="cart")
    5656              : !!
    5657              : !!    ! NB: Acoustic modes are ignored here
    5658              : !!    do nu=4,natom3
    5659              : !!      wqnu = self%phfrq(nu, iang) !; if (ephtk_skip_phmode(nu, wqnu, self%phmodes_skip, dtset%eph_phrange_w)) cycle
    5660              : !!      inv_wqnu2 = one / wqnu ** 2
    5661              : !!
    5662              : !!      ! cnum = q.\sum_k Z_k.d(q,nu)
    5663              : !!      cp3 = czero
    5664              : !!      do iatom=1, cryst%natom
    5665              : !!        cp3 = cp3 + matmul(ifc%zeff(:, :, iatom), cmplx(displ_cart(1,:,iatom, nu), displ_cart(2,:,iatom, nu), kind=dp))
    5666              : !!      end do
    5667              : !!      cnum = dot_product(qpt_cart, cp3); qzd2 = abs(cnum) ** 2
    5668              : !!
    5669              : !!      ! Compute spherical average.
    5670              : !!      !zpr_frohl_sphcorr(nu) = zpr_frohl_sphcorr(nu) + self%angwgth(iang) * abs(cnum) ** 2 * inv_qepsq2 / wqnu ** 2
    5671              : !!
    5672              : !!      do ink=1,nk_size
    5673              : !!        do itemp=1,ntemp
    5674              : !!          sig0_nk(ink, itemp) = sig0_nk(ink, itemp) + self%angwgth(iang) * qzd2 * inv_qepsq2 * inv_wqnu2
    5675              : !!          !z0_nk(ink, itemp) = z0_nk(ink, itemp) +
    5676              : !!         end do ! itemp
    5677              : !!      end do ! ink
    5678              : !!
    5679              : !!      ! Get phonon occupation for all temperatures.
    5680              : !!      !nqnu_tlist = occ_be(wqnu, kTmesh(:), zero)
    5681              : !!
    5682              : !!      if (nwr > 0) then
    5683              : !!      !  ! NB: summing over f * angwgth gives the spherical average 1/(4pi) \int domega f(omega)
    5684              : !!      !  weight = four_pi * self%angwgth(iang) * abs(cnum) ** 2 * inv_qepsq2 / wqnu
    5685              : !!      !  do ib_k=1,nbcalc_ks
    5686              : !!      !    band_ks = ib_k + bstart_ks - 1; eig0nk = ebands%eig(band_ks, ik_ibz, spin)
    5687              : !!      !    do it=1,sigma%ntemp
    5688              : !!      !      f_nk = f_tlist_b(it,ib_k)
    5689              : !!      !      nqnu = nqnu_tlist(it)
    5690              : !!      !      fmw_frohl_sphcorr(:,nu,it,ib_k) = fmw_frohl_sphcorr(:,nu,it,ib_k) + &
    5691              : !!      !        ((nqnu + f_nk      ) / (sigma%wrmesh_b(:,ib_k) - eig0nk + wqnu + sigma%ieta) + &
    5692              : !!      !         (nqnu - f_nk + one) / (sigma%wrmesh_b(:,ib_k) - eig0nk - wqnu + sigma%ieta) ) * weight
    5693              : !!      !    end do ! it
    5694              : !!      !  end do ! ib_k
    5695              : !!      end if
    5696              : !!
    5697              : !!    end do
    5698              : !!    end associate
    5699              : !!  end do ! iang
    5700              : !!
    5701              : !!  do ink=1,nk_size
    5702              : !!    do itemp=1,ntemp
    5703              : !!      sig0_nk(ink, itemp) = sig0_nk(ink, itemp) * q0rad / (pi * cryst%ucvol) * (two * f_nk(ink, itemp) - one)
    5704              : !!      !z0_nk(ink, itemp) = z0_nk(ink, itemp) +
    5705              : !!     end do ! itemp
    5706              : !!  end do ! ink
    5707              : !!
    5708              : !!  call xmpi_sum(sig0_nk, comm, ierr)
    5709              : !!  call xmpi_sum(z0_nk, comm, ierr)
    5710              : !!
    5711              : !! end subroutine frohl_integrator_eval
    5712              : !!***
    5713              : 
    5714              : !!****f* m_epthk/frohl_integrator_free
    5715              : !! NAME
    5716              : !!
    5717              : !! FUNCTION
    5718              : !! Free dynamical memory
    5719              : !!
    5720              : !! SOURCE
    5721              : 
    5722            0 : subroutine frohl_integrator_free(self)
    5723              : 
    5724              : !Arguments ------------------------------------
    5725              :  class(frohl_integrator_t),intent(inout) :: self
    5726              : !************************************************************************
    5727              : 
    5728            0 :  ABI_SFREE(self%qvers_cart)
    5729            0 :  ABI_SFREE(self%angwgth)
    5730            0 :  ABI_SFREE(self%phfrq)
    5731            0 :  ABI_SFREE(self%displ_cart)
    5732              : 
    5733            0 : end subroutine frohl_integrator_free
    5734              : !!***
    5735              : 
    5736            0 : end module m_sigmaph
    5737              : !!***
        

Generated by: LCOV version 2.3-1