LCOV - code coverage report
Current view: top level - src/78_eph - m_phgamma.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 76.5 % 1765 1351
Test Date: 2026-11-10 16:57:26 Functions: 76.5 % 34 26
Branches: 50.7 % 5231 2653

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_phgamma
       2                 :             : !! NAME
       3                 :             : !!
       4                 :             : !! FUNCTION
       5                 :             : !!  Computation of phonon linewidths, isotropic superconducting properties,
       6                 :             : !!  and transport properties in metals within the LOVA approximation
       7                 :             : !!  to the linearized Boltzmann equation.
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !!  Copyright (C) 2008-2026 ABINIT group (MG)
      11                 :             : !!  This file is distributed under the terms of the
      12                 :             : !!  GNU General Public License, see ~abinit/COPYING
      13                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !!
      15                 :             : !! TODO
      16                 :             : !!  1) Implement restart capabilities (eph_restart).
      17                 :             : !!  2) Sum over the IBZ(q) on the FS instead of full BZ.
      18                 :             : !!  3) Gaussian adaptive smearing for double delta (tetra version from libtetrabz really slow!).
      19                 :             : !!  4) Automatic detections of energy window, improve filtering techniques.
      20                 :             : !!  5) Interface with KERANGE trick
      21                 :             : !!  6) More examples and tutorials (using precomputed Netcdf files).
      22                 :             : !!  7) Implement SKW interpolation for ph linewidths and/or linear interpolation (I don't trust plain Fourier interpolation).
      23                 :             : !!  8) Perform more benchmarks with dense meshes to detect hotspots and memory bottlenecks.
      24                 :             : !!  9) Test spin and SOC.
      25                 :             : !!
      26                 :             : !! SOURCE
      27                 :             : 
      28                 :             : #if defined HAVE_CONFIG_H
      29                 :             : #include "config.h"
      30                 :             : #endif
      31                 :             : 
      32                 :             : #include "abi_common.h"
      33                 :             : 
      34                 :             : module m_phgamma
      35                 :             : 
      36                 :             :  use, intrinsic :: iso_c_binding
      37                 :             :  use defs_basis
      38                 :             :  use m_abicore
      39                 :             :  use m_xmpi
      40                 :             :  use m_errors
      41                 :             :  use m_krank
      42                 :             :  use m_htetra
      43                 :             :  use m_tetrahedron
      44                 :             :  use libtetrabz
      45                 :             :  use m_ifc
      46                 :             :  use m_ebands
      47                 :             :  use m_fstab
      48                 :             :  use m_nctk
      49                 :             :  use netcdf
      50                 :             :  use m_wfk
      51                 :             :  use m_ddb
      52                 :             :  use m_ddk
      53                 :             :  use m_dvdb
      54                 :             :  use m_crystal
      55                 :             :  use m_fft
      56                 :             :  use m_hamiltonian
      57                 :             :  use m_pawcprj
      58                 :             :  use m_dtset
      59                 :             :  use m_dtfil
      60                 :             :  use m_ephtk
      61                 :             :  use m_mkffnl
      62                 :             : 
      63                 :             :  use defs_abitypes,    only : mpi_type
      64                 :             :  use defs_datatypes,   only : pseudopotential_type
      65                 :             :  use m_time,           only : cwtime, cwtime_report
      66                 :             :  use m_fstrings,       only : toupper, itoa, sjoin, ktoa, ltoa, strcat
      67                 :             :  use m_numeric_tools,  only : arth, wrap2_pmhalf, simpson_int, simpson, mkherm, get_diag, isdiagmat
      68                 :             :  use m_io_tools,       only : open_file, iomode_from_fname
      69                 :             :  use m_symtk,          only : littlegroup_q
      70                 :             :  use m_geometry,       only : normv
      71                 :             :  use m_special_funcs,  only : gaussian
      72                 :             :  use m_fftcore,        only : ngfft_seq, get_kg
      73                 :             :  use m_cgtools,        only : cg_zdotc
      74                 :             :  use m_kg,             only : getph, mkkpg
      75                 :             :  use m_dynmat,         only : symdyma, ftgam_init, ftgam, asrif9
      76                 :             :  use m_bz_mesh,        only : kpath_t
      77                 :             :  use m_special_funcs,  only : fermi_dirac
      78                 :             :  use m_kpts,           only : kpts_ibz_from_kptrlatt, tetra_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map
      79                 :             :  use defs_elphon,      only : complete_gamma !, complete_gamma_tr
      80                 :             :  use m_getgh1c,        only : getgh1c, rf_transgrid_and_pack
      81                 :             :  use m_pawang,         only : pawang_type
      82                 :             :  use m_pawrad,         only : pawrad_type
      83                 :             :  use m_pawtab,         only : pawtab_type
      84                 :             :  use m_pawfgr,         only : pawfgr_type
      85                 :             :  use m_wfd,            only : wfd_t
      86                 :             :  use m_pstat,          only : pstat_proc
      87                 :             :  use m_lgroup,         only : lgroup_t
      88                 :             :  use m_abi_linalg,     only : abi_gpu_xgemm_d
      89                 :             : 
      90                 :             :  implicit none
      91                 :             : 
      92                 :             :  private
      93                 :             : !!***
      94                 :             : 
      95                 :             :  public :: eph_phgamma
      96                 :             :  public :: find_ewin
      97                 :             : 
      98                 :             : !----------------------------------------------------------------------
      99                 :             : 
     100                 :             : !!****t* m_phgamma/phgamma_t
     101                 :             : !! NAME
     102                 :             : !! phgamma_t
     103                 :             : !!
     104                 :             : !! FUNCTION
     105                 :             : !! Provides methods for computing phonon linewidths, interpolating the results
     106                 :             : !! in q-space and evaluate superconducting properties within the isotropic formalism.
     107                 :             : !!
     108                 :             : !! SOURCE
     109                 :             : 
     110                 :             :  type,public :: phgamma_t
     111                 :             : 
     112                 :             :   integer :: natom = -1
     113                 :             :   ! Number of atoms per unit cell.
     114                 :             : 
     115                 :             :   integer :: natom3 = -1
     116                 :             :   ! Number of phonon branches i.e. 3*natom.
     117                 :             : 
     118                 :             :   integer :: nsppol = -1
     119                 :             :   ! Number of independent spin polarizations.
     120                 :             : 
     121                 :             :   integer :: nspinor = -1
     122                 :             :   ! Number of spinorial components.
     123                 :             : 
     124                 :             :   integer :: nqibz = -1
     125                 :             :   ! Number of q-points in the IBZ.
     126                 :             : 
     127                 :             :   integer :: my_nqibz = -1
     128                 :             :   ! Number of q-points in the IBZ treated by the current MPI processor
     129                 :             : 
     130                 :             :   integer :: nqbz = -1
     131                 :             :   ! Number of q-points in the BZ.
     132                 :             : 
     133                 :             :   integer :: eph_scalprod = 0
     134                 :             :   ! This to call anaddb routines. Note that eph_scalprod 1 is not supported in eph.
     135                 :             : 
     136                 :             :   integer :: bcorr = 0
     137                 :             :    ! 1 to include Blochl correction in the tetrahedron method else 0.
     138                 :             : 
     139                 :             :   integer :: prteliash = 0
     140                 :             :   ! This flag activates the computation of the Eliashberg function.
     141                 :             : 
     142                 :             :   integer :: nrpt = -1
     143                 :             :   ! Number of R-points in the real space representation of the gamma matrices.
     144                 :             : 
     145                 :             :   integer :: symgamma
     146                 :             :   ! 1 if gamma matrices should be symmetrized by symdyma when using Fourier interpolation
     147                 :             : 
     148                 :             :   integer :: asr
     149                 :             :   ! If the "Acoustic rule" at Gamma should be enforced.
     150                 :             : 
     151                 :             :   integer :: ndir_transp = 0
     152                 :             :   ! 0 if no transport, otherwise 3.
     153                 :             : 
     154                 :             :   integer :: ngqpt(3)
     155                 :             :   ! Number of divisions in the q-mesh.
     156                 :             : 
     157                 :             :   integer :: nene = -1
     158                 :             :   ! Number of chemical potential values used for inelastic integration
     159                 :             : 
     160                 :             :   !integer :: my_nqpt
     161                 :             :   !integer,allocatable :: my_iqpt(:)
     162                 :             : 
     163                 :             :   integer :: my_nfsk_q = -1
     164                 :             :   ! Number of k-points in the FS treated by this MPI processor for a given q.
     165                 :             :   ! Computed in phgamma_setup_qpoint.
     166                 :             : 
     167                 :             :   integer,allocatable :: my_ifsk_q(:)
     168                 :             :   ! Index of the FS k-points treated by this processor for a given q
     169                 :             :   ! Computed in phgamma_setup_qpoint.
     170                 :             : 
     171                 :             :   integer :: my_nspins = -1
     172                 :             :    ! Number of spins treated by the MPI rank.
     173                 :             : 
     174                 :             :   integer,allocatable :: my_spins(:)
     175                 :             :    ! my_spins(my_nspins)
     176                 :             :    ! Indirect table giving the spin indices treated by this rank.
     177                 :             :    ! Used only the collinear case with nspinor == 1
     178                 :             : 
     179                 :             :   !integer :: my_npert
     180                 :             :    ! Number of atomic perturbations or phonon modes treated by this MPI rank.
     181                 :             : 
     182                 :             :   !integer(i1b),allocatable :: itreat_qibz(:)
     183                 :             :    ! itreat_qibz(nqibz)
     184                 :             :    ! Table used to distribute potentials over q-points in the IBZ.
     185                 :             :    ! The loop over qpts in the IBZ(k) is MPI distributed inside qpt_comm accordinging to this table.
     186                 :             :    ! 0 if this IBZ point is not treated by this proc.
     187                 :             :    ! 1 if this IBZ is treated.
     188                 :             : 
     189                 :             :   !integer,allocatable :: my_pinfo(:,:)
     190                 :             :    ! my_pinfo(3, my_npert)
     191                 :             :    ! my_pinfo(1, ip) gives the `idir` index of the ip-th perturbation.
     192                 :             :    ! my_pinfo(2, ip) gives the `ipert` index of the ip-th perturbation.
     193                 :             :    ! my_pinfo(3, ip) gives `pertcase`=idir + (ipert-1)*3
     194                 :             : 
     195                 :             :   !integer,allocatable :: pert_table(:,:)
     196                 :             :    ! pert_table(2, natom3)
     197                 :             :    ! pert_table(1, npert): rank of the processor treating this atomic perturbation.
     198                 :             :    ! pert_table(2, npert): my_ip index in my_pinfo table, -1 if this rank is not treating ipert.
     199                 :             : 
     200                 :             :   integer, allocatable :: my_iqibz(:)
     201                 :             :   ! indices of ibz iq in local array. -1 if iq does not belong to current proc
     202                 :             : 
     203                 :             :   integer, allocatable :: my_iqbz(:)
     204                 :             :   ! List of iq_ibz indices treated by current proc
     205                 :             : 
     206                 :             :   real(dp) :: enemin
     207                 :             :   ! Minimal chemical potential value used for inelastic integration Copied from fstab
     208                 :             : 
     209                 :             :   real(dp) :: deltaene
     210                 :             :   ! Chemical potential increment for inelastic integration Copied from fstab
     211                 :             :   !   for simplicity could be made equal to phonon frequency step
     212                 :             : 
     213                 :             :   real(dp) :: gprim(3,3)
     214                 :             :   ! Needed for Fourier interpolation.
     215                 :             :   ! NOTE: gprim (not gprimd) is used for all FT interpolations,
     216                 :             :   ! to be consistent with the dimensions of the rpt, which come from anaddb.
     217                 :             : 
     218                 :             :   real(dp),allocatable :: n0(:)
     219                 :             :    ! (%nsppol)
     220                 :             :    ! Density of states at the Fermi level per spin in a.u.
     221                 :             : 
     222                 :             :   real(dp),allocatable :: qibz(:,:)
     223                 :             :   ! qibz(3,nqibz)
     224                 :             :   ! Reduced coordinates of the q-points in the IBZ.
     225                 :             : 
     226                 :             :   real(dp),allocatable :: wtq(:)
     227                 :             :   ! wtq(nqibz)
     228                 :             :   ! Weights of the q-points in the IBZ (normalized to one)
     229                 :             : 
     230                 :             :   real(dp),allocatable :: qbz(:,:)
     231                 :             :   ! qbz(3,nqbz)
     232                 :             :   ! Reduced coordinates of the q-points in the BZ.
     233                 :             : 
     234                 :             :   real(dp),allocatable :: rpt(:,:)
     235                 :             :   ! rpt(3,nrpt)
     236                 :             :   !  Reduced coordinates ***in terms of rprim*** of the lattice points used
     237                 :             :   !  for the Fourier transform of the phonon linewidths.
     238                 :             : 
     239                 :             :   real(dp),allocatable :: wghatm(:,:,:)
     240                 :             :   ! wghatm(natom,natom,nrpt)
     241                 :             :   ! Weights used in the FT of the phonon linewidths.
     242                 :             : 
     243                 :             :   real(dp),allocatable :: vals_qibz(:,:,:,:,:)
     244                 :             :   ! vals_qibz(2,natom3,natom3,nqibz,nsppol)) in reduced coordinates for each q-point in the IBZ.
     245                 :             :   ! vals_qibz {\tau'\alpha',\tau\alpha} = sum over k, im_kq, in_k
     246                 :             :   !   <psi_{k+q,im_kq} | H(1)_{\tau'\alpha'} | psi_{k,in_k}>*  \cdot
     247                 :             :   !   <psi_{k+q,im_kq} | H(1)_{\tau \alpha } | psi_{k,in_k}>
     248                 :             : 
     249                 :             :   !NOTE: choice to put nsppol before or after nqbz is a bit arbitrary
     250                 :             :   !   abinit uses nband,nkpt,nsppol, but here for convenience nkpt_phon,nsppol,nqbz interpolation is on qpt
     251                 :             :   !MG: I think that nsppol should be the last dimension set call to ftgam.
     252                 :             : 
     253                 :             :   real(dp),allocatable :: vals_rpt(:,:,:,:)
     254                 :             :   ! vals_rpt(2,natom3**2,nrpt,nsppol)
     255                 :             :   ! tgamma matrices in real space in reduced coordinates. Used for the Fourier interpolation.
     256                 :             : 
     257                 :             :   ! transport stuff with velocity factors
     258                 :             :   real(dp),allocatable :: vals_in_qibz(:,:,:,:,:,:)
     259                 :             :   real(dp),allocatable :: vals_out_qibz(:,:,:,:,:,:)
     260                 :             :   ! vals_XX_qibz(2,9,natom3,natom3,nqibz,nsppol)) in reduced coordinates for each q-point in the IBZ.
     261                 :             : 
     262                 :             :   real(dp),allocatable :: vals_in_rpt(:,:,:,:,:)
     263                 :             :   real(dp),allocatable :: vals_out_rpt(:,:,:,:,:)
     264                 :             :   ! vals_XX_rpt(2,9,natom3**2,nrpt,nsppol)
     265                 :             :   ! tgamma matrices in real space in reduced coordinates.
     266                 :             : 
     267                 :             :   ! gamma matrices keeping full electron energy dependency
     268                 :             :   real(dp),allocatable :: vals_ee(:,:,:,:,:,:,:)
     269                 :             :   ! vals_eew(2, nene, nene, natom3, natom3, nqibz, nsppol)
     270                 :             : 
     271                 :             :   contains
     272                 :             : 
     273                 :             :    procedure :: free => phgamma_free
     274                 :             :     ! Free memory.
     275                 :             : 
     276                 :             :    procedure :: interp => phgamma_interp
     277                 :             :     ! Interpolates the phonon linewidths.
     278                 :             : 
     279                 :             :    procedure :: eval_qibz => phgamma_eval_qibz
     280                 :             :     ! Evaluate phonon linewidths without Fourier interpolation.
     281                 :             : 
     282                 :             :    procedure :: interp_setup => phgamma_interp_setup
     283                 :             :     ! Compute the tables used for the interpolation in q-space.
     284                 :             : 
     285                 :             :    procedure :: linwid => phgamma_linwid
     286                 :             :     ! Interpolate linewidths along an arbitrary q-path.
     287                 :             : 
     288                 :             :  end type phgamma_t
     289                 :             : 
     290                 :             :  public :: phgamma_init          ! Creation method.
     291                 :             : !!***
     292                 :             : 
     293                 :             : !----------------------------------------------------------------------
     294                 :             : 
     295                 :             : !!****t* m_phgamma/a2fw_t
     296                 :             : !! NAME
     297                 :             : !! a2fw_t
     298                 :             : !!
     299                 :             : !! FUNCTION
     300                 :             : !! Store the Eliashberg function a2F(w).
     301                 :             : !!
     302                 :             : !! SOURCE
     303                 :             : 
     304                 :             :  type,public :: a2fw_t
     305                 :             : 
     306                 :             :   integer :: nomega
     307                 :             :   ! Number of frequency points in a2f(w).
     308                 :             : 
     309                 :             :   integer :: nsppol
     310                 :             :   ! Number of independent spin polarizations.
     311                 :             : 
     312                 :             :   integer :: natom3
     313                 :             :   ! Number of phonon modes.
     314                 :             : 
     315                 :             :   integer :: nene
     316                 :             :   ! Number of chemical potential values used for inelastic integration
     317                 :             : 
     318                 :             :   real(dp) :: enemin
     319                 :             :   ! Minimal chemical potential value used for inelastic integration Copied from fstab
     320                 :             : 
     321                 :             :   real(dp) :: deltaene
     322                 :             :   ! Chemical potential increment for inelastic integration Copied from fstab
     323                 :             :   ! for simplicity could be made equal to phonon frequency step
     324                 :             : 
     325                 :             :   real(dp) :: omega_min, omega_max
     326                 :             :   ! min and Max frequency (Ha) in the linear mesh.
     327                 :             : 
     328                 :             :   real(dp) :: wstep
     329                 :             :   ! Step of the linear mesh
     330                 :             : 
     331                 :             :   real(dp) :: smear
     332                 :             :   ! Gaussian broadening used to approximated the Dirac distribution.
     333                 :             : 
     334                 :             :   integer :: nqshift
     335                 :             :   ! Number of shifts in the q-mesh
     336                 :             : 
     337                 :             :   integer :: ngqpt(3)
     338                 :             :   ! The q-mesh used for calculating vals(w).
     339                 :             : 
     340                 :             :   real(dp),allocatable :: qshift(:,:)
     341                 :             :   ! qshift(3,nqshift)
     342                 :             :   ! The shifts used to generate the q-mesh.
     343                 :             : 
     344                 :             :   real(dp),allocatable :: n0(:)
     345                 :             :   ! n0(nsppol)
     346                 :             :   ! Electronic DOS at the Fermi level.
     347                 :             : 
     348                 :             :   real(dp),allocatable :: omega(:)
     349                 :             :   ! omega(nomega)
     350                 :             :   ! Frequency mesh in Hartree (linear).
     351                 :             : 
     352                 :             :   real(dp),allocatable :: vals(:,:,:)
     353                 :             :   ! vals(nomega, 0:natom3, nsppol)
     354                 :             :   ! Eliashberg function
     355                 :             :   !   vals(w, 1:natom3, 1:nsppol): a2f(w) decomposed per phonon branch and spin
     356                 :             :   !   vals(w, 0       , 1:nsppol): a2f(w) summed over phonons modes, decomposed in spin
     357                 :             : 
     358                 :             :   real(dp),allocatable :: vals_ee(:,:,:,:)
     359                 :             :   ! vals_ee(nene,nene,nomega,nsppol)
     360                 :             :   ! Eliashberg function
     361                 :             :   !   vals(e,e',w,0,1:nsppol): a2f(e,e',w) summed over phonons modes, decomposed in spin
     362                 :             : 
     363                 :             :   real(dp),allocatable :: lambdaw(:,:,:)
     364                 :             :   ! lambda(nomega,0:natom3,nsppol)
     365                 :             : 
     366                 :             :   contains
     367                 :             : 
     368                 :             :    procedure :: init => a2fw_init            !
     369                 :             :     ! Calculates the FS averaged alpha^2F(w) function.
     370                 :             : 
     371                 :             :    procedure :: free => a2fw_free
     372                 :             :     ! Free the memory allocated in the structure.
     373                 :             : 
     374                 :             :    procedure :: write => a2fw_write
     375                 :             :     ! Write alpha^2F(w) to an external file in text/netcdf format
     376                 :             : 
     377                 :             :    procedure :: get_moment => a2fw_get_moment
     378                 :             :     ! Compute moments of alpha^2F(w)/w .
     379                 :             :  end type a2fw_t
     380                 :             : !!***
     381                 :             : 
     382                 :             : !!****t* m_phgamma/a2fw_tr_t
     383                 :             : !! NAME
     384                 :             : !! a2fw_tr_t
     385                 :             : !!
     386                 :             : !! FUNCTION
     387                 :             : !! Store the Eliashberg transport spectral functions:
     388                 :             : !!    a2F_trin(w, x, x')
     389                 :             : !!    a2F_trout(w, x, x')
     390                 :             : !!    a2F_tr(w, x, x') = in - out
     391                 :             : !!    a2F_tr_gen(e, e', w, x, x')
     392                 :             : !!
     393                 :             : !! SOURCE
     394                 :             : 
     395                 :             :  type,public :: a2fw_tr_t
     396                 :             : 
     397                 :             :   integer :: nomega
     398                 :             :   ! Number of frequency points in a2f_tr(w).
     399                 :             : 
     400                 :             :   integer :: nene
     401                 :             :   ! Number of chemical potential values used for inelastic integration
     402                 :             :   ! Number of electron points in a2f_tr_gen(e,e',w).
     403                 :             : 
     404                 :             :   integer :: nsppol
     405                 :             :   ! Number of independent spin polarizations.
     406                 :             : 
     407                 :             :   integer :: natom3
     408                 :             :   ! Number of phonon modes.
     409                 :             : 
     410                 :             :   real(dp) :: enemin
     411                 :             :   ! Minimal chemical potential value used for inelastic integration
     412                 :             : 
     413                 :             :   real(dp) :: deltaene
     414                 :             :   ! Chemical potential increment for inelastic integration
     415                 :             : 
     416                 :             :   real(dp) :: omega_min,omega_max
     417                 :             :   ! min and Max frequency (Ha) in the linear mesh.
     418                 :             : 
     419                 :             :   real(dp) :: wstep
     420                 :             :   ! Step of the linear mesh
     421                 :             : 
     422                 :             :   real(dp) :: smear
     423                 :             :   ! Gaussian broadening used to approximated the Dirac distribution.
     424                 :             : 
     425                 :             :   integer :: nqshift
     426                 :             :   ! Number of shifts in the q-mesh
     427                 :             : 
     428                 :             :   integer :: ngqpt(3)
     429                 :             :   ! The q-mesh used for calculating vals(w).
     430                 :             : 
     431                 :             :   real(dp),allocatable :: qshift(:,:)
     432                 :             :   ! qshift(3,nqshift)
     433                 :             :   ! The shifts used to generate the q-mesh.
     434                 :             : 
     435                 :             :   real(dp),allocatable :: n0(:)
     436                 :             :   ! n0(nsppol)
     437                 :             :   ! Electronic DOS at the Fermi level.
     438                 :             : 
     439                 :             :   real(dp),allocatable :: omega(:)
     440                 :             :   ! omega(nomega)
     441                 :             :   ! Frequency mesh in Hartree (linear).
     442                 :             : 
     443                 :             :   real(dp),allocatable :: vals_in(:,:,:,:,:)
     444                 :             :   real(dp),allocatable :: vals_out(:,:,:,:,:)
     445                 :             :   ! vals_in(nomega,3,3,0:natom3,nsppol)
     446                 :             :   ! Eliashberg transport functions for in and out scattering
     447                 :             :   !   vals_in(w,3,3,1:natom3,1:nsppol): a2f_tr(w) decomposed per phonon branch and spin
     448                 :             :   !   vals_in(w,3,3,0,1:nsppol): a2f_tr(w) summed over phonons modes, decomposed in spin
     449                 :             : 
     450                 :             :   real(dp),allocatable :: vals_tr(:,:,:,:,:)
     451                 :             :   ! vals_tr(nomega,3,3,0:natom3,nsppol)
     452                 :             :   ! transport spectral function = in-out
     453                 :             : 
     454                 :             :   real(dp),allocatable :: vals_tr_gen(:,:,:,:,:,:,:)
     455                 :             :   ! vals(nene,nene,nomega,3,3,nsppol)
     456                 :             :   ! generalized transport spectral function from PB Allen Phys. Rev. Lett. 59, 1460 (1987) [[cite:Allen1987]]
     457                 :             : 
     458                 :             :   real(dp),allocatable :: lambdaw_tr(:,:,:,:,:)
     459                 :             :   ! lambda(nomega,3,3,0:natom3,nsppol)
     460                 :             : 
     461                 :             :   contains
     462                 :             : 
     463                 :             :   procedure :: init =>  a2fw_tr_init
     464                 :             :    ! Calculates the FS averaged alpha^2F_tr,in,out(w, x, x') functions.
     465                 :             : 
     466                 :             :   procedure :: free => a2fw_tr_free
     467                 :             :    ! Free the memory allocated in the structure.
     468                 :             : 
     469                 :             :   procedure :: write => a2fw_tr_write
     470                 :             :    ! Write alpha^2F(w) to an external file in text/netcdf format
     471                 :             : 
     472                 :             :  end type a2fw_tr_t
     473                 :             : !!***
     474                 :             : 
     475                 :             :  real(dp),private,parameter :: EPH_Q0TOL = 0.01_dp
     476                 :             : 
     477                 :             : contains  !=====================================================
     478                 :             : !!***
     479                 :             : 
     480                 :             : !----------------------------------------------------------------------
     481                 :             : 
     482                 :             : !!****f* m_phgamma/phgamma_free
     483                 :             : !! NAME
     484                 :             : !! phgamma_free
     485                 :             : !!
     486                 :             : !! FUNCTION
     487                 :             : !!  Free the dynamic memory
     488                 :             : !!
     489                 :             : !! SOURCE
     490                 :             : 
     491                 :           5 : subroutine phgamma_free(gams)
     492                 :             : 
     493                 :             : !Arguments ------------------------------------
     494                 :             :  class(phgamma_t),intent(inout) :: gams
     495                 :             : ! *************************************************************************
     496                 :             : 
     497                 :             :  !real
     498         [ +  - ]:           5 :  ABI_SFREE(gams%n0)
     499         [ +  - ]:           5 :  ABI_SFREE(gams%qibz)
     500         [ +  - ]:           5 :  ABI_SFREE(gams%wtq)
     501         [ +  - ]:           5 :  ABI_SFREE(gams%qbz)
     502         [ +  - ]:           5 :  ABI_SFREE(gams%rpt)
     503         [ +  - ]:           5 :  ABI_SFREE(gams%wghatm)
     504         [ +  - ]:           5 :  ABI_SFREE(gams%vals_qibz)
     505         [ +  - ]:           5 :  ABI_SFREE(gams%vals_rpt)
     506         [ +  - ]:           5 :  ABI_SFREE(gams%vals_in_qibz)
     507         [ +  - ]:           5 :  ABI_SFREE(gams%vals_in_rpt)
     508         [ +  - ]:           5 :  ABI_SFREE(gams%vals_out_qibz)
     509         [ +  - ]:           5 :  ABI_SFREE(gams%vals_out_rpt)
     510         [ -  + ]:           5 :  ABI_SFREE(gams%vals_ee)
     511         [ +  - ]:           5 :  ABI_SFREE(gams%my_iqibz)
     512         [ +  - ]:           5 :  ABI_SFREE(gams%my_ifsk_q)
     513         [ +  - ]:           5 :  ABI_SFREE(gams%my_spins)
     514                 :             : 
     515                 :           5 : end subroutine phgamma_free
     516                 :             : !!***
     517                 :             : 
     518                 :             : !----------------------------------------------------------------------
     519                 :             : 
     520                 :             : !!****f* m_phgamma/phgamma_init
     521                 :             : !! NAME
     522                 :             : !! phgamma_init
     523                 :             : !!
     524                 :             : !! FUNCTION
     525                 :             : !!  Creation method for the phgamma_t datatype.
     526                 :             : !!
     527                 :             : !! INPUTS
     528                 :             : !! cryst<crystal_t>
     529                 :             : !! ifc<ifc_type>=Interatomic force constants.
     530                 :             : !! symdynmat=1 to activa symmetrization of gamma matrices.
     531                 :             : !! ngqpt(3)=Q-mesh divisions
     532                 :             : !! n0(dtset%nsppol)=Density of states at the Fermi level per spin.
     533                 :             : !!
     534                 :             : !! OUTPUT
     535                 :             : !! gams<phgamma_t>
     536                 :             : !!
     537                 :             : !! SOURCE
     538                 :             : 
     539         [ +  - ]:           5 : subroutine phgamma_init(gams, cryst, ifc, ebands, fstab, dtset, eph_scalprod, ngqpt, n0, comm)
     540                 :             : 
     541                 :             : !Arguments ------------------------------------
     542                 :             : !scalars
     543                 :             :  class(phgamma_t),intent(out) :: gams
     544                 :             :  integer,intent(in) :: eph_scalprod, comm
     545                 :             :  type(crystal_t),intent(in) :: cryst
     546                 :             :  type(ifc_type),intent(in) :: ifc
     547                 :             :  type(ebands_t),intent(in) :: ebands
     548                 :             :  type(fstab_t), intent(in) :: fstab
     549                 :             :  type(dataset_type),intent(in) :: dtset
     550                 :             : !arrays
     551                 :             :  integer,intent(in) :: ngqpt(3)
     552                 :             :  real(dp),intent(in) :: n0(dtset%nsppol)
     553                 :             : 
     554                 :             : !Local variables-------------------------------
     555                 :             : !scalars
     556                 :             :  integer :: my_rank, nproc, ierr, nsppol, natom3, qptopt, qtimrev
     557                 :             : !arrays
     558                 :             :  integer :: qptrlatt(3,3)
     559                 :             : ! *************************************************************************
     560                 :             : 
     561                 :           5 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
     562                 :             : 
     563                 :             :  ! Set basic dimensions.
     564                 :           5 :  nsppol = dtset%nsppol; gams%nsppol = nsppol; gams%nspinor = dtset%nspinor
     565                 :             : 
     566                 :           5 :  gams%natom = cryst%natom; gams%natom3 = 3*cryst%natom; natom3 = gams%natom3
     567                 :             : 
     568                 :           5 :  gams%symgamma = dtset%symdynmat; gams%eph_scalprod = eph_scalprod
     569                 :             :  !gams%asr = ifc%asr
     570                 :           5 :  gams%asr = 0
     571                 :           5 :  gams%prteliash = dtset%prteliash
     572                 :             : 
     573         [ +  - ]:           5 :  gams%ndir_transp = 0; if (dtset%eph_transport > 0) gams%ndir_transp = 3
     574                 :             : 
     575                 :             :  ! Copy DOS.
     576   [ -  +  +  -  :          15 :  ABI_MALLOC(gams%n0, (nsppol))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     577   [ -  +  +  + ]:          15 :  gams%n0 = n0
     578                 :             : 
     579                 :           5 :  gams%nene = fstab%nene
     580                 :           5 :  gams%enemin = fstab%enemin
     581                 :           5 :  gams%deltaene = fstab%deltaene
     582                 :             : 
     583                 :             :  ! Setup IBZ, weights and BZ. Always use q --> -q symmetry for phonons even in systems wo inversion
     584         [ +  + ]:          20 :  gams%ngqpt = ngqpt
     585                 :           5 :  qptrlatt = 0; qptrlatt(1,1) = ngqpt(1); qptrlatt(2,2) = ngqpt(2); qptrlatt(3,3) = ngqpt(3)
     586         [ -  + ]:           5 :  qptopt = ebands%kptopt; if (dtset%qptopt /= 0) qptopt = dtset%qptopt
     587                 :             :  qtimrev = kpts_timrev_from_kptopt(qptopt)
     588                 :             : 
     589                 :             :  call kpts_ibz_from_kptrlatt(cryst, qptrlatt, qptopt, 1, [zero, zero, zero], &
     590   [ -  +  -  +  :           5 :                              gams%nqibz, gams%qibz, gams%wtq, gams%nqbz, gams%qbz)
                   -  + ]
     591                 :             : 
     592                 :             :  ! Allocate matrices in the IBZ.
     593   [ -  +  +  -  :          30 :  ABI_MALLOC_OR_DIE(gams%vals_qibz, (2, natom3, natom3, gams%nqibz, nsppol), ierr)
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  -  
                      + ]
     594   [ +  +  +  +  :        1901 :  gams%vals_qibz = zero
          +  +  +  +  +  
                      + ]
     595                 :             : 
     596         [ +  - ]:           5 :  if (dtset%eph_transport > 0) then
     597   [ -  +  +  -  :          30 :    ABI_MALLOC_OR_DIE(gams%vals_in_qibz, (2, 9, natom3, natom3, gams%nqibz, nsppol), ierr)
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  -  
                      + ]
     598   [ +  +  +  +  :       15626 :    gams%vals_in_qibz = zero
          +  +  +  +  +  
                +  +  + ]
     599   [ -  +  +  -  :          30 :    ABI_MALLOC_OR_DIE(gams%vals_out_qibz, (2, 9, natom3, natom3, gams%nqibz, nsppol), ierr)
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  -  
                      + ]
     600   [ +  +  +  +  :       15626 :    gams%vals_out_qibz = zero
          +  +  +  +  +  
                +  +  + ]
     601                 :             :  end if
     602                 :             : 
     603         [ -  + ]:           5 :  if (gams%prteliash == 3) then
     604   [ #  #  #  #  :           0 :    ABI_MALLOC_OR_DIE(gams%vals_ee, (2, gams%nene, gams%nene, natom3, natom3, gams%nqibz, nsppol), ierr)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     605   [ #  #  #  #  :           0 :    gams%vals_ee = zero
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     606                 :             :  end if
     607                 :             : 
     608                 :             :  ! Prepare Fourier interpolation.
     609   [ +  +  +  + ]:          65 :  gams%gprim = ifc%gprim
     610                 :           5 :  gams%nrpt  = ifc%nrpt
     611   [ -  +  +  -  :          15 :  ABI_MALLOC(gams%rpt, (3, gams%nrpt))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     612   [ +  -  +  -  :        1870 :  gams%rpt = ifc%rpt
          -  +  -  -  -  
          -  -  -  +  +  
                   +  + ]
     613   [ -  +  +  -  :          25 :  ABI_MALLOC(gams%wghatm, (gams%natom, gams%natom, gams%nrpt))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     614   [ +  -  +  -  :        1405 :  gams%wghatm = ifc%wghatm
          +  -  -  +  -  
          -  -  -  -  -  
          -  -  +  +  +  
                +  +  + ]
     615                 :             : 
     616                 :           5 : end subroutine phgamma_init
     617                 :             : !!***
     618                 :             : 
     619                 :             : !----------------------------------------------------------------------
     620                 :             : 
     621                 :             : !!****f* m_phgamma/phgamma_ncwrite
     622                 :             : !! NAME
     623                 :             : !! phgamma_ncwrite
     624                 :             : !!
     625                 :             : !! FUNCTION
     626                 :             : !!  Write the results stored in the phgamma_t datatype to netcdf file.
     627                 :             : !!
     628                 :             : !! INPUTS
     629                 :             : !! cryst<crystal_t>=Crystalline structure.
     630                 :             : !! ifc<ifc_type>=Interatomic force constants.
     631                 :             : !! ncid=Netcdf file handler (already open in the caller).
     632                 :             : !!
     633                 :             : !! SOURCE
     634                 :             : 
     635                 :           5 : subroutine phgamma_ncwrite(gams, cryst, ifc, ncid)
     636                 :             : 
     637                 :             : !Arguments ------------------------------------
     638                 :             : !scalars
     639                 :             :  class(phgamma_t),intent(inout) :: gams
     640                 :             :  type(crystal_t),intent(in) :: cryst
     641                 :             :  type(ifc_type),intent(in) :: ifc
     642                 :             :  integer,intent(in) :: ncid
     643                 :             : 
     644                 :             : !Local variables-------------------------------
     645                 :             : !scalars
     646                 :             :  integer :: max_nqpt = 50
     647                 :             :  integer :: iq_ibz,spin,mu, units(2)
     648                 :             :  real(dp) :: lambda_tot, cpu, wall, gflops
     649                 :             :  character(len=500) :: msg
     650                 :             : !arrays
     651                 :          10 :  real(dp) :: phfrq(3*cryst%natom), gamma_ph(3*cryst%natom), lambda_ph(3*cryst%natom)
     652                 :          10 :  real(dp) :: displ_cart(2,3*cryst%natom,3*cryst%natom)
     653                 :             : ! *************************************************************************
     654                 :             : 
     655         [ +  + ]:          15 :  units = [std_out, ab_out]
     656                 :           5 :  call cwtime(cpu, wall, gflops, "start")
     657                 :             : 
     658                 :             :  ! Write data to files for each q point, also compute total lambda.
     659                 :           5 :  lambda_tot = zero
     660         [ +  + ]:          10 :  do spin=1,gams%nsppol
     661         [ +  + ]:          66 :    do iq_ibz=1,gams%nqibz
     662                 :             : 
     663                 :             :      ! Get phonon frequencies, gamma(q,nu) and lambda(q,nu).
     664                 :             :      ! Quantities are already summed over (collinear) spin channels if nsppol == 1.
     665                 :          61 :      call gams%eval_qibz(cryst, ifc, iq_ibz, spin, phfrq, gamma_ph, lambda_ph, displ_cart)
     666                 :             : 
     667         [ +  + ]:         244 :      do mu=1,gams%natom3
     668                 :         244 :        lambda_tot = lambda_tot + lambda_ph(mu) * gams%wtq(iq_ibz)
     669                 :             :      end do
     670                 :             : 
     671                 :             :      ! Write data to netcdf file
     672         [ +  - ]:          61 :      if (ncid /= nctk_noid) then
     673         [ +  - ]:          61 :        if (spin == 1) then
     674   [ +  +  -  +  :         183 :          NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phfreq_qibz"), phfrq, start=[1, iq_ibz]))
                   -  - ]
     675   [ +  +  -  +  :         305 :          NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phdispl_cart_qibz'), displ_cart, start=[1, 1, 1, iq_ibz]))
                   -  - ]
     676                 :             :        end if
     677   [ +  +  -  +  :         244 :        NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phgamma_qibz'), gamma_ph, start=[1, iq_ibz, spin]))
                   -  - ]
     678   [ +  +  -  +  :         244 :        NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'phlambda_qibz'), lambda_ph, start=[1, iq_ibz, spin]))
                   -  - ]
     679                 :             :      end if
     680                 :             : 
     681                 :             :      ! Output to the main output file
     682         [ +  - ]:          66 :      if (iq_ibz <= max_nqpt) then
     683         [ -  + ]:          61 :        if (gams%nsppol == 2) then
     684                 :           0 :          write(msg,'(2a,3es16.6,a,i1,a,a)')ch10,&
     685                 :           0 :            ' q-point =',gams%qibz(:, iq_ibz),'   spin = ',spin,ch10,&
     686                 :           0 :            ' Mode number    Frequency (Ha)  Linewidth (Ha)  Lambda(q,n)'
     687                 :             :        else
     688                 :          61 :          write(msg,'(2a,3es16.6,a,a)')ch10,&
     689                 :          61 :            ' q-point =',gams%qibz(:, iq_ibz),ch10,&
     690                 :         122 :            ' Mode number    Frequency (Ha)  Linewidth (Ha)  Lambda(q,n)'
     691                 :             :        end if
     692                 :          61 :        call wrtout(units, msg)
     693         [ +  + ]:         244 :        do mu=1,gams%natom3
     694                 :         183 :          write(msg,'(i5,es20.6,2es16.6)')mu, phfrq(mu), gamma_ph(mu), lambda_ph(mu)
     695                 :         244 :          call wrtout(units, msg)
     696                 :             :        end do
     697                 :             :      else
     698         [ #  # ]:           0 :       if (iq_ibz == max_nqpt + 1) then
     699                 :           0 :         call wrtout(units, sjoin(" No more that:", itoa(max_nqpt), " q-points are reported in the main output file"))
     700                 :           0 :         call wrtout(units, " Use A2f.nc and AbiPy to analyze the results.")
     701                 :             :       end if
     702                 :             :      end if
     703                 :             : 
     704                 :             :    end do
     705                 :             :    ! Add blank lines to output files between spins
     706                 :          10 :    call wrtout(units, "", do_flush=.True.)
     707                 :             :  end do
     708                 :             : 
     709                 :           5 :  write(ab_out,"(a,f8.4)")" lambda= ",lambda_tot
     710                 :             :  !write(ab_out,"(a,f8.4)")" omega_log= ",omega_log
     711                 :             : 
     712                 :           5 :  call cwtime_report(" phgamma_ncwrite:", cpu, wall, gflops)
     713                 :             : 
     714                 :           5 : end subroutine phgamma_ncwrite
     715                 :             : !!***
     716                 :             : 
     717                 :             : !----------------------------------------------------------------------
     718                 :             : 
     719                 :             : !!****f* m_phgamma/tgamma_symm
     720                 :             : !! NAME
     721                 :             : !! tgamma_symm
     722                 :             : !!
     723                 :             : !! FUNCTION
     724                 :             : !!  Symmetrize the tgamma matrix
     725                 :             : !!
     726                 :             : !! INPUTS
     727                 :             : !! qpt(3)=phonon wavevector in reduced coordinates.
     728                 :             : !! cryst<crystal_t>=Crystalline structure.
     729                 :             : !!
     730                 :             : !! SOURCE
     731                 :             : 
     732                 :       14809 : subroutine tgamma_symm(cryst, qpt, tgamma)
     733                 :             : 
     734                 :             : !Arguments ------------------------------------
     735                 :             : !scalars
     736                 :             :  type(crystal_t),intent(in) :: cryst
     737                 :             : !arrays
     738                 :             :  real(dp),intent(in) :: qpt(3)
     739                 :             :  real(dp),intent(inout) :: tgamma(2,3*cryst%natom,3*cryst%natom)
     740                 :             : 
     741                 :             : !Local variables-------------------------------
     742                 :             : !scalars
     743                 :             :  integer :: ii,natom3,k
     744                 :             : !arrays
     745                 :       29618 :  real(dp) :: tgcart(2,3*cryst%natom,3*cryst%natom)
     746                 :       14809 :  real(dp) :: umat(2,3*cryst%natom,3*cryst%natom),tmp_mat(2,3*cryst%natom,3*cryst%natom)
     747                 :             : ! *********************************************************************
     748                 :             : 
     749                 :             :  ! Build U matrix.
     750   [ +  +  +  +  :      459079 :  umat = zero; k = 1
                   +  + ]
     751         [ +  + ]:       29618 :  do ii=1,cryst%natom
     752   [ +  +  +  + ]:      192517 :    umat(1,k:k+2, k:k+2) = cryst%gprimd
     753                 :       29618 :    k = k + 3
     754                 :             :  end do
     755                 :             : 
     756                 :       14809 :  natom3 = 3 * cryst%natom
     757                 :             : 
     758                 :             :  ! Reduced --> Cartesian
     759                 :       14809 :  call zgemm('N', 'N', natom3, natom3, natom3, cone, tgamma, natom3, umat, natom3, czero, tmp_mat, natom3)
     760                 :       14809 :  call zgemm('T', 'N', natom3, natom3, natom3, cone, umat, natom3, tmp_mat, natom3, czero, tgcart, natom3)
     761                 :             : 
     762                 :             :  ! Make the matrix hermitian
     763                 :       14809 :  call mkherm(tgcart, 3*cryst%natom)
     764                 :             : 
     765                 :             :  ! Symmetrize tgamma matrix.
     766                 :       14809 :  call symdyma(tgcart, cryst%indsym, cryst%natom, cryst%nsym, qpt, cryst%rprimd, cryst%symrel, cryst%symafm)
     767                 :             : 
     768   [ +  +  +  +  :      459079 :  umat = zero; k = 1
                   +  + ]
     769         [ +  + ]:       29618 :  do ii=0,cryst%natom-1
     770   [ +  +  +  + ]:      192517 :    umat(1,k:k+2, k:k+2) = cryst%rprimd
     771                 :       29618 :    k = k + 3
     772                 :             :  end do
     773                 :             : 
     774                 :             :  ! Cartesian --> Reduced
     775                 :       14809 :  call zgemm('N', 'N', natom3, natom3, natom3, cone, tgcart, natom3, umat, natom3, czero, tmp_mat, natom3)
     776                 :       14809 :  call zgemm('T', 'N', natom3, natom3, natom3, cone, umat, natom3, tmp_mat, natom3, czero, tgamma, natom3)
     777                 :             : 
     778                 :       14809 : end subroutine tgamma_symm
     779                 :             : !!***
     780                 :             : 
     781                 :             : !----------------------------------------------------------------------
     782                 :             : 
     783                 :             : !!****f* m_phgamma/phgamma_eval_qibz
     784                 :             : !! NAME
     785                 :             : !! phgamma_eval_qibz
     786                 :             : !!
     787                 :             : !! FUNCTION
     788                 :             : !! Compute the phonon linewidths for q-points in the IBZ without performing the interpolation.
     789                 :             : !!
     790                 :             : !! INPUTS
     791                 :             : !!  cryst<crystal_t>=Crystal structure.
     792                 :             : !!  ifc<ifc_type>=Interatomic force constants.
     793                 :             : !!  iq_ibz=Index of the q-point in the IBZ array.
     794                 :             : !!  spin=Spin index. See notes below.
     795                 :             : !!
     796                 :             : !! OUTPUT
     797                 :             : !!  phfrq(gams%natom3)=Phonon frequencies
     798                 :             : !!  gamma_ph(gams%natom3)=Phonon linewidths.
     799                 :             : !!  lambda_ph(gams%natom3)=coupling strength coefficients
     800                 :             : !!  displ_cart(2,3,cry%natom,3*cryst%natom)=Phonon displacement in cartesian coordinates.
     801                 :             : !!  [gamma_ph_ee]
     802                 :             : !!
     803                 :             : !! NOTES
     804                 :             : !!  If nsppol == 1 and nspinor == 1, lambda and gamma are already summed over the two equivalent spin channels.
     805                 :             : !!  If nsppol == 2, lambda and gamma are the particular contributions given by the input spin index.
     806                 :             : !!  Client code is responsible for assembling the final observables by summing over spins.
     807                 :             : !!
     808                 :             : !! SOURCE
     809                 :             : 
     810                 :           0 : subroutine phgamma_eval_qibz(gams, cryst, ifc, iq_ibz, spin, phfrq, gamma_ph, lambda_ph, displ_cart, gamma_ph_ee)
     811                 :             : 
     812                 :             : !Arguments ------------------------------------
     813                 :             : !scalars
     814                 :             :  class(phgamma_t),intent(inout) :: gams
     815                 :             :  integer,intent(in) :: iq_ibz,spin
     816                 :             :  type(crystal_t),intent(in) :: cryst
     817                 :             :  type(ifc_type),intent(in) :: ifc
     818                 :             : !arrays
     819                 :             :  real(dp),intent(out) :: phfrq(gams%natom3),gamma_ph(gams%natom3),lambda_ph(gams%natom3)
     820                 :             :  real(dp),intent(out) :: displ_cart(2,3,cryst%natom,3*cryst%natom)
     821                 :             :  real(dp),intent(out),optional :: gamma_ph_ee(gams%nene,gams%nene,gams%natom3)
     822                 :             : 
     823                 :             : !Local variables-------------------------------
     824                 :             : !scalars
     825                 :             :  integer :: natom3, nu1, iene, jene
     826                 :             :  real(dp) :: spinfact
     827                 :             :  !character(len=500) :: msg
     828                 :             :  !arrays
     829                 :         244 :  real(dp) :: displ_red(2,gams%natom3,gams%natom3), work_qnu(gams%natom3), gam_atm(2,gams%natom3,gams%natom3)
     830                 :             : ! *************************************************************************
     831                 :             : 
     832                 :         122 :  natom3 = gams%natom3
     833                 :             : 
     834                 :             :  ! Get phonon frequencies and eigenvectors.
     835                 :         122 :  call ifc%fourq(cryst, gams%qibz(:,iq_ibz), phfrq, displ_cart, out_displ_red=displ_red)
     836                 :             : 
     837                 :             :  ! Scalar product with the displ_red vectors.
     838                 :             :  ! Note that the factor 1 / (2 * omega_qnu) coming from |g|^2 is absorbed in the expressions below.
     839         [ +  + ]:         488 :  gam_atm = reshape(gams%vals_qibz(:,:,:,iq_ibz,spin), [2, natom3, natom3])
     840                 :         122 :  call ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, gamma_ph)
     841                 :             : 
     842   [ -  +  -  - ]:         122 :  if (present(gamma_ph_ee) .and. gams%my_iqibz(iq_ibz) /= -1) then
     843         [ #  # ]:           0 :    do iene = 1, gams%nene
     844         [ #  # ]:           0 :      do jene = 1, gams%nene
     845         [ #  # ]:           0 :        gam_atm = reshape(gams%vals_ee(:,jene,iene,:,:,iq_ibz,spin), [2, natom3, natom3])
     846                 :           0 :        call ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, work_qnu)
     847         [ #  # ]:           0 :        gamma_ph_ee(jene, iene, :) = work_qnu
     848                 :             :      end do
     849                 :             :    end do
     850                 :             :  end if
     851                 :             : 
     852                 :             :  ! Compute lambda
     853                 :             :  ! TODO: check this - looks like a factor of 2 wrt the inline documentation!
     854                 :             :  ! NB: one factor of 2 comes from the phonon propagator and BE factor,
     855                 :             :  ! then you have to be careful with the convention for the Fermi level DOS
     856                 :             :  !
     857                 :             :  ! spinfact should be 1 for a normal non sppol calculation without spinorbit
     858                 :             :  ! for spinors it should also be 1 as bands are twice as numerous but n0 has been divided by 2
     859                 :             :  ! for nsppol 2 it should be 0.5 as we have 2 spin channels to sum
     860                 :         122 :  spinfact = two / (gams%nsppol * gams%nspinor)
     861                 :             : 
     862         [ +  + ]:         488 :  do nu1=1,gams%natom3
     863                 :         366 :    gamma_ph(nu1) =  gamma_ph(nu1) * pi * spinfact
     864                 :         366 :    lambda_ph(nu1) = zero
     865         [ +  + ]:         366 :    if (abs(phfrq(nu1)) > EPHTK_WTOL) lambda_ph(nu1) = gamma_ph(nu1) / (two * pi * gams%n0(spin) * phfrq(nu1)**2)
     866                 :             :    !if (abs(phfrq(nu1)) > EPHTK_WTOL) lambda_ph(nu1) = gamma_ph(nu1) / (two * pi * sum(gams%n0(:)) * phfrq(nu1)**2)
     867   [ -  +  -  -  :         488 :    if (present(gamma_ph_ee)) gamma_ph_ee(:,:,nu1) =  gamma_ph_ee(:,:,nu1) * pi * spinfact
                   -  - ]
     868                 :             :  end do
     869                 :             : 
     870                 :             :  ! This to avoid spurious results for the acoustic modes as gamma(q) --> 0 and lambda(q) --> 0 for q --> 0.
     871                 :             :  ! Here we set everything to zero when we are inside a sphere of radius EPH_Q0TOL as this acoustic rule
     872                 :             :  ! is not fulfilled due to numerical inaccuracies.
     873         [ +  + ]:         122 :  if (normv(gams%qibz(:,iq_ibz), cryst%gmet, "G") < EPH_Q0TOL) then
     874         [ +  + ]:          40 :    gamma_ph(1:3) = zero
     875         [ +  + ]:          40 :    lambda_ph(1:3) = zero
     876                 :             :  end if
     877                 :             : 
     878         [ -  + ]:         122 : end subroutine phgamma_eval_qibz
     879                 :             : !!***
     880                 :             : 
     881                 :             : !----------------------------------------------------------------------
     882                 :             : 
     883                 :             : !!****f* m_phgamma/phgamma_interp
     884                 :             : !! NAME
     885                 :             : !! phgamma_interp
     886                 :             : !!
     887                 :             : !! FUNCTION
     888                 :             : !!  Interpolate the phonon linewidths at a given q-point.
     889                 :             : !!
     890                 :             : !! INPUTS
     891                 :             : !!  cryst<crystal_t>=crystalline structure.
     892                 :             : !!  ifc<ifc_type>=Interatomic force constants.
     893                 :             : !!  spin=Spin index
     894                 :             : !!  qpt(3)=q-point in reduced coordinates
     895                 :             : !!  gamma_ph(3*natom)=Phonon linewidths
     896                 :             : !!
     897                 :             : !! OUTPUT
     898                 :             : !!  gamma_ph(gams%natom3)=Interpolated Phonon linewidths.
     899                 :             : !!  lamda_ph(3*natom)=Lambda coefficients for the different phonon modes.
     900                 :             : !!  phfrq(3*natom)=phonon frequencies at current q
     901                 :             : !!  displ_cart(2,3,natom,3*natom) = Phonon displacement in Cartesian coordinates
     902                 :             : !!
     903                 :             : !! SOURCE
     904                 :             : 
     905                 :           0 : subroutine phgamma_interp(gams, cryst, ifc, spin, qpt, phfrq, gamma_ph, lambda_ph, displ_cart, gamma_ph_ee)
     906                 :             : 
     907                 :             : !Arguments ------------------------------------
     908                 :             : !scalars
     909                 :             :  class(phgamma_t),intent(inout) :: gams
     910                 :             :  integer,intent(in) :: spin
     911                 :             :  type(crystal_t),intent(in) :: cryst
     912                 :             :  type(ifc_type),intent(in) :: ifc
     913                 :             : !arrays
     914                 :             :  real(dp),intent(in) :: qpt(3)
     915                 :             :  real(dp),intent(out) :: phfrq(gams%natom3),gamma_ph(gams%natom3),lambda_ph(gams%natom3)
     916                 :             :  real(dp),intent(out) :: displ_cart(2,3,cryst%natom,3*cryst%natom)
     917                 :             :  real(dp),intent(out),optional :: gamma_ph_ee(gams%nene,gams%nene,gams%natom3)
     918                 :             : 
     919                 :             : !Local variables-------------------------------
     920                 :             : !scalars
     921                 :             :  integer,parameter :: qtor0 = 0
     922                 :             :  integer, save :: icall=0
     923                 :             :  integer :: natom3,nu1
     924                 :             :  real(dp) :: spinfact
     925                 :             :  character(len=500) :: msg
     926                 :             :  !arrays
     927                 :        1860 :  real(dp) :: displ_red(2,gams%natom3,gams%natom3), gam_now(2,gams%natom3**2), gam_atm(2,gams%natom3,gams%natom3)
     928                 :         930 :  real(dp),allocatable :: coskr(:,:),sinkr(:,:)
     929                 :             : ! *************************************************************************
     930                 :             : 
     931                 :             :  ! Compute internal tables used for Fourier interpolation.
     932         [ +  + ]:         930 :  if (.not. allocated(gams%vals_rpt)) call gams%interp_setup(cryst)
     933                 :             : 
     934   [ -  +  -  - ]:         930 :  if (present(gamma_ph_ee) .and. icall == 0) then
     935   [ #  #  #  #  :           0 :    gamma_ph_ee = zero
                   #  # ]
     936                 :             :    write (msg,'(3a)')&
     937                 :           0 :      " For the moment gams_ee matrix elements are not FT interpolated wrt q,",ch10,&
     938                 :           0 :      " only evaluated on the electron k grid. The resulting a2feew will be 0"
     939                 :           0 :    ABI_WARNING(msg)
     940                 :           0 :    icall = 1
     941                 :             :  end if
     942                 :             : 
     943                 :         930 :  natom3 = gams%natom3
     944                 :             : 
     945                 :             :  ! Taken from mkph_linwid
     946                 :             :  ! This reduced version of ftgkk supposes the kpoints have been integrated
     947                 :             :  ! in integrate_gamma. Do FT from real-space gamma grid to 1 qpt.
     948   [ -  +  +  -  :        2790 :  ABI_MALLOC(coskr, (1, gams%nrpt))
          +  -  +  -  -  
                +  -  + ]
     949   [ -  +  +  -  :        1860 :  ABI_MALLOC(sinkr, (1, gams%nrpt))
             -  +  -  + ]
     950                 :             :  ! TODO: This is not optimal
     951                 :         930 :  call ftgam_init(gams%gprim, 1, gams%nrpt, qpt, gams%rpt, coskr, sinkr)
     952                 :             : 
     953                 :         930 :  call ftgam(gams%wghatm, gam_now, gams%vals_rpt(:,:,:,spin), gams%natom, 1, gams%nrpt, qtor0, coskr, sinkr)
     954                 :             : 
     955                 :             :  ! This call is not executed in elphon!
     956         [ +  - ]:         930 :  if (gams%symgamma == 1) call tgamma_symm(cryst, qpt, gam_now)
     957                 :             : 
     958         [ -  + ]:         930 :  ABI_FREE(coskr)
     959         [ -  + ]:         930 :  ABI_FREE(sinkr)
     960                 :             : 
     961                 :             :  ! Get phonon frequencies and eigenvectors.
     962                 :         930 :  call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red)
     963                 :             : 
     964                 :             :  ! Scalar product with the displ_red
     965         [ +  + ]:        3720 :  gam_atm = reshape(gam_now, [2, natom3, natom3])
     966                 :         930 :  call ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, gamma_ph)
     967                 :             : 
     968                 :             :  ! Compute lambda
     969                 :             :  ! spinfact should be 1 for a normal non sppol calculation without spinorbit
     970                 :             :  ! for spinors it should also be 1 as bands are twice as numerous but n0 has been divided by 2
     971                 :             :  ! for nsppol 2 it should be 0.5 as we have 2 spin channels to sum
     972                 :         930 :  spinfact = two / (gams%nsppol * gams%nspinor)
     973                 :             : 
     974                 :             :  ! Compute lambda
     975         [ +  + ]:        3720 :  do nu1=1,gams%natom3
     976                 :        2790 :    gamma_ph(nu1) = gamma_ph(nu1) * pi * spinfact
     977                 :        2790 :    lambda_ph(nu1) = zero
     978         [ +  + ]:        3720 :    if (abs(phfrq(nu1)) > EPHTK_WTOL) lambda_ph(nu1) = gamma_ph(nu1) / (two * pi * gams%n0(spin) * phfrq(nu1)**2)
     979                 :             :  end do
     980                 :             : 
     981                 :             :  ! This to avoid spurious results for the acoustic modes.
     982                 :             :  ! In principle, gamma(q) --> 0 and lambda(q) --> 0 for q --> 0
     983                 :             :  ! but the Fourier interpolated gammas do not fulfill this property so we set everything
     984                 :             :  ! to zero when we are inside a sphere or radius
     985         [ +  + ]:         930 :  if (normv(qpt, cryst%gmet, "G") < EPH_Q0TOL) then
     986                 :             :    !write(std_out,*)"Setting values to zero."
     987         [ +  + ]:          40 :    gamma_ph(1:3) = zero
     988         [ +  + ]:          40 :    lambda_ph(1:3) = zero
     989                 :             :  end if
     990                 :             : 
     991         [ -  + ]:         930 : end subroutine phgamma_interp
     992                 :             : !!***
     993                 :             : 
     994                 :             : !----------------------------------------------------------------------
     995                 :             : 
     996                 :             : !!****f* m_phgamma/phgamma_interp_setup
     997                 :             : !! NAME
     998                 :             : !! phgamma_interp_setup
     999                 :             : !!
    1000                 :             : !! FUNCTION
    1001                 :             : !!  This routines prepares the internal tables used to interpolate the linewidths in q-space
    1002                 :             : !!
    1003                 :             : !! INPUTS
    1004                 :             : !!
    1005                 :             : !! SOURCE
    1006                 :             : 
    1007                 :           5 : subroutine phgamma_interp_setup(gams, cryst)
    1008                 :             : 
    1009                 :             : !Arguments ------------------------------------
    1010                 :             : !scalars
    1011                 :             :  class(phgamma_t),intent(inout) :: gams
    1012                 :             :  type(crystal_t),intent(in) :: cryst
    1013                 :             : 
    1014                 :             : !Local variables-------------------------------
    1015                 :             : !scalars
    1016                 :             :  integer,parameter :: qtor1 = 1
    1017                 :             :  integer :: iq_bz,iq_ibz,spin,ierr,ii
    1018                 :             :  !character(len=500) :: msg
    1019                 :             : !arrays
    1020                 :           5 :  integer,allocatable :: qirredtofull(:),qpttoqpt(:,:,:)
    1021                 :           5 :  real(dp),allocatable :: coskr(:,:),sinkr(:,:), gamma_qpt(:,:,:,:),atmfrc(:,:), vals_bz(:,:,:,:)
    1022                 :             : ! *************************************************************************
    1023                 :             : 
    1024   [ -  +  +  -  :          25 :  ABI_MALLOC_OR_DIE(vals_bz, (2, gams%natom3**2, gams%nqbz, gams%nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  +  -  -  
                +  -  + ]
    1025   [ +  +  +  +  :       21514 :  vals_bz = zero
             +  +  +  + ]
    1026                 :             : 
    1027                 :             :  ! Build tables needed by complete_gamma.
    1028                 :           5 :  call ephtk_mkqtabs(cryst, gams%nqibz, gams%qibz, gams%nqbz, gams%qbz, qirredtofull, qpttoqpt)
    1029                 :             : 
    1030                 :             :  ! Fill BZ array with IBZ data.
    1031         [ +  + ]:          10 :  do spin=1,gams%nsppol
    1032         [ +  + ]:          71 :    do iq_ibz=1,gams%nqibz
    1033                 :          61 :      iq_bz = qirredtofull(iq_ibz)
    1034         [ +  + ]:         188 :      vals_bz(:,:,iq_bz,spin) = reshape(gams%vals_qibz(:,:,:,iq_ibz,spin), [2, gams%natom3**2])
    1035                 :             :    end do
    1036                 :             :  end do
    1037                 :             : 
    1038                 :             :  ! Complete vals_bz in the full BZ.
    1039                 :             :  ! FIXME: Change complete_gamma API to pass (..., nsppol)
    1040   [ -  +  +  -  :          25 :  ABI_MALLOC(gamma_qpt, (2, gams%natom3**2, gams%nsppol, gams%nqbz))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    1041         [ +  + ]:          10 :  do spin=1,gams%nsppol
    1042   [ +  +  +  +  :       21514 :    gamma_qpt(:, :, spin, :) = vals_bz(:, :, :, spin)
                   +  + ]
    1043                 :             :  end do
    1044                 :             : 
    1045                 :             :  call complete_gamma(cryst, gams%natom3, gams%nsppol, gams%nqibz, gams%nqbz, &
    1046                 :           5 :    gams%eph_scalprod, qirredtofull, qpttoqpt, gamma_qpt)
    1047                 :             : 
    1048         [ +  + ]:          10 :  do spin=1,gams%nsppol
    1049   [ +  +  +  +  :       21514 :    vals_bz(:, :, :, spin) = gamma_qpt(:, :, spin, :)
                   +  + ]
    1050                 :             :  end do
    1051                 :             : 
    1052         [ -  + ]:           5 :  ABI_FREE(gamma_qpt)
    1053         [ -  + ]:           5 :  ABI_FREE(qirredtofull)
    1054         [ -  + ]:           5 :  ABI_FREE(qpttoqpt)
    1055                 :             : 
    1056                 :             :  ! This call is not executed in elphon!
    1057         [ +  - ]:           5 :  if (gams%symgamma == 1) then
    1058         [ +  + ]:          10 :    do spin=1,gams%nsppol
    1059         [ +  + ]:         778 :      do iq_bz=1,gams%nqbz
    1060                 :         773 :        call tgamma_symm(cryst, gams%qbz(:,iq_bz), vals_bz(:,:,iq_bz,spin))
    1061                 :             :      end do
    1062                 :             :    end do
    1063                 :             :  end if
    1064                 :             : 
    1065                 :             :  ! Now FT to real space too
    1066                 :             :  ! NOTE: gprim (not gprimd) is used for all FT interpolations,
    1067                 :             :  ! to be consistent with the dimensions of the rpt, which come from anaddb.
    1068   [ -  +  +  -  :          25 :  ABI_MALLOC_OR_DIE(gams%vals_rpt, (2, gams%natom3**2, gams%nrpt, gams%nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  -  +  +  -  
                   -  + ]
    1069   [ +  +  +  +  :       13030 :  gams%vals_rpt = zero
             +  +  +  + ]
    1070                 :             : 
    1071                 :             :  ! q --> r
    1072   [ -  +  +  -  :          20 :  ABI_MALLOC(coskr, (gams%nqbz, gams%nrpt))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1073   [ -  +  +  -  :          15 :  ABI_MALLOC(sinkr, (gams%nqbz, gams%nrpt))
          -  +  +  -  -  
                +  -  + ]
    1074                 :           5 :  call ftgam_init(gams%gprim, gams%nqbz, gams%nrpt, gams%qbz, gams%rpt, coskr, sinkr)
    1075                 :             : 
    1076         [ +  + ]:          10 :  do spin=1,gams%nsppol
    1077                 :             :    call ftgam(gams%wghatm, vals_bz(:,:,:,spin), gams%vals_rpt(:,:,:,spin), gams%natom, gams%nqbz,&
    1078                 :           5 :               gams%nrpt, qtor1, coskr, sinkr)
    1079                 :             : 
    1080                 :             :    ! Enforce "acoustic" rule on vals_rpt. NB: This call is not executed in elphon!
    1081         [ -  + ]:          10 :    if (gams%asr /= 0) then
    1082   [ #  #  #  #  :           0 :      ABI_MALLOC(atmfrc, (3*gams%natom*3*gams%natom, gams%nrpt))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1083         [ #  # ]:           0 :      do ii=1,2
    1084   [ #  #  #  #  :           0 :        atmfrc = gams%vals_rpt(ii,:,:,spin)
          #  #  #  #  #  
                #  #  # ]
    1085                 :             :        !gals%vals_rpt(2,:,,spin) = zero
    1086                 :           0 :        call asrif9(gams%asr, atmfrc, gams%natom, gams%nrpt, gams%rpt, gams%wghatm)
    1087   [ #  #  #  # ]:           0 :        gams%vals_rpt(ii,:,:,spin) = atmfrc
    1088                 :             :      end do
    1089         [ #  # ]:           0 :      ABI_FREE(atmfrc)
    1090                 :             :    end if
    1091                 :             :  end do
    1092                 :             : 
    1093         [ -  + ]:           5 :  ABI_FREE(vals_bz)
    1094         [ -  + ]:           5 :  ABI_FREE(coskr)
    1095         [ -  + ]:           5 :  ABI_FREE(sinkr)
    1096                 :             : 
    1097                 :           5 : end subroutine phgamma_interp_setup
    1098                 :             : !!***
    1099                 :             : 
    1100                 :             : !----------------------------------------------------------------------
    1101                 :             : 
    1102                 :             : !!****f* m_phgamma/phgamma_vv_eval_qibz
    1103                 :             : !! NAME
    1104                 :             : !! phgamma_vv_eval_qibz
    1105                 :             : !!
    1106                 :             : !! FUNCTION
    1107                 :             : !! Compute the phonon linewidths times velocity squared, for q-points in the IBZ without performing interpolation.
    1108                 :             : !!
    1109                 :             : !! INPUTS
    1110                 :             : !!  gams<phgamma_t>
    1111                 :             : !!  cryst<crystal_t>=Crystal structure.
    1112                 :             : !!  ifc<ifc_type>=Interatomic force constants.
    1113                 :             : !!  iq_ibz=Index of the q-point in the IBZ array.
    1114                 :             : !!  spin=Spin index
    1115                 :             : !!
    1116                 :             : !! OUTPUT
    1117                 :             : !!  phfrq(gams%natom3)=Phonon frequencies
    1118                 :             : !!  gamma_in_ph(gams%natom3)=Phonon linewidths.
    1119                 :             : !!  gamma_out_ph(gams%natom3)=Phonon linewidths.
    1120                 :             : !!  lambda_in_ph(gams%natom3)=Phonon linewidths.
    1121                 :             : !!  lambda_out_ph(gams%natom3)=Phonon linewidths.
    1122                 :             : !!
    1123                 :             : !! SOURCE
    1124                 :             : 
    1125                 :          61 : subroutine phgamma_vv_eval_qibz(gams, cryst, ifc, iq_ibz, spin, phfrq, gamma_in_ph, gamma_out_ph, lambda_in_ph, lambda_out_ph)
    1126                 :             : 
    1127                 :             : !Arguments ------------------------------------
    1128                 :             : !scalars
    1129                 :             :  class(phgamma_t),intent(inout) :: gams
    1130                 :             :  integer,intent(in) :: iq_ibz,spin
    1131                 :             :  type(crystal_t),intent(in) :: cryst
    1132                 :             :  type(ifc_type),intent(in) :: ifc
    1133                 :             : !arrays
    1134                 :             :  real(dp),intent(out) :: phfrq(gams%natom3)
    1135                 :             :  real(dp),intent(out) :: gamma_in_ph(3,3,gams%natom3),lambda_in_ph(3,3,gams%natom3)
    1136                 :             :  real(dp),intent(out) :: gamma_out_ph(3,3,gams%natom3),lambda_out_ph(3,3,gams%natom3)
    1137                 :             : 
    1138                 :             : !Local variables-------------------------------
    1139                 :             : !scalars
    1140                 :             :  integer,parameter :: qtor0 = 0
    1141                 :             :  integer :: natom3, nu1, idir, jdir, ii
    1142                 :             :  real(dp) :: spinfact
    1143                 :             :  !character(len=500) :: msg
    1144                 :             : !arrays
    1145                 :         122 :  real(dp) :: displ_cart(2,3,cryst%natom,3*cryst%natom), displ_red(2,gams%natom3,gams%natom3)
    1146                 :         122 :  real(dp) :: work_qnu(gams%natom3), gam_atm(2,gams%natom3,gams%natom3)
    1147                 :             : ! *************************************************************************
    1148                 :             : 
    1149                 :          61 :  natom3 = gams%natom3
    1150                 :             : 
    1151                 :             :  ! Get phonon frequencies and eigenvectors.
    1152                 :          61 :  call ifc%fourq(cryst, gams%qibz(:,iq_ibz), phfrq, displ_cart, out_displ_red=displ_red)
    1153                 :             : 
    1154         [ +  + ]:         244 :  do jdir=1,3
    1155         [ +  + ]:         793 :    do idir=1,3
    1156                 :         549 :      ii = idir + gams%ndir_transp * (jdir - 1)
    1157                 :             : 
    1158                 :             :      ! Scalar product with the displ_red vectors.
    1159         [ +  + ]:        2196 :      gam_atm = reshape(gams%vals_in_qibz(:,ii,:,:,iq_ibz,spin), [2, natom3, natom3])
    1160                 :         549 :      call ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, work_qnu)
    1161         [ +  + ]:        2196 :      gamma_in_ph(idir,jdir,:) = work_qnu
    1162                 :             : 
    1163         [ +  + ]:        2196 :      gam_atm = reshape(gams%vals_out_qibz(:,ii,:,:,iq_ibz,spin), [2, natom3, natom3])
    1164                 :         549 :      call ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, work_qnu)
    1165         [ +  + ]:        2379 :      gamma_out_ph(idir,jdir,:) = work_qnu
    1166                 :             :    end do ! idir
    1167                 :             :  end do ! jdir
    1168                 :             : 
    1169                 :             :  ! TODO : check this - looks like a factor of 2 wrt the inline documentation!
    1170                 :             :  !spinfact should be 1 for a normal non sppol calculation without spinorbit
    1171                 :             :  !for spinors it should also be 1 as bands are twice as numerous but n0 has been divided by 2
    1172                 :             :  !for sppol 2 it should be 0.5 as we have 2 spin channels to sum
    1173                 :          61 :  spinfact = two / (gams%nsppol*gams%nspinor)
    1174                 :             : 
    1175                 :             :  ! Compute lambda transport.
    1176         [ +  + ]:         244 :  do jdir =1,3
    1177         [ +  + ]:         793 :    do idir =1,3
    1178         [ +  + ]:        2379 :      do nu1=1,gams%natom3
    1179                 :        1647 :        gamma_in_ph(idir,jdir,nu1)  =  gamma_in_ph(idir,jdir,nu1)  * pi * spinfact
    1180                 :        1647 :        gamma_out_ph(idir,jdir,nu1) =  gamma_out_ph(idir,jdir,nu1) * pi * spinfact
    1181                 :        1647 :        lambda_in_ph(idir,jdir,nu1)  = zero
    1182                 :        1647 :        lambda_out_ph(idir,jdir,nu1) = zero
    1183         [ +  + ]:        2196 :        if (abs(phfrq(nu1)) > EPHTK_WTOL) then
    1184                 :        1512 :          lambda_in_ph(idir,jdir,nu1)  = gamma_in_ph(idir,jdir,nu1)  / (two * pi * gams%n0(spin) * phfrq(nu1)**2)
    1185                 :        1512 :          lambda_out_ph(idir,jdir,nu1) = gamma_out_ph(idir,jdir,nu1) / (two * pi * gams%n0(spin) * phfrq(nu1)**2)
    1186                 :             :        end if
    1187                 :             :      end do
    1188                 :             :    end do ! idir
    1189                 :             :  end do ! jdir
    1190                 :             : 
    1191                 :          61 : end subroutine phgamma_vv_eval_qibz
    1192                 :             : !!***
    1193                 :             : 
    1194                 :             : !----------------------------------------------------------------------
    1195                 :             : 
    1196                 :             : !!****f* m_phgamma/phgamma_vv_interp
    1197                 :             : !! NAME
    1198                 :             : !! phgamma_vv_interp
    1199                 :             : !!
    1200                 :             : !! FUNCTION
    1201                 :             : !!  Interpolate the linewidths at a given q-point.
    1202                 :             : !!
    1203                 :             : !! INPUTS
    1204                 :             : !!  cryst<crystal_t>=crystalline structure.
    1205                 :             : !!  ifc<ifc_type>=Interatomic force constants.
    1206                 :             : !!  spin=Spin index
    1207                 :             : !!  qpt(3)=q-point in reduced coordinates
    1208                 :             : !!  gamma_ph(3*natom)=Phonon linewidths
    1209                 :             : !!  displ_cart(2,3,cryst%natom,3*cryst%natom)=Phonon displacement in cartesian coordinates.
    1210                 :             : !!
    1211                 :             : !! OUTPUT
    1212                 :             : !!  phfrq(3*natom)=phonon frequencies at current q
    1213                 :             : !!  gamma_out_ph(gams%natom3)=Interpolated Phonon linewidths.
    1214                 :             : !!  lambda_in_ph(3*natom)=Lambda coefficients for the different phonon modes.
    1215                 :             : !!  lambda_out_ph(3*natom)=Lambda coefficients for the different phonon modes.
    1216                 :             : !!
    1217                 :             : !! SOURCE
    1218                 :             : 
    1219                 :         725 : subroutine phgamma_vv_interp(gams, cryst, ifc, spin, qpt, phfrq, gamma_in_ph, gamma_out_ph, lambda_in_ph, lambda_out_ph)
    1220                 :             : 
    1221                 :             : !Arguments ------------------------------------
    1222                 :             : !scalars
    1223                 :             :  class(phgamma_t),intent(inout) :: gams
    1224                 :             :  type(crystal_t),intent(in) :: cryst
    1225                 :             :  type(ifc_type),intent(in) :: ifc
    1226                 :             :  integer,intent(in) :: spin
    1227                 :             : !arrays
    1228                 :             :  real(dp),intent(in) :: qpt(3)
    1229                 :             :  real(dp),intent(out) :: phfrq(gams%natom3)
    1230                 :             :  real(dp),intent(out) :: gamma_in_ph(3,3,gams%natom3),lambda_in_ph(3,3,gams%natom3)
    1231                 :             :  real(dp),intent(out) :: gamma_out_ph(3,3,gams%natom3),lambda_out_ph(3,3,gams%natom3)
    1232                 :             : 
    1233                 :             : !Local variables-------------------------------
    1234                 :             : !scalars
    1235                 :             :  integer,parameter :: qtor0 = 0
    1236                 :             :  integer :: natom3, nu1, idir,jdir,ii
    1237                 :             :  real(dp) :: spinfact
    1238                 :             :  !character(len=500) :: msg
    1239                 :             :  !arrays
    1240                 :        1450 :  real(dp) :: displ_cart(2,3,cryst%natom,3*cryst%natom), displ_red(2,gams%natom3,gams%natom3),work_qnu(gams%natom3)
    1241                 :        1450 :  real(dp) :: gam_in_now(2,3,3,gams%natom3**2), gam_out_now(2,3,3,gams%natom3**2), gam_atm(2,gams%natom3,gams%natom3)
    1242                 :         725 :  real(dp),allocatable :: coskr(:,:),sinkr(:,:)
    1243                 :             : ! *************************************************************************
    1244                 :             : 
    1245                 :             :  ! Compute internal tables used for Fourier interpolation.
    1246         [ +  + ]:         725 :  if (.not.allocated(gams%vals_in_rpt)) call phgamma_vv_interp_setup(gams, cryst)
    1247                 :             : 
    1248                 :         725 :  natom3 = gams%natom3
    1249                 :             : 
    1250                 :             :  ! Get phonon frequencies and eigenvectors.
    1251                 :         725 :  call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red)
    1252                 :             : 
    1253                 :             :  ! Taken from mkph_linwid
    1254                 :             :  ! This reduced version of ftgkk supposes the kpoints have been integrated
    1255                 :             :  ! in integrate_gamma. Do FT from real-space gamma grid to 1 qpt.
    1256   [ -  +  +  -  :        2175 :  ABI_MALLOC(coskr, (1,gams%nrpt))
          +  -  +  -  -  
                +  -  + ]
    1257   [ -  +  +  -  :        1450 :  ABI_MALLOC(sinkr, (1,gams%nrpt))
             -  +  -  + ]
    1258                 :             :  ! TODO: This is not optimal
    1259                 :         725 :  call ftgam_init(gams%gprim, 1, gams%nrpt, qpt, gams%rpt, coskr, sinkr)
    1260                 :             : 
    1261         [ +  + ]:        2900 :  do idir=1,3
    1262         [ +  + ]:        9425 :    do jdir=1,3
    1263                 :        6525 :      ii = idir+gams%ndir_transp*(jdir-1)
    1264                 :             : 
    1265   [ +  -  +  -  :    33988725 :      call ftgam(gams%wghatm, gam_in_now, gams%vals_in_rpt(:,ii,:,:,spin), gams%natom, 1, gams%nrpt, qtor0, coskr, sinkr)
          +  +  +  +  +  
          +  +  -  +  +  
             +  +  +  + ]
    1266   [ +  -  +  -  :    33988725 :      call ftgam(gams%wghatm, gam_out_now, gams%vals_out_rpt(:,ii,:,:,spin), gams%natom, 1, gams%nrpt, qtor0, coskr, sinkr)
          +  +  +  +  +  
          +  +  -  +  +  
             +  +  +  + ]
    1267                 :             : 
    1268                 :             :      ! This call is not executed in elphon!
    1269                 :             :      ! TODO: needs to take into account the matrix nature of _in_ and _out_ gammas
    1270         [ +  - ]:        6525 :      if (gams%symgamma == 1) then
    1271                 :        6525 :        call tgamma_symm(cryst, qpt, gam_in_now)
    1272                 :        6525 :        call tgamma_symm(cryst, qpt, gam_out_now)
    1273                 :             :      end if
    1274                 :             : 
    1275                 :             :      ! Scalar product with the displ_red
    1276         [ +  + ]:       26100 :      gam_atm = reshape(gam_in_now, [2, natom3, natom3])
    1277                 :        6525 :      call ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, work_qnu)
    1278         [ +  + ]:       26100 :      gamma_in_ph(idir,jdir,:) = work_qnu
    1279                 :             : 
    1280         [ +  + ]:       26100 :      gam_atm = reshape(gam_out_now, [2, natom3, natom3])
    1281                 :        6525 :      call ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, work_qnu)
    1282         [ +  + ]:       28275 :      gamma_out_ph(idir,jdir,:) = work_qnu
    1283                 :             :    end do
    1284                 :             :  end do
    1285                 :             : 
    1286         [ -  + ]:         725 :  ABI_FREE(coskr)
    1287         [ -  + ]:         725 :  ABI_FREE(sinkr)
    1288                 :             : 
    1289                 :             :  ! Compute lambda
    1290                 :             :  ! spinfact should be 1 for a normal non sppol calculation without spinorbit
    1291                 :             :  ! for spinors it should also be 1 as bands are twice as numerous but n0 has been divided by 2
    1292                 :             :  ! for sppol 2 it should be 0.5 as we have 2 spin channels to sum
    1293                 :         725 :  spinfact = two / (gams%nsppol * gams%nspinor)
    1294                 :             : 
    1295                 :             :  ! Compute lambda
    1296         [ +  + ]:        2900 :  do nu1=1,gams%natom3
    1297         [ +  + ]:        9425 :    do idir=1,3
    1298         [ +  + ]:       28275 :      do jdir=1,3
    1299                 :       19575 :        gamma_in_ph(idir,jdir,nu1) = gamma_in_ph(idir,jdir,nu1) * pi * spinfact
    1300                 :       19575 :        gamma_out_ph(idir,jdir,nu1) = gamma_out_ph(idir,jdir,nu1) * pi * spinfact
    1301                 :       19575 :        lambda_in_ph(idir,jdir,nu1) = zero
    1302                 :       19575 :        lambda_out_ph(idir,jdir,nu1) = zero
    1303         [ +  + ]:       26100 :        if (abs(phfrq(nu1)) > EPHTK_WTOL) then
    1304                 :       19440 :          lambda_in_ph(idir,jdir,nu1)  = gamma_in_ph(idir,jdir,nu1) / (two * pi * gams%n0(spin) * phfrq(nu1)**2)
    1305                 :       19440 :          lambda_out_ph(idir,jdir,nu1) = gamma_out_ph(idir,jdir,nu1) / (two * pi * gams%n0(spin) * phfrq(nu1)**2)
    1306                 :             :        end if
    1307                 :             :      end do
    1308                 :             :    end do
    1309                 :             :  end do
    1310                 :             : 
    1311                 :         725 : end subroutine phgamma_vv_interp
    1312                 :             : !!***
    1313                 :             : 
    1314                 :             : !----------------------------------------------------------------------
    1315                 :             : 
    1316                 :             : !!****f* m_phgamma/phgamma_vv_interp_setup
    1317                 :             : !! NAME
    1318                 :             : !! phgamma_vv_interp_setup
    1319                 :             : !!
    1320                 :             : !! FUNCTION
    1321                 :             : !!  This routines prepare the internal tables used to interpolate the vv_linewidths in q-space
    1322                 :             : !!
    1323                 :             : !! INPUTS
    1324                 :             : !!  action =
    1325                 :             : !!    "INIT" to allocate and compute the internal tables (default)
    1326                 :             : !!    "FREE" to deallocate the internal tables.
    1327                 :             : !!
    1328                 :             : !! SOURCE
    1329                 :             : 
    1330                 :           5 : subroutine phgamma_vv_interp_setup(gams, cryst)
    1331                 :             : 
    1332                 :             : !Arguments ------------------------------------
    1333                 :             :  class(phgamma_t),intent(inout) :: gams
    1334                 :             :  type(crystal_t),intent(in) :: cryst
    1335                 :             : 
    1336                 :             : !Local variables-------------------------------
    1337                 :             : !scalars
    1338                 :             :  integer,parameter :: qtor1 = 1
    1339                 :             :  integer :: iq_bz,iq_ibz,spin,ierr, ii, idir, jdir
    1340                 :             :  !character(len=500) :: msg
    1341                 :             : !arrays
    1342                 :           5 :  integer,allocatable :: qirredtofull(:),qpttoqpt(:,:,:)
    1343                 :           5 :  real(dp),allocatable :: coskr(:,:),sinkr(:,:), vals_in_bz(:,:,:,:,:), vals_out_bz(:,:,:,:,:)
    1344                 :             : ! *************************************************************************
    1345                 :             : 
    1346   [ -  +  +  -  :          25 :  ABI_MALLOC_OR_DIE(vals_in_bz,(2, 9, gams%natom3**2, gams%nqbz, gams%nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  +  -  -  
                +  -  + ]
    1347   [ -  +  +  -  :          25 :  ABI_MALLOC_OR_DIE(vals_out_bz,(2, 9, gams%natom3**2, gams%nqbz, gams%nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  +  -  -  
                +  -  + ]
    1348   [ +  +  +  +  :      194314 :  vals_in_bz = zero
          +  +  +  +  +  
                      + ]
    1349   [ +  +  +  +  :      194314 :  vals_out_bz = zero
          +  +  +  +  +  
                      + ]
    1350                 :             : 
    1351                 :             :  ! Build tables needed by complete_gamma.
    1352                 :           5 :  call ephtk_mkqtabs(cryst, gams%nqibz, gams%qibz, gams%nqbz, gams%qbz, qirredtofull, qpttoqpt)
    1353                 :             : 
    1354                 :             :  ! Fill BZ array with IBZ data.
    1355         [ +  + ]:          10 :  do spin=1,gams%nsppol
    1356         [ +  + ]:          71 :    do iq_ibz=1,gams%nqibz
    1357                 :          61 :      iq_bz = qirredtofull(iq_ibz)
    1358         [ +  + ]:         244 :      vals_in_bz(:,:,:,iq_bz,spin) = reshape(gams%vals_in_qibz(:,:,:,:,iq_ibz,spin), [2, 9, gams%natom3**2])
    1359         [ +  + ]:         249 :      vals_out_bz(:,:,:,iq_bz,spin) = reshape(gams%vals_out_qibz(:,:,:,:,iq_ibz,spin), [2, 9, gams%natom3**2])
    1360                 :             :    end do
    1361                 :             :  end do
    1362                 :             : 
    1363                 :             :  ! Complete vals_bz in the full BZ.
    1364                 :             :  !TODO!!! rotate the vv in and out matrices, according to the symmetry operation, instead of just copying them
    1365                 :             :  !call complete_gamma_vv(cryst, gams%natom3, gams%nsppol, gams%nqibz, gams%nqbz,&
    1366                 :             :  !  gams%eph_scalprod, qirredtofull, qpttoqpt, vals_in_bz(:,:,:,:,spin))
    1367                 :             :  !call complete_gamma_vv(cryst, gams%natom3, gams%nsppol, gams%nqibz, gams%nqbz,&
    1368                 :             :  !  gams%eph_scalprod, qirredtofull, qpttoqpt, vals_out_bz(:,:,:,:,spin))
    1369                 :             : 
    1370                 :             :  ! TODO: replace the above with these calls from anaddb
    1371                 :             :  !call complete_gamma_tr(cryst,elph_ds%ep_scalprod,elph_ds%nbranch,elph_ds%nqptirred,&
    1372                 :             :  !&   elph_ds%nqpt_full,elph_ds%nsppol,elph_tr_ds%gamma_qpt_trout,elph_ds%qirredtofull,qpttoqpt)
    1373                 :             : 
    1374                 :             :  ! TODO: idem for vv_vals 3x3 matrices
    1375                 :             : 
    1376         [ -  + ]:           5 :  ABI_FREE(qirredtofull)
    1377         [ -  + ]:           5 :  ABI_FREE(qpttoqpt)
    1378                 :             : 
    1379                 :             :  !! This call is not executed in elphon!
    1380                 :             :  !if (gams%symgamma == 1) then
    1381                 :             :  !  do spin=1,gams%nsppol
    1382                 :             :  !    do iq_bz=1,gams%nqbz
    1383                 :             :  !      call tgamma_symm_vv(cryst, gams%qbz(:,iq_bz), vals_in_bz(:,:,:,iq_bz,spin))
    1384                 :             :  !      call tgamma_symm_vv(cryst, gams%qbz(:,iq_bz), vals_out_bz(:,:,:,iq_bz,spin))
    1385                 :             :  !    end do
    1386                 :             :  !  end do
    1387                 :             :  !end if
    1388                 :             : 
    1389                 :             :  ! Now FT to real space
    1390                 :             :  ! NOTE: gprim (not gprimd) is used for all FT interpolations,
    1391                 :             :  ! to be consistent with the dimensions of the rpt, which come from anaddb.
    1392                 :             :  ! TODO: this is needed only if FT is used, not when the linear interpolation is employed.
    1393                 :             :  !if (.not. allocated(gams%vals_in_rpt)) then
    1394   [ -  +  +  -  :          25 :  ABI_MALLOC_OR_DIE(gams%vals_in_rpt, (2, 9, gams%natom3**2, gams%nrpt, gams%nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  -  +  +  -  
                   -  + ]
    1395   [ -  +  +  -  :          25 :  ABI_MALLOC_OR_DIE(gams%vals_out_rpt, (2, 9, gams%natom3**2, gams%nrpt, gams%nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  -  +  +  -  
                   -  + ]
    1396   [ +  +  +  +  :      117655 :  gams%vals_in_rpt = zero
          +  +  +  +  +  
                      + ]
    1397   [ +  +  +  +  :      117655 :  gams%vals_out_rpt = zero
          +  +  +  +  +  
                      + ]
    1398                 :             : 
    1399                 :             :  ! q --> r
    1400   [ -  +  +  -  :          20 :  ABI_MALLOC(coskr, (gams%nqbz,gams%nrpt))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1401   [ -  +  +  -  :          15 :  ABI_MALLOC(sinkr, (gams%nqbz,gams%nrpt))
          -  +  +  -  -  
                +  -  + ]
    1402                 :           5 :  call ftgam_init(gams%gprim, gams%nqbz, gams%nrpt, gams%qbz, gams%rpt, coskr, sinkr)
    1403                 :             : 
    1404         [ +  + ]:          10 :  do spin=1,gams%nsppol
    1405         [ +  + ]:          25 :    do idir=1,3
    1406         [ +  + ]:          65 :      do jdir=1,3
    1407                 :          45 :        ii = idir+gams%ndir_transp*(jdir-1)
    1408                 :             :        ! TODO: this is no contiguous in memory and will be slow. Make adapted ftgam?
    1409                 :             :        call ftgam(gams%wghatm, vals_in_bz(:,ii,:,:,spin), gams%vals_in_rpt(:,ii,:,:,spin), gams%natom, gams%nqbz,&
    1410   [ +  -  +  +  :      621477 :          gams%nrpt, qtor1, coskr, sinkr)
          +  +  +  +  +  
          -  +  -  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  -  +  +  +  
                +  +  + ]
    1411                 :             :        call ftgam(gams%wghatm, vals_out_bz(:,ii,:,:,spin), gams%vals_out_rpt(:,ii,:,:,spin), gams%natom, gams%nqbz,&
    1412   [ +  -  +  +  :      621492 :          gams%nrpt, qtor1, coskr, sinkr)
          +  +  +  +  +  
          -  +  -  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  -  +  +  +  
                +  +  + ]
    1413                 :             :      end do
    1414                 :             :    end do
    1415                 :             :  end do
    1416                 :             : 
    1417         [ -  + ]:           5 :  ABI_FREE(vals_in_bz)
    1418         [ -  + ]:           5 :  ABI_FREE(vals_out_bz)
    1419         [ -  + ]:           5 :  ABI_FREE(coskr)
    1420         [ -  + ]:           5 :  ABI_FREE(sinkr)
    1421                 :             : 
    1422                 :           5 : end subroutine phgamma_vv_interp_setup
    1423                 :             : !!***
    1424                 :             : !----------------------------------------------------------------------
    1425                 :             : 
    1426                 :             : !!****f* m_phgamma/phgamma_linwid
    1427                 :             : !! NAME
    1428                 :             : !! phgamma_linwid
    1429                 :             : !!
    1430                 :             : !! FUNCTION
    1431                 :             : !!  Interpolate the phonon linewidths along an arbitrary q-path (use Fourier interpolation).
    1432                 :             : !!
    1433                 :             : !! INPUTS
    1434                 :             : !!  cryst<crystal_t>=Info on the unit cell and symmetries.
    1435                 :             : !!  ifc<ifc_type>=Interatomic force constants.
    1436                 :             : !!  ndivsm=Number of points used to sample the smallest segment
    1437                 :             : !!  nvert = Number of extrema in qverts
    1438                 :             : !!  qverts(3,nvert) = vertices of reciprocal space trajectory
    1439                 :             : !!  basename=name used to create the different output files (text format).
    1440                 :             : !!  ncid=Netcdf file handler (already open in the caller).
    1441                 :             : !!  comm=MPI communicator
    1442                 :             : !!
    1443                 :             : !! OUTPUT
    1444                 :             : !!  wminmax=Minimum and max phonon frequency obtained on the path (Hartree units)
    1445                 :             : !!
    1446                 :             : !! SOURCE
    1447                 :             : 
    1448                 :           5 : subroutine phgamma_linwid(gams, cryst, ifc, ndivsm, nvert, qverts, basename, ncid, wminmax, comm)
    1449                 :             : 
    1450                 :             : !Arguments ------------------------------------
    1451                 :             : !scalars
    1452                 :             :  class(phgamma_t),intent(inout) :: gams
    1453                 :             :  integer,intent(in) :: nvert,ndivsm,comm,ncid
    1454                 :             :  type(crystal_t),intent(in) :: cryst
    1455                 :             :  type(ifc_type),intent(in) :: ifc
    1456                 :             :  character(len=*),intent(in) :: basename
    1457                 :             : !arrays
    1458                 :             :  real(dp),intent(in) :: qverts(3,nvert)
    1459                 :             :  real(dp),intent(out) :: wminmax(2)
    1460                 :             : 
    1461                 :             : !Local variables-------------------------------
    1462                 :             : !scalars
    1463                 :             :  integer,parameter :: master = 0
    1464                 :             :  integer :: natom,ii,mu,iqpt,natom3,nsppol,ierr, spin,unt,nqpt,nrpt,cnt,nproc,my_rank, ncerr
    1465                 :             :  real(dp) :: omega_min,omega_max,wtmp,omega
    1466                 :             :  character(len=500) :: msg
    1467                 :           5 :  type(kpath_t) :: qpath
    1468                 :             : !arrays
    1469                 :          10 :  real(dp) :: gamma_spin(gams%nsppol),lambda_spin(gams%nsppol)
    1470                 :          10 :  real(dp) :: displ_cart(2,3*cryst%natom,3*cryst%natom)
    1471                 :          10 :  real(dp) :: phfrq(3*cryst%natom),gamma_ph(3*cryst%natom),lambda_ph(3*cryst%natom), qpt(3),shift(3)
    1472                 :           5 :  real(dp),allocatable :: all_phfreq(:,:),all_gammaq(:,:,:),all_lambdaq(:,:,:),all_displ_cart(:,:,:,:)
    1473                 :             : ! *********************************************************************
    1474                 :             : 
    1475                 :           5 :  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    1476                 :           5 :  natom = cryst%natom; natom3 = gams%natom3; nsppol = gams%nsppol; nrpt = gams%nrpt
    1477                 :             : 
    1478                 :             :  ! Define the q-path along which phonon linwid will be interpolated.
    1479                 :           5 :  call qpath%init(qverts, cryst%gprimd, ndivsm)
    1480                 :           5 :  nqpt = qpath%npts
    1481                 :             : 
    1482                 :             :  ! Allocate workspace arrays for MPI.
    1483   [ -  +  +  -  :         840 :  ABI_CALLOC(all_phfreq, (natom3, nqpt))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1484   [ -  +  +  -  :         850 :  ABI_CALLOC(all_gammaq, (natom3, nqpt, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  +  +  +  +  
                   +  + ]
    1485   [ -  +  +  -  :         845 :  ABI_CALLOC(all_lambdaq, (natom3, nqpt, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  +  +  +  
                +  +  + ]
    1486   [ -  +  +  -  :        6380 :  ABI_CALLOC(all_displ_cart, (2, natom3, natom3, nqpt))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  +  +  +  +  
             +  +  +  + ]
    1487                 :             : 
    1488                 :             :  ! initialize the minimum and maximum phonon frequency
    1489                 :           5 :  omega_min = huge(one); omega_max = -huge(one)
    1490                 :             : 
    1491                 :             :  ! Interpolation along specified path in q space (keep spin dep.)
    1492                 :           5 :  cnt = 0
    1493         [ +  + ]:          10 :  do spin=1,nsppol
    1494         [ +  + ]:         215 :    do iqpt=1,nqpt
    1495         [ -  + ]:         205 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle
    1496         [ +  + ]:         820 :      call wrap2_pmhalf(qpath%points(:,iqpt), qpt, shift)
    1497                 :             : 
    1498                 :             :      ! Get phgamma
    1499                 :         205 :      call gams%interp(cryst, ifc, spin, qpt, phfrq, gamma_ph, lambda_ph, displ_cart)
    1500         [ +  + ]:         820 :      all_gammaq(:, iqpt, spin) = gamma_ph
    1501         [ +  + ]:         820 :      all_lambdaq(:, iqpt, spin) = lambda_ph
    1502         [ +  - ]:         205 :      if (spin == 1) then
    1503         [ +  + ]:         820 :        all_phfreq(:, iqpt) = phfrq
    1504   [ +  +  +  +  :        6355 :        all_displ_cart(:, :, :, iqpt) = displ_cart
                   +  + ]
    1505                 :             :      end if
    1506                 :             : 
    1507                 :             :      ! Find max/min phonon frequency along path chosen
    1508                 :             :      ! presumed to be representative of full BZ to within 10 percent
    1509                 :         205 :      omega_min = min(omega_min, phfrq(1))
    1510                 :         210 :      omega_max = max(omega_max, phfrq(natom3))
    1511                 :             :    end do ! end iqpt do
    1512                 :             :  end do ! spin
    1513                 :             : 
    1514                 :             :  ! Collect results
    1515         [ -  + ]:           5 :  if (omega_min > tol12) omega_min = zero
    1516                 :           5 :  wtmp = omega_min; call xmpi_min(wtmp, omega_min, comm, ierr)
    1517                 :           5 :  wtmp = omega_max; call xmpi_max(wtmp, omega_max, comm, ierr)
    1518         [ +  + ]:          15 :  wminmax = [omega_min, omega_max]
    1519                 :             : 
    1520                 :           5 :  call xmpi_sum_master(all_gammaq, master, comm, ierr)
    1521                 :           5 :  call xmpi_sum_master(all_lambdaq, master, comm, ierr)
    1522                 :           5 :  call xmpi_sum_master(all_phfreq, master, comm, ierr)
    1523                 :           5 :  call xmpi_sum_master(all_displ_cart, master, comm, ierr)
    1524                 :             : 
    1525                 :             :  ! Master writes text file with final results.
    1526                 :             :  ! 3 * natom blocks, one block for each phonon mode.
    1527                 :             :  ! Each block contains:
    1528                 :             :  !   iqpt  omega_(q) gamma(q) lambda(q) nesting(q) ....
    1529                 :             : 
    1530         [ +  - ]:           5 :  if (xmpi_comm_rank(comm) == master) then
    1531         [ -  + ]:           5 :    if (open_file(strcat(basename, '_PHGAMMA'), msg, newunit=unt, action="write", form="formatted", status="unknown") /= 0) then
    1532                 :           5 :      ABI_ERROR(msg)
    1533                 :             :    end if
    1534                 :             : 
    1535                 :           5 :    write(unt,'(a)')     '#'
    1536                 :           5 :    write(unt,'(a)')     '# ABINIT package: E-PH band structure file. Hartree units'
    1537                 :           5 :    write(unt,'(a)')     '#'
    1538                 :           5 :    write(unt,'(a,i0,a)')'# Phonon frequencies, ph linewidths and lambda calculated on ',nqpt,' q-points'
    1539         [ +  + ]:          10 :    call qpath%print([unt], header="Description of the q-path:", pre="#")
    1540         [ +  + ]:          15 :    do ii=1,2; write(unt,'(a)')     "# "; end do
    1541                 :             : 
    1542         [ +  + ]:          10 :    write(unt,'(a,e16.6)')"# Total DOS at Fermi level ",sum(gams%n0)
    1543         [ +  + ]:          10 :    do spin=1,nsppol
    1544                 :          10 :      write(unt,"(a,i0,a,e16.6)")"# The DOS at Fermi level for spin ",spin," is ",gams%n0(spin)
    1545                 :             :    end do
    1546                 :             : 
    1547         [ +  + ]:          20 :    do mu=1,natom3
    1548                 :          15 :      write(unt,'(a)')"#"
    1549         [ +  - ]:          15 :      if (nsppol == 1) write(unt,'(a,i0,a)')"# phonon mode [",mu,"] q-index omega gamma lambda"
    1550         [ -  + ]:          15 :      if (nsppol == 2) write(unt,'(a,i0,a)')&
    1551                 :           0 :        "# phonon mode [",mu,"] q-index omega gamma_tot lambda_tot gamma[spin=1] lambda[spin=1] gamma[2] lambda[2]"
    1552                 :          15 :      write(unt,'(a)')"#"
    1553         [ +  + ]:         635 :      do iqpt=1,nqpt
    1554                 :         615 :        omega = all_phfreq(mu, iqpt)
    1555         [ +  + ]:        1230 :        gamma_spin = all_gammaq(mu, iqpt, :)
    1556         [ +  + ]:        1230 :        lambda_spin = all_lambdaq(mu, iqpt, :)
    1557         [ +  - ]:         630 :        if (nsppol == 1) then
    1558                 :         615 :          write(unt,'(i8,3es16.6)' )iqpt,omega,gamma_spin(1),lambda_spin(1)
    1559                 :             :        else
    1560                 :           0 :          write(unt,'(i8,es20.6,6es16.6)' )iqpt,omega,&
    1561   [ #  #  #  # ]:           0 :             sum(gamma_spin),sum(lambda_spin),gamma_spin(1),lambda_spin(1),gamma_spin(2),lambda_spin(2)
    1562                 :             :        end if
    1563                 :             :      end do
    1564                 :             :    end do
    1565                 :             : 
    1566                 :           5 :    close(unt)
    1567                 :             : 
    1568                 :             :    ! Write data to netcdf file
    1569         [ +  - ]:           5 :    if (ncid /= nctk_noid) then
    1570                 :             :      ncerr = nctk_def_dims(ncid, [&
    1571                 :             :        nctkdim_t("natom3", 3*natom), nctkdim_t("nqpath", nqpt), nctkdim_t("number_of_spins", nsppol) &
    1572         [ +  + ]:          20 :      ], defmode=.True.)
    1573         [ -  + ]:           5 :      NCF_CHECK(ncerr)
    1574                 :             : 
    1575                 :             :      ncerr = nctk_def_arrays(ncid, [&
    1576                 :             :        nctkarr_t('qpath', "dp", "number_of_reduced_dimensions, nqpath"), &
    1577                 :             :        nctkarr_t('phfreq_qpath', "dp", "natom3, nqpath"), &
    1578                 :             :        nctkarr_t('phdispl_cart_qpath', "dp", "two, natom3, natom3, nqpath"), &
    1579                 :             :        nctkarr_t('phgamma_qpath', "dp", "natom3, nqpath, number_of_spins"), &
    1580         [ +  + ]:          30 :        nctkarr_t('phlambda_qpath', "dp", "natom3, nqpath, number_of_spins")])
    1581         [ -  + ]:           5 :      NCF_CHECK(ncerr)
    1582                 :             : 
    1583         [ -  + ]:           5 :      NCF_CHECK(nctk_set_datamode(ncid))
    1584         [ -  + ]:           5 :      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "qpath"), qpath%points))
    1585         [ -  + ]:           5 :      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phfreq_qpath"), all_phfreq))
    1586         [ -  + ]:           5 :      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phdispl_cart_qpath"), all_displ_cart))
    1587         [ -  + ]:           5 :      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phgamma_qpath"), all_gammaq))
    1588         [ -  + ]:           5 :      NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "phlambda_qpath"), all_lambdaq))
    1589                 :             :    end if
    1590                 :             :  end if ! master
    1591                 :             : 
    1592         [ -  + ]:           5 :  ABI_FREE(all_phfreq)
    1593         [ -  + ]:           5 :  ABI_FREE(all_gammaq)
    1594         [ -  + ]:           5 :  ABI_FREE(all_lambdaq)
    1595         [ -  + ]:           5 :  ABI_FREE(all_displ_cart)
    1596                 :             : 
    1597                 :           5 :  call qpath%free()
    1598                 :             : 
    1599   [ -  +  -  +  :          10 : end subroutine phgamma_linwid
          -  +  -  +  -  
                      + ]
    1600                 :             : !!***
    1601                 :             : 
    1602                 :             : !----------------------------------------------------------------------
    1603                 :             : 
    1604                 :             : !!****f* m_phgamma/a2fw_free
    1605                 :             : !! NAME
    1606                 :             : !! a2fw_free
    1607                 :             : !!
    1608                 :             : !! FUNCTION
    1609                 :             : !!  Free the memory allocated in a2f
    1610                 :             : !!
    1611                 :             : !! SOURCE
    1612                 :             : 
    1613                 :          10 : subroutine a2fw_free(a2f)
    1614                 :             : 
    1615                 :             : !Arguments ------------------------------------
    1616                 :             :  class(a2fw_t),intent(inout) :: a2f
    1617                 :             : ! *********************************************************************
    1618                 :             : 
    1619                 :             :  ! integer
    1620         [ +  - ]:          10 :  ABI_SFREE(a2f%qshift)
    1621                 :             : 
    1622                 :             :  ! real
    1623         [ +  - ]:          10 :  ABI_SFREE(a2f%n0)
    1624         [ +  - ]:          10 :  ABI_SFREE(a2f%omega)
    1625         [ +  - ]:          10 :  ABI_SFREE(a2f%vals)
    1626         [ -  + ]:          10 :  ABI_SFREE(a2f%vals_ee)
    1627         [ +  - ]:          10 :  ABI_SFREE(a2f%lambdaw)
    1628                 :             : 
    1629                 :          10 : end subroutine a2fw_free
    1630                 :             : !!***
    1631                 :             : 
    1632                 :             : !----------------------------------------------------------------------
    1633                 :             : 
    1634                 :             : !!****f* m_phgamma/a2fw_init
    1635                 :             : !! NAME
    1636                 :             : !! a2fw_init
    1637                 :             : !!
    1638                 :             : !! FUNCTION
    1639                 :             : !!  Calculates the FS averaged alpha^2F(w) function
    1640                 :             : !!
    1641                 :             : !! INPUTS
    1642                 :             : !!  cryst<crystal_t>=Info on the unit cell.
    1643                 :             : !!  ifc<ifc_type>=Interatomic force constants.
    1644                 :             : !!  gams<phgamma_t>=Structure storing the phonon linewidths.
    1645                 :             : !!  wstep=Step for linear frequency mesh in Ha.
    1646                 :             : !!  wminmax(2)=Minimum and maximum phonon frequency. Used to construct the linear mesh for A2F(w).
    1647                 :             : !!  ph_intmeth=Integration method for phonons: 1 for gaussian, 2 for tetrahedra
    1648                 :             : !!  smear=Gaussian broadening used to approximate the Dirac delta.
    1649                 :             : !!  ngqpt(3)=Divisions of the Q-mesh used for interpolating the phonon linewidths (see also nqshift and qshift).
    1650                 :             : !!  nqshift=Number of shifts used to generated the Q-mesh.
    1651                 :             : !!  qshift(3,nqshift)=The shifts.
    1652                 :             : !!  comm=MPI communicator
    1653                 :             : !!  [qintp]=If set to False, ngqgpt, nqshift, qshift and qptop are ignored and
    1654                 :             : !!     A2F(w) is computed from the IBZ values stored in gams. Default: True i.e use Fourier interpolation.
    1655                 :             : !!  [qptopt]=Controls the generation of the q-points. If not specified, the routine takes fully into account
    1656                 :             : !!    the symmetries of the system to generate the q points in the IBZone i.e. qptopt=1
    1657                 :             : !!    Other values of qptopt can be used for debugging purpose.
    1658                 :             : !!
    1659                 :             : !! OUTPUT
    1660                 :             : !!  a2f<a2fw_t>=Structure storing the Eliashberg function a2F(w).
    1661                 :             : !!
    1662                 :             : !! SOURCE
    1663                 :             : 
    1664                 :          10 : subroutine a2fw_init(a2f, gams, cryst, ifc, ph_intmeth, wstep, wminmax, smear, ngqpt, nqshift, qshift, comm, &
    1665                 :             :                      qintp, qptopt) ! optional
    1666                 :             : 
    1667                 :             : !Arguments ------------------------------------
    1668                 :             : !scalars
    1669                 :             :  class(a2fw_t),target,intent(out) :: a2f
    1670                 :             :  integer,intent(in) :: ph_intmeth,nqshift,comm
    1671                 :             :  integer,intent(in),optional :: qptopt
    1672                 :             :  real(dp),intent(in) :: wstep,smear
    1673                 :             :  logical,optional,intent(in) :: qintp
    1674                 :             :  type(phgamma_t),intent(inout) :: gams
    1675                 :             :  type(ifc_type),intent(in) :: ifc
    1676                 :             :  type(crystal_t),intent(in) :: cryst
    1677                 :             : !arrays
    1678                 :             :  integer,intent(in) :: ngqpt(3)
    1679                 :             :  real(dp),intent(in) :: wminmax(2),qshift(3,nqshift)
    1680                 :             : 
    1681                 :             : !Local variables -------------------------
    1682                 :             : !scalars
    1683                 :             :  integer,parameter :: master = 0
    1684                 :             :  integer :: my_qptopt,iq_ibz,nqibz,ount,my_rank,nproc,cnt
    1685                 :             :  integer :: mu,iw,natom3,nsppol,spin,ierr,nomega,nqbz
    1686                 :             :  integer :: iene, jene, itemp, ntemp, jene_jump, spinfactor
    1687                 :             :  real(dp) :: cpu,wall,gflops
    1688                 :             :  real(dp) :: lambda_iso,omega,omega_log,xx,omega_min,omega_max,ww,mustar,tc_macmill
    1689                 :             :  real(dp) :: temp_el, min_temp, delta_temp, chempot, ene1, ene2, G0
    1690                 :             :  logical :: do_qintp
    1691                 :             :  character(len=500) :: msg
    1692                 :          10 :  type(htetra_t) :: tetra_q
    1693                 :             : !arrays
    1694                 :             :  integer :: qptrlatt(3,3),new_qptrlatt(3,3)
    1695                 :          20 :  real(dp) :: displ_cart(2,3,cryst%natom,3*cryst%natom)
    1696                 :          40 :  real(dp) :: phfrq(gams%natom3),gamma_ph(gams%natom3),lambda_ph(gams%natom3), invphfrq(gams%natom3)
    1697                 :          10 :  real(dp),allocatable :: my_qshift(:,:), gamma_ph_ee(:,:,:,:), tmp_a2f(:)
    1698                 :          10 :  real(dp),contiguous, pointer :: a2f_1d(:)
    1699                 :          10 :  real(dp),allocatable :: qibz(:,:),wtq(:),qbz(:,:), a2f_1mom(:),a2flogmom(:),a2flogmom_int(:),wdt(:,:)
    1700                 :          10 :  real(dp),allocatable :: lambda_tetra(:,:,:),phfreq_tetra(:,:), tmp_gaussian(:,:)
    1701                 :          10 :  real(dp),allocatable :: a2feew_partial(:), a2feew_partial_int(:), a2feew_w(:), a2feew_w_int(:)
    1702                 :             : ! *********************************************************************
    1703                 :             : 
    1704                 :          10 :  call cwtime(cpu, wall, gflops, "start")
    1705                 :          10 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
    1706                 :             : 
    1707         [ +  - ]:          10 :  my_qptopt = 1; if (present(qptopt)) my_qptopt = qptopt
    1708         [ +  + ]:          10 :  do_qintp = .True.; if (present(qintp)) do_qintp = qintp
    1709                 :          10 :  nsppol = gams%nsppol; natom3 = gams%natom3
    1710                 :             : 
    1711         [ -  + ]:          10 :  if (gams%prteliash == 3) then
    1712   [ #  #  #  #  :           0 :    ABI_MALLOC(gamma_ph_ee, (gams%nene, gams%nene, gams%natom3, gams%nsppol))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1713                 :             :  end if
    1714                 :             : 
    1715         [ +  + ]:          10 :  if (do_qintp) then
    1716                 :             :    ! Generate fine q-mesh, find the IBZ and the corresponding weights.
    1717                 :           5 :    qptrlatt = 0; qptrlatt(1,1) = ngqpt(1); qptrlatt(2,2) = ngqpt(2); qptrlatt(3,3) = ngqpt(3)
    1718                 :             : 
    1719                 :             :    call kpts_ibz_from_kptrlatt(cryst, qptrlatt, my_qptopt, nqshift, qshift, nqibz, qibz, wtq, nqbz, qbz, &
    1720                 :           5 :       new_kptrlatt=new_qptrlatt, new_shiftk=my_qshift)
    1721         [ -  + ]:           5 :    ABI_FREE(qbz)
    1722                 :             : 
    1723                 :             :    ! Store quantities that cannot be easily (and safely) calculated if we only know the IBZ.
    1724         [ +  + ]:          20 :    a2f%ngqpt = ngqpt; a2f%nqshift = size(my_qshift, dim=2)
    1725   [ -  +  +  -  :          15 :    ABI_MALLOC(a2f%qshift, (3, a2f%nqshift))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1726   [ +  -  +  -  :          30 :    a2f%qshift = my_qshift
          -  +  -  -  -  
          -  -  -  +  +  
                   +  + ]
    1727         [ -  + ]:           5 :    ABI_FREE(my_qshift)
    1728                 :             : 
    1729                 :             :  else
    1730                 :             :    ! No interpolation. Use q-mesh parameters from gams%
    1731         [ +  + ]:          20 :    a2f%ngqpt = gams%ngqpt; a2f%nqshift = 1
    1732                 :           5 :    nqibz = gams%nqibz
    1733   [ -  +  +  -  :          15 :    ABI_MALLOC(qibz, (3, nqibz))
          +  -  +  -  -  
                +  -  + ]
    1734   [ -  +  +  -  :          15 :    ABI_MALLOC(wtq, (nqibz))
          +  -  +  -  -  
                +  -  + ]
    1735   [ -  +  -  + ]:           5 :    ABI_MALLOC(a2f%qshift, (3, a2f%nqshift))
    1736   [ +  -  +  -  :         320 :    qibz = gams%qibz; wtq = gams%wtq
          -  +  -  -  -  
          -  -  -  +  +  
          +  +  +  -  -  
          +  -  -  -  -  
                   +  + ]
    1737   [ +  +  +  + ]:          25 :    a2f%qshift = zero ! Note: assuming q-mesh centered on Gamma.
    1738                 :             :  end if
    1739                 :             : 
    1740                 :          10 :  call cwtime_report(" a2fw_init, q-setup:", cpu, wall, gflops)
    1741                 :             : 
    1742                 :             :  ! Define Min and max frequency for the mesh (enlarge it a bit)
    1743                 :          10 :  omega_min = wminmax(1); omega_max = wminmax(2)
    1744                 :          10 :  omega_min = omega_min - 0.1*abs(omega_min)
    1745         [ -  + ]:          10 :  if (omega_min >= zero) omega_min = one/Ha_meV
    1746                 :          10 :  omega_max = omega_max + 0.1*abs(omega_max)
    1747                 :             : 
    1748                 :          10 :  a2f%nsppol = nsppol; a2f%natom3 = gams%natom3; a2f%smear = smear
    1749                 :          10 :  a2f%omega_min = omega_min; a2f%omega_max = omega_max
    1750                 :          10 :  nomega = int((omega_max - omega_min) / wstep); a2f%nomega = nomega; a2f%wstep = wstep
    1751                 :          10 :  a2f%nene = gams%nene
    1752                 :          10 :  a2f%enemin = gams%enemin
    1753                 :          10 :  a2f%deltaene = gams%deltaene
    1754                 :             : 
    1755   [ -  +  +  -  :          30 :  ABI_MALLOC(a2f%n0, (nsppol))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1756   [ +  -  -  +  :          30 :  a2f%n0 = gams%n0
          -  -  -  -  -  
                -  +  + ]
    1757                 :             :  ! Build linear mesh.
    1758   [ -  +  +  -  :          30 :  ABI_MALLOC(a2f%omega, (nomega))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1759   [ +  -  +  -  :        4750 :  a2f%omega = arth(omega_min, wstep, nomega)
          -  +  -  -  +  
                      + ]
    1760                 :             : 
    1761   [ -  +  +  -  :       19020 :  ABI_CALLOC(a2f%vals, (nomega,0:natom3, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  -  +  +  +  
             +  +  +  + ]
    1762   [ -  +  +  -  :       19010 :  ABI_CALLOC(a2f%lambdaw, (nomega,0:natom3, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
             +  +  +  +  
                      + ]
    1763                 :             : 
    1764         [ -  + ]:          10 :  if (gams%prteliash == 3) then
    1765   [ #  #  #  #  :           0 :    ABI_CALLOC(a2f%vals_ee, (gams%nene, gams%nene, nomega, nsppol))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1766                 :             :  end if
    1767                 :             : 
    1768   [ -  +  +  -  :          20 :  ABI_MALLOC(tmp_a2f, (nomega))
             -  +  -  + ]
    1769                 :             : 
    1770         [ +  + ]:          10 :  if (ph_intmeth == 2) then
    1771                 :             :    ! Prepare tetrahedron integration.
    1772                 :           8 :    call cwtime(cpu, wall, gflops, "start")
    1773                 :             : 
    1774                 :           8 :    qptrlatt = 0; qptrlatt(1, 1) = a2f%ngqpt(1); qptrlatt(2, 2) = a2f%ngqpt(2); qptrlatt(3, 3) = a2f%ngqpt(3)
    1775                 :           8 :    tetra_q = tetra_from_kptrlatt(cryst, my_qptopt, qptrlatt, a2f%nqshift, a2f%qshift, nqibz, qibz, comm, msg, ierr)
    1776         [ -  + ]:           8 :    if (ierr /= 0) ABI_ERROR(msg)
    1777                 :             : 
    1778   [ -  +  +  -  :        1971 :    ABI_CALLOC(lambda_tetra, (nqibz, natom3, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  +  +  +  +  
                   +  + ]
    1779   [ -  +  +  -  :        1955 :    ABI_CALLOC(phfreq_tetra, (nqibz, natom3))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    1780                 :           8 :    cnt = 0
    1781         [ +  + ]:         641 :    do iq_ibz = 1, nqibz
    1782         [ +  - ]:         633 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle  ! MPI parallelism.
    1783                 :         633 :      call ifc%fourq(cryst, qibz(:,iq_ibz), phfrq, displ_cart)
    1784                 :             :      ! save for tetrahedron interpolation
    1785         [ +  + ]:        2540 :      phfreq_tetra(iq_ibz,:) = phfrq(:)
    1786                 :             :    end do
    1787                 :           8 :    call xmpi_sum(phfreq_tetra, comm, ierr)
    1788                 :          16 :    call cwtime_report(" a2fw_init%tetra", cpu, wall, gflops)
    1789                 :             :  end if
    1790                 :             : 
    1791                 :          10 :  call cwtime(cpu, wall, gflops, "start")
    1792                 :             : 
    1793                 :             :  ! DEV_MJV
    1794                 :             :  !open(unit=900, file="a2fvals_ee.dat"); write (900,*) '# do_qintp ', do_qintp
    1795                 :             : 
    1796                 :             :  ! Loop over spins and q-points in the IBZ. For the moment parallelize over iq_ibz
    1797         [ +  + ]:          20 :  do spin=1,nsppol
    1798                 :          10 :    cnt = 0
    1799         [ +  + ]:         806 :    do iq_ibz=1,nqibz
    1800                 :             :      ! TODO: for the moment the memory is not distributed, only the calculation exception is vals_ee
    1801         [ -  + ]:         786 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism.
    1802                 :             : 
    1803                 :             :      ! Interpolate or evaluate gamma directly.
    1804         [ +  + ]:         786 :      if (do_qintp) then
    1805         [ -  + ]:         725 :        if (gams%prteliash == 3) then
    1806                 :           0 :          call gams%interp(cryst,ifc,spin,qibz(:,iq_ibz),phfrq,gamma_ph,lambda_ph,displ_cart,gamma_ph_ee=gamma_ph_ee(:,:,:,spin))
    1807                 :             :        else
    1808                 :         725 :          call gams%interp(cryst,ifc,spin,qibz(:,iq_ibz),phfrq,gamma_ph,lambda_ph,displ_cart)
    1809                 :             :        end if
    1810                 :             :      else
    1811         [ -  + ]:          61 :        if (gams%prteliash == 3) then
    1812                 :           0 :          call gams%eval_qibz(cryst,ifc,iq_ibz,spin,phfrq,gamma_ph,lambda_ph,displ_cart,gamma_ph_ee=gamma_ph_ee(:,:,:,spin))
    1813                 :             :        else
    1814                 :          61 :          call gams%eval_qibz(cryst,ifc,iq_ibz,spin,phfrq,gamma_ph,lambda_ph, displ_cart)
    1815                 :             :        end if
    1816                 :             :      end if
    1817                 :             : 
    1818                 :          10 :      select case (ph_intmeth)
    1819                 :             :      case (1)
    1820                 :             :        ! Gaussian: Add all contributions from the phonon modes at this qpoint to a2f
    1821                 :             :        ! (note that unstable modes are included).
    1822   [ -  +  +  -  :         612 :        ABI_MALLOC(tmp_gaussian, (nomega, natom3))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1823         [ +  + ]:         612 :        do mu=1,natom3
    1824         [ +  + ]:      217566 :          tmp_a2f = zero
    1825         [ +  + ]:      217566 :          do iw=1,nomega
    1826                 :      217107 :            xx = a2f%omega(iw) - phfrq(mu)
    1827                 :      217107 :            tmp_gaussian(iw, mu) = gaussian(xx, smear)
    1828                 :      217566 :            tmp_a2f(iw) = tmp_a2f(iw) + tmp_gaussian(iw,mu) * lambda_ph(mu) * abs(phfrq(mu))
    1829                 :             :          end do
    1830         [ +  + ]:      217719 :          a2f%vals(:,mu,spin) = a2f%vals(:,mu,spin) + tmp_a2f * wtq(iq_ibz)
    1831                 :             :        end do
    1832                 :             : 
    1833         [ -  + ]:         153 :        if (gams%prteliash == 3) then
    1834                 :             :          ! reset phfrq for low freq modes
    1835         [ #  # ]:           0 :          invphfrq = zero
    1836         [ #  # ]:           0 :          do mu=1,natom3
    1837         [ #  # ]:           0 :            if (abs(phfrq(mu)) > EPHTK_WTOL) invphfrq(mu) = one / abs(phfrq(mu))
    1838                 :             :          end do
    1839                 :             : 
    1840         [ #  # ]:           0 :          do iene= 1, gams%nene
    1841         [ #  # ]:           0 :            do jene= 1, gams%nene
    1842         [ #  # ]:           0 :              tmp_a2f = zero
    1843                 :             :              ! TODO: following block is just a GEMM
    1844         [ #  # ]:           0 :              do mu=1,natom3
    1845         [ #  # ]:           0 :                do iw=1,nomega
    1846                 :           0 :                  tmp_a2f(iw) = tmp_a2f(iw) + tmp_gaussian(iw,mu) * gamma_ph_ee(jene,iene,mu,spin) * invphfrq(mu)
    1847                 :             :                end do
    1848                 :             :              end do
    1849                 :             : 
    1850         [ #  # ]:           0 :              a2f%vals_ee(jene, iene, :, spin) = a2f%vals_ee(jene, iene, :, spin) + tmp_a2f(:) * wtq(iq_ibz)
    1851                 :             :              !if (iene == gams%nene/2 .and. jene == gams%nene/2) then
    1852                 :             :              !  write (900, '(a,E20.10,2x,2x,I6,3E20.10)') '#', wtq(iq_ibz), iq_ibz, invphfrq(1:3)
    1853                 :             :              !  do iw=1,nomega
    1854                 :             :              !    write (900, '(i6,2x,E20.10,2x,3E20.10,2x,3E20.10)') iw, a2f%vals_ee(jene, iene, iw, spin), &
    1855                 :             :              !        gamma_ph_ee(jene,iene,:,spin), tmp_gaussian(iw,1:3)
    1856                 :             :              !  end do
    1857                 :             :              !  write (900,*)
    1858                 :             :              !end if
    1859                 :             :            end do
    1860                 :             :          end do
    1861                 :             :        end if
    1862                 :             : 
    1863         [ -  + ]:         153 :        ABI_FREE(tmp_gaussian)
    1864                 :             : 
    1865                 :             :      case (2)
    1866                 :             :        ! Tetra: store data.
    1867         [ +  + ]:        2532 :        do mu=1,natom3
    1868                 :        2532 :          lambda_tetra(iq_ibz, mu, spin) = lambda_ph(mu) * abs(phfrq(mu))
    1869                 :             :        end do
    1870                 :             : 
    1871         [ -  + ]:         633 :        if (gams%prteliash == 3) then
    1872                 :           0 :          ABI_ERROR("Eliashberg function with tetra not coded")
    1873                 :             :        end if
    1874                 :             : 
    1875                 :             :      case default
    1876      [ +  +  - ]:         786 :        ABI_ERROR(sjoin("Wrong ph_intmeth:", itoa(ph_intmeth)))
    1877                 :             :      end select
    1878                 :             : 
    1879                 :             :    end do ! iq_ibz
    1880                 :             :  end do ! spin
    1881                 :             : 
    1882                 :             :  !DEV_MJV
    1883                 :             :  !close(900)
    1884                 :             : 
    1885         [ +  + ]:          10 :  if (ph_intmeth == 2) then
    1886                 :             :    ! workspace for tetra.
    1887   [ -  +  +  -  :          24 :    ABI_MALLOC(wdt, (nomega, 2))
          +  -  +  -  -  
                +  -  + ]
    1888                 :             : 
    1889                 :             :    ! For each mode get its contribution
    1890         [ +  + ]:          16 :    do spin=1,nsppol
    1891         [ +  + ]:          40 :      do mu=1,natom3
    1892                 :          24 :        cnt = 0
    1893         [ +  + ]:        1931 :        do iq_ibz=1,nqibz
    1894                 :             :          ! NB: if we are interpolating the gamma, nqibz > gams%nqibz
    1895         [ +  - ]:        1899 :          cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism.
    1896                 :             : 
    1897                 :        1899 :          call tetra_q%get_onewk(iq_ibz, gams%bcorr, nomega, nqibz, phfreq_tetra(:,mu), omega_min, omega_max, one, wdt)
    1898   [ +  +  +  + ]:     1802151 :          wdt = wdt * wtq(iq_ibz)
    1899                 :             : 
    1900                 :             :          ! Accumulate (Integral of a2F is computed afterwards)
    1901         [ +  + ]:      900150 :          a2f%vals(:,mu,spin) = a2f%vals(:,mu,spin) + wdt(:,1) * lambda_tetra(iq_ibz,mu,spin)
    1902                 :             :          !a2f%lambdaw(:,mu,spin) = a2f%lambdaw(:,mu,spin) + wdt(:,2) * lambda_tetra(iq_ibz, mu, spin)
    1903                 :             :       end do
    1904                 :             :      end do
    1905                 :             :    end do
    1906                 :             : 
    1907                 :             :    ! Free memory allocated for tetra.
    1908         [ -  + ]:           8 :    ABI_FREE(wdt)
    1909         [ -  + ]:           8 :    ABI_FREE(lambda_tetra)
    1910         [ -  + ]:           8 :    ABI_FREE(phfreq_tetra)
    1911                 :           8 :    call tetra_q%free()
    1912                 :             :  end if
    1913                 :             : 
    1914                 :             :  ! Collect final results on each node
    1915                 :          10 :  call xmpi_sum(a2f%vals, comm, ierr)
    1916         [ +  + ]:          20 :  do spin=1,nsppol
    1917   [ +  +  +  + ]:       18940 :    a2f%vals(:,0,spin) = sum(a2f%vals(:,1:natom3,spin), dim=2)
    1918                 :             :    ! previously would divide by g(eF, spin)
    1919                 :             :    !a2f%vals(:,:,spin) = a2f%vals(:,:,spin) / (two_pi*a2f%n0(spin))
    1920                 :             :  end do
    1921                 :             : 
    1922         [ -  + ]:          10 :  if (gams%prteliash == 3) then
    1923                 :             :    ! For the moment vals_ee only works with gaussians
    1924                 :           0 :    call xmpi_sum(a2f%vals_ee, comm, ierr)
    1925         [ #  # ]:           0 :    do spin=1,nsppol
    1926   [ #  #  #  #  :           0 :      a2f%vals_ee(:,:,:,spin) = a2f%vals_ee(:,:,:,spin) / (two * pi * gams%n0(spin))
                   #  # ]
    1927                 :             :    end do
    1928                 :             :  end if
    1929                 :             : 
    1930                 :          10 :  call cwtime_report(" a2fw_init, a2f_eval:", cpu, wall, gflops)
    1931                 :             : 
    1932   [ -  +  +  -  :          20 :  ABI_MALLOC(a2f_1mom, (nomega))
             -  +  -  + ]
    1933   [ -  +  +  -  :          20 :  ABI_MALLOC(a2flogmom, (nomega))
             -  +  -  + ]
    1934   [ -  +  +  -  :          20 :  ABI_MALLOC(a2flogmom_int, (nomega))
             -  +  -  + ]
    1935                 :             : 
    1936                 :             :  !call a2fw_print_info()
    1937                 :             : 
    1938                 :             :  ! Compute lambda(w) resolved in spin and phonon mode.
    1939                 :             :  ! lambda(w) = int a2F(w')/w' dw'
    1940         [ +  + ]:          20 :  do spin=1,nsppol
    1941         [ +  + ]:          60 :    do mu=0,natom3
    1942                 :             : 
    1943         [ +  + ]:       18960 :      do iw=1,nomega
    1944                 :       18920 :        ww = a2f%omega(iw)
    1945         [ +  - ]:       18960 :        if (abs(ww) > EPHTK_WTOL) then
    1946                 :       18920 :           a2f_1mom(iw) = a2f%vals(iw, mu, spin) / abs(ww)
    1947                 :             :        else
    1948                 :           0 :           a2f_1mom(iw) = zero
    1949                 :             :        end if
    1950                 :             :      end do
    1951                 :             : 
    1952                 :          50 :      call simpson_int(nomega, wstep, a2f_1mom, a2f%lambdaw(:, mu, spin))
    1953                 :             :    end do
    1954                 :             :  end do
    1955                 :             : 
    1956                 :             :  ! print log moments of the alpha^2 F function (for each spin, note degeneracy factor).
    1957                 :          10 :  spinfactor = int(2 / nsppol / gams%nspinor)
    1958         [ +  + ]:          20 :  do spin=1,nsppol
    1959                 :          10 :    a2f_1d => a2f%vals(:,0,spin)
    1960                 :             : 
    1961                 :          10 :    lambda_iso = a2f%get_moment(0, spin)
    1962                 :             : 
    1963                 :             :    ! Get log moment of alpha^2F.
    1964         [ +  + ]:        4740 :    a2flogmom = zero
    1965         [ +  + ]:        4740 :    do iw=1,nomega
    1966                 :        4730 :      omega = a2f%omega(iw)
    1967         [ +  - ]:        4740 :      if (abs(omega) > EPHTK_WTOL) then
    1968                 :             :        !a2flogmom(iw) = (two / lambda_iso) * a2f_1d(iw) * log(abs(omega)) / abs(omega)
    1969                 :             :        ! I (WHO??? GMATTEO?) think this is the correct expression.
    1970                 :        4730 :        a2flogmom(iw) = (spinfactor / lambda_iso) * a2f_1d(iw) * log(abs(omega)) / abs(omega)
    1971                 :             :      end if
    1972                 :             :    end do
    1973                 :          10 :    call simpson_int(nomega, wstep, a2flogmom, a2flogmom_int)
    1974                 :          10 :    omega_log = exp(a2flogmom_int(nomega))
    1975                 :             : 
    1976                 :          10 :    mustar = 0.12
    1977                 :          10 :    tc_macmill = omega_log/1.2_dp * exp((-1.04_dp*(one+lambda_iso)) / (lambda_iso-mustar*(one+0.62_dp*lambda_iso)))
    1978                 :             : 
    1979         [ +  - ]:          20 :    if (my_rank == master) then
    1980                 :          10 :      ount = std_out
    1981         [ -  + ]:          10 :      if (nsppol > 1) then
    1982                 :           0 :        write(msg,'(3a)') ch10,' Warning: some of the following quantities should be integrated over spin', ch10
    1983                 :           0 :        call wrtout(ount, msg)
    1984                 :             :      end if
    1985                 :             : 
    1986         [ +  + ]:          10 :      if (do_qintp) then
    1987                 :           5 :        write(ount,'(a,i3)') ' Superconductivity: isotropic evaluation of parameters from electron-phonon coupling (interpolated) for spin ', spin
    1988                 :             :      else
    1989                 :           5 :        write(ount,'(a,i3)') ' Superconductivity: isotropic evaluation of parameters from electron-phonon coupling (coarse grid) for spin ', spin
    1990                 :             :      endif
    1991                 :          10 :      write(ount,'(a,es16.6)')            ' isotropic lambda = ',lambda_iso
    1992                 :          10 :      write(ount,'(a,es16.6,a,es16.6,a)' )' omegalog  = ',omega_log,' (Ha) ', omega_log * Ha_K, ' (Kelvin) '
    1993                 :          10 :      write(ount,'(a,es16.6,a,es16.6,a)') ' MacMillan Tc = ',tc_macmill,' (Ha) ', tc_macmill * Ha_K, ' (Kelvin) '
    1994                 :          10 :      write(ount,"(a)")                   ' Positive moments of alpha2F:'
    1995                 :          10 :      write(ount,'(a,es16.6)' )           ' lambda <omega^2> = ',a2f%get_moment(2, spin)
    1996                 :          10 :      write(ount,'(a,es16.6)' )           ' lambda <omega^3> = ',a2f%get_moment(3, spin)
    1997                 :          10 :      write(ount,'(a,es16.6)' )           ' lambda <omega^4> = ',a2f%get_moment(4, spin)
    1998                 :          10 :      write(ount,'(a,es16.6)' )           ' lambda <omega^5> = ',a2f%get_moment(5, spin)
    1999                 :             :    end if
    2000                 :             :  end do
    2001                 :             : 
    2002                 :             :  ! Calculate the temperature dependence of the a2f(e,e',w) integrals (G_0(T_e)
    2003                 :             :  ! as in PRL 110 016405 (2013) [[cite:Arnaud2013]])
    2004   [ -  +  -  - ]:          10 :  if (gams%prteliash == 3 .and. my_rank == master) then
    2005                 :           0 :    ntemp = 100
    2006                 :           0 :    min_temp = zero
    2007                 :           0 :    delta_temp = 40._dp ! Kelvin
    2008   [ #  #  #  #  :           0 :    ABI_MALLOC(a2feew_partial, (a2f%nene))
          #  #  #  #  #  
                #  #  # ]
    2009   [ #  #  #  #  :           0 :    ABI_MALLOC(a2feew_partial_int, (a2f%nene))
             #  #  #  # ]
    2010   [ #  #  #  #  :           0 :    ABI_MALLOC(a2feew_w, (nomega))
             #  #  #  # ]
    2011   [ #  #  #  #  :           0 :    ABI_MALLOC(a2feew_w_int, (nomega))
             #  #  #  # ]
    2012                 :             : 
    2013         [ #  # ]:           0 :    if (open_file("EPC_strength_aafo_T.dat", msg, newunit=ount, form="formatted", action="write", status="unknown") /= 0) then
    2014                 :           0 :      ABI_ERROR(msg)
    2015                 :             :    end if
    2016                 :             : 
    2017                 :           0 :    write(ount, "(a)")"# temp_el, G_0(T_e) in W/m^3/K, spin"
    2018         [ #  # ]:           0 :    do spin=1,nsppol
    2019         [ #  # ]:           0 :      do itemp = 1, ntemp
    2020                 :           0 :        temp_el = min_temp + (itemp-1)*delta_temp
    2021                 :             : 
    2022                 :             :        ! TODO: need to evolve the chemical potential with T, but I do not have access to the full DOS here!!
    2023                 :             :        ! possible fix using local information on DOS variation near E_F...
    2024                 :           0 :        chempot = a2f%enemin + half * a2f%nene * a2f%deltaene
    2025                 :             : 
    2026         [ #  # ]:           0 :        do iw=1,nomega
    2027                 :           0 :          omega = a2f%omega(iw)
    2028                 :           0 :          jene_jump = nint(omega/a2f%deltaene)
    2029         [ #  # ]:           0 :          a2feew_partial = zero
    2030         [ #  # ]:           0 :          do iene=1,a2f%nene
    2031                 :           0 :            ene1 = a2f%enemin + (iene-1)*a2f%deltaene
    2032                 :           0 :            ene2 = ene1 + omega
    2033                 :             :            a2feew_partial(iene) = a2f%vals_ee(min(a2f%nene,iene+jene_jump), iene, iw, spin) * &
    2034                 :           0 :               (fermi_dirac(ene1, chempot, temp_el/Ha_K) - fermi_dirac(ene2, chempot, temp_el/Ha_K))
    2035                 :             :          end do
    2036                 :           0 :          call simpson_int(a2f%nene, a2f%deltaene, a2feew_partial, a2feew_partial_int)
    2037                 :           0 :          a2feew_w(iw) = a2feew_partial_int(a2f%nene)
    2038                 :             :        end do
    2039                 :           0 :        call simpson_int(nomega, wstep, a2feew_w, a2feew_w_int)
    2040                 :           0 :        G0 = a2feew_w_int(nomega) * two_pi * a2f%n0(spin) / cryst%ucvol
    2041                 :             :        ! conversion factor for G0 to SI units =  Ha_J / Time_Sec / (Bohr_meter)**3 ~ 1.2163049915755545e+30
    2042                 :           0 :        write(ount, "(2(e20.10,2x),i5)") temp_el, G0  * kb_HaK / Time_Sec / (Bohr_meter)**3, spin !* Ha_J???
    2043                 :             :      end do
    2044                 :             :    end do
    2045                 :           0 :    close(ount)
    2046                 :             : 
    2047         [ #  # ]:           0 :    ABI_FREE(a2feew_partial)
    2048         [ #  # ]:           0 :    ABI_FREE(a2feew_partial_int)
    2049         [ #  # ]:           0 :    ABI_FREE(a2feew_w)
    2050         [ #  # ]:           0 :    ABI_FREE(a2feew_w_int)
    2051         [ #  # ]:           0 :    ABI_FREE(gamma_ph_ee)
    2052                 :             :  end if
    2053                 :             : 
    2054         [ -  + ]:          10 :  ABI_FREE(tmp_a2f)
    2055         [ -  + ]:          10 :  ABI_FREE(a2f_1mom)
    2056         [ -  + ]:          10 :  ABI_FREE(a2flogmom)
    2057         [ -  + ]:          10 :  ABI_FREE(a2flogmom_int)
    2058         [ -  + ]:          10 :  ABI_FREE(qibz)
    2059         [ -  + ]:          10 :  ABI_FREE(wtq)
    2060                 :             : 
    2061   [ +  -  -  +  :          70 : end subroutine a2fw_init
          -  +  -  +  -  
          +  -  -  -  -  
          -  +  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
                      + ]
    2062                 :             : !!***
    2063                 :             : 
    2064                 :             : !----------------------------------------------------------------------
    2065                 :             : 
    2066                 :             : !!****f* m_phgamma/a2fw_get_moment
    2067                 :             : !! NAME
    2068                 :             : !! a2fw_get_moment
    2069                 :             : !!
    2070                 :             : !! FUNCTION
    2071                 :             : !!  Compute \int dw [a2F(w)/w] w^n. From Allen PRL 59 1460 [[cite:Allen1987]].
    2072                 :             : !!  See also [[cite:Grimvall1981]], Eq 6.72 page 175)
    2073                 :             : !!
    2074                 :             : !! INPUTS
    2075                 :             : !!  nn=Value of n
    2076                 :             : !!  spin=The spin component. 0 to sum over spins.
    2077                 :             : !!
    2078                 :             : !! OUTPUT
    2079                 :             : !!  a2fw_get_moment = \int dw [a2F(w)/w] w^n
    2080                 :             : !!  [out_int(x)] = \int^{x} dw [a2F(w)/w] w^n
    2081                 :             : !!
    2082                 :             : !! SOURCE
    2083                 :             : 
    2084                 :          50 : real(dp) function a2fw_get_moment(a2f, nn, spin, out_int)
    2085                 :             : 
    2086                 :             : !Arguments ------------------------------------
    2087                 :             :  class(a2fw_t),intent(in) :: a2f
    2088                 :             :  integer,intent(in) :: spin,nn
    2089                 :             : !arrays
    2090                 :             :  real(dp),intent(out),optional :: out_int(a2f%nomega)
    2091                 :             : 
    2092                 :             : !Local variables -------------------------
    2093                 :             : !scalars
    2094                 :             :  integer :: iw
    2095                 :             :  real(dp) :: omg, omg_nm1
    2096                 :             : !arrays
    2097                 :          50 :  real(dp) :: ff(a2f%nomega), int_ff(a2f%nomega), values(a2f%nomega)
    2098                 :             : ! *********************************************************************
    2099                 :             : 
    2100                 :             :  ! Construct the integrand function. [a2F(w)/w] w^n
    2101   [ +  +  +  + ]:       47350 :  ff = zero; int_ff = zero
    2102                 :             : 
    2103         [ -  + ]:          50 :  if (spin == 0) then
    2104         [ #  # ]:           0 :    if (a2f%nsppol == 1) then
    2105         [ #  # ]:           0 :       values = a2f%vals(:, 0, 1)
    2106                 :             :       !if (a2f%nspinor == 1) values = two * values
    2107         [ #  # ]:           0 :    else if (a2f%nsppol == 2) then
    2108   [ #  #  #  # ]:           0 :      values = sum(a2f%vals(:, 0, :), dim=2)
    2109                 :             :    end if
    2110                 :             : 
    2111                 :             :  else
    2112         [ +  + ]:       23700 :    values = a2f%vals(:, 0, spin)
    2113                 :             :  end if
    2114                 :             : 
    2115         [ +  + ]:          50 :  if (nn - 1 >= 0) then
    2116         [ +  + ]:       18960 :    do iw=1,a2f%nomega
    2117                 :       18920 :      omg = a2f%omega(iw)
    2118                 :       18920 :      omg_nm1 = omg ** (nn - 1)
    2119                 :       18960 :      ff(iw) = values(iw) * omg_nm1
    2120                 :             :    end do
    2121                 :             :  else
    2122         [ +  + ]:        4740 :    do iw=1,a2f%nomega
    2123                 :        4730 :      omg = a2f%omega(iw)
    2124         [ +  - ]:        4730 :      omg_nm1 = zero; if (abs(omg) > EPHTK_WTOL) omg_nm1 = omg**(nn-1)
    2125                 :        4740 :      ff(iw) = values(iw) * omg_nm1
    2126                 :             :    end do
    2127                 :             :  end if
    2128                 :             : 
    2129                 :             :  ! Integration with simpson rule on a linear mesh.
    2130                 :          50 :  call simpson_int(a2f%nomega, a2f%wstep, ff, int_ff)
    2131                 :             : 
    2132                 :          50 :  a2fw_get_moment = int_ff(a2f%nomega)
    2133   [ -  +  -  - ]:          50 :  if (present(out_int)) out_int = int_ff
    2134                 :             : 
    2135                 :          50 : end function a2fw_get_moment
    2136                 :             : !!***
    2137                 :             : 
    2138                 :             : !----------------------------------------------------------------------
    2139                 :             : 
    2140                 :             : !!****f* m_phgamma/a2fw_tr_moment
    2141                 :             : !! NAME
    2142                 :             : !! a2fw_tr_moment
    2143                 :             : !!
    2144                 :             : !! FUNCTION
    2145                 :             : !!  Compute \int dw [a2F_tr(w)/w] w^n
    2146                 :             : !!  From Allen PRL 59 1460 [[cite:Allen1987]] and later PRB papers.
    2147                 :             : !!  See also [[cite:Grimvall1981]] book.
    2148                 :             : !!
    2149                 :             : !! INPUTS
    2150                 :             : !!  nn=Value of n
    2151                 :             : !!  spin=The spin component
    2152                 :             : !!
    2153                 :             : !! OUTPUT
    2154                 :             : !!  a2fw_tr_moment = \int dw [a2F_tr(w)/w] w^n
    2155                 :             : !!  [out_int(x)] = \int^{x} dw [a2F_tr(w)/w] w^n
    2156                 :             : !!
    2157                 :             : !! SOURCE
    2158                 :             : 
    2159         [ -  + ]:          50 : function a2fw_tr_moment(a2f_tr, nn, spin, out_int)
    2160                 :             : 
    2161                 :             : !Arguments ------------------------------------
    2162                 :             : !scalars
    2163                 :             :  class(a2fw_tr_t),intent(in) :: a2f_tr
    2164                 :             :  integer,intent(in) :: spin,nn
    2165                 :             : !arrays
    2166                 :             :  real(dp),intent(out),optional :: out_int(a2f_tr%nomega,3,3)
    2167                 :             :  real(dp) :: a2fw_tr_moment(3,3)
    2168                 :             : 
    2169                 :             : !Local variables -------------------------
    2170                 :             : !scalars
    2171                 :             :  integer :: iw, idir, jdir
    2172                 :             :  real(dp) :: omg,omg_nm1
    2173                 :             : !arrays
    2174         [ -  + ]:          50 :  real(dp) :: ff(a2f_tr%nomega),int_ff(a2f_tr%nomega)
    2175                 :             : ! *********************************************************************
    2176                 :             : 
    2177         [ +  + ]:         200 :  do jdir = 1, 3
    2178         [ +  + ]:         650 :    do idir = 1, 3
    2179                 :             :      ! Construct the integrand function. [a2F_tr(w)/w] w^n
    2180   [ +  +  +  + ]:      426150 :      ff = zero; int_ff = zero
    2181                 :             : 
    2182         [ +  + ]:         450 :      if (nn-1 >= 0) then
    2183         [ +  + ]:      170640 :        do iw=1,a2f_tr%nomega
    2184                 :      170280 :          omg = a2f_tr%omega(iw)
    2185                 :      170280 :          omg_nm1 = omg ** (nn-1)
    2186                 :      170640 :          ff(iw) = a2f_tr%vals_tr(iw,idir,jdir,0,spin) * omg_nm1
    2187                 :             :        end do
    2188                 :             :      else
    2189         [ +  + ]:       42660 :        do iw=1,a2f_tr%nomega
    2190                 :       42570 :          omg = a2f_tr%omega(iw)
    2191         [ +  - ]:       42570 :          omg_nm1 = zero; if (abs(omg) > EPHTK_WTOL) omg_nm1 = omg**(nn-1)
    2192                 :       42660 :          ff(iw) = a2f_tr%vals_tr(iw,idir,jdir,0,spin) * omg_nm1
    2193                 :             :        end do
    2194                 :             :      end if
    2195                 :             : 
    2196                 :             :      ! Integration with simpson rule on a linear mesh.
    2197                 :         450 :      call simpson_int(a2f_tr%nomega, a2f_tr%wstep, ff, int_ff)
    2198                 :             : 
    2199                 :         450 :      a2fw_tr_moment(idir, jdir) = int_ff(a2f_tr%nomega)
    2200   [ -  +  -  - ]:         600 :      if (present(out_int)) out_int(:,idir,jdir) = int_ff(:)
    2201                 :             :    end do
    2202                 :             :  end do
    2203                 :             : 
    2204                 :             : end function a2fw_tr_moment
    2205                 :             : !!***
    2206                 :             : 
    2207                 :             : !----------------------------------------------------------------------
    2208                 :             : 
    2209                 :             : !!****f* m_phgamma/a2fw_write
    2210                 :             : !! NAME
    2211                 :             : !! a2fw_write
    2212                 :             : !!
    2213                 :             : !! FUNCTION
    2214                 :             : !!  Write alpha^2F(w) to an external file in text form
    2215                 :             : !!
    2216                 :             : !! INPUTS
    2217                 :             : !!  basename=Filename for output.
    2218                 :             : !!  post=String appended to netcdf variables e.g. _qcoarse, _qintp
    2219                 :             : !!  ncid=Netcdf file handler. Set it to nctk_noid to disable output.
    2220                 :             : !!
    2221                 :             : !! OUTPUT
    2222                 :             : !!  Output is written to file. This routine should be called by one MPI proc.
    2223                 :             : !!
    2224                 :             : !! SOURCE
    2225                 :             : 
    2226                 :          10 : subroutine a2fw_write(a2f, basename, post, ncid)
    2227                 :             : 
    2228                 :             : !Arguments ------------------------------------
    2229                 :             : !scalars
    2230                 :             :  class(a2fw_t),intent(in) :: a2f
    2231                 :             :  character(len=*),intent(in) :: basename, post
    2232                 :             :  integer,intent(in) :: ncid
    2233                 :             : 
    2234                 :             : !Local variables -------------------------
    2235                 :             : !scalars
    2236                 :             :  integer :: iw,spin,unt,ii,mu, ncerr
    2237                 :             :  character(len=500) :: dim1_name, msg
    2238                 :             :  character(len=fnlen) :: path
    2239                 :             : ! *********************************************************************
    2240                 :             : 
    2241                 :             :  ! Write spin-resolved a2F(w)
    2242         [ +  - ]:          10 :  path = strcat(basename, "_A2FW")
    2243         [ -  + ]:          10 :  if (open_file(path, msg, newunit=unt, form="formatted", action="write", status="unknown") /= 0) then
    2244                 :           0 :    ABI_ERROR(msg)
    2245                 :             :  end if
    2246                 :             : 
    2247                 :          10 :  call write_a2fw_header()
    2248                 :             : 
    2249         [ +  - ]:          10 :  if (a2f%nsppol == 1) then
    2250                 :          10 :    write(unt,'(a)')"# Frequency, a2F(w), lambda(w)"
    2251         [ +  + ]:        4740 :    do iw=1,a2f%nomega
    2252                 :        4740 :      write(unt,*) a2f%omega(iw), a2f%vals(iw,0,1), a2f%lambdaw(iw,0,1)
    2253                 :             :    end do
    2254                 :             : 
    2255                 :             :  else
    2256                 :           0 :    write(unt,'(a)')"# Frequency, a2F_tot(w), lambda_tot(w)dw, a2F_spin1(w), lambda_spin1(w) ..."
    2257         [ #  # ]:           0 :    do iw=1,a2f%nomega
    2258                 :           0 :      write(unt,'(E20.10,3x,3(2E20.10, 2x))') a2f%omega(iw), &
    2259   [ #  #  #  # ]:           0 :                   sum(a2f%vals(iw,0,:)) , sum(a2f%lambdaw(iw,0,:)), &  ! TOT
    2260                 :           0 :                   a2f%vals(iw,0,1)      , a2f%lambdaw(iw,0,1),      &  ! UP
    2261                 :           0 :                   a2f%vals(iw,0,2)      , a2f%lambdaw(iw,0,2)          ! DOWN
    2262                 :             :    end do
    2263                 :             :  end if
    2264                 :             : 
    2265                 :          10 :  close(unt)
    2266                 :             : 
    2267                 :             :  ! Write phonon contributions to a2F(w)
    2268         [ +  - ]:          10 :  path = strcat(basename, "_PH_A2FW")
    2269         [ -  + ]:          10 :  if (open_file(path, msg, newunit=unt, form="formatted", action="write", status="unknown") /= 0) then
    2270                 :           0 :    ABI_ERROR(msg)
    2271                 :             :  end if
    2272                 :          10 :  call write_a2fw_header()
    2273                 :             : 
    2274         [ +  - ]:          10 :  if (a2f%nsppol == 1) then
    2275         [ +  + ]:          50 :    do mu=0,a2f%natom3
    2276                 :          40 :      write(unt,'(a,i0)')"# Phonon mode ",mu
    2277                 :          40 :      write(unt,'(a)')"# Frequency, a2F(w), lambda(w)"
    2278         [ +  + ]:       18960 :      do iw=1,a2f%nomega
    2279                 :       18960 :        write(unt,*) a2f%omega(iw), a2f%vals(iw,mu,1), a2f%lambdaw(iw,mu,1)
    2280                 :             :      end do
    2281         [ +  + ]:         130 :      do ii=1,2; write(unt,'(a)')""; end do
    2282                 :             :    end do
    2283                 :             : 
    2284                 :             :  else
    2285         [ #  # ]:           0 :    do mu=0,a2f%natom3
    2286                 :           0 :      write(unt,'(a,i0)')"# Phonon mode ",mu
    2287                 :           0 :      write(unt,'(a)')"# Frequency, a2F_tot(w), lambda_tot(w)dw, a2F_spin1(w), lambda_spin1(w) ..."
    2288         [ #  # ]:           0 :      do iw=1,a2f%nomega
    2289                 :           0 :        write(unt,'(E20.10,3x,3(2E20.10, 2x))') a2f%omega(iw), &
    2290   [ #  #  #  # ]:           0 :                     sum(a2f%vals(iw,mu,:)), sum(a2f%lambdaw(iw,mu,:)), &  ! TOT
    2291                 :           0 :                     a2f%vals(iw,mu,1)     , a2f%lambdaw(iw,mu,1),      &  ! UP
    2292                 :           0 :                     a2f%vals(iw,mu,2)     , a2f%lambdaw(iw,mu,2)          ! DOWN
    2293                 :             :      end do
    2294                 :             :    end do
    2295                 :             :  end if
    2296                 :             : 
    2297                 :          10 :  close(unt)
    2298                 :             : 
    2299         [ +  - ]:          10 :  if (ncid /= nctk_noid) then
    2300                 :             :    ! Define dimensions.
    2301         [ +  - ]:          10 :    dim1_name = strcat("a2f_nomega", post)
    2302                 :             :    ncerr = nctk_def_dims(ncid, [ &
    2303                 :             :      nctkdim_t(dim1_name, a2f%nomega), &
    2304                 :             :      nctkdim_t("natom3p1", a2f%natom3 + 1), nctkdim_t("number_of_spins", a2f%nsppol) &
    2305         [ +  + ]:          40 :      ], defmode=.True.)
    2306         [ -  + ]:          10 :    NCF_CHECK(ncerr)
    2307                 :             : 
    2308                 :             :    ncerr = nctk_def_arrays(ncid, [ &
    2309                 :             :      nctkarr_t(strcat('a2f_mesh', post), "dp", dim1_name), &
    2310                 :             :      nctkarr_t(strcat('a2f_values', post), "dp", strcat(dim1_name, ", natom3p1, number_of_spins")), &
    2311                 :             :      nctkarr_t(strcat('a2f_lambdaw', post), "dp", strcat(dim1_name, ", natom3p1, number_of_spins")) &
    2312   [ +  -  +  -  :          40 :      ])
          +  -  +  -  +  
                -  +  + ]
    2313         [ -  + ]:          10 :    NCF_CHECK(ncerr)
    2314                 :             : 
    2315         [ -  + ]:          10 :    NCF_CHECK(nctk_set_datamode(ncid))
    2316         [ -  + ]:          10 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, strcat("a2f_mesh", post)), a2f%omega))
    2317         [ -  + ]:          10 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, strcat("a2f_values", post)), a2f%vals))
    2318         [ -  + ]:          10 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, strcat("a2f_lambdaw", post)), a2f%lambdaw))
    2319                 :             :  end if
    2320                 :             : 
    2321                 :             : contains
    2322                 :             : 
    2323                 :          20 : subroutine write_a2fw_header()
    2324                 :             : 
    2325                 :             :  ! Output the header.
    2326                 :          20 :  write(unt,'(a)')              '#'
    2327                 :          20 :  write(unt,'(a)')              '# ABINIT package: a2F(w) file'
    2328                 :          20 :  write(unt,'(a)')              '#'
    2329                 :          20 :  write(unt,'(a)')              '# a2F(w) function integrated over the FS. omega in a.u.'
    2330         [ +  - ]:          20 :  write(unt,'(2a)')             '# ngqpt: ',trim(ltoa(a2f%ngqpt))
    2331                 :          20 :  write(unt,'(a,i0,3(a,e16.6))')'# number of frequencies: ',a2f%nomega," between omega_min: ",a2f%omega_min,&
    2332                 :          40 :                                ' Ha and omega_max: ',a2f%omega_max,' Ha with step:',a2f%wstep
    2333                 :          20 :  write(unt,'(a,e16.6)')        '#  the smearing width for gaussians is ',a2f%smear
    2334         [ +  + ]:          40 :  write(unt,'(a,e16.6)')"# Total DOS at Fermi level ",sum(a2f%n0)
    2335         [ +  + ]:          40 :  do spin=1,a2f%nsppol
    2336                 :          40 :    write(unt,"(a,i0,a,e16.6)")"# The DOS at Fermi level for spin ",spin," is ",a2f%n0(spin)
    2337                 :             :  end do
    2338         [ +  + ]:          60 :  do ii=1,2; write(unt,'(a)')     "# "; end do
    2339                 :             : 
    2340                 :          20 : end subroutine write_a2fw_header
    2341                 :             : 
    2342                 :             : end subroutine a2fw_write
    2343                 :             : !!***
    2344                 :             : 
    2345                 :             : !----------------------------------------------------------------------
    2346                 :             : !!****f* m_phgamma/a2fw_ee_write
    2347                 :             : !! NAME
    2348                 :             : !! a2fw_ee_write
    2349                 :             : !!
    2350                 :             : !! FUNCTION
    2351                 :             : !!  Write alpha^2F(e,e',w) to an external file in text form
    2352                 :             : !!
    2353                 :             : !! INPUTS
    2354                 :             : !!  basename=Filename for output.
    2355                 :             : !!
    2356                 :             : !! OUTPUT
    2357                 :             : !!  Output is written to file. This routine should be called by one MPI proc.
    2358                 :             : !!
    2359                 :             : !! SOURCE
    2360                 :             : 
    2361                 :           0 : subroutine a2fw_ee_write(a2f, basename)
    2362                 :             : 
    2363                 :             : !Arguments ------------------------------------
    2364                 :             :  class(a2fw_t),intent(in) :: a2f
    2365                 :             :  character(len=*),intent(in) :: basename
    2366                 :             : 
    2367                 :             : !Local variables -------------------------
    2368                 :             : !scalars
    2369                 :             :  integer :: iw, spin, unt, ii, iene, jene
    2370                 :             :  real(dp) :: ene1, ene2
    2371                 :             :  character(len=500) :: msg
    2372                 :             :  character(len=fnlen) :: path
    2373                 :             : ! *********************************************************************
    2374                 :             : 
    2375                 :             :  ! Write spin-resolved a2F(e,e',w)
    2376         [ #  # ]:           0 :  path = strcat(basename, "_A2FEEW")
    2377         [ #  # ]:           0 :  if (open_file(path, msg, newunit=unt, form="formatted", action="write", status="unknown") /= 0) then
    2378                 :           0 :    ABI_ERROR(msg)
    2379                 :             :  end if
    2380                 :             : 
    2381                 :           0 :  call write_a2fw_header()
    2382                 :             : 
    2383                 :           0 :  write(unt,'(a)')"# en2, en1, Frequency, a2F_tot(w) (presently summed over spin)"
    2384         [ #  # ]:           0 :  do iw=1,a2f%nomega
    2385         [ #  # ]:           0 :    do iene=1,a2f%nene
    2386                 :           0 :      ene1 = a2f%enemin + (iene-1)*a2f%deltaene
    2387         [ #  # ]:           0 :      do jene=1,a2f%nene
    2388                 :           0 :        ene2 = a2f%enemin + (jene-1)*a2f%deltaene
    2389         [ #  # ]:           0 :        write(unt,'(3E20.10,2x,E20.10)') ene2, ene1, a2f%omega(iw), sum(a2f%vals_ee(jene,iene,iw,:))   ! TOT
    2390                 :             :      end do
    2391                 :             :    end do
    2392                 :             :  end do
    2393                 :             : 
    2394                 :           0 :  close(unt)
    2395                 :             : 
    2396                 :             :  ! Write spin-resolved a2F(ef, ef, w)
    2397         [ #  # ]:           0 :  path = strcat(basename, "_A2FW_reference")
    2398         [ #  # ]:           0 :  if (open_file(path, msg, newunit=unt, form="formatted", status="unknown") /= 0) then
    2399                 :           0 :    ABI_ERROR(msg)
    2400                 :             :  end if
    2401                 :             : 
    2402                 :           0 :  call write_a2fw_header()
    2403                 :             : 
    2404                 :           0 :  write(unt,'(a)')"# Frequency, a2F_tot(ef,ef,w) for comparison with normal a2F(w) (presently summed over spin)"
    2405                 :           0 :  iene = int(a2f%nene/2)
    2406                 :           0 :  jene = int(a2f%nene/2)
    2407         [ #  # ]:           0 :  do iw=1,a2f%nomega
    2408         [ #  # ]:           0 :    write(unt,'(E20.10,2x,E20.10)') a2f%omega(iw), sum(a2f%vals_ee(jene,iene,iw,:))   ! TOT
    2409                 :             :  end do
    2410                 :             : 
    2411                 :           0 :  close(unt)
    2412                 :             : 
    2413                 :             : contains
    2414                 :             : 
    2415                 :           0 : subroutine write_a2fw_header()
    2416                 :             : 
    2417                 :             :  ! Output the header.
    2418                 :           0 :  write(unt,'(a)')              '#'
    2419                 :           0 :  write(unt,'(a)')              '# ABINIT package: a2F(e,eprime,w) file'
    2420                 :           0 :  write(unt,'(a)')              '#'
    2421                 :           0 :  write(unt,'(a)')              '# a2F(e,eprime,w) function integrated over the FS. omega in a.u.'
    2422         [ #  # ]:           0 :  write(unt,'(2a)')             '# ngqpt: ',trim(ltoa(a2f%ngqpt))
    2423                 :           0 :  write(unt,'(a,i0,2(a,e16.6))')'# number of energies: ',a2f%nene," from enemin: ",a2f%enemin,' Ha with step ', a2f%deltaene
    2424                 :           0 :  write(unt,'(a,i0,3(a,e16.6))')'# number of frequencies: ',a2f%nomega," between omega_min: ",a2f%omega_min, &
    2425                 :           0 :                                ' Ha and omega_max: ',a2f%omega_max,' Ha with step:',a2f%wstep
    2426                 :           0 :  write(unt,'(a,e16.6)')         '#  the smearing width for gaussians is ',a2f%smear
    2427         [ #  # ]:           0 :  write(unt,'(a,e16.6)')"# Total DOS at Fermi level ",sum(a2f%n0)
    2428         [ #  # ]:           0 :  do spin=1,a2f%nsppol
    2429                 :           0 :    write(unt,"(a,i0,a,e16.6)")"# The DOS at Fermi level for spin ",spin," is ",a2f%n0(spin)
    2430                 :             :  end do
    2431         [ #  # ]:           0 :  do ii=1,2
    2432                 :           0 :    write(unt,'(a)')     "# "
    2433                 :             :  end do
    2434                 :             : 
    2435                 :           0 : end subroutine write_a2fw_header
    2436                 :             : 
    2437                 :             : end subroutine a2fw_ee_write
    2438                 :             : !!***
    2439                 :             : 
    2440                 :             : !----------------------------------------------------------------------
    2441                 :             : 
    2442                 :             : !!****f* m_phgamma/a2fw_tr_free
    2443                 :             : !! NAME
    2444                 :             : !! a2fw_tr_free
    2445                 :             : !!
    2446                 :             : !! FUNCTION
    2447                 :             : !!  Free the memory allocated in a2fw_tr_t
    2448                 :             : !!
    2449                 :             : !! SOURCE
    2450                 :             : 
    2451                 :          10 : subroutine a2fw_tr_free(a2f_tr)
    2452                 :             : 
    2453                 :             : !Arguments ------------------------------------
    2454                 :             :  class(a2fw_tr_t),intent(inout) :: a2f_tr
    2455                 :             : ! *********************************************************************
    2456                 :             : 
    2457                 :             :  ! integer
    2458         [ +  - ]:          10 :  ABI_SFREE(a2f_tr%qshift)
    2459                 :             : 
    2460                 :             :  ! real
    2461         [ +  - ]:          10 :  ABI_SFREE(a2f_tr%n0)
    2462         [ +  - ]:          10 :  ABI_SFREE(a2f_tr%omega)
    2463         [ +  - ]:          10 :  ABI_SFREE(a2f_tr%vals_in)
    2464         [ +  - ]:          10 :  ABI_SFREE(a2f_tr%vals_out)
    2465         [ +  - ]:          10 :  ABI_SFREE(a2f_tr%vals_tr)
    2466         [ -  + ]:          10 :  ABI_SFREE(a2f_tr%vals_tr_gen)
    2467         [ +  - ]:          10 :  ABI_SFREE(a2f_tr%lambdaw_tr)
    2468                 :             : 
    2469                 :          10 : end subroutine a2fw_tr_free
    2470                 :             : !!***
    2471                 :             : 
    2472                 :             : !----------------------------------------------------------------------
    2473                 :             : 
    2474                 :             : !!****f* m_phgamma/a2fw_tr_init
    2475                 :             : !! NAME
    2476                 :             : !! a2fw_tr_init
    2477                 :             : !!
    2478                 :             : !! FUNCTION
    2479                 :             : !!  Calculates the FS averaged alpha^2F_tr,in,out(w) functions
    2480                 :             : !!
    2481                 :             : !! INPUTS
    2482                 :             : !!  cryst<crystal_t>=Info on the unit cell.
    2483                 :             : !!  ifc<ifc_type>=Interatomic force constants.
    2484                 :             : !!  gams<phgamma_t>=Structure storing the phonon linewidths.
    2485                 :             : !!  wstep=Step for linear frequency mesh in Ha.
    2486                 :             : !!  wminmax(2)=Minimum and maximum phonon frequency. Used to construct the linear mesh for A2F(w).
    2487                 :             : !!  ph_intmeth=Integration method for phonons: 1 for gaussian, 2 for tetrahedra
    2488                 :             : !!  smear=Gaussian broadening used to approximate the Dirac delta.
    2489                 :             : !!  ngqpt(3)=Divisions of the Q-mesh used for interpolating the phonon linewidths (see also nqshift and qshift).
    2490                 :             : !!  nqshift=Number of shifts used to generated the Q-mesh.
    2491                 :             : !!  qshift(3,nqshift)=The shifts.
    2492                 :             : !!  comm=MPI communicator
    2493                 :             : !!  [qintp]=If set to False, ngqgpt, nqshift, qshift and qptop  are ignored and
    2494                 :             : !!     A2F(w) is computed from the IBZ values stored in gams. Default: True i.e use Fourier interpolation.
    2495                 :             : !!  [qptopt]=Controls the generation of the q-points. If not specified, the routine takes fully into account
    2496                 :             : !!    the symmetries of the system to generate the q points in the IBZone i.e. qptopt=1
    2497                 :             : !!    Other values of qptopt can be used for debugging purpose.
    2498                 :             : !!
    2499                 :             : !! OUTPUT
    2500                 :             : !!  a2f_tr<a2fw_tr_t>=Structure storing the Eliashberg transport function a2F_tr(w).
    2501                 :             : !!
    2502                 :             : !! SOURCE
    2503                 :             : 
    2504                 :          10 : subroutine a2fw_tr_init(a2f_tr, gams, cryst, ifc, ph_intmeth, wstep, wminmax, smear, ngqpt, nqshift, qshift, comm,&
    2505                 :             :                         qintp, qptopt) ! optional
    2506                 :             : 
    2507                 :             : !Arguments ------------------------------------
    2508                 :             : !scalars
    2509                 :             :  class(a2fw_tr_t),target,intent(out) :: a2f_tr
    2510                 :             :  integer,intent(in) :: ph_intmeth,nqshift,comm
    2511                 :             :  integer,intent(in),optional :: qptopt
    2512                 :             :  real(dp),intent(in) :: wstep,smear
    2513                 :             :  logical,optional,intent(in) :: qintp
    2514                 :             :  type(phgamma_t),intent(inout) :: gams
    2515                 :             :  type(ifc_type),intent(in) :: ifc
    2516                 :             :  type(crystal_t),intent(in) :: cryst
    2517                 :             : !arrays
    2518                 :             :  integer,intent(in) :: ngqpt(3)
    2519                 :             :  real(dp),intent(in) :: wminmax(2),qshift(3,nqshift)
    2520                 :             : 
    2521                 :             : !Local variables -------------------------
    2522                 :             : !scalars
    2523                 :             :  integer,parameter :: master = 0
    2524                 :             :  integer :: my_qptopt,iq_ibz,nqibz,ount,my_rank,nproc,cnt
    2525                 :             :  integer :: mu,iw,natom3,nsppol,spin,ierr,nomega,nqbz, idir, jdir
    2526                 :             :  real(dp) :: omega,xx,omega_min,omega_max,ww, cpu, wall, gflops
    2527                 :             :  logical :: do_qintp
    2528                 :             :  character(len=500) :: msg
    2529                 :          10 :  type(htetra_t) :: tetra_q
    2530                 :             : !arrays
    2531                 :             :  integer :: qptrlatt(3,3),new_qptrlatt(3,3)
    2532                 :          20 :  real(dp) :: lambda_iso(3,3), omega_log(3,3), phfrq(gams%natom3)
    2533                 :          20 :  real(dp) :: gamma_in_ph(3,3,gams%natom3), gamma_out_ph(3,3,gams%natom3)
    2534                 :          30 :  real(dp) :: lambda_in_ph(3,3,gams%natom3), lambda_out_ph(3,3,gams%natom3)
    2535                 :          10 :  real(dp),allocatable :: tmp_a2f_in(:,:,:), tmp_a2f_out(:,:,:), my_qshift(:,:)
    2536                 :          10 :  real(dp), contiguous, pointer :: a2f_tr_1d(:)
    2537                 :          10 :  real(dp),allocatable :: qibz(:,:),wtq(:),qbz(:,:)
    2538                 :          10 :  real(dp),allocatable :: a2f_tr_1mom(:),a2f_tr_logmom(:),a2f_tr_logmom_int(:),wdt(:,:)
    2539                 :          10 :  real(dp),allocatable :: lambda_in_tetra(:,:,:,:,:),phfreq_tetra(:,:,:), lambda_out_tetra(:,:,:,:,:)
    2540                 :             : ! *********************************************************************
    2541                 :             : 
    2542         [ +  - ]:          10 :  my_qptopt = 1; if (present(qptopt)) my_qptopt = qptopt
    2543         [ +  + ]:          10 :  do_qintp = .True.; if (present(qintp)) do_qintp = qintp
    2544                 :             : 
    2545                 :          10 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
    2546                 :          10 :  nsppol = gams%nsppol; natom3 = gams%natom3
    2547                 :             : 
    2548                 :          10 :  call cwtime(cpu, wall, gflops, "start")
    2549                 :             : 
    2550         [ +  + ]:          10 :  if (do_qintp) then
    2551                 :             :    ! Generate the q-mesh by finding the IBZ and the corresponding weights.
    2552                 :           5 :    qptrlatt = 0; qptrlatt(1,1) = ngqpt(1); qptrlatt(2,2) = ngqpt(2); qptrlatt(3,3) = ngqpt(3)
    2553                 :             : 
    2554                 :             :    call kpts_ibz_from_kptrlatt(cryst, qptrlatt, my_qptopt, nqshift, qshift, nqibz, qibz, wtq, nqbz, qbz, &
    2555                 :           5 :       new_kptrlatt=new_qptrlatt, new_shiftk=my_qshift)
    2556         [ -  + ]:           5 :    ABI_FREE(qbz)
    2557                 :             : 
    2558                 :             :    ! Store quantities that cannot be easily (and safely) calculated if we only know the IBZ.
    2559         [ +  + ]:          20 :    a2f_tr%ngqpt = ngqpt; a2f_tr%nqshift = size(my_qshift, dim=2)
    2560   [ -  +  +  -  :          15 :    ABI_MALLOC(a2f_tr%qshift, (3, a2f_tr%nqshift))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    2561   [ +  -  +  -  :          30 :    a2f_tr%qshift = my_qshift
          -  +  -  -  -  
          -  -  -  +  +  
                   +  + ]
    2562         [ -  + ]:           5 :    ABI_FREE(my_qshift)
    2563                 :             : 
    2564                 :             :  else
    2565                 :             :    ! No interpolation. Use q-mesh parameters from gams%
    2566         [ +  + ]:          20 :    a2f_tr%ngqpt = gams%ngqpt; a2f_tr%nqshift = 1
    2567                 :           5 :    nqibz = gams%nqibz
    2568   [ -  +  +  -  :          15 :    ABI_MALLOC(qibz, (3,nqibz))
          +  -  +  -  -  
                +  -  + ]
    2569   [ -  +  +  -  :          15 :    ABI_MALLOC(wtq, (nqibz))
          +  -  +  -  -  
                +  -  + ]
    2570   [ -  +  -  + ]:           5 :    ABI_MALLOC(a2f_tr%qshift, (3, a2f_tr%nqshift))
    2571   [ +  -  +  -  :         320 :    qibz = gams%qibz; wtq = gams%wtq
          -  +  -  -  -  
          -  -  -  +  +  
          +  +  +  -  -  
          +  -  -  -  -  
                   +  + ]
    2572   [ +  +  +  + ]:          25 :    a2f_tr%qshift = zero ! Note: assuming q-mesh centered on Gamma.
    2573                 :             :  end if
    2574                 :             : 
    2575                 :          10 :  call cwtime_report(" a2fw_tr_init, q-setup", cpu, wall, gflops)
    2576                 :             : 
    2577                 :             :  ! Define Min and max frequency for the mesh (enlarge it a bit)
    2578                 :          10 :  omega_min = wminmax(1); omega_max = wminmax(2)
    2579                 :          10 :  omega_min = omega_min - 0.1*abs(omega_min)
    2580         [ -  + ]:          10 :  if (omega_min >= zero) omega_min = one/Ha_meV
    2581                 :          10 :  omega_max = omega_max + 0.1*abs(omega_max)
    2582                 :             : 
    2583                 :          10 :  a2f_tr%nsppol = nsppol; a2f_tr%natom3 = gams%natom3; a2f_tr%smear = smear
    2584                 :          10 :  a2f_tr%omega_min = omega_min; a2f_tr%omega_max = omega_max
    2585                 :          10 :  nomega = int((omega_max - omega_min) / wstep); a2f_tr%nomega = nomega; a2f_tr%wstep = wstep
    2586                 :             : 
    2587   [ -  +  +  -  :          30 :  ABI_MALLOC(a2f_tr%n0, (nsppol))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    2588   [ +  -  -  +  :          30 :  a2f_tr%n0 = gams%n0
          -  -  -  -  -  
                -  +  + ]
    2589                 :             :  ! Build linear mesh.
    2590   [ -  +  +  -  :          30 :  ABI_MALLOC(a2f_tr%omega, (nomega))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    2591   [ +  -  +  -  :        4750 :  a2f_tr%omega = arth(omega_min, wstep, nomega)
          -  +  -  -  +  
                      + ]
    2592                 :             : 
    2593   [ -  +  +  -  :      170870 :  ABI_CALLOC(a2f_tr%vals_in, (nomega, 3, 3, 0:natom3, nsppol))
          +  -  -  +  +  
          -  -  +  +  -  
          +  -  +  -  -  
          +  -  +  -  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    2594   [ -  +  +  -  :      170850 :  ABI_CALLOC(a2f_tr%vals_out, (nomega,3, 3, 0:natom3, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
             +  +  +  + ]
    2595   [ -  +  +  -  :      170850 :  ABI_CALLOC(a2f_tr%vals_tr, (nomega,3, 3, 0:natom3, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
             +  +  +  + ]
    2596   [ -  +  +  -  :      170850 :  ABI_CALLOC(a2f_tr%lambdaw_tr, (nomega, 3, 3, 0:natom3, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
             +  +  +  + ]
    2597   [ -  +  +  -  :          30 :  ABI_MALLOC(tmp_a2f_in, (nomega, 3, 3))
          +  -  +  -  -  
                +  -  + ]
    2598   [ -  +  +  -  :          20 :  ABI_MALLOC(tmp_a2f_out, (nomega, 3, 3))
             -  +  -  + ]
    2599                 :             : 
    2600         [ +  + ]:          10 :  if (ph_intmeth == 2) then
    2601                 :           8 :    call cwtime(cpu, wall, gflops, "start")
    2602                 :             : 
    2603                 :             :    ! Prepare tetrahedron integration.
    2604                 :           8 :    qptrlatt = 0; qptrlatt(1, 1) = a2f_tr%ngqpt(1); qptrlatt(2, 2) = a2f_tr%ngqpt(2); qptrlatt(3, 3) = a2f_tr%ngqpt(3)
    2605                 :           8 :    tetra_q = tetra_from_kptrlatt(cryst, my_qptopt, qptrlatt, a2f_tr%nqshift, a2f_tr%qshift, nqibz, qibz, comm, msg, ierr)
    2606         [ -  + ]:           8 :    if (ierr/=0) ABI_ERROR(msg)
    2607                 :             : 
    2608   [ -  +  +  -  :          48 :    ABI_MALLOC_OR_DIE(lambda_in_tetra, (nqibz, 3, 3, natom3, nsppol), ierr)
          +  -  -  +  +  
          -  -  +  +  -  
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    2609   [ -  +  +  -  :          32 :    ABI_MALLOC_OR_DIE(lambda_out_tetra, (nqibz, 3, 3, natom3, nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
             -  +  -  + ]
    2610   [ +  +  +  +  :       17419 :    lambda_in_tetra = zero
          +  +  +  +  +  
                      + ]
    2611   [ +  +  +  +  :       17419 :    lambda_out_tetra = zero
          +  +  +  +  +  
                      + ]
    2612                 :             : 
    2613   [ -  +  +  -  :          40 :    ABI_MALLOC_OR_DIE(phfreq_tetra, (nqibz, natom3, nsppol), ierr)
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  +  -  -  
                +  -  + ]
    2614   [ +  +  +  +  :        1939 :    phfreq_tetra = zero
                   +  + ]
    2615                 :             : 
    2616                 :          16 :    call cwtime_report(" a2fw_tr_init%tetra,", cpu, wall, gflops)
    2617                 :             :  end if
    2618                 :             : 
    2619                 :          10 :  call cwtime(cpu, wall, gflops, "start")
    2620                 :             : 
    2621                 :             :  ! Loop over spins and qpoints in the IBZ
    2622                 :          10 :  cnt = 0
    2623         [ +  + ]:          20 :  do spin=1,nsppol
    2624         [ +  + ]:         806 :    do iq_ibz=1,nqibz
    2625         [ +  - ]:         786 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle
    2626                 :             : 
    2627                 :             :      ! Interpolate or evaluate lambda transport coefficients.
    2628         [ +  + ]:         786 :      if (do_qintp) then
    2629                 :         725 :        call phgamma_vv_interp(gams,cryst,ifc,spin,qibz(:,iq_ibz),phfrq,gamma_in_ph,gamma_out_ph,lambda_in_ph,lambda_out_ph)
    2630                 :             :      else
    2631                 :          61 :        call phgamma_vv_eval_qibz(gams,cryst,ifc,iq_ibz,spin,phfrq,gamma_in_ph,gamma_out_ph,lambda_in_ph,lambda_out_ph)
    2632                 :             :      end if
    2633                 :             : 
    2634                 :          10 :      select case (ph_intmeth)
    2635                 :             :      case (1)
    2636                 :             :        ! Gaussian: Add all contributions from the phonon modes at this qpoint to a2f_tr
    2637                 :             :        ! (note that unstable modes are included).
    2638         [ +  + ]:         612 :        do mu=1,natom3
    2639   [ +  +  +  +  :     1959930 :          tmp_a2f_in = zero
                   +  + ]
    2640   [ +  +  +  +  :     1959930 :          tmp_a2f_out = zero
                   +  + ]
    2641         [ +  + ]:      217566 :          do iw=1,nomega
    2642                 :      217107 :            xx = a2f_tr%omega(iw) - phfrq(mu)
    2643   [ +  +  +  + ]:     2822391 :            tmp_a2f_in(iw,:,:)  = tmp_a2f_in(iw,:,:)  + gaussian(xx, smear) * lambda_in_ph(:,:,mu)  * abs(phfrq(mu))
    2644   [ +  +  +  + ]:     2822850 :            tmp_a2f_out(iw,:,:) = tmp_a2f_out(iw,:,:) + gaussian(xx, smear) * lambda_out_ph(:,:,mu) * abs(phfrq(mu))
    2645                 :             :          end do
    2646   [ +  +  +  +  :     1959930 :          a2f_tr%vals_in(:,:,:,mu,spin)  = a2f_tr%vals_in(:,:,:,mu,spin)  + tmp_a2f_in(:,:,:) * wtq(iq_ibz)
                   +  + ]
    2647   [ +  +  +  +  :     1960083 :          a2f_tr%vals_out(:,:,:,mu,spin) = a2f_tr%vals_out(:,:,:,mu,spin) + tmp_a2f_out(:,:,:) * wtq(iq_ibz)
                   +  + ]
    2648                 :             :        end do
    2649                 :             : 
    2650                 :             :      case (2)
    2651                 :             :        ! Tetra: store data.
    2652   [ +  +  -  +  :        2685 :        do mu=1,natom3
                      + ]
    2653   [ +  +  +  + ]:       24687 :          lambda_in_tetra(iq_ibz, :,:, mu, spin) = lambda_in_ph(:,:,mu) * abs(phfrq(mu))
    2654   [ +  +  +  + ]:       24687 :          lambda_out_tetra(iq_ibz, :,:, mu, spin) = lambda_out_ph(:,:,mu) * abs(phfrq(mu))
    2655                 :        2532 :          phfreq_tetra(iq_ibz, mu, spin) = phfrq(mu)
    2656                 :             :        end do
    2657                 :             :      end select
    2658                 :             : 
    2659                 :             :    end do ! iq_ibz
    2660                 :             :  end do ! spin
    2661                 :             : 
    2662         [ +  + ]:          10 :  if (ph_intmeth == 2) then
    2663                 :             :    ! Collect results on each node.
    2664                 :           8 :    call xmpi_sum(lambda_in_tetra, comm, ierr)
    2665                 :           8 :    call xmpi_sum(lambda_out_tetra, comm, ierr)
    2666                 :           8 :    call xmpi_sum(phfreq_tetra, comm, ierr)
    2667                 :             : 
    2668                 :             :    ! workspace for tetra.
    2669   [ -  +  +  -  :          24 :    ABI_MALLOC(wdt, (nomega, 2))
          +  -  +  -  -  
                +  -  + ]
    2670                 :             : 
    2671                 :             :    ! TODO: with the tetra_get_onewk call we can integrate this above
    2672                 :             :    ! and avoid allocating all of lambda_in_tetra and phfreq_tetra!!!
    2673                 :             :    ! For each mode get its contribution
    2674                 :           8 :    cnt = 0
    2675         [ +  + ]:          16 :    do spin=1,nsppol
    2676         [ +  + ]:          40 :      do mu=1,natom3
    2677         [ +  + ]:        1931 :        do iq_ibz=1,nqibz
    2678         [ +  - ]:        1899 :          cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! mpi-parallelism
    2679                 :             : 
    2680                 :        1899 :          call tetra_q%get_onewk(iq_ibz, gams%bcorr, nomega, nqibz, phfreq_tetra(:,mu,spin), omega_min, omega_max, one, wdt)
    2681   [ +  +  +  + ]:     1802151 :          wdt = wdt * wtq(iq_ibz)
    2682                 :             : 
    2683                 :             :          ! Accumulate (Integral of a2F_tr is computed afterwards)
    2684         [ +  + ]:        7620 :          do idir=1,3
    2685         [ +  + ]:       24687 :            do jdir=1,3
    2686                 :             :              a2f_tr%vals_in(:,idir,jdir,mu,spin)  = a2f_tr%vals_in(:,idir,jdir,mu,spin)  &
    2687         [ +  + ]:     8101134 :                 + wdt(:,1) * lambda_in_tetra(iq_ibz,idir,jdir,mu,spin)
    2688                 :             :              a2f_tr%vals_out(:,idir,jdir,mu,spin) = a2f_tr%vals_out(:,idir,jdir,mu,spin) &
    2689         [ +  + ]:     8106831 :                 + wdt(:,1) * lambda_out_tetra(iq_ibz,idir,jdir,mu,spin)
    2690                 :             :              !a2f_tr%lambdaw(:,mu,spin) = a2f_tr%lambdaw(:,mu,spin) + wdt(:,2) * lambda_XX_tetra(iq_ibz, mu, spin)
    2691                 :             :            end do
    2692                 :             :          end do
    2693                 :             :        end do
    2694                 :             :      end do
    2695                 :             :    end do
    2696                 :             : 
    2697         [ -  + ]:           8 :    ABI_FREE(wdt)
    2698         [ -  + ]:           8 :    ABI_FREE(lambda_in_tetra)
    2699         [ -  + ]:           8 :    ABI_FREE(lambda_out_tetra)
    2700         [ -  + ]:           8 :    ABI_FREE(phfreq_tetra)
    2701                 :          16 :    call tetra_q%free()
    2702                 :             :  end if
    2703                 :             : 
    2704                 :             :  ! Collect final results on each node
    2705                 :          10 :  call xmpi_sum(a2f_tr%vals_in, comm, ierr)
    2706                 :          10 :  call xmpi_sum(a2f_tr%vals_out, comm, ierr)
    2707                 :             : 
    2708                 :             :  ! TODO: divide by g(eF, spin)
    2709                 :             :  ! check normalization with N(0) and <v^2> from Savrasov eq 20
    2710         [ +  + ]:          20 :  do spin=1,nsppol
    2711   [ +  +  +  +  :      170410 :    a2f_tr%vals_in(:,:,:,0,spin)  = sum(a2f_tr%vals_in(:,:,:,1:natom3,spin), dim=4)
             +  +  +  + ]
    2712   [ +  +  +  +  :      170420 :    a2f_tr%vals_out(:,:,:,0,spin) = sum(a2f_tr%vals_out(:,:,:,1:natom3,spin), dim=4)
             +  +  +  + ]
    2713                 :             :    !a2f_tr%vals(:,:,spin) = a2f_tr%vals(:,:,spin) / (two_pi * a2f_tr%n0(spin))
    2714                 :             :  end do
    2715                 :             : 
    2716   [ +  -  +  -  :      170830 :  a2f_tr%vals_tr = a2f_tr%vals_out - a2f_tr%vals_in
          +  -  +  -  +  
          -  -  +  -  -  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    2717                 :             : 
    2718                 :          10 :  call cwtime_report(" a2fw_tr_init, a2f_eval", cpu, wall, gflops)
    2719                 :             : 
    2720                 :             :  ! NOTE: for the moment calculate the log moms etc on just the trace of the a2f functions
    2721   [ -  +  +  -  :          20 :  ABI_MALLOC(a2f_tr_1mom, (nomega))
             -  +  -  + ]
    2722   [ -  +  +  -  :          20 :  ABI_MALLOC(a2f_tr_logmom, (nomega))
             -  +  -  + ]
    2723   [ -  +  +  -  :          20 :  ABI_MALLOC(a2f_tr_logmom_int, (nomega))
             -  +  -  + ]
    2724                 :             : 
    2725                 :             :  !call a2fw_tr_print_info()
    2726                 :             : 
    2727                 :             :  ! Compute lambda_tr(w) (resolved in spin mode and directions)
    2728         [ +  + ]:          20 :  do spin=1,nsppol
    2729         [ +  + ]:          60 :    do mu=0,natom3
    2730         [ +  + ]:         170 :      do idir=1,3
    2731         [ +  + ]:         520 :        do jdir=1,3
    2732                 :             : 
    2733         [ +  + ]:      170640 :          do iw=1,nomega
    2734                 :      170280 :            ww = a2f_tr%omega(iw)
    2735         [ +  - ]:      170640 :            if (abs(ww) > EPHTK_WTOL) then
    2736                 :      170280 :               a2f_tr_1mom(iw)  = a2f_tr%vals_tr(iw,idir,jdir,mu,spin) / abs(ww)
    2737                 :             :            else
    2738                 :           0 :               a2f_tr_1mom(iw) = zero
    2739                 :             :            end if
    2740                 :             :            ! TODO: Strange that the first value of int(f) is not set to zero!
    2741                 :             :            ! FIXME: The frequency integration overestimates lambda if there are negative phonon frequencies!
    2742                 :             :          end do
    2743                 :             : 
    2744                 :         480 :          call simpson_int(nomega, wstep, a2f_tr_1mom, a2f_tr%lambdaw_tr(:,idir,jdir,mu,spin))
    2745                 :             :        end do ! jdir
    2746                 :             :      end do ! idir
    2747                 :             :    end do ! mu
    2748                 :             :  end do ! spin
    2749                 :             : 
    2750         [ +  - ]:          10 :  if (my_rank == master) then
    2751                 :          10 :    ount = std_out
    2752         [ -  + ]:          10 :    if (nsppol > 1) then
    2753                 :           0 :      write(msg,'(3a)') ch10,'Comment: some of the following quantities should be integrated over spin', ch10
    2754                 :           0 :      call wrtout(ount, msg)
    2755                 :             :    end if
    2756                 :             :  end if
    2757                 :             : 
    2758         [ +  + ]:          20 :  do spin=1,nsppol
    2759                 :          10 :    lambda_iso = a2fw_tr_moment(a2f_tr, 0, spin)
    2760                 :             : 
    2761         [ +  + ]:          40 :    do idir=1,3
    2762         [ +  + ]:         130 :      do jdir=1,3
    2763                 :          90 :        a2f_tr_1d => a2f_tr%vals_tr(:,idir,jdir,0,spin)
    2764                 :             : 
    2765                 :             :        ! Get log moment of alpha^2F.
    2766         [ +  + ]:       42660 :        a2f_tr_logmom = zero
    2767         [ +  + ]:       42660 :        do iw=1,nomega
    2768                 :       42570 :          omega = a2f_tr%omega(iw)
    2769   [ +  -  +  - ]:       42660 :          if (abs(omega) > EPHTK_WTOL .and. abs(lambda_iso(idir,jdir)) > EPHTK_WTOL) then
    2770                 :       42570 :            a2f_tr_logmom(iw) = (two/lambda_iso(idir,jdir)) * a2f_tr_1d(iw)*log(abs(omega))/abs(omega)
    2771                 :             :          end if
    2772                 :             :        end do
    2773                 :          90 :        call simpson_int(nomega, wstep, a2f_tr_logmom, a2f_tr_logmom_int)
    2774                 :             :        !write(std_out,*)' iw,nomega,greatest_real,a2f_tr_logmom_int(nomega)=',& iw,nomega,greatest_real,a2f_tr_logmom_int(nomega)
    2775         [ +  - ]:         120 :        if(abs(a2f_tr_logmom_int(nomega)) < log(greatest_real*tol6)) then
    2776                 :          90 :          omega_log(idir,jdir) = exp(a2f_tr_logmom_int(nomega))
    2777                 :             :        else
    2778                 :           0 :          omega_log(idir,jdir)=greatest_real*tol6
    2779                 :             :        endif
    2780                 :             :      end do
    2781                 :             :    end do
    2782                 :             : 
    2783                 :             :    ! TODO: make output only for irred values xx yy zz and top half of matrix
    2784         [ +  - ]:          20 :    if (my_rank == master) then
    2785         [ +  + ]:          10 :      if (do_qintp) then
    2786                 :           5 :        write(ount,'(a)')' Evaluation of parameters analogous to electron-phonon coupling for 3x3 directions (interpolated) '
    2787                 :             :      else
    2788                 :           5 :        write(ount,'(a)')' Evaluation of parameters analogous to electron-phonon coupling for 3x3 directions (coarse grid) '
    2789                 :             :      endif
    2790                 :          10 :      write(ount,'(a,3(3es10.3,2x))') ' lambda = ',lambda_iso
    2791                 :          10 :      write(ount,'(a,3(3es10.3,2x),a)' )' omegalog  = ',omega_log,' (Ha) '
    2792   [ +  +  +  + ]:         130 :      write(ount,'(a,3(3es10.3,2x),a)' )'             ',omega_log*Ha_K, ' (Kelvin) '
    2793                 :          10 :      write(ount,"(a)")'    positive moments of alpha2Ftr:'
    2794   [ +  +  +  + ]:         130 :      write(ount,'(a,9(es10.3,2x))' )' lambda <omega^2> = ',a2fw_tr_moment(a2f_tr, 2, spin)
    2795   [ +  +  +  + ]:         130 :      write(ount,'(a,9(es10.3,2x))' )' lambda <omega^3> = ',a2fw_tr_moment(a2f_tr, 3, spin)
    2796   [ +  +  +  + ]:         130 :      write(ount,'(a,9(es10.3,2x))' )' lambda <omega^4> = ',a2fw_tr_moment(a2f_tr, 4, spin)
    2797   [ +  +  +  + ]:         130 :      write(ount,'(a,9(es10.3,2x))' )' lambda <omega^5> = ',a2fw_tr_moment(a2f_tr, 5, spin)
    2798                 :             :    end if
    2799                 :             :  end do
    2800                 :             : 
    2801         [ -  + ]:          10 :  ABI_FREE(tmp_a2f_in)
    2802         [ -  + ]:          10 :  ABI_FREE(tmp_a2f_out)
    2803         [ -  + ]:          10 :  ABI_FREE(a2f_tr_1mom)
    2804         [ -  + ]:          10 :  ABI_FREE(a2f_tr_logmom)
    2805         [ -  + ]:          10 :  ABI_FREE(a2f_tr_logmom_int)
    2806         [ -  + ]:          10 :  ABI_FREE(qibz)
    2807         [ -  + ]:          10 :  ABI_FREE(wtq)
    2808                 :             : 
    2809   [ +  -  -  +  :          70 : end subroutine a2fw_tr_init
          -  +  -  +  -  
          +  -  -  -  -  
          -  +  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
                      + ]
    2810                 :             : !!***
    2811                 :             : 
    2812                 :             : !----------------------------------------------------------------------
    2813                 :             : 
    2814                 :             : !!****f* m_phgamma/a2fw_tr_write
    2815                 :             : !! NAME
    2816                 :             : !! a2fw_tr_write
    2817                 :             : !!
    2818                 :             : !! FUNCTION
    2819                 :             : !!  Write alpha^2F_tr(w) to an external file in text form
    2820                 :             : !!
    2821                 :             : !! INPUTS
    2822                 :             : !!  basename=Filename for output.
    2823                 :             : !!  post=String appended to netcdf variables e.g. _qcoarse, _qintp
    2824                 :             : !!  ncid=Netcdf file handler. Set it to nctk_noid to disable output.
    2825                 :             : !!
    2826                 :             : !! OUTPUT
    2827                 :             : !!  Output is written to file. This routine should be called by one MPI proc.
    2828                 :             : !!
    2829                 :             : !! SOURCE
    2830                 :             : 
    2831                 :          10 : subroutine a2fw_tr_write(a2f_tr, basename, post, ncid)
    2832                 :             : 
    2833                 :             : !Arguments ------------------------------------
    2834                 :             : !scalars
    2835                 :             :  class(a2fw_tr_t),intent(in) :: a2f_tr
    2836                 :             :  integer,intent(in) :: ncid
    2837                 :             :  character(len=*),intent(in) :: basename, post
    2838                 :             : 
    2839                 :             : !Local variables -------------------------
    2840                 :             : !scalars
    2841                 :             :  integer :: iw,spin,unt,ii,mu,idir, jdir, ncerr
    2842                 :             :  character(len=500) :: dim1_name, msg
    2843                 :             :  character(len=fnlen) :: path
    2844                 :             : ! *********************************************************************
    2845                 :             : 
    2846                 :             :  ! Write spin-resolved a2F_tr(w)
    2847         [ +  - ]:          10 :  path = strcat(basename, "_A2FW_tr")
    2848         [ -  + ]:          10 :  if (open_file(path, msg, newunit=unt, form="formatted", action="write", status="unknown") /= 0) then
    2849                 :           0 :    ABI_ERROR(msg)
    2850                 :             :  end if
    2851                 :             : 
    2852                 :          10 :  call write_a2fw_tr_header()
    2853                 :             : 
    2854                 :             :  ! Reminder: vals_tr(nomega,3,3,0:natom3,nsppol)
    2855                 :             : 
    2856         [ +  - ]:          10 :  if (a2f_tr%nsppol == 1) then
    2857                 :          10 :    write(unt,'(a)')"# Frequency, a2F_tr(w,i,j)"
    2858         [ +  + ]:        4740 :    do iw=1,a2f_tr%nomega
    2859                 :        4740 :      write(unt,'(e16.6, 2x, 3(3e16.6,1x))') a2f_tr%omega(iw), a2f_tr%vals_tr(iw,:,:,0,1)
    2860                 :             :    end do
    2861                 :          10 :    write(unt,'(3a)')ch10, ch10, "# Frequency, lambda(w,i,j)"
    2862         [ +  + ]:        4740 :    do iw=1,a2f_tr%nomega
    2863                 :        4740 :      write(unt,'(e16.6, 2x, 3(3e16.6,1x))') a2f_tr%omega(iw), a2f_tr%lambdaw_tr(iw,:,:,0,1)
    2864                 :             :    end do
    2865                 :             : 
    2866                 :             :  else
    2867                 :           0 :    write(unt,'(a)')"# Frequency, a2F_tr_tot(w,i,j), a2F_tr_spin1(w,i,j) ..."
    2868         [ #  # ]:           0 :    do iw=1,a2f_tr%nomega
    2869                 :           0 :      write(unt,'(e16.6, 2x, 3(3e16.6,1x), 2x,  3(3e16.6,1x), 2x,  3(3e16.6,1x))') a2f_tr%omega(iw), &
    2870   [ #  #  #  #  :           0 :                   ((sum(a2f_tr%vals_tr(iw,idir,jdir,0,:)), idir=1,3), jdir=1,3) , &
                   #  # ]
    2871                 :           0 :                   a2f_tr%vals_tr(iw,:,:,0,1), &  ! UP
    2872   [ #  #  #  # ]:           0 :                   a2f_tr%vals_tr(iw,:,:,0,2)     ! DOWN
    2873                 :             :    end do
    2874                 :           0 :    write(unt,'(3a)') ch10, ch10, "# Frequency, lambda_tr_tot(w,i,j)dw, lambda_tr_spin1(w,i,j) ..."
    2875         [ #  # ]:           0 :    do iw=1,a2f_tr%nomega
    2876                 :           0 :      write(unt,'(e16.6, 2x, 3(3e16.6,1x), 2x, 3(3e16.6,1x), 2x,      3(3e16.6,1x), 2x,  3(3e16.6,1x))') a2f_tr%omega(iw), &
    2877   [ #  #  #  #  :           0 :                   ((sum(a2f_tr%lambdaw_tr(iw,idir,jdir,0,:)), idir=1,3), jdir=1,3) , &  ! TOT
                   #  # ]
    2878                 :           0 :                   a2f_tr%lambdaw_tr(iw,:,:,0,1), &  ! UP
    2879   [ #  #  #  # ]:           0 :                   a2f_tr%lambdaw_tr(iw,:,:,0,2)     ! DOWN
    2880                 :             :    end do
    2881                 :             :  end if
    2882                 :             : 
    2883                 :          10 :  close(unt)
    2884                 :             : 
    2885                 :             :  ! Write phonon mode contributions to a2F_tr(w,i,j)
    2886         [ +  - ]:          10 :  path = strcat(basename, "_PH_A2FW_tr")
    2887         [ -  + ]:          10 :  if (open_file(path, msg, newunit=unt, form="formatted", action="write", status="unknown") /= 0) then
    2888                 :           0 :    ABI_ERROR(msg)
    2889                 :             :  end if
    2890                 :          10 :  call write_a2fw_tr_header()
    2891                 :             : 
    2892                 :             :  ! Reminder: vals_tr(nomega,3,3,0:natom3,nsppol)
    2893         [ +  - ]:          10 :  if (a2f_tr%nsppol == 1) then
    2894         [ +  + ]:          50 :    do mu=0,a2f_tr%natom3
    2895                 :          40 :      write(unt,'(a,i0)')"# Phonon mode ",mu
    2896                 :          40 :      write(unt,'(a)')"# Frequency, a2F_tr(w)"
    2897         [ +  + ]:       18960 :      do iw=1,a2f_tr%nomega
    2898                 :       18960 :        write(unt,'(e16.6,2x,3(3e16.6,1x))') a2f_tr%omega(iw), a2f_tr%vals_tr(iw,:,:,mu,1)
    2899                 :             :      end do
    2900         [ +  + ]:         120 :      do ii=1,2; write(unt,'(a)')""; end do
    2901                 :          40 :      write(unt,'(a)')"# Frequency, lambda_tr(w)"
    2902         [ +  + ]:       18960 :      do iw=1,a2f_tr%nomega
    2903                 :       18960 :        write(unt,'(e16.6,2x,3(3e16.6,1x))') a2f_tr%omega(iw), a2f_tr%lambdaw_tr(iw,:,:,mu,1)
    2904                 :             :      end do
    2905         [ +  + ]:         130 :      do ii=1,2; write(unt,'(a)')""; end do
    2906                 :             :    end do
    2907                 :             : 
    2908                 :             :  else
    2909         [ #  # ]:           0 :    do mu=0,a2f_tr%natom3
    2910                 :           0 :      write(unt,'(a,i0)')"# Phonon mode ",mu
    2911                 :           0 :      write(unt,'(a)')"# Frequency, a2F_tot(w), a2F_spin1(w) ..."
    2912         [ #  # ]:           0 :      do iw=1,a2f_tr%nomega
    2913                 :           0 :        write(unt,*) a2f_tr%omega(iw), &
    2914   [ #  #  #  #  :           0 :                     sum(a2f_tr%vals_tr(iw,:,:,mu,:)), &  ! TOT
                   #  # ]
    2915                 :           0 :                     a2f_tr%vals_tr(iw,:,:,mu,1)     , &  ! UP
    2916                 :           0 :                     a2f_tr%vals_tr(iw,:,:,mu,2)          ! DOWN
    2917                 :             :      end do
    2918                 :           0 :      write(unt,'(3a)')ch10,ch10,"# Frequency, lambda_tot(w)dw, lambda_spin1(w) ..."
    2919         [ #  # ]:           0 :      do iw=1,a2f_tr%nomega
    2920                 :           0 :        write(unt,*) a2f_tr%omega(iw), &
    2921   [ #  #  #  #  :           0 :                      sum(a2f_tr%lambdaw_tr(iw,:,:,mu,:)), &  ! TOT
                   #  # ]
    2922                 :           0 :                      a2f_tr%lambdaw_tr(iw,:,:,mu,1),      &  ! UP
    2923                 :           0 :                      a2f_tr%lambdaw_tr(iw,:,:,mu,2)          ! DOWN
    2924                 :             :      end do
    2925                 :             :    end do
    2926                 :             :  end if
    2927                 :             : 
    2928                 :          10 :  close(unt)
    2929                 :             : 
    2930         [ +  - ]:          10 :  if (ncid /= nctk_noid) then
    2931                 :             :    ! Define dimensions.
    2932         [ +  - ]:          10 :    dim1_name = strcat("a2ftr_nomega", post)
    2933                 :             :    ncerr = nctk_def_dims(ncid, [ &
    2934                 :             :      nctkdim_t(dim1_name, a2f_tr%nomega), &
    2935                 :             :      nctkdim_t("natom3p1", a2f_tr%natom3 + 1), nctkdim_t("number_of_spins", a2f_tr%nsppol) &
    2936         [ +  + ]:          40 :    ], defmode=.True.)
    2937         [ -  + ]:          10 :    NCF_CHECK(ncerr)
    2938                 :             : 
    2939                 :             :    ncerr = nctk_def_arrays(ncid, [ &
    2940                 :             :      nctkarr_t(strcat('a2ftr_mesh', post), "dp", dim1_name), &
    2941                 :             :      nctkarr_t(strcat('a2ftr_values', post), "dp", strcat(dim1_name, ", three, three, natom3p1, number_of_spins")), &
    2942                 :             :      nctkarr_t(strcat('a2ftr_lambdaw', post), "dp", strcat(dim1_name, ", three, three, natom3p1, number_of_spins")) &
    2943   [ +  -  +  -  :          40 :    ])
          +  -  +  -  +  
                -  +  + ]
    2944         [ -  + ]:          10 :    NCF_CHECK(ncerr)
    2945                 :             : 
    2946         [ -  + ]:          10 :    NCF_CHECK(nctk_set_datamode(ncid))
    2947         [ -  + ]:          10 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, strcat("a2ftr_mesh", post)), a2f_tr%omega))
    2948         [ -  + ]:          10 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, strcat("a2ftr_values", post)), a2f_tr%vals_tr))
    2949         [ -  + ]:          10 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, strcat("a2ftr_lambdaw", post)), a2f_tr%lambdaw_tr))
    2950                 :             :  end if
    2951                 :             : 
    2952                 :             : contains
    2953                 :             : 
    2954                 :          20 : subroutine write_a2fw_tr_header()
    2955                 :             : 
    2956                 :             :  ! Output the header.
    2957                 :          20 :  write(unt,'(a)')              '#'
    2958                 :          20 :  write(unt,'(a)')              '# ABINIT package: a2F_tr(w) file'
    2959                 :          20 :  write(unt,'(a)')              '#'
    2960                 :          20 :  write(unt,'(a)')              '# a2F_tr(w) function integrated over the FS. omega in a.u.'
    2961         [ +  - ]:          20 :  write(unt,'(2a)')             '# ngqpt: ',trim(ltoa(a2f_tr%ngqpt))
    2962                 :          20 :  write(unt,'(a,i0,3(a,e16.6))')'# number of frequencies: ',a2f_tr%nomega," between omega_min: ",a2f_tr%omega_min,&
    2963                 :          40 :                                ' Ha and omega_max: ',a2f_tr%omega_max,' Ha with step:',a2f_tr%wstep
    2964                 :          20 :  write(unt,'(a,e16.6)')        '#  the smearing width for gaussians is ',a2f_tr%smear
    2965         [ -  + ]:          20 :  if (a2f_tr%nsppol == 2) then
    2966         [ #  # ]:           0 :    write(unt,'(a,e16.6)')"# Total DOS at Fermi level ",sum(a2f_tr%n0)
    2967                 :             :  end if
    2968         [ +  + ]:          40 :  do spin=1,a2f_tr%nsppol
    2969                 :          40 :    write(unt,"(a,i0,a,e16.6)")"# The DOS at Fermi level for spin ",spin," is ",a2f_tr%n0(spin)
    2970                 :             :  end do
    2971         [ +  + ]:          60 :  do ii=1,2; write(unt,'(a)')     "# "; end do
    2972                 :             : 
    2973                 :          20 : end subroutine write_a2fw_tr_header
    2974                 :             : 
    2975                 :             : end subroutine a2fw_tr_write
    2976                 :             : !!***
    2977                 :             : 
    2978                 :             : !----------------------------------------------------------------------
    2979                 :             : 
    2980                 :             : !!****f* m_phgamma/eph_phgamma
    2981                 :             : !! NAME
    2982                 :             : !!  eph_phgamma
    2983                 :             : !!
    2984                 :             : !! FUNCTION
    2985                 :             : !!  Compute phonon linewidths in metals.
    2986                 :             : !!
    2987                 :             : !! INPUTS
    2988                 :             : !! wk0_path=String with the path to the GS unperturbed WFK file.
    2989                 :             : !! ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
    2990                 :             : !! dtset<dataset_type>=All input variables for this dataset.
    2991                 :             : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    2992                 :             : !! dvdb<dbdb_type>=Database with the DFPT SCF potentials.
    2993                 :             : !! ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
    2994                 :             : !! pawfgr <type(pawfgr_type)>=fine grid parameters and related data
    2995                 :             : !! pawang<pawang_type)>=PAW angular mesh and related data.
    2996                 :             : !! pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
    2997                 :             : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
    2998                 :             : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
    2999                 :             : !! comm=MPI communicator.
    3000                 :             : !!
    3001                 :             : !! OUTPUT
    3002                 :             : !!
    3003                 :             : !! SOURCE
    3004                 :             : 
    3005                 :           5 : subroutine eph_phgamma(wfk0_path, dtfil, ngfft, ngfftf, dtset, cryst, ebands, dvdb, ifc, &
    3006                 :           5 :                        pawfgr, pawang, pawrad, pawtab, psps, mpi_enreg, comm)
    3007                 :             : 
    3008                 :             : !Arguments ------------------------------------
    3009                 :             : !scalars
    3010                 :             :  character(len=*),intent(in) :: wfk0_path
    3011                 :             :  integer,intent(in) :: comm
    3012                 :             :  type(datafiles_type),intent(in) :: dtfil
    3013                 :             :  type(dataset_type),intent(in) :: dtset
    3014                 :             :  type(crystal_t),intent(in) :: cryst
    3015                 :             :  type(ebands_t),intent(in) :: ebands
    3016                 :             :  type(dvdb_t),intent(inout) :: dvdb
    3017                 :             :  type(pawang_type),intent(in) :: pawang
    3018                 :             :  type(pseudopotential_type),intent(in) :: psps
    3019                 :             :  type(pawfgr_type),intent(in) :: pawfgr
    3020                 :             :  type(ifc_type),intent(in) :: ifc
    3021                 :             :  type(mpi_type),intent(in) :: mpi_enreg
    3022                 :             : !arrays
    3023                 :             :  integer,intent(in) :: ngfft(18),ngfftf(18)
    3024                 :             :  type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
    3025                 :             :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
    3026                 :             : 
    3027                 :             : !Local variables ------------------------------
    3028                 :             : !scalars
    3029                 :             :  integer,parameter :: tim_getgh1c = 1, berryopt0 = 0, qptopt1 = 1, master = 0, ndat1 = 1, eph_scalprod0 = 0
    3030                 :             :  integer :: my_rank,nproc,mband,nsppol,nkibz,idir,ipert,iq_ibz
    3031                 :             :  integer :: cplex,db_iqpt,natom,natom3,ipc,ipc1,ipc2,nspinor,onpw
    3032                 :             :  integer :: bstart_k,bstart_kq,nb_k,nb_kq,band_k, band_kq, in_k, im_kq
    3033                 :             :  integer :: ik_ibz,ik_bz,ikq_bz,ikq_ibz,isym_k,isym_kq,trev_k,trev_kq !,timrev_q
    3034                 :             :  integer :: ik_fs, my_ik, my_is, spin, istwf_k, istwf_kq, npw_k, npw_kq
    3035                 :             :  integer :: ii,jj,ipw,mpw,my_mpw,mnb,ierr,cnt,ncid
    3036                 :             :  integer :: n1, n2, n3, n4, n5, n6, nspden, ltetra
    3037                 :             :  integer :: sij_opt, usecprj, usevnl, optlocal, optnl, opt_gvnlx1
    3038                 :             :  integer :: nfft,nfftf,mgfft,mgfftf,nkpg
    3039                 :             :  integer :: jene, iene, comm_rpt, nesting, my_npert, my_ip, my_iq, ncerr, edos_intmeth
    3040                 :             :  real(dp) :: cpu, wall, gflops, cpu_q, wall_q, gflops_q, cpu_k, wall_k, gflops_k, cpu_all, wall_all, gflops_all
    3041                 :             :  real(dp) :: edos_step, edos_broad, sigma, ecut, eig0nk ! eshift,
    3042                 :             :  logical :: gen_eigenpb, need_velocities, isirr_k, isirr_kq, print_time_k, need_ftinterp
    3043                 :           5 :  type(wfd_t) :: wfd
    3044                 :             :  type(fstab_t),pointer :: fs
    3045                 :           5 :  type(gs_hamiltonian_type) :: gs_hamkq
    3046                 :           5 :  type(rf_hamiltonian_type) :: rf_hamkq
    3047                 :           5 :  type(edos_t) :: edos
    3048                 :           5 :  type(phgamma_t) :: gams
    3049                 :           5 :  type(a2fw_t) :: a2fw
    3050                 :           5 :  type(a2fw_tr_t) :: a2fw_tr
    3051   [ +  +  -  +  :          50 :  type(ddkop_t) :: ddkop
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  +  -  +  
          -  +  +  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  -  
                      + ]
    3052                 :             :  type(xcomm_t) :: pert_comm, qs_comm, qpt_comm, bsum_comm, kpt_comm, spin_comm, pkb_comm !, ncwrite_comm
    3053                 :           5 :  type(krank_t) :: krank
    3054                 :           5 :  type(htetra_t) :: tetra
    3055                 :             :  !type(lgroup_t) :: lg_q
    3056                 :             :  character(len=500) :: msg
    3057                 :             :  character(len=fnlen) :: path
    3058                 :             : !arrays
    3059                 :             :  integer :: g0_k(3),g0bz_kq(3),g0_kq(3),units(2)
    3060                 :             :  integer :: indkk_kq(6,1), work_ngfft(18),gmax(3),my_gmax(3),gamma_ngqpt(3) !g0ibz_kq(3),
    3061                 :           5 :  integer,allocatable :: kg_k(:,:),kg_kq(:,:),gtmp(:,:),nband(:,:),wfd_istwfk(:), my_pinfo(:,:), pert_table(:,:) !, qibz_done(:)
    3062                 :          10 :  real(dp) :: kk(3),kq(3),kk_ibz(3),kq_ibz(3),qpt(3), lf(2),rg(2),res(2), vk(3), vkq(3), wminmax(2), n0(ebands%nsppol)
    3063                 :          10 :  real(dp) :: resvv_in(2,9), resvv_out(2,9), phfrq(3*cryst%natom), abc(3)
    3064                 :           5 :  real(dp),allocatable :: kinpw_k(:), kinpw_kq(:), displ_cart(:,:,:,:), displ_red(:,:,:,:)
    3065                 :           5 :  real(dp),allocatable :: grad_berry(:,:), kpg_kq(:,:), kpg_k(:,:)
    3066                 :           5 :  real(dp),allocatable :: ffnl_k(:,:,:,:), ffnl_kq(:,:,:,:), ph3d_k(:,:,:), ph3d_kq(:,:,:)
    3067                 :           5 :  real(dp),allocatable :: v1scf(:,:,:,:), tgam(:,:,:), gkq_atm(:,:,:,:), gkq_atm_ipc(:,:,:), lambda(:)
    3068                 :          10 :  real(dp),allocatable :: bras_kq(:,:,:), kets_k(:,:,:), h1_kets_kq(:,:,:), cg_work(:,:)
    3069                 :           5 :  real(dp),allocatable :: ph1d(:,:), vlocal(:,:,:,:), vlocal1(:,:,:,:,:)
    3070                 :           5 :  real(dp),allocatable :: dummy_vtrial(:,:), gvnlx1(:,:,:), work(:,:,:,:)
    3071                 :           5 :  real(dp),allocatable :: gs1c_kq(:,:), v1_work(:,:,:,:), vcart_ibz(:,:,:,:)
    3072                 :          10 :  real(dp),allocatable :: wt_ek(:,:), wt_ekq(:,:), dbldelta_wts(:,:)
    3073                 :           5 :  real(dp),allocatable :: tgamvv_in(:,:,:,:),  vv_kk(:,:,:), tgamvv_out(:,:,:,:), vv_kkq(:,:,:), tmp_vals_ee(:,:,:,:,:), emesh(:)
    3074                 :          10 :  logical,allocatable :: bks_mask(:,:,:),keep_ur(:,:,:)
    3075                 :           5 :  type(fstab_t),target,allocatable :: fstab(:)
    3076                 :           5 :  type(pawcprj_type),allocatable  :: cwaveprj0(:,:)
    3077                 :             : #ifdef HAVE_MPI
    3078                 :             :  integer :: ndims, comm_cart, me_cart, coords(5)
    3079                 :             :  logical :: reorder
    3080                 :           5 :  integer,allocatable :: dims(:)
    3081                 :           5 :  logical,allocatable :: periods(:), keepdim(:)
    3082                 :             : #endif
    3083                 :             : !************************************************************************
    3084                 :             : 
    3085                 :           5 :  if (psps%usepaw == 1) then
    3086                 :           0 :    ABI_ERROR("PAW not implemented")
    3087                 :             :    ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/))
    3088                 :             :  end if
    3089                 :             : 
    3090                 :           5 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
    3091         [ +  + ]:          15 :  units = [std_out, ab_out]
    3092                 :           5 :  call wrtout(std_out, " Computing ph linewidths in metals.")
    3093                 :           5 :  call cwtime(cpu_all, wall_all, gflops_all, "start")
    3094                 :           5 :  call pstat_proc%print(_PSTAT_ARGS_)
    3095                 :             : 
    3096                 :             :  ! Copy important dimensions
    3097                 :           5 :  natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands%nsppol; nspinor = ebands%nspinor; nspden = dtset%nspden
    3098                 :           5 :  nkibz = ebands%nkpt; mband = ebands%mband
    3099                 :             : 
    3100                 :             :  ! FFT meshes
    3101         [ +  + ]:          20 :  nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3))
    3102   [ +  +  +  + ]:          35 :  nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3))
    3103                 :           5 :  n1 = ngfft(1); n2 = ngfft(2); n3 = ngfft(3)
    3104                 :           5 :  n4 = ngfft(4); n5 = ngfft(5); n6 = ngfft(6)
    3105                 :             : 
    3106                 :             :  ! Compute electron DOS.
    3107                 :             :  !call dtset%get_edos_params(edos_intmeth, edos_step, edos_broad)
    3108         [ -  + ]:           5 :  edos_intmeth = 2; if (dtset%prtdos /= 0) edos_intmeth = dtset%prtdos
    3109                 :             :  edos_step = dtset%dosdeltae; edos_broad = dtset%tsmear
    3110                 :           5 :  edos_step = 0.01 * eV_Ha; edos_broad = 0.3 * eV_Ha
    3111   [ -  +  -  +  :           5 :  edos = ebands%get_edos(cryst, edos_intmeth, edos_step, edos_broad, comm)
          -  +  -  +  -  
                      + ]
    3112                 :             : 
    3113                 :             :  ! Store DOS per spin channel.
    3114         [ +  + ]:          10 :  n0(:) = edos%gef(1:edos%nsppol)
    3115         [ +  - ]:           5 :  if (my_rank == master) then
    3116                 :           5 :    call edos%print(units)
    3117                 :           5 :    call edos%write(strcat(dtfil%filnam_ds(4), "_EDOS"))
    3118                 :             :  end if
    3119                 :             : 
    3120                 :             :  ! Find Fermi surface k-points
    3121                 :             :  ! TODO: support kptopt, change setup of k-points if tetra: fist tetra weights then k-points on the Fermi surface!
    3122   [ -  +  +  -  :          20 :  ABI_MALLOC(fstab, (nsppol))
          +  -  +  -  -  
          +  -  +  +  +  
          +  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  + ]
    3123                 :           5 :  call fstab_init(fstab, ebands, cryst, dtset, tetra, comm)
    3124                 :           5 :  call tetra%free()
    3125                 :             : 
    3126                 :             :  ! Define q-mesh. eph_ngqpt_fine activates the Fourier interpolation of the DFPT potentials.
    3127   [ +  +  +  +  :          26 :  gamma_ngqpt = ifc%ngqpt; if (all(dtset%eph_ngqpt_fine /= 0)) gamma_ngqpt = dtset%eph_ngqpt_fine
          +  +  +  +  +  
                      + ]
    3128                 :             : 
    3129                 :           5 :  call phgamma_init(gams, cryst, ifc, ebands, fstab(1), dtset, eph_scalprod0, gamma_ngqpt, n0, comm)
    3130                 :             : 
    3131                 :           5 :  call wrtout(std_out, sjoin(" q-mesh for phonon linewidths:", ltoa(gamma_ngqpt)))
    3132                 :           5 :  call wrtout(std_out, sjoin(" Will compute:", itoa(gams%nqibz), "q-points in the IBZ"))
    3133                 :           5 :  call pstat_proc%print(_PSTAT_ARGS_)
    3134                 :             : 
    3135                 :             :  ! Select option for double delta with tetra.
    3136                 :             :  !  2 for the optimized tetrahedron method.
    3137                 :             :  ! -2 for the linear tetrahedron method.
    3138                 :           5 :  ltetra = 0
    3139         [ +  + ]:           5 :  if (dtset%eph_intmeth ==  2) ltetra = 2
    3140         [ -  + ]:           5 :  if (dtset%eph_intmeth == -2) ltetra = 1
    3141                 :             : 
    3142                 :             :  ! Compute optimal energy window for tetra.
    3143                 :             :  !call find_ewin(gams%nqibz, gams%qibz, cryst, ebands, ltetra, sigma, comm)
    3144                 :             : 
    3145                 :             :  ! ========================
    3146                 :             :  ! === MPI DISTRIBUTION ===
    3147                 :             :  ! ========================
    3148                 :             :  ! Init for sequential execution.
    3149                 :           5 :  my_npert = natom3
    3150                 :             : 
    3151   [ +  +  +  -  :          30 :  if (any(dtset%eph_np_pqbks /= 0)) then
                   -  + ]
    3152                 :             :    ! Use parameters from input file.
    3153                 :           0 :    pert_comm%nproc = dtset%eph_np_pqbks(1)
    3154                 :           0 :    qpt_comm%nproc  = dtset%eph_np_pqbks(2)
    3155                 :           0 :    bsum_comm%nproc = dtset%eph_np_pqbks(3)
    3156                 :           0 :    kpt_comm%nproc = dtset%eph_np_pqbks(4)
    3157                 :           0 :    spin_comm%nproc = dtset%eph_np_pqbks(5)
    3158                 :           0 :    my_npert = natom3 / pert_comm%nproc
    3159         [ #  # ]:           0 :    ABI_CHECK(my_npert > 0, "pert_comm_nproc cannot be greater than 3 * natom.")
    3160         [ #  # ]:           0 :    ABI_CHECK(mod(natom3, pert_comm%nproc) == 0, "pert_comm_nproc must divide 3 * natom.")
    3161                 :             :  else
    3162                 :             :    ! Automatic grid generation
    3163                 :             :    ! Not the most efficient distribution if large number of MPI procs.
    3164                 :             :    ! TODO: Add parallelism over perturbations although it's less efficient than the parallelism over k
    3165                 :             :    ! It starts to be interesting if we implement symmetries in the k-integration though.
    3166                 :             : 
    3167                 :             :    ! TODO: Spin
    3168                 :             :    ! Automatic grid generation over q-points and spins.
    3169                 :             :    !if (new%nsppol == 2 .and. mod(nprocs, 2) == 0) then
    3170                 :             :    !  spin_comm%nproc = 2
    3171                 :             :    !  new%qpt_comm%nproc = nprocs / 2
    3172                 :             :    !else
    3173                 :             :    !  new%qpt_comm%nproc = nprocs
    3174                 :             :    !end if
    3175                 :             : 
    3176                 :             :    ! Handle parallelism over perturbations first.
    3177                 :             :    ! Use MPI communicator to distribute the 3 * natom perturbations to reduce memory requirements for DFPT potentials.
    3178                 :             :    ! Ideally, perturbations are equally distributed --> total number of CPUs should be divisible by 3 * natom.
    3179                 :             :    ! or at least, divisible by one integer i for i in [2, 3 * natom - 1].
    3180                 :             : 
    3181   [ -  +  -  - ]:           5 :    if (nsppol == 2 .and. mod(nproc, 2) == 0) then
    3182                 :           0 :      spin_comm%nproc = 2
    3183                 :           0 :      kpt_comm%nproc = nproc / 2
    3184                 :             :    else
    3185                 :             :      ! Try to have 3 perts per proc first because the q-point parallelism is more efficient.
    3186                 :             :      ! The memory for W(R,r,ipert) will increase though.
    3187                 :             :      !do cnt=natom,2,-1
    3188                 :             :      !  if (mod(nprocs, cnt) == 0 .and. mod(natom3, cnt) == 0) then
    3189                 :             :      !    pert_comm%nproc = cnt; new%my_npert = natom3 / cnt; exit
    3190                 :             :      !  end if
    3191                 :             :      !end do
    3192                 :             : 
    3193                 :             :      !if (pert_comm%nproc == 1) then
    3194                 :             :      !  ! Try again with more procs.
    3195                 :             :      !  do cnt=natom3,2,-1
    3196                 :             :      !    if (mod(nprocs, cnt) == 0 .and. mod(natom3, cnt) == 0) then
    3197                 :             :      !      pert_comm%nproc = cnt; new%my_npert = natom3 / cnt; exit
    3198                 :             :      !    end if
    3199                 :             :      !  end do
    3200                 :             :      !end if
    3201                 :             : 
    3202                 :             :      !if (new%my_npert == natom3 .and. nprocs > 1) then
    3203                 :             :      !  ABI_WARNING("The number of MPI procs should be divisible by 3*natom to reduce memory requirements!")
    3204                 :             :      !end if
    3205                 :             : 
    3206                 :           5 :      kpt_comm%nproc = nproc
    3207                 :             :    end if
    3208                 :             :  end if
    3209                 :             : 
    3210                 :             :  ! Consistency check.
    3211         [ -  + ]:           5 :  if (pert_comm%nproc * qpt_comm%nproc * bsum_comm%nproc * kpt_comm%nproc * spin_comm%nproc /= nproc) then
    3212                 :             :    write(msg, "(a,i0,3a, 6(a,1x,i0))") &
    3213                 :           0 :      "Cannot create 5d Cartesian grid with total nproc: ", nproc, ch10, &
    3214                 :           0 :      "Idle processes are not supported. The product of the `nproc_*` vars should be equal to nproc.", ch10, &
    3215                 :           0 :      "pert_nproc (", pert_comm%nproc, ") x qpt_nproc (", qpt_comm%nproc, ") x bsum_nproc (", bsum_comm%nproc, &
    3216                 :           0 :      ") x kcalc_nproc (", kpt_comm%nproc, ") x spin_nproc (", spin_comm%nproc, ") != ", &
    3217                 :           0 :      pert_comm%nproc * qpt_comm%nproc * bsum_comm%nproc * kpt_comm%nproc * spin_comm%nproc
    3218                 :           0 :    ABI_ERROR(msg)
    3219                 :             :  end if
    3220                 :             : 
    3221         [ -  + ]:           5 :  ABI_CHECK(bsum_comm%nproc == 1, "Band parallelism not implemented in m_phgamma")
    3222                 :             : 
    3223                 :             : #ifdef HAVE_MPI
    3224                 :             :  ! Create 5d cartesian communicator: 3*natom perturbations, q-points in IBZ, bands in FS, kpoints in FS, spins
    3225                 :           5 :  ndims = 5
    3226         [ -  + ]:           5 :  ABI_MALLOC(dims, (ndims))
    3227         [ -  + ]:           5 :  ABI_MALLOC(periods, (ndims))
    3228         [ -  + ]:           5 :  ABI_MALLOC(keepdim, (ndims))
    3229         [ +  + ]:          30 :  periods(:) = .False.; reorder = .False.
    3230   [ -  +  +  + ]:          35 :  dims = [pert_comm%nproc, qpt_comm%nproc, bsum_comm%nproc, kpt_comm%nproc, spin_comm%nproc]
    3231                 :             : 
    3232                 :           5 :  call MPI_CART_CREATE(comm, ndims, dims, periods, reorder, comm_cart, ierr)
    3233                 :             :  ! Find the index and coordinates of the current processor
    3234                 :           5 :  call MPI_COMM_RANK(comm_cart, me_cart, ierr)
    3235                 :           5 :  call MPI_CART_COORDS(comm_cart, me_cart, ndims, coords, ierr)
    3236                 :             : 
    3237                 :             :  ! Create communicator to distribute natom3 perturbations.
    3238         [ +  + ]:          30 :  keepdim = .False.; keepdim(1) = .True.
    3239                 :           5 :  call MPI_CART_SUB(comm_cart, keepdim, pert_comm%value, ierr); pert_comm%me = xmpi_comm_rank(pert_comm%value)
    3240                 :             :  ! Create communicator for qpoints in self-energy integration.
    3241         [ +  + ]:          30 :  keepdim = .False.; keepdim(2) = .True.
    3242                 :           5 :  call MPI_CART_SUB(comm_cart, keepdim, qpt_comm%value, ierr); qpt_comm%me = xmpi_comm_rank(qpt_comm%value)
    3243                 :             :  ! Create communicator for bands for band summation
    3244         [ +  + ]:          30 :  keepdim = .False.; keepdim(3) = .True.
    3245                 :           5 :  call MPI_CART_SUB(comm_cart, keepdim, bsum_comm%value, ierr); bsum_comm%me = xmpi_comm_rank(bsum_comm%value)
    3246                 :             :  ! Create communicator for kpoints.
    3247         [ +  + ]:          30 :  keepdim = .False.; keepdim(4) = .True.
    3248                 :           5 :  call MPI_CART_SUB(comm_cart, keepdim, kpt_comm%value, ierr); kpt_comm%me = xmpi_comm_rank(kpt_comm%value)
    3249                 :             :  ! Create communicator for spins.
    3250         [ +  + ]:          30 :  keepdim = .False.; keepdim(5) = .True.
    3251                 :           5 :  call MPI_CART_SUB(comm_cart, keepdim, spin_comm%value, ierr); spin_comm%me = xmpi_comm_rank(spin_comm%value)
    3252                 :             :  ! Create communicator for the (qpoint, spin) loops
    3253         [ +  + ]:          30 :  keepdim = .False.; keepdim(2) = .True.; keepdim(5) = .True.
    3254                 :           5 :  call MPI_CART_SUB(comm_cart, keepdim, qs_comm%value, ierr); qs_comm%me = xmpi_comm_rank(qs_comm%value)
    3255                 :             :  ! Create communicator for the (perturbation, k-point, band_sum)
    3256   [ +  +  +  + ]:          40 :  keepdim = .False.; keepdim(1) = .True.; keepdim(3:4) = .True.
    3257                 :           5 :  call MPI_CART_SUB(comm_cart, keepdim, pkb_comm%value, ierr); pkb_comm%me = xmpi_comm_rank(pkb_comm%value)
    3258                 :             : 
    3259         [ -  + ]:           5 :  ABI_FREE(dims)
    3260         [ -  + ]:           5 :  ABI_FREE(periods)
    3261                 :           5 :  ABI_FREE(keepdim)
    3262                 :           5 :  call xmpi_comm_free(comm_cart)
    3263                 :             : #endif
    3264                 :             : 
    3265                 :             :  ! Distribute spins and q-points in IBZ.
    3266         [ -  + ]:           5 :  call xmpi_split_cyclic(nsppol, spin_comm%value, gams%my_nspins, gams%my_spins)
    3267         [ -  + ]:           5 :  ABI_CHECK(gams%my_nspins > 0, sjoin("nsppol (", itoa(nsppol), ") < spin_comm_nproc (", itoa(spin_comm%nproc), ")"))
    3268                 :             : 
    3269         [ -  + ]:           5 :  call xmpi_split_cyclic(gams%nqibz, qpt_comm%value, gams%my_nqibz, gams%my_iqibz)
    3270         [ -  + ]:           5 :  ABI_CHECK(gams%my_nqibz > 0, sjoin("nqibz (", itoa(gams%nqibz), ") < qpt_comm_nproc (", itoa(qpt_comm%nproc), ")"))
    3271                 :             : 
    3272                 :             :  !ABI_CALLOC(qibz_done, (gams%nqibz))
    3273         [ +  - ]:           5 :  path = strcat(dtfil%filnam_ds(4), "_A2F.nc")
    3274                 :           5 :  ncid = nctk_noid
    3275                 :             : 
    3276         [ +  - ]:           5 :  if (my_rank == master) then
    3277                 :           5 :    call cwtime(cpu, wall, gflops, "start")
    3278                 :             : 
    3279                 :           5 :    write(std_out, "(/,a)")" === MPI parallelism ==="
    3280                 :             :    !write(std_out, "(2(a,i0))")"P Allocating and summing bands from my_bsum_start: ", self%my_bsum_start, &
    3281                 :             :    !    " up to my_bsum_stop: ", self%my_bsum_stop
    3282                 :           5 :    write(std_out, "(a,i0)")"P Number of CPUs for parallelism over perturbations: ", pert_comm%nproc
    3283                 :           5 :    write(std_out, "(a,i0)")"P Number of perturbations treated by this CPU: ", my_npert
    3284                 :           5 :    write(std_out, "(a,i0)")"P Number of CPUs for parallelism over q-points: ", qpt_comm%nproc
    3285                 :             :    !write(std_out, "(2(a,i0))")"P Number of q-points in the IBZ treated by this proc: " , &
    3286                 :             :    !    count(self%itreat_qibz == 1), " of ", self%nqibz
    3287                 :           5 :    write(std_out, "(a,i0)")"P Number of CPUs for parallelism over bands: ", bsum_comm%nproc
    3288                 :           5 :    write(std_out, "(a,i0)")"P Number of CPUs for parallelism over spins: ", spin_comm%nproc
    3289                 :           5 :    write(std_out, "(a,i0)")"P Number of CPUs for parallelism over k-points: ", kpt_comm%nproc
    3290                 :             :    !write(std_out, "(2(a,i0),/)")"P Number of k-point in Sigma_nk treated by this proc: ", self%my_nkcalc, " of ", self%nkcalc
    3291                 :             : 
    3292                 :             :    ! Master creates the netcdf file used to store the results of the calculation.
    3293         [ -  + ]:           5 :    NCF_CHECK(nctk_open_create(ncid, path, xmpi_comm_self))
    3294         [ -  + ]:           5 :    NCF_CHECK(cryst%ncwrite(ncid))
    3295         [ -  + ]:           5 :    NCF_CHECK(ebands%ncwrite(ncid))
    3296         [ -  + ]:           5 :    NCF_CHECK(edos%ncwrite(ncid))
    3297                 :             : 
    3298                 :             :    ! Add dimensions.
    3299         [ +  + ]:          15 :    ncerr = nctk_def_dims(ncid, [nctkdim_t("nqibz", gams%nqibz), nctkdim_t("natom3", natom3)], defmode=.True.)
    3300         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3301         [ +  + ]:          20 :    ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "eph_intmeth", "eph_transport", "symdynmat"])
    3302         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3303         [ +  + ]:          10 :    ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "ph_intmeth"])
    3304         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3305         [ +  + ]:          25 :    ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "eph_fsewin", "eph_fsmear", "eph_extrael", "eph_fermie"])
    3306         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3307         [ +  + ]:          15 :    ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "ph_wstep", "ph_smear"])
    3308         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3309                 :             : 
    3310                 :             :    ! Define arrays for results.
    3311                 :             :    ncerr = nctk_def_arrays(ncid, [ &
    3312                 :             :      nctkarr_t("ngqpt", "int", "three"), &
    3313                 :             :      nctkarr_t("eph_ngqpt_fine", "int", "three"), &
    3314                 :             :      nctkarr_t("ddb_ngqpt", "int", "three"), &
    3315                 :             :      nctkarr_t("ph_ngqpt", "int", "three"), &
    3316                 :             :      nctkarr_t('qibz', "dp", "number_of_reduced_dimensions, nqibz"), &
    3317                 :             :      nctkarr_t('wtq', "dp", "nqibz"), &
    3318                 :             :      !nctkarr_t('qibz_done', "int", "nqibz"), &
    3319                 :             :      nctkarr_t('phfreq_qibz', "dp", "natom3, nqibz"), &
    3320                 :             :      nctkarr_t('phdispl_cart_qibz', "dp", "two, natom3, natom3, nqibz"), &
    3321                 :             :      nctkarr_t('phgamma_qibz', "dp", "natom3, nqibz, number_of_spins"), &
    3322                 :             :      nctkarr_t('phlambda_qibz', "dp", "natom3, nqibz, number_of_spins") &
    3323         [ +  + ]:          55 :    ])
    3324         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3325                 :             : 
    3326                 :             :    ! ======================================================
    3327                 :             :    ! Write data that do not depend on the (kpt, spin) loop.
    3328                 :             :    ! ======================================================
    3329         [ -  + ]:           5 :    NCF_CHECK(nctk_set_datamode(ncid))
    3330                 :             : 
    3331                 :             :    ncerr = nctk_write_iscalars(ncid, &
    3332                 :             :      [character(len=nctk_slen) :: "eph_intmeth", "eph_transport", "symdynmat", "ph_intmeth"], &
    3333   [ +  +  +  + ]:          45 :      [dtset%eph_intmeth, dtset%eph_transport, dtset%symdynmat, dtset%ph_intmeth])
    3334         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3335                 :             :    ncerr = nctk_write_dpscalars(ncid, &
    3336                 :             :      [character(len=nctk_slen) :: "eph_fsewin", "eph_fsmear", "eph_extrael", "eph_fermie", "ph_wstep", "ph_smear"], &
    3337   [ +  +  +  + ]:          65 :      [dtset%eph_fsewin, dtset%eph_fsmear, dtset%eph_extrael, dtset%eph_fermie, dtset%ph_wstep, dtset%ph_smear])
    3338         [ -  + ]:           5 :    NCF_CHECK(ncerr)
    3339                 :             : 
    3340         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'qibz'), gams%qibz))
    3341         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'wtq'), gams%wtq))
    3342                 :             :    !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, 'qibz_done'), qibz_done))
    3343         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ngqpt"), gamma_ngqpt))
    3344         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_ngqpt_fine"), dtset%eph_ngqpt_fine))
    3345         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ph_ngqpt"), dtset%ph_ngqpt))
    3346         [ -  + ]:           5 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ddb_ngqpt"), dtset%ddb_ngqpt))
    3347                 :             :    !NCF_CHECK(nf90_close(ncid))
    3348                 :           5 :    call cwtime_report(" Creation of A2F.nc", cpu, wall, gflops, end_str=ch10)
    3349                 :             :  end if
    3350                 :             :  !call xmpi_barrier(comm)
    3351                 :             : 
    3352                 :             :  ! Now reopen the file inside ncwrite_comm to perform parallel-IO (required for q-point parallelism).
    3353                 :             :  !if (self%ncwrite_comm%value /= xmpi_comm_null) then
    3354                 :             :  !  NCF_CHECK(nctk_open_modify(self%ncid, path, self%ncwrite_comm%value))
    3355                 :             :  !  NCF_CHECK(nctk_set_datamode(self%ncid))
    3356                 :             :  !end if
    3357                 :           5 :  call edos%free()
    3358                 :             : 
    3359                 :             :  ! Open the DVDB file
    3360                 :           5 :  call dvdb%open_read(ngfftf, xmpi_comm_self)
    3361         [ -  + ]:           5 :  ABI_CHECK(dvdb%has_fields("pot1", msg), msg)
    3362                 :             : 
    3363         [ -  + ]:           5 :  if (pert_comm%nproc > 1) then
    3364                 :             :    ! Activate parallelism over perturbations
    3365                 :             :    ! Build table with list of perturbations treated by this CPU inside pert_comm
    3366   [ #  #  #  # ]:           0 :    call ephtk_set_pertables(cryst%natom, my_npert, pert_table, my_pinfo, pert_comm%value)
    3367                 :           0 :    call dvdb%set_pert_distrib(my_npert, natom3, my_pinfo, pert_table, pert_comm%value)
    3368         [ #  # ]:           0 :    ABI_FREE(my_pinfo)
    3369         [ #  # ]:           0 :    ABI_FREE(pert_table)
    3370                 :             :  end if
    3371                 :             : 
    3372                 :             :  ! Check whether all q-points are available in the input DVDB file.
    3373                 :           5 :  need_ftinterp = .False.
    3374         [ +  + ]:          66 :  do iq_ibz=1,gams%nqibz
    3375         [ -  + ]:          66 :    if (dvdb%findq(gams%qibz(:,iq_ibz) ) == -1) then
    3376                 :           0 :      need_ftinterp = .True.; exit
    3377                 :             :    end if
    3378                 :             :  end do
    3379                 :           5 :  call wrtout(std_out, " ", do_flush=.True.)
    3380                 :             : 
    3381                 :             :  ! Find correspondence IBZ --> set of q-points in DVDB.
    3382                 :             :  ! Activate FT interpolation automatically if required q-points in the IBZ are not found in the DVDB.
    3383                 :             :  !need_ftinterp = .False.
    3384                 :             :  !ABI_MALLOC(qibz2dvdb, (sigma%nqibz))
    3385                 :             :  !if (dvdb%find_qpts(sigma%nqibz, sigma%qibz, qibz2dvdb, comm) /= 0) then
    3386                 :             :  !  call wrtout(units, " Cannot find eph_ngqpt_fine q-points in DVDB --> Activating Fourier interpolation.")
    3387                 :             :  !  need_ftinterp = .True.
    3388                 :             :  !else
    3389                 :             :  !  call wrtout(units, " DVDB file contains all q-points in the IBZ --> Reading DFPT potentials from file.")
    3390                 :             :  !  need_ftinterp = .False.
    3391                 :             :  !end if
    3392                 :             : 
    3393                 :             :  !if (.not. need_ftinterp .and. dtset%eph_use_ftinterp /= 0) then
    3394                 :             :  !  ABI_WARNING("Enforcing FT interpolation for q-points even if it's not strictly needed.")
    3395                 :             :  !  need_ftinterp = .True.
    3396                 :             :  !end if
    3397                 :             : 
    3398         [ -  + ]:           5 :  if (need_ftinterp) then
    3399                 :           0 :    call wrtout(units, " Cannot find eph_ngqpt_fine q-points in DVDB --> Activating Fourier interpolation.")
    3400                 :             :    ! Prepare Fourier interpolation of DFPT potentials.
    3401                 :           0 :    comm_rpt = xmpi_comm_self
    3402                 :             :    !comm_rpt = bqs_comm%value
    3403                 :           0 :    call dvdb%ftinterp_setup(dtset%ddb_ngqpt, qptopt1, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt)
    3404                 :             :  end if
    3405                 :             : 
    3406                 :             :  ! Initialize the wave function descriptor.
    3407                 :             :  ! Only wavefunctions on the FS are stored in wfd.
    3408                 :             :  ! Need all k-points on the FS because of k+q, spin is not distributed for the time being.
    3409                 :             :  ! It would be possible to reduce the memory allocated per MPI-rank via OpenMP.
    3410                 :             : 
    3411   [ -  +  +  -  :          20 :  ABI_MALLOC(nband, (nkibz, nsppol))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    3412   [ -  +  +  -  :          25 :  ABI_MALLOC(bks_mask, (mband, nkibz, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    3413   [ -  +  +  -  :          20 :  ABI_MALLOC(keep_ur, (mband, nkibz ,nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
                   -  + ]
    3414   [ +  +  +  +  :        1905 :  nband = mband; bks_mask = .False.; keep_ur = .False.
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
    3415                 :             : 
    3416         [ +  + ]:          10 :  do my_is=1,gams%my_nspins
    3417                 :           5 :    spin = gams%my_spins(my_is); fs => fstab(spin)
    3418         [ +  + ]:         700 :    do ik_bz=1,fs%nkfs
    3419                 :         690 :      ik_ibz = fs%indkk_fs(1, ik_bz)
    3420                 :         690 :      bstart_k = fs%bstart_cnt_ibz(1, ik_ibz); nb_k = fs%bstart_cnt_ibz(2, ik_ibz)
    3421         [ +  + ]:        1385 :      bks_mask(bstart_k:bstart_k+nb_k-1, ik_ibz, spin) = .True.
    3422                 :             :    end do
    3423                 :             :  end do
    3424                 :             :  !bks_mask(1:mband,:,:) = .True. ! no memory distribution, each node has the full set of states.
    3425                 :             : 
    3426                 :             :  ! Impose istwfk = 1 for all k-points. This is also done in respfn (see inkpts)
    3427                 :             :  ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
    3428   [ -  +  +  -  :          15 :  ABI_MALLOC(wfd_istwfk, (nkibz))
          +  -  +  -  -  
                +  -  + ]
    3429         [ +  + ]:         150 :  wfd_istwfk = 1
    3430                 :             : 
    3431                 :           5 :  ecut = dtset%ecut ! dtset%dilatmx
    3432                 :             :  call wfd%init(cryst, pawtab, psps, keep_ur, mband, nband, nkibz, nsppol, bks_mask,&
    3433                 :             :    nspden, nspinor, ecut, dtset%ecutsm, dtset%dilatmx, wfd_istwfk, ebands%kptns, ngfft,&
    3434                 :           5 :    dtset%nloalg, dtset%prtvol, dtset%pawprtvol, comm)
    3435                 :             : 
    3436         [ +  + ]:          10 :  call wfd%print([std_out], header="Wavefunctions on the Fermi surface")
    3437                 :             : 
    3438         [ -  + ]:           5 :  ABI_FREE(nband)
    3439         [ -  + ]:           5 :  ABI_FREE(keep_ur)
    3440         [ -  + ]:           5 :  ABI_FREE(wfd_istwfk)
    3441                 :             : 
    3442                 :             :  ! Read wavefunctions.
    3443                 :           5 :  call wfd%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
    3444                 :             : 
    3445                 :             :  ! one-dimensional structure factor information on the coarse grid.
    3446   [ +  -  -  +  :          15 :  ABI_MALLOC(ph1d, (2, 3*(2*mgfft+1)*natom))
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
    3447                 :           5 :  call getph(cryst%atindx, natom, n1, n2, n3, ph1d, cryst%xred)
    3448                 :             : 
    3449                 :             :  ! mpw is the maximum number of plane-waves over k and k+q where k and k+q are in the BZ.
    3450                 :             :  ! we also need the max components of the G-spheres (k, k+q) in order to allocate the workspace array work
    3451                 :             :  ! that will be used to symmetrize the wavefunctions in G-space.
    3452                 :           5 :  call cwtime(cpu, wall, gflops, "start")
    3453                 :           5 :  call wrtout(std_out, " Computing mpw. This may take some time for dense k/q meshes...")
    3454                 :             :  !call fstab_get_mpw_gmax(nsppol, fstab, mpw, gmax, comm)
    3455                 :           5 :  mpw = 0; gmax = 0; cnt = 0
    3456                 :             : 
    3457                 :             :  ! FIXME: This is an hotspot due to the loop over nkfs.
    3458                 :             :  ! Should use a geometric approach to compute mpw gmax.
    3459         [ +  + ]:          10 :  do spin=1,nsppol
    3460                 :           5 :    fs => fstab(spin)
    3461         [ +  + ]:         700 :    do ik_bz=1,fs%nkfs
    3462         [ +  - ]:         690 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism inside comm
    3463         [ +  + ]:        2760 :      kk = fs%kpts(:, ik_bz)
    3464                 :             :      ! Compute G sphere, returning npw. Note istwfk == 1.
    3465         [ -  + ]:         690 :      call get_kg(kk, 1, ecut, cryst%gmet, onpw, gtmp)
    3466                 :         690 :      mpw = max(mpw, onpw)
    3467         [ +  + ]:       52350 :      do ipw=1,onpw
    3468         [ +  + ]:      207330 :        do ii=1,3
    3469                 :      206640 :         gmax(ii) = max(gmax(ii), abs(gtmp(ii,ipw)))
    3470                 :             :        end do
    3471                 :             :      end do
    3472         [ -  + ]:         690 :      ABI_FREE(gtmp)
    3473                 :             : 
    3474         [ +  + ]:        9113 :      do iq_ibz=1,gams%nqibz
    3475         [ +  + ]:       33672 :        qpt = gams%qibz(:,iq_ibz)
    3476                 :             :        ! TODO: g0 umklapp here can enter into play!
    3477                 :             :        ! fstab should contains the max of the umlapp G-vectors.
    3478                 :             :        ! gmax could not be large enough!
    3479         [ +  + ]:       33672 :        kq = kk + qpt
    3480         [ -  + ]:        8418 :        call get_kg(kq, 1, ecut, cryst%gmet, onpw, gtmp)
    3481                 :        8418 :        mpw = max(mpw, onpw)
    3482         [ +  + ]:      633595 :        do ipw=1,onpw
    3483         [ +  + ]:     2509126 :          do ii=1,3
    3484                 :     2500708 :           gmax(ii) = max(gmax(ii), abs(gtmp(ii,ipw)))
    3485                 :             :          end do
    3486                 :             :        end do
    3487         [ -  + ]:        9108 :        ABI_FREE(gtmp)
    3488                 :             :      end do
    3489                 :             : 
    3490                 :             :    end do ! ik_bz
    3491                 :             :  end do ! spin
    3492                 :             : 
    3493                 :           5 :  my_mpw = mpw; call xmpi_max(my_mpw, mpw, comm, ierr)
    3494                 :           5 :  my_gmax = gmax; call xmpi_max(my_gmax, gmax, comm, ierr)
    3495                 :           5 :  call wrtout(std_out, sjoin(' Optimal value of mpw: ', itoa(mpw)))
    3496                 :           5 :  call cwtime_report(" Computation of gmax and mpw:", cpu, wall, gflops)
    3497                 :             : 
    3498                 :             :  ! Init work_ngfft
    3499         [ +  + ]:          20 :  gmax = gmax + 4 ! FIXME: this is to account for umklapp
    3500         [ +  + ]:          20 :  gmax = 2*gmax + 1
    3501                 :           5 :  call ngfft_seq(work_ngfft, gmax)
    3502                 :             :  !write(std_out,*)"work_ngfft(1:3): ",work_ngfft(1:3)
    3503   [ -  +  +  -  :          25 :  ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6)))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    3504                 :             : 
    3505                 :             :  ! Allow PW-arrays dimensioned with mpw
    3506   [ -  +  +  -  :          15 :  ABI_MALLOC(kg_k, (3, mpw))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    3507   [ -  +  +  -  :          10 :  ABI_MALLOC(kg_kq, (3, mpw))
          -  +  -  +  -  
                      + ]
    3508                 :             : 
    3509                 :             :  ! TODO FOR PAW
    3510                 :           5 :  usecprj = 0
    3511   [ -  +  +  -  :          10 :  ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj))
          -  +  -  +  -  
                      + ]
    3512                 :             : 
    3513                 :             :  ! Prepare call to getgh1c
    3514                 :           5 :  usevnl = 0
    3515                 :           5 :  optlocal = 1    ! local part of H^(1) is computed in gh1c=<G|H^(1)|C>
    3516                 :           5 :  optnl = 2       ! non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
    3517                 :           5 :  opt_gvnlx1 = 0  ! gvnlx1 is output
    3518                 :             : 
    3519   [ -  +  -  + ]:           5 :  ABI_MALLOC(grad_berry, (2, nspinor*(berryopt0/4)))
    3520                 :             : 
    3521                 :             :  ! This part is taken from dfpt_vtorho
    3522                 :             :  !==== Initialize most of the Hamiltonian (and derivative) ====
    3523                 :             :  !1) Allocate all arrays and initialize quantities that do not depend on k and spin.
    3524                 :             :  !2) Perform the setup needed for the non-local factors:
    3525                 :             :  ! Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk.
    3526                 :             :  ! PAW: Initialize the overlap coefficients and allocate the Dij coefficients.
    3527                 :             : 
    3528                 :             :  call gs_hamkq%init(psps, pawtab, nspinor, nsppol, nspden, natom, &
    3529                 :             :    dtset%typat, cryst%xred, nfft, mgfft, ngfft, cryst%rprimd, dtset%nloalg, &
    3530                 :             :    comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab, mpi_spintab=mpi_enreg%my_isppoltab, &
    3531                 :           5 :    usecprj=usecprj, ph1d=ph1d, nucdipmom=dtset%nucdipmom, gpu_option=dtset%gpu_option)
    3532                 :             : 
    3533                 :             :  ! Allocate vlocal. Note nvloc
    3534                 :             :  ! I set vlocal to huge to trigger possible bugs (DFPT routines should not access the data)
    3535   [ -  +  +  -  :          30 :  ABI_MALLOC(vlocal, (n4, n5, n6, gs_hamkq%nvloc))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
    3536   [ +  +  +  +  :       10990 :  vlocal = huge(one)
             +  +  +  + ]
    3537                 :             : 
    3538                 :             :  ! Allocate work space arrays.
    3539   [ -  +  +  -  :          20 :  ABI_MALLOC(tgam, (2, natom3, natom3))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3540   [ -  +  +  -  :          20 :  ABI_MALLOC(displ_cart, (2, 3, cryst%natom, natom3))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    3541   [ -  +  +  -  :          15 :  ABI_MALLOC(displ_red, (2, 3, cryst%natom, natom3))
          -  +  +  -  -  
                +  -  + ]
    3542   [ -  +  +  -  :        8665 :  ABI_CALLOC(dummy_vtrial, (nfftf, nspden))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  +  +  +  
                      + ]
    3543                 :             : 
    3544                 :             :  ! TODO: Save data to netcdf file for each q in IBZ and then read data to build a2Fw once all big
    3545                 :             :  ! datastructures (wfd, dvdb) have been deallocated.
    3546                 :             :  ! As a side effect, one can also implement restart over q-points
    3547                 :             : 
    3548                 :             :  ! Create ddkop object to compute group velocities if needed.
    3549                 :             :  !
    3550                 :             :  !   1) precompute group velocities in the IBZ and the ihave_ikibz_spin file (common to all procs)
    3551                 :             :  !   2) Use symmetries to reconstruct v_kq from vcart_ibz
    3552                 :             :  !
    3553                 :             :  ! NB: All procs store in memory the same set of Bloch states inside the energy window.
    3554                 :             : 
    3555                 :           5 :  call ddkop%init(dtset, cryst, pawtab, psps, wfd%mpi_enreg, mpw, wfd%ngfft)
    3556                 :             : 
    3557                 :           5 :  call cwtime(cpu, wall, gflops, "start", msg=" Computing v_nk matrix elements for all states on the FS...")
    3558                 :           5 :  ii = huge(1); jj = -1
    3559         [ +  + ]:          10 :  do spin=1,nsppol
    3560                 :           5 :    ii = min(ii, fstab(spin)%bmin)
    3561                 :          10 :    jj = max(jj, fstab(spin)%bmax)
    3562                 :             :  end do
    3563   [ -  +  +  -  :        1335 :  ABI_CALLOC(vcart_ibz, (3, ii:jj, nkibz, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  -  +  +  +  
          +  +  +  +  +  
                      + ]
    3564   [ -  +  +  -  :          15 :  ABI_MALLOC(cg_work, (2, mpw * wfd%nspinor))
          +  -  +  -  -  
                +  -  + ]
    3565                 :             : 
    3566                 :           5 :  cnt = 0
    3567         [ +  + ]:          10 :  do spin=1,nsppol
    3568                 :           5 :    fs => fstab(spin)
    3569         [ +  + ]:         155 :    do ik_ibz=1,ebands%nkpt
    3570         [ +  + ]:         580 :      kk = ebands%kptns(:, ik_ibz); npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz)
    3571                 :             :      ! NB: The two checks below are global --> all procs will cycle.
    3572   [ +  +  +  +  :         760 :      if (all(bks_mask(:, ik_ibz, spin) .eqv. .False.)) cycle
                   +  + ]
    3573         [ -  + ]:          30 :      if (npw_k == 1) cycle
    3574         [ +  - ]:          30 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism.
    3575                 :             : 
    3576                 :          30 :      call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kk, istwf_k, npw_k, wfd%kdata(ik_ibz)%kg_k)
    3577                 :             : 
    3578         [ +  + ]:          95 :      do band_k=fs%bmin,fs%bmax
    3579         [ +  + ]:          60 :        if (.not. bks_mask(band_k, ik_ibz, spin)) cycle
    3580                 :          30 :        call wfd%copy_cg(band_k, ik_ibz, spin, cg_work)
    3581                 :          30 :        eig0nk = ebands%eig(band_k, ik_ibz, spin)
    3582                 :          30 :        vk = ddkop%get_vdiag(eig0nk, istwf_k, npw_k, wfd%nspinor, cg_work, cwaveprj0)
    3583         [ +  + ]:         265 :        vcart_ibz(:, band_k, ik_ibz, spin) = vk
    3584                 :             : 
    3585                 :             :        ! TODO: Use ebands_get_edos_matrix_elements
    3586                 :             :        ! reald(dp) :: vv_fs(3,3,nsppol)
    3587                 :             :        !vv_fs = zero
    3588                 :             :        !sigma = fs%eph_fsmear
    3589                 :             :        !if (fs%eph_fsmear < zero) then
    3590                 :             :        !  sigma = max(maxval([(abs(dot_product(fs%vk(:, ib2), fs%kmesh_cartvec(:,ii))), ii=1,3)]), fs%min_smear)
    3591                 :             :        !end if
    3592                 :             :        !fs_wtk = gaussian(emesh - ebands%eig(band_k, ik_ibz, spin), sigma) / (one * fs%nktot)
    3593                 :             :        !do ii=1,3
    3594                 :             :        !  do jj=1,3
    3595                 :             :        !    vv_fs(ii,jj,spin) = vv_fs(ii,jj,spin) + vk(ii) * vk(jj) * fs_wtk
    3596                 :             :        !  end do
    3597                 :             :        !end do
    3598                 :             :        !call xmpi_sum(vv_fs, comm, ierr)
    3599                 :             :      end do
    3600                 :             :    end do
    3601                 :             :  end do ! spin
    3602                 :             : 
    3603                 :           5 :  call xmpi_sum(vcart_ibz, comm, ierr)
    3604         [ -  + ]:           5 :  ABI_FREE(cg_work)
    3605                 :           5 :  call cwtime_report(" Computation of group velocities", cpu, wall, gflops)
    3606                 :             : 
    3607         [ -  + ]:           5 :  ABI_FREE(bks_mask)
    3608                 :             : 
    3609                 :             :  !Write v_nk to disk.
    3610                 :             :  !if (my_rank == master) then
    3611                 :             :  !  NCF_CHECK(nf90_put_var(sigma%ncid, nctk_idname(sigma%ncid, "vcart_ibz"), vcart_ibz))
    3612                 :             :  !end if
    3613                 :             : 
    3614         [ +  - ]:           5 :  if (dtset%eph_transport > 0) then
    3615   [ -  +  +  -  :          20 :    ABI_MALLOC(tgamvv_in, (2, 9, natom3, natom3))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3616   [ -  +  +  -  :          15 :    ABI_MALLOC(tgamvv_out, (2, 9, natom3, natom3))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    3617                 :             :  end if
    3618                 :             : 
    3619                 :             :  ! Build krank object to find k-points
    3620                 :           5 :  call krank%from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.)
    3621                 :           5 :  call pstat_proc%print(_PSTAT_ARGS_)
    3622                 :             : 
    3623                 :             :  ! Loop over my q-points in the IBZ.
    3624         [ +  + ]:          66 :  do my_iq=1,gams%my_nqibz
    3625                 :          61 :    iq_ibz = gams%my_iqibz(my_iq)
    3626                 :             : 
    3627                 :             :    ! TODO: Restart capabilities
    3628                 :             :    ! Check if this (kpoint, spin) was already calculated
    3629                 :             :    !if (all(qibz_done(iq_ibz, :) == 1)) cycle
    3630                 :             : 
    3631                 :          61 :    call cwtime(cpu_q, wall_q, gflops_q, "start")
    3632                 :             : 
    3633         [ +  + ]:         244 :    qpt = gams%qibz(:, iq_ibz)
    3634         [ +  - ]:          61 :    msg = sjoin("[", itoa(iq_ibz), "/", itoa(gams%nqibz), "]")
    3635                 :          61 :    call wrtout(std_out, sjoin(" Computing ph linewidths for IBZ q-point:", ktoa(qpt), msg))
    3636                 :             : 
    3637   [ +  +  +  +  :        1891 :    tgam = zero
                   +  + ]
    3638         [ +  - ]:          61 :    if (dtset%eph_transport > 0) then
    3639   [ +  +  +  +  :       31171 :      tgamvv_in = zero; tgamvv_out = zero
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
    3640                 :             :    end if
    3641                 :             : 
    3642         [ +  - ]:          61 :    if (.not. need_ftinterp) then
    3643                 :             :      ! No interpolation --> find the index of the q-point in the DVDB.
    3644                 :          61 :      db_iqpt = dvdb%findq(qpt)
    3645                 :             : 
    3646         [ +  - ]:          61 :      if (db_iqpt /= -1) then
    3647                 :             :        ! Read and reconstruct the dvscf potentials for all 3*natom perturbations.
    3648                 :             :        ! This call allocates v1scf(cplex, nfftf, nspden, 3*natom))
    3649         [ -  + ]:          61 :        call dvdb%readsym_allv1(db_iqpt, cplex, nfftf, ngfftf, v1scf, pkb_comm%value)
    3650                 :             : 
    3651         [ -  + ]:          61 :        if (dvdb%my_npert /= natom3) then
    3652                 :             :          ! Extract my npert from v1scf
    3653   [ #  #  #  #  :           0 :          ABI_MALLOC(v1_work, (cplex, nfftf, nspden, dvdb%my_npert))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    3654         [ #  # ]:           0 :          do my_ip=1,dvdb%my_npert
    3655   [ #  #  #  #  :           0 :            v1_work(:,:,:,my_ip) = v1scf(:,:,:,dvdb%my_pinfo(3, my_ip))
                   #  # ]
    3656                 :             :          end do
    3657         [ #  # ]:           0 :          ABI_MOVE_ALLOC(v1_work, v1scf)
    3658                 :             :        end if
    3659                 :             : 
    3660                 :             :      else
    3661                 :           0 :        ABI_ERROR(sjoin("Cannot find q-point:", ktoa(qpt), "in the DVDB file."))
    3662                 :             :      end if
    3663                 :             : 
    3664                 :             :    else
    3665                 :             :      ! Use Fourier interpolation of DFPT potentials to get my_npert potentials.
    3666                 :           0 :      cplex = 2
    3667   [ #  #  #  #  :           0 :      ABI_MALLOC(v1scf, (cplex, nfft, nspden, dvdb%my_npert))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    3668                 :           0 :      call dvdb%ftinterp_qpt(qpt, nfftf, ngfftf, v1scf, dvdb%comm_rpt)
    3669                 :             :    end if
    3670                 :             : 
    3671                 :             :    ! Compute the little group of the q-point so that we can compute g(k,q) only for k in the IBZ_q
    3672                 :             :    !if (dtset%symsigma /= 0) then
    3673                 :             :    !  timrev_q = kpts_timrev_from_kptopt(my_qptopt)
    3674                 :             :    !  call lg_q%init(cryst, qpt, timrev_q, gstore%nkbz, gstore%kbz, gstore%nkibz, gstore%kibz, xmpi_comm_self)
    3675                 :             :    !end if
    3676                 :             : 
    3677                 :             :    !if (dtset%symsigma /= 0) then
    3678                 :             :    !  ii = lg_q%findq_ibzk(kk)
    3679                 :             :    !  if (ii == -1) then
    3680                 :             :    !    call wrtout(std_out, sjoin(" my_ik:", itoa(my_ik), kk_string, " not in IBZ_q --> skipping iteration"))
    3681                 :             :    !    cycle
    3682                 :             :    !    ! TODO: Check fillvalue (should be zero)
    3683                 :             :    !  end if
    3684                 :             :    !  weight_k = lg_q%weights(ii)
    3685                 :             :    !end if
    3686                 :             :    !call lg_q%free()
    3687                 :             : 
    3688                 :             :    ! Get phonon frequencies and eigenvectors for this q-point.
    3689                 :          61 :    call ifc%fourq(cryst, qpt, phfrq, displ_cart, out_displ_red=displ_red)
    3690                 :          61 :    wminmax(1) = min(wminmax(1), phfrq(1))
    3691                 :          61 :    wminmax(2) = max(wminmax(2), phfrq(3*cryst%natom))
    3692                 :             : 
    3693                 :             :    ! Allocate vlocal1 with correct cplex. Note nvloc and my_npert.
    3694   [ -  +  +  -  :         427 :    ABI_MALLOC(vlocal1, (cplex*n4, n5, n6, gs_hamkq%nvloc, my_npert))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
          -  +  -  +  -  
             -  +  -  + ]
    3695                 :             : 
    3696                 :             :    ! Loop over my spins.
    3697         [ +  + ]:         122 :    do my_is=1,gams%my_nspins
    3698                 :          61 :      spin = gams%my_spins(my_is); fs => fstab(spin)
    3699                 :             : 
    3700         [ -  + ]:          61 :      if (dtset%prteliash == 3) then
    3701   [ #  #  #  #  :           0 :        ABI_CALLOC_OR_DIE(tmp_vals_ee, (2, gams%nene, gams%nene, natom3, natom3), ierr)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    3702                 :             :        ! Energy mesh for electrons in a2F(e,e',w) NB: It depends on the spin through enemin
    3703   [ #  #  #  #  :           0 :        ABI_MALLOC(emesh, (gams%nene))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    3704         [ #  # ]:           0 :        emesh = arth(fs%enemin, fs%deltaene, gams%nene)
    3705                 :             :      end if
    3706                 :             : 
    3707                 :             :      ! Set up local potential vlocal1 with proper dimensioning from vtrial1 taking into account the spin.
    3708         [ +  + ]:         244 :      do my_ip=1,my_npert
    3709                 :             :        call rf_transgrid_and_pack(spin, nspden, psps%usepaw, cplex, nfftf, nfft, ngfft, gs_hamkq%nvloc,&
    3710                 :         244 :                                   pawfgr, mpi_enreg, dummy_vtrial, v1scf(:,:,:,my_ip), vlocal, vlocal1(:,:,:,:,my_ip))
    3711                 :             :      end do
    3712                 :             : 
    3713                 :             :      ! Continue to initialize the GS Hamiltonian
    3714                 :          61 :      call gs_hamkq%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.)
    3715                 :             : 
    3716                 :             :      ! Allocate workspace for wavefunctions. Make npw larger than expected.
    3717                 :             :      ! maxnb is the maximum number of bands crossing the FS, used to dimension arrays.
    3718                 :          61 :      mnb = fs%maxnb
    3719                 :             :      ! The weights for the integration of the double-delta.
    3720   [ -  +  +  -  :         244 :      ABI_MALLOC(dbldelta_wts, (mnb, mnb))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3721                 :             : 
    3722         [ +  - ]:          61 :      if (dtset%eph_transport > 0) then
    3723   [ -  +  +  -  :         244 :        ABI_MALLOC(vv_kk, (9, mnb, mnb))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3724   [ -  +  +  -  :         183 :        ABI_MALLOC(vv_kkq, (9, mnb, mnb))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    3725                 :             :      end if
    3726                 :             : 
    3727         [ -  + ]:          61 :      if (dtset%prteliash == 3) then
    3728   [ #  #  #  #  :           0 :        ABI_MALLOC(wt_ek, (gams%nene, mnb))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    3729   [ #  #  #  #  :           0 :        ABI_MALLOC(wt_ekq, (gams%nene, mnb))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    3730                 :             :      end if
    3731                 :             : 
    3732                 :             :      ! =====================================
    3733                 :             :      ! Integration over the FS for this spin
    3734                 :             :      ! =====================================
    3735                 :             :      ! Compute integration weights and distribute k-points (gams%my_nfsk_q) inside kpt_comm
    3736                 :          61 :      call phgamma_setup_qpoint(gams, fs, cryst, ebands, spin, ltetra, qpt, nesting, kpt_comm%value)
    3737                 :             : 
    3738         [ +  + ]:        6265 :      do my_ik=1,gams%my_nfsk_q
    3739   [ +  +  +  -  :        6204 :        print_time_k = (my_ik <= 2 .or. (fs%nkfs > 100 .and. mod(my_ik, 200) == 0))
                   -  + ]
    3740                 :         122 :        if (print_time_k) call cwtime(cpu_k, wall_k, gflops_k, "start")
    3741                 :             : 
    3742                 :             :        ! The k-point and the symmetries relating the BZ k-point to the IBZ.
    3743                 :        6204 :        ik_fs = gams%my_ifsk_q(my_ik)
    3744         [ +  + ]:       24816 :        kk = fs%kpts(:, ik_fs)
    3745                 :        6204 :        ik_ibz = fs%indkk_fs(1, ik_fs); isym_k = fs%indkk_fs(2, ik_fs)
    3746         [ +  + ]:       24816 :        trev_k = fs%indkk_fs(6, ik_fs); g0_k = fs%indkk_fs(3:5,ik_fs)
    3747   [ +  +  +  +  :       19906 :        isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
             +  +  -  + ]
    3748         [ +  + ]:       24816 :        kk_ibz = ebands%kptns(:,ik_ibz)
    3749                 :             : 
    3750                 :             :        ! Number of bands crossing the Fermi level at k.
    3751                 :        6204 :        bstart_k = fs%bstart_cnt_ibz(1, ik_ibz); nb_k = fs%bstart_cnt_ibz(2, ik_ibz)
    3752                 :             : 
    3753                 :             :        ! Find k+q in the extended zone and extract symmetry info. cycle if k+q not in FS.
    3754                 :             :        ! Be careful here because there are two umklapp vectors to be considered:
    3755                 :             :        !
    3756                 :             :        !   k + q = k_bz + g0_bz = IS(k_ibz) + g0_ibz + g0_bz
    3757                 :             :        !
    3758         [ +  + ]:       24816 :        kq = kk + qpt; ikq_bz = fs%findkg0(kq, g0bz_kq)
    3759                 :             : 
    3760                 :             :        ! Skip this point if kq does not belong to the FS window.
    3761         [ +  + ]:        6204 :        if (ikq_bz == -1) cycle
    3762                 :             : 
    3763         [ -  + ]:        2864 :        if (kpts_map("symrel", ebands%kptopt, cryst, krank, 1, kq, indkk_kq) /= 0) then
    3764                 :             :          write(msg, '(9a)' ) &
    3765                 :           0 :           "The WFK file cannot be used to compute phonon linewidths.",ch10, &
    3766                 :           0 :           "At least one of the k-points on the FS could not be generated from a symmetrical one.", ch10, &
    3767   [ #  #  #  # ]:           0 :           "q-mesh: ", trim(ltoa(gamma_ngqpt)), ", k-mesh (from kptrlatt) ", trim(ltoa(get_diag(ebands%kptrlatt))), &
    3768                 :           0 :           'Action: check your WFK file and the (k, q) point input variables.'
    3769                 :           0 :           ABI_ERROR(msg)
    3770                 :             :        end if
    3771                 :             : 
    3772                 :             :        ! The k+q point and the symmetries relating it to the IBZ.
    3773                 :        2864 :        ikq_ibz = indkk_kq(1, 1); isym_kq = indkk_kq(2, 1)
    3774         [ +  + ]:       11456 :        trev_kq = indkk_kq(6, 1); g0_kq = indkk_kq(3:5, 1)
    3775   [ +  +  +  +  :        6934 :        isirr_kq = (isym_kq == 1 .and. trev_kq == 0 .and. all(g0_kq == 0))
             +  +  +  + ]
    3776         [ +  + ]:       11456 :        kq_ibz = ebands%kptns(:, ikq_ibz)
    3777                 :             : 
    3778                 :             :        ! If we have used the KERANGE trick, we may have k or k+q points with just one G component set to zero
    3779                 :             :        ! so we skip this transition immediately. This should happen only if fsewin > sigma_erange.
    3780   [ +  -  +  - ]:        2864 :        if (wfd%npwarr(ik_ibz) == 1 .or. wfd%npwarr(ikq_ibz) == 1) cycle
    3781                 :             : 
    3782                 :             :        ! Number of bands crossing the Fermi level at k+q.
    3783                 :        2864 :        bstart_kq = fs%bstart_cnt_ibz(1, ikq_ibz); nb_kq = fs%bstart_cnt_ibz(2, ikq_ibz)
    3784         [ -  + ]:        2864 :        ABI_CHECK(nb_k <= mnb .and. nb_kq <= mnb, "wrong nband")
    3785                 :             : 
    3786                 :             :        ! Get npw_k, kg_k and symmetrize wavefunctions from IBZ (if needed).
    3787                 :             :        call wfd%sym_ug_kg_npw(ecut, kk, kk_ibz, bstart_k, nb_k, spin, fs%indkk_fs(:,ik_fs), cryst, &
    3788         [ -  + ]:        2864 :                               work_ngfft, work, istwf_k, npw_k, kg_k, kets_k)
    3789                 :             : 
    3790                 :             :        ! Get npw_kq, kg_kq and symmetrize wavefunctions from IBZ (if needed).
    3791                 :             :        call wfd%sym_ug_kg_npw(ecut, kq, kq_ibz, bstart_kq, nb_kq, spin, indkk_kq(:,1), cryst, &
    3792         [ -  + ]:        2864 :                               work_ngfft, work, istwf_kq, npw_kq, kg_kq, bras_kq)
    3793                 :             : 
    3794                 :             :        call gs_hamkq%eph_setup_k("k" , kk, istwf_k, npw_k, kg_k, dtset, cryst, psps, &       ! in
    3795   [ -  +  -  +  :        2864 :                                  nkpg, kpg_k, ffnl_k, kinpw_k, ph3d_k, pert_comm%value)      ! out
             -  +  -  + ]
    3796                 :             : 
    3797                 :             :        call gs_hamkq%eph_setup_k("kq", kq, istwf_k, npw_kq, kg_kq, dtset, cryst, psps, &     ! in
    3798   [ -  +  -  +  :        2864 :                                  nkpg, kpg_kq, ffnl_kq, kinpw_kq, ph3d_kq, pert_comm%value)  ! out
             -  +  -  + ]
    3799                 :             : 
    3800                 :             :        ! If PAW, one has to solve a generalized eigenproblem
    3801         [ -  + ]:        2864 :        gen_eigenpb = psps%usepaw == 1; sij_opt = 0; if (gen_eigenpb) sij_opt = 1
    3802                 :             : 
    3803   [ -  +  +  -  :        8592 :        ABI_MALLOC(lambda, (nb_k))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    3804   [ -  +  +  -  :       14320 :        ABI_MALLOC(gkq_atm, (2, nb_kq, nb_k, natom3))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
    3805   [ -  +  +  -  :       11456 :        ABI_MALLOC(h1_kets_kq, (2, npw_kq*nspinor, nb_k))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3806   [ -  +  +  -  :        8592 :        ABI_MALLOC(gvnlx1, (2, npw_kq*nspinor, nb_k))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    3807   [ +  -  -  -  :        8592 :        ABI_MALLOC(gs1c_kq, (2, npw_kq*nspinor*nb_k*((sij_opt+1)/2)))
          +  -  -  +  -  
             +  -  +  -  
                      + ]
    3808   [ -  +  +  -  :       11456 :        ABI_MALLOC(gkq_atm_ipc, (2, nb_kq, nb_k))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3809                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    3810                 :             :       !$OMP TARGET ENTER DATA MAP(alloc:gkq_atm_ipc) IF (dtset%gpu_option == ABI_GPU_OPENMP)
    3811                 :             :       !$OMP TARGET ENTER DATA MAP(to:kets_k, bras_kq) IF (dtset%gpu_option == ABI_GPU_OPENMP)
    3812                 :             :       !$OMP TARGET ENTER DATA MAP(alloc:h1_kets_kq, gvnlx1, kets_k, bras_kq) IF (dtset%gpu_option == ABI_GPU_OPENMP)
    3813                 :             :       !$OMP TARGET ENTER DATA MAP(alloc:gs1c_kq) IF (dtset%gpu_option == ABI_GPU_OPENMP .and. sij_opt /= 0)
    3814                 :             : #endif
    3815                 :             : 
    3816                 :             :        ! Loop over all my atomic perturbations and compute gkq_atm.
    3817         [ +  + ]:       11456 :        do my_ip=1,my_npert
    3818                 :        8592 :          idir = dvdb%my_pinfo(1, my_ip); ipert = dvdb%my_pinfo(2, my_ip); ipc = dvdb%my_pinfo(3, my_ip)
    3819                 :             : 
    3820                 :             :          ! Prepare application of the NL part.
    3821                 :        8592 :          call rf_hamkq%init(cplex, gs_hamkq, ipert, has_e1kbsc=.true.)
    3822                 :        8592 :          call rf_hamkq%load_spin(spin, vlocal1=vlocal1(:,:,:,:,my_ip), with_nonlocal=.true.)
    3823                 :             : 
    3824                 :             : #if 1
    3825                 :             :          ! Calculate dvscf * psi_k, results stored in h1_kets_kq on the k+q sphere.
    3826                 :             :          ! Compute H(1) applied to GS wavefunction Psi(0)
    3827         [ +  + ]:       17184 :          do in_k=1,nb_k
    3828                 :             :            ! Use scissor shift on 0-order eigenvalue
    3829                 :        8592 :            band_k = in_k + bstart_k - 1
    3830                 :       17184 :            lambda(in_k) = ebands%eig(band_k, ik_ibz, spin) - dtset%dfpt_sciss
    3831                 :             :          end do
    3832                 :             :          !call ebands%get_dfpt_eshifted(gqk%bstart_k, nb_k, ik_ibz, spin, dtset%dfpt_sciss, lambda)
    3833                 :             : 
    3834                 :             :          call getgh1c(berryopt0, kets_k, cwaveprj0, h1_kets_kq, &
    3835                 :             :                       grad_berry, gs1c_kq, gs_hamkq, gvnlx1, idir, ipert, lambda, mpi_enreg, nb_k, optlocal, &
    3836                 :        8592 :                       optnl, opt_gvnlx1, rf_hamkq, sij_opt, tim_getgh1c, usevnl)
    3837                 :             : 
    3838                 :             : #else
    3839                 :             :          do in_k=1,nb_k
    3840                 :             :            ! Use scissor shift on 0-order eigenvalue
    3841                 :             :            band_k = in_k + bstart_k - 1
    3842                 :             :            eshift = ebands%eig(band_k, ik_ibz, spin) - dtset%dfpt_sciss
    3843                 :             : 
    3844                 :             :            call getgh1c(berryopt0, kets_k(:,:,in_k), cwaveprj0, h1_kets_kq(:,:,in_k), &
    3845                 :             :                         grad_berry, gs1c_kq, gs_hamkq, gvnlx1, idir, ipert, [eshift], mpi_enreg, ndat1, optlocal, &
    3846                 :             :                         optnl, opt_gvnlx1, rf_hamkq, sij_opt, tim_getgh1c, usevnl)
    3847                 :             :          end do ! in_k
    3848                 :             : #endif
    3849                 :             : 
    3850                 :        8592 :          call rf_hamkq%free()
    3851                 :             : 
    3852                 :             :          ! Calculate <psi_{k+q,m}|dvscf_q|psi_{k,n}> for this perturbation.
    3853                 :             :          ! No need to handle istwf_kq because it's always 1.
    3854         [ -  + ]:        8592 :          if (dtset%gpu_option == ABI_GPU_OPENMP) then
    3855                 :             :            call abi_gpu_xgemm_d(2, 'C', 'N', nb_kq, nb_k, npw_kq*nspinor, cone, bras_kq, npw_kq*nspinor, &
    3856                 :           0 :                                h1_kets_kq, npw_kq*nspinor, czero, gkq_atm_ipc, nb_kq)
    3857                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    3858                 :             :            !$OMP TARGET UPDATE FROM(gkq_atm_ipc)
    3859                 :             : #endif
    3860                 :             : 
    3861                 :             :          else
    3862                 :             :            call ZGEMM('C', 'N', nb_kq, nb_k, npw_kq*nspinor, cone, bras_kq, npw_kq*nspinor, &
    3863                 :        8592 :                       h1_kets_kq, npw_kq*nspinor, czero, gkq_atm_ipc, nb_kq)
    3864                 :             :          end if
    3865                 :             : 
    3866                 :             :          ! Transfer data
    3867   [ +  +  +  +  :       45824 :          gkq_atm(:,:,:,ipc) = gkq_atm_ipc
                   +  + ]
    3868                 :             :        end do ! my_ip (loop over my_npert atomic perturbations)
    3869                 :             : 
    3870                 :             :        ! Collect gkq_atm inside pert_comm so that all procs can operate on the data.
    3871         [ -  + ]:        2864 :        if (pert_comm%nproc > 1) call xmpi_sum(gkq_atm, pert_comm%value, ierr)
    3872                 :             : 
    3873         [ -  + ]:        2864 :        ABI_FREE(ffnl_k)
    3874         [ -  + ]:        2864 :        ABI_FREE(ffnl_kq)
    3875         [ -  + ]:        2864 :        ABI_FREE(kpg_kq)
    3876         [ -  + ]:        2864 :        ABI_FREE(kpg_k)
    3877         [ -  + ]:        2864 :        ABI_FREE(kinpw_k)
    3878         [ -  + ]:        2864 :        ABI_FREE(kinpw_kq)
    3879         [ -  + ]:        2864 :        ABI_FREE(ph3d_k)
    3880         [ -  + ]:        2864 :        ABI_FREE(ph3d_kq)
    3881                 :             : 
    3882                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    3883                 :             :        !$OMP TARGET EXIT DATA MAP(delete:h1_kets_kq, gvnlx1, kets_k, bras_kq) IF (dtset%gpu_option == ABI_GPU_OPENMP)
    3884                 :             :        !$OMP TARGET EXIT DATA MAP(delete:gs1c_kq) IF (dtset%gpu_option == ABI_GPU_OPENMP .and. sij_opt /= 0)
    3885                 :             : #endif
    3886         [ -  + ]:        2864 :        ABI_FREE(kets_k)
    3887         [ -  + ]:        2864 :        ABI_FREE(bras_kq)
    3888         [ -  + ]:        2864 :        ABI_FREE(h1_kets_kq)
    3889         [ -  + ]:        2864 :        ABI_FREE(gs1c_kq)
    3890         [ -  + ]:        2864 :        ABI_FREE(gvnlx1)
    3891                 :             : 
    3892                 :             :        ! Compute group velocities if we are in transport mode or adaptive gaussian or
    3893                 :             :        ! tetrahedron with libtetrabz returning nesting condition.
    3894   [ -  +  -  -  :        2864 :        need_velocities = dtset%eph_transport > 0 .or. fs%eph_fsmear < zero .or. nesting /= 0
                   -  - ]
    3895                 :             : 
    3896                 :             :        if (need_velocities) then
    3897                 :             :          ! Compute diagonal matrix elements of velocity operator with DFPT routines
    3898                 :             :          ! Velocities are in Cartesian coordinates.
    3899                 :             :          !
    3900                 :             :          ! If k+q is not in the IBZ, we need to recostruct the value by symmetry using v(Sq) = S v(q).
    3901                 :             :          ! Use transpose(R) because we are using the tables for the wavefunctions
    3902                 :             :          ! In this case listkk has been called with symrec and use_symrec=False
    3903                 :             :          ! so q_bz = S^T q_ibz where S is the isym_kq symmetry
    3904                 :             : 
    3905                 :             :          !call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kk, istwf_k, npw_k, kg_k)
    3906         [ +  + ]:        5728 :          do in_k=1,nb_k
    3907                 :        2864 :            band_k = in_k + bstart_k - 1
    3908         [ +  + ]:       11456 :            vk = vcart_ibz(:, band_k, ik_ibz, spin)
    3909         [ +  + ]:        2864 :            if (.not. isirr_k) then
    3910                 :        2754 :              vk = matmul(transpose(cryst%symrel_cart(:,:,isym_k)), vk)
    3911   [ -  +  -  - ]:        2754 :              if (trev_k /= 0) vk = -vk
    3912                 :             :            end if
    3913                 :             :            !vk = ddkop%get_vdiag(ebands%eig(band_k, ik_ibz, spin), &
    3914                 :             :            !                     istwf_k, npw_k, wfd%nspinor, kets_k(:,:,in_k), cwaveprj0)
    3915         [ +  + ]:       14320 :            fs%vk(:,in_k) = vk
    3916                 :             :          end do
    3917                 :             : 
    3918                 :             :          !call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kq, istwf_kq, npw_kq, kg_kq)
    3919         [ +  + ]:        5728 :          do im_kq=1,nb_kq
    3920                 :        2864 :            band_kq = im_kq + bstart_kq - 1
    3921         [ +  + ]:       11456 :            vkq = vcart_ibz(:, band_kq, ikq_ibz, spin)
    3922         [ +  + ]:        2864 :            if (.not. isirr_kq) then
    3923                 :        2833 :              vkq = matmul(transpose(cryst%symrel_cart(:,:,isym_kq)), vkq)
    3924   [ -  +  -  - ]:        2833 :              if (trev_kq /= 0) vkq = -vkq
    3925                 :             :            end if
    3926                 :             :            !vkq = ddkop%get_vdiag(ebands%eig(band_kq, ikq_ibz, spin), &
    3927                 :             :            !                                 istwf_kq, npw_kq, wfd%nspinor, bras_kq(:,:,im_kq), cwaveprj0)
    3928         [ +  + ]:       14320 :            fs%vkq(:,im_kq) = vkq
    3929                 :             :          end do
    3930                 :             :        end if
    3931                 :             : 
    3932                 :             :        ! Compute weights for double delta integration at the Fermi level.
    3933                 :             :        ! Note that we have to call the routine here after the initialization of fs%vk and fs%vkq
    3934                 :             :        ! TODO: Could precompute weights before entering the loop, apply filter and compute MPI-distribution
    3935                 :        2864 :        call fs%get_dbldelta_weights(ebands, ik_fs, ik_ibz, ikq_ibz, spin, nesting, dbldelta_wts)
    3936                 :             :        ! Multiply by the weight of the q-point if we are summing over the IBZ(q).
    3937                 :             :        !dbldelta_wts = dbldelta_wts * wtk_lgq
    3938                 :             : 
    3939                 :             :        ! Accumulate results in tgam (sum over FS k-points and bands for this spin).
    3940         [ +  + ]:       11456 :        do ipc2=1,natom3
    3941         [ +  + ]:       37232 :          do ipc1=1,natom3
    3942         [ +  + ]:       60144 :            do in_k=1,nb_k
    3943         [ +  + ]:       77328 :              do im_kq=1,nb_kq
    3944         [ +  + ]:       77328 :                lf = gkq_atm(:, im_kq, in_k, ipc1)
    3945         [ +  + ]:       77328 :                rg = gkq_atm(:, im_kq, in_k, ipc2)
    3946                 :       25776 :                res(1) = lf(1) * rg(1) + lf(2) * rg(2)
    3947                 :       25776 :                res(2) = lf(1) * rg(2) - lf(2) * rg(1)
    3948         [ +  + ]:      103104 :                tgam(:,ipc1,ipc2) = tgam(:,ipc1,ipc2) + res(:) * dbldelta_wts(im_kq, in_k)
    3949                 :             :              end do
    3950                 :             :            end do
    3951                 :             :          end do
    3952                 :             :        end do
    3953                 :             : 
    3954         [ +  - ]:        2864 :        if (dtset%eph_transport > 0) then
    3955                 :             :          ! TODO: could almost make this a BLAS call plus a reshape...
    3956         [ +  + ]:        5728 :          do in_k = 1,nb_k
    3957         [ +  + ]:        8592 :            do im_kq = 1,nb_kq
    3958         [ +  + ]:       14320 :              do ipc2 = 1,3
    3959         [ +  + ]:       37232 :                do ipc1 = 1,3
    3960                 :             :                  ! vk x vk
    3961                 :       25776 :                  vv_kk(ipc1 + (ipc2-1)*3, im_kq, in_k) = fs%vk(ipc1, im_kq) * fs%vk(ipc2, in_k)
    3962                 :             :                  ! vk x vk+q
    3963                 :       34368 :                  vv_kkq(ipc1 + (ipc2-1)*3, im_kq, in_k) = fs%vkq(ipc1, im_kq) * fs%vk(ipc2, in_k)
    3964                 :             :                end do
    3965                 :             :              end do
    3966                 :             :            end do
    3967                 :             :          end do
    3968                 :             : 
    3969                 :             :          ! Accumulate results (sum over FS and bands).
    3970         [ +  + ]:       11456 :          do ipc2=1,natom3
    3971         [ +  + ]:       37232 :            do ipc1=1,natom3
    3972         [ +  + ]:       60144 :               do in_k=1,nb_k
    3973         [ +  + ]:       77328 :                 do im_kq=1,nb_kq
    3974         [ +  + ]:       77328 :                   lf = gkq_atm(:, im_kq, in_k, ipc1)
    3975         [ +  + ]:       77328 :                   rg = gkq_atm(:, im_kq, in_k, ipc2)
    3976                 :             :                   ! res was missing in MJV version!
    3977                 :       25776 :                   res(1) = lf(1) * rg(1) + lf(2) * rg(2)
    3978                 :       25776 :                   res(2) = lf(1) * rg(2) - lf(2) * rg(1)
    3979         [ +  + ]:      257760 :                   resvv_in(1,:) = res(1) * vv_kkq(:,im_kq, in_k)
    3980         [ +  + ]:      257760 :                   resvv_in(2,:) = res(2) * vv_kkq(:,im_kq, in_k)
    3981         [ +  + ]:      257760 :                   resvv_out(1,:) = res(1) * vv_kk(:,im_kq, in_k)
    3982         [ +  + ]:      257760 :                   resvv_out(2,:) = res(2) * vv_kk(:,im_kq, in_k)
    3983   [ +  +  +  + ]:      721728 :                   tgamvv_in(:,:,ipc1, ipc2)  = tgamvv_in(:,:,ipc1,ipc2) + resvv_in * dbldelta_wts(im_kq, in_k)
    3984   [ +  +  +  + ]:      747504 :                   tgamvv_out(:,:,ipc1, ipc2) = tgamvv_out(:,:,ipc1,ipc2) + resvv_out * dbldelta_wts(im_kq, in_k)
    3985                 :             :                 end do
    3986                 :             :               end do
    3987                 :             :            end do
    3988                 :             :          end do
    3989                 :             :        end if ! add transport things
    3990                 :             : 
    3991         [ -  + ]:        2864 :        if (dtset%prteliash == 3) then
    3992                 :             :          ! Precompute deltas with gaussian (tetra is not supported here
    3993                 :             :          ! also because one should allocate (nene, nene, mband, mband)
    3994                 :             :          !call get_dbldelta_weights_emesh()
    3995         [ #  # ]:           0 :          do in_k=1,nb_k
    3996                 :           0 :            band_k = in_k + bstart_k - 1
    3997                 :           0 :            sigma = fs%eph_fsmear
    3998         [ #  # ]:           0 :            if (fs%eph_fsmear < zero) then
    3999         [ #  # ]:           0 :              do ii=1,3
    4000         [ #  # ]:           0 :                abc(ii) = abs(dot_product(fs%vk(:, in_k), fs%kmesh_cartvec(:,ii)))
    4001                 :             :              end do
    4002   [ #  #  #  #  :           0 :              sigma = max(maxval(abc), fs%min_smear)
                   #  # ]
    4003                 :             :            end if
    4004         [ #  # ]:           0 :            wt_ek(:, in_k) = gaussian(emesh - ebands%eig(band_k, ik_ibz, spin), sigma) / sqrt(one * fs%nktot)
    4005                 :             :          end do
    4006                 :             : 
    4007         [ #  # ]:           0 :          do im_kq=1,nb_kq
    4008                 :           0 :            band_kq = im_kq + bstart_kq - 1
    4009                 :           0 :            sigma = fs%eph_fsmear
    4010         [ #  # ]:           0 :            if (fs%eph_fsmear < zero) then
    4011         [ #  # ]:           0 :              do ii=1,3
    4012         [ #  # ]:           0 :                abc(ii) = abs(dot_product(fs%vkq(:, im_kq), fs%kmesh_cartvec(:,ii)))
    4013                 :             :              end do
    4014   [ #  #  #  #  :           0 :              sigma = max(maxval(abc), fs%min_smear)
                   #  # ]
    4015                 :             :            end if
    4016         [ #  # ]:           0 :            wt_ekq(:, im_kq) = gaussian(emesh - ebands%eig(band_kq, ikq_ibz, spin), sigma) / sqrt(one * fs%nktot)
    4017                 :             :          end do
    4018                 :             : 
    4019         [ #  # ]:           0 :          do in_k=1,nb_k
    4020         [ #  # ]:           0 :            do im_kq=1,nb_kq
    4021         [ #  # ]:           0 :              do ipc2=1,natom3
    4022         [ #  # ]:           0 :                do ipc1=1,natom3
    4023         [ #  # ]:           0 :                  lf = gkq_atm(:, im_kq, in_k, ipc1)
    4024         [ #  # ]:           0 :                  rg = gkq_atm(:, im_kq, in_k, ipc2)
    4025                 :           0 :                  res(1) = lf(1) * rg(1) + lf(2) * rg(2)
    4026                 :           0 :                  res(2) = lf(1) * rg(2) - lf(2) * rg(1)
    4027         [ #  # ]:           0 :                  do jene = 1, gams%nene
    4028         [ #  # ]:           0 :                    do iene = 1, gams%nene
    4029                 :             :                      ! TODO: distribute this in procs over q. Make a temp array here for 1 q
    4030                 :             :                      ! then mpi sync it and save it only on 1 processor below after mpisum over k
    4031                 :             :                      tmp_vals_ee(:,iene,jene,ipc1,ipc2) = tmp_vals_ee(:,iene,jene,ipc1,ipc2) + &
    4032         [ #  # ]:           0 :                        res(:) * wt_ekq(iene, im_kq) * wt_ek(jene, in_k)
    4033                 :             :                    end do
    4034                 :             :                  end do
    4035                 :             :                end do
    4036                 :             :              end do
    4037                 :             :            end do
    4038                 :             :          end do
    4039                 :             :        end if ! prteliash == 3
    4040                 :             : 
    4041         [ -  + ]:        2864 :        ABI_FREE(lambda)
    4042         [ -  + ]:        2864 :        ABI_FREE(gkq_atm)
    4043                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    4044                 :             :        !$OMP TARGET EXIT DATA MAP(delete:gkq_atm_ipc) IF (dtset%gpu_option == ABI_GPU_OPENMP)
    4045                 :             : #endif
    4046         [ -  + ]:        2864 :        ABI_FREE(gkq_atm_ipc)
    4047                 :             : 
    4048         [ +  + ]:        2925 :        if (print_time_k) then
    4049                 :          66 :          write(msg,'(5x,2(a,i0),a)')"k-point [", my_ik, "/", gams%my_nfsk_q, "]"
    4050                 :          66 :          call cwtime_report(msg, cpu_k, wall_k, gflops_k)
    4051                 :             :        end if
    4052                 :             :      end do ! imyk: sum over k-points on the BZ FS for this spin.
    4053                 :             : 
    4054         [ -  + ]:          61 :      ABI_FREE(dbldelta_wts)
    4055         [ -  + ]:          61 :      ABI_SFREE(wt_ek)
    4056         [ -  + ]:          61 :      ABI_SFREE(wt_ekq)
    4057                 :             : 
    4058                 :             :      ! Collect tgam values inside kpt comm and divide by the total number of k-points in the full mesh.
    4059                 :          61 :      call xmpi_sum(tgam, kpt_comm%value, ierr)
    4060                 :             : 
    4061                 :             :      ! Symmetrize gamma matrices (default). Note that this call is not executed in elphon!
    4062         [ +  - ]:          61 :      if (gams%symgamma == 1) call tgamma_symm(cryst, gams%qibz(:,iq_ibz), tgam)
    4063                 :             : 
    4064                 :             :      ! Save results in gams.
    4065   [ +  +  +  +  :        1891 :      gams%vals_qibz(:,:,:,iq_ibz, spin) = tgam
                   +  + ]
    4066                 :             : 
    4067         [ +  - ]:          61 :      if (dtset%eph_transport > 0) then
    4068         [ -  + ]:          61 :        ABI_FREE(vv_kk)
    4069         [ -  + ]:          61 :        ABI_FREE(vv_kkq)
    4070                 :          61 :        call xmpi_sum(tgamvv_in, kpt_comm%value, ierr)
    4071                 :          61 :        call xmpi_sum(tgamvv_out, kpt_comm%value, ierr)
    4072   [ +  +  +  +  :       15616 :        gams%vals_in_qibz(:,:,:,:,iq_ibz,spin)  = tgamvv_in
             +  +  +  + ]
    4073   [ +  +  +  +  :       15616 :        gams%vals_out_qibz(:,:,:,:,iq_ibz,spin) = tgamvv_out
             +  +  +  + ]
    4074                 :             :      end if
    4075                 :             : 
    4076         [ -  + ]:         183 :      if (dtset%prteliash == 3) then
    4077                 :           0 :        call xmpi_sum(tmp_vals_ee, kpt_comm%value, ierr)
    4078                 :             :        !TODO: write arrays to ncfile.
    4079   [ #  #  #  #  :           0 :        gams%vals_ee(:,:,:,:,:, iq_ibz, spin) = tmp_vals_ee
          #  #  #  #  #  
                      # ]
    4080         [ #  # ]:           0 :        ABI_FREE(tmp_vals_ee)
    4081         [ #  # ]:           0 :        ABI_FREE(emesh)
    4082                 :             :      end if
    4083                 :             :    end do ! spin
    4084                 :             : 
    4085         [ -  + ]:          61 :    ABI_FREE(v1scf)
    4086         [ -  + ]:          61 :    ABI_FREE(vlocal1)
    4087                 :             : 
    4088                 :          61 :    write(msg,'(2(a,i0),a)')" Computation of q-point [", iq_ibz, "/", gams%nqibz, "]"
    4089                 :         127 :    call cwtime_report(msg, cpu_q, wall_q, gflops_q, end_str=ch10)
    4090                 :             :  end do ! iq_ibz
    4091                 :             : 
    4092                 :           5 :  call cwtime_report(" phonon linewidths q-loop", cpu_all, wall_all, gflops_all, end_str=ch10)
    4093                 :             : 
    4094                 :             :  ! Free memory
    4095         [ -  + ]:           5 :  ABI_FREE(grad_berry)
    4096         [ -  + ]:           5 :  ABI_FREE(dummy_vtrial)
    4097         [ -  + ]:           5 :  ABI_FREE(work)
    4098         [ -  + ]:           5 :  ABI_FREE(ph1d)
    4099         [ -  + ]:           5 :  ABI_FREE(vlocal)
    4100         [ -  + ]:           5 :  ABI_FREE(kg_k)
    4101         [ -  + ]:           5 :  ABI_FREE(kg_kq)
    4102         [ -  + ]:           5 :  ABI_FREE(tgam)
    4103         [ -  + ]:           5 :  ABI_FREE(displ_cart)
    4104         [ -  + ]:           5 :  ABI_FREE(displ_red)
    4105                 :             :  !ABI_FREE(qibz_done)
    4106         [ +  - ]:           5 :  ABI_SFREE(vcart_ibz)
    4107                 :           5 :  call krank%free()
    4108                 :             : 
    4109         [ +  - ]:           5 :  ABI_SFREE(tgamvv_in)
    4110         [ +  - ]:           5 :  ABI_SFREE(tgamvv_out)
    4111                 :           5 :  call ddkop%free(); call gs_hamkq%free(); call wfd%free()
    4112         [ +  + ]:          10 :  do spin=1,ebands%nsppol
    4113                 :          10 :    call fstab(spin)%free()
    4114                 :             :  end do
    4115   [ +  -  +  +  :          10 :  ABI_FREE(fstab)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  + ]
    4116                 :           5 :  call pawcprj_free(cwaveprj0)
    4117   [ +  -  -  +  :           5 :  ABI_FREE(cwaveprj0)
          -  -  -  -  -  
                      + ]
    4118                 :             : 
    4119                 :             :  ! Collect results on each node
    4120                 :           5 :  call cwtime(cpu_all, wall_all, gflops_all, "start")
    4121                 :           5 :  call xmpi_sum(gams%vals_qibz, qs_comm%value, ierr)
    4122         [ +  - ]:           5 :  if (dtset%eph_transport > 0) then
    4123                 :           5 :    call xmpi_sum(gams%vals_in_qibz, qs_comm%value, ierr)
    4124                 :           5 :    call xmpi_sum(gams%vals_out_qibz, qs_comm%value, ierr)
    4125                 :             :  end if
    4126         [ -  + ]:           5 :  if (dtset%prteliash == 3) call xmpi_sum(gams%vals_ee, qs_comm%value, ierr)
    4127                 :           5 :  call cwtime_report(" xmpi_sum", cpu_all, wall_all, gflops_all)
    4128                 :             : 
    4129                 :             :  ! Deallocate MPI communicators.
    4130                 :           5 :  call pert_comm%free(); call qpt_comm%free(); call bsum_comm%free(); call qs_comm%free()
    4131                 :           5 :  call kpt_comm%free(); call spin_comm%free(); call pkb_comm%free()
    4132                 :             :  !call ncwrite_comm%free()
    4133                 :             : 
    4134                 :             :  ! Print gamma(IBZ) to ab_out and ncid.
    4135         [ +  - ]:           5 :  if (my_rank == master) call phgamma_ncwrite(gams, cryst, ifc, ncid)
    4136                 :             : 
    4137                 :             :  ! Interpolate linewidths along the q-path.
    4138         [ -  + ]:           5 :  if (dtset%ph_nqpath <= 0) then
    4139                 :             :    write(msg, '(7a,es16.6,4a)' ) &
    4140                 :           0 :     'You have not specified a path for the linewidth calculation - no interpolation or output will be done ',ch10,&
    4141                 :           0 :     'Action: check your input variables ph_nqpath and ph_qpath'
    4142                 :           0 :    ABI_WARNING(msg)
    4143                 :             :  else
    4144                 :           5 :    call gams%linwid(cryst, ifc, dtset%ph_ndivsm, dtset%ph_nqpath, dtset%ph_qpath, dtfil%filnam_ds(4), ncid, wminmax, comm)
    4145                 :             :  end if
    4146                 :             : 
    4147                 :             :  ! Compute a2Fw using the ab-initio q-points (no interpolation here)
    4148                 :             :  call a2fw%init(gams, cryst, ifc, dtset%ph_intmeth, dtset%ph_wstep, wminmax, dtset%ph_smear, &
    4149                 :           5 :    dtset%ph_ngqpt, dtset%ph_nqshift, dtset%ph_qshift, comm, qintp=.False., qptopt=1)
    4150                 :             : 
    4151         [ +  - ]:           5 :  if (my_rank == master) then
    4152                 :           5 :    call a2fw%write(strcat(dtfil%filnam_ds(4), "_NOINTP"), "_qcoarse", ncid)
    4153         [ -  + ]:           5 :    if (dtset%prteliash == 3) call a2fw_ee_write(a2fw, strcat(dtfil%filnam_ds(4), "_NOINTP"))
    4154                 :             :  end if
    4155                 :           5 :  call a2fw%free()
    4156                 :             : 
    4157                 :             :  ! Compute a2Fw using Fourier interpolation (R -> q) and ph_ngqpt grid.
    4158                 :             :  call a2fw%init(gams, cryst, ifc, dtset%ph_intmeth, dtset%ph_wstep, wminmax, dtset%ph_smear, &
    4159                 :           5 :    dtset%ph_ngqpt, dtset%ph_nqshift, dtset%ph_qshift, comm, qptopt=1)
    4160                 :             : 
    4161         [ +  - ]:           5 :  if (my_rank == master) then
    4162                 :           5 :    call a2fw%write(dtfil%filnam_ds(4), "_qintp", ncid)
    4163         [ -  + ]:           5 :    if (dtset%prteliash == 3) call a2fw_ee_write(a2fw, dtfil%filnam_ds(4))
    4164                 :             :  end if
    4165                 :             : 
    4166                 :           5 :  call a2fw%free()
    4167                 :             : 
    4168                 :             :  ! Compute A2fw using Fourier interpolation and full BZ for debugging purposes.
    4169                 :             :  !call a2fw%init(gams, cryst, ifc, dtset%ph_intmeth, dtset%ph_wstep, wminmax, dtset%ph_smear,&
    4170                 :             :  !  dtset%ph_ngqpt, dtset%ph_nqshift, dtset%ph_qshift, comm, qptopt=3)
    4171                 :             :  !if (my_rank == master) call a2fw%write(strcat(dtfil%filnam_ds(4), "_A2FW_QPTOPT3"), "fake", nctk_noid)
    4172                 :             :  !call a2fw%free()
    4173                 :             : 
    4174         [ +  - ]:           5 :  if (dtset%eph_transport == 1) then
    4175                 :             :    ! Calculate and output transport quantities
    4176                 :             : 
    4177                 :             :    ! Compute a2Fw_tr using ab-initio q-points (no interpolation)
    4178                 :             :    call a2fw_tr%init(gams, cryst, ifc, dtset%ph_intmeth, dtset%ph_wstep, wminmax, dtset%ph_smear,&
    4179                 :           5 :      dtset%ph_ngqpt, dtset%ph_nqshift, dtset%ph_qshift, comm, qintp=.False., qptopt=1)
    4180                 :             : 
    4181         [ +  - ]:           5 :    if (my_rank == master) call a2fw_tr%write(strcat(dtfil%filnam_ds(4), "_NOINTP"), "_qcoarse", ncid)
    4182                 :           5 :    call a2fw_tr%free()
    4183                 :             : 
    4184                 :             :    ! Compute a2Fw_tr using Fourier interpolation (R --> q) and ph_ngqpt grid
    4185                 :             :    call a2fw_tr%init(gams, cryst, ifc, dtset%ph_intmeth, dtset%ph_wstep, wminmax, dtset%ph_smear,&
    4186                 :           5 :      dtset%ph_ngqpt, dtset%ph_nqshift, dtset%ph_qshift, comm, qptopt=1)
    4187                 :             : 
    4188         [ +  - ]:           5 :    if (my_rank == master) call a2fw_tr%write(dtfil%filnam_ds(4), "_qintp", ncid)
    4189                 :           5 :    call a2fw_tr%free()
    4190                 :             : 
    4191                 :             :    ! Compute A2fw_tr using Fourier interpolation and full BZ for debugging purposes.
    4192                 :             :    !call a2fw_tr%init(gams, cryst, ifc, dtset%ph_intmeth, dtset%ph_wstep, wminmax, dtset%ph_smear,&
    4193                 :             :    !  dtset%ph_ngqpt, dtset%ph_nqshift, dtset%ph_qshift, comm, qptopt=3)
    4194                 :             :    !if (my_rank == master) call a2fw_tr%write(strcat(dtfil%filnam_ds(4), "_A2FWTR_QPTOPT3"), "fake", nctk_noid)
    4195                 :             :    !call a2fw_tr%free()
    4196                 :             :  end if
    4197                 :             : 
    4198         [ +  - ]:           5 :  if (my_rank == master) then
    4199         [ -  + ]:           5 :    NCF_CHECK(nf90_close(ncid))
    4200                 :             :  end if
    4201                 :             : 
    4202                 :           5 :  call gams%free()
    4203                 :             : 
    4204   [ -  +  -  +  :         115 : end subroutine eph_phgamma
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  +  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  +  +  -  
          +  -  +  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
    4205                 :             : !!***
    4206                 :             : 
    4207                 :             : !----------------------------------------------------------------------
    4208                 :             : 
    4209                 :             : !!****f* m_phgamma/phgamma_setup_qpoint
    4210                 :             : !! NAME
    4211                 :             : !! phgamma_setup_qpoint
    4212                 :             : !!
    4213                 :             : !! FUNCTION
    4214                 :             : !!
    4215                 :             : !! SOURCE
    4216                 :             : 
    4217                 :          61 : subroutine phgamma_setup_qpoint(gams, fs, cryst, ebands, spin, ltetra, qpt, nesting, comm)
    4218                 :             : 
    4219                 :             : !Arguments ------------------------------------
    4220                 :             :  class(phgamma_t),intent(inout) :: gams
    4221                 :             :  type(fstab_t),intent(inout) :: fs
    4222                 :             :  type(crystal_t),intent(in) :: cryst
    4223                 :             :  type(ebands_t),intent(in) :: ebands
    4224                 :             :  integer,intent(in) :: spin, ltetra, comm
    4225                 :             :  integer,intent(out) :: nesting
    4226                 :             : !arrays
    4227                 :             :  real(dp),intent(in) :: qpt(3)
    4228                 :             : 
    4229                 :             : !Local variables-------------------------------
    4230                 :             : !scalars
    4231                 :             :  integer,parameter :: enough = 5
    4232                 :             :  integer :: nkbz, ierr, nb, ik_bz, ik_ibz, ikq_ibz, ikq_fs, ik_fs, i1, i2, i3, nkfs_q, nene, ib1, ib2 ! band_k, band_kq
    4233                 :             :  real(dp),parameter :: max_occ1 = one
    4234                 :             :  real(dp) :: cpu, wall, gflops, enemin, enemax
    4235                 :             :  character(len=500) :: msg
    4236                 :          61 :  type(krank_t) :: ibz_krank
    4237                 :          61 :  type(t_tetrahedron) :: tetra
    4238                 :             :  character(len=80) :: errorstring
    4239                 :             : !arrays
    4240                 :             :  integer :: nge(3), ngw(3), g0bz_kq(3)
    4241                 :          61 :  integer,allocatable :: select_ikfs(:), indkpt(:), kbz2fs(:) !, symrecfm(:,:,:)
    4242                 :             :  real(dp) :: kk(3), kq(3)
    4243                 :          61 :  real(dp),allocatable :: eig_k(:,:), eig_kq(:,:), wght_bz(:,:,:), kbz(:,:)
    4244                 :          61 :  real(dp),allocatable :: work_k(:), work_kq(:), dtweightde(:,:,:), tweight(:,:,:)
    4245                 :             : ! *************************************************************************
    4246                 :             : 
    4247                 :          61 :  call cwtime(cpu, wall, gflops, "start")
    4248                 :             : 
    4249                 :             :  ! The double delta with tetra is ill-defined for q == 0. Set nesting to 1 and return
    4250                 :          61 :  nesting = 0
    4251   [ +  +  +  +  :          76 :  if (abs(fs%eph_intmeth) == 2 .and. all(abs(qpt) < tol12)) then
             +  +  +  + ]
    4252                 :           2 :    ABI_COMMENT("Tetrahedron for double grid with q = 0 is ill-defined. Using adaptive gaussian.")
    4253                 :           2 :    nesting = 1
    4254                 :             :  end if
    4255                 :             : 
    4256   [ +  +  +  + ]:          61 :  if (fs%eph_intmeth == 1 .or. nesting == 1) then
    4257                 :             :    ! Gaussian method:
    4258                 :             :    ! Distribute k-points within the FS window inside comm.
    4259                 :             :    ! 1) Select k-points such that k+q is still inside the FS window
    4260                 :             :    ! 2) Distribute effective k-points assuming all procs in comm have all FS k-points (no filtering).
    4261   [ -  +  +  -  :          78 :    ABI_MALLOC(select_ikfs, (fs%nkfs))
          +  -  +  -  -  
                +  -  + ]
    4262                 :          26 :    nkfs_q = 0
    4263         [ +  + ]:        3614 :    do ik_fs=1,fs%nkfs
    4264         [ +  + ]:       14352 :      kq = fs%kpts(:, ik_fs) + qpt
    4265         [ +  + ]:        3588 :      ikq_fs = fs%findkg0(kq, g0bz_kq); if (ikq_fs == -1) cycle
    4266                 :        1536 :      nkfs_q = nkfs_q + 1
    4267                 :        3614 :      select_ikfs(nkfs_q) = ik_fs
    4268                 :             :    end do
    4269         [ +  + ]:          26 :    ABI_SFREE(gams%my_ifsk_q)
    4270         [ -  + ]:          26 :    call xmpi_split_list(nkfs_q, select_ikfs, comm, gams%my_nfsk_q, gams%my_ifsk_q)
    4271         [ -  + ]:          26 :    ABI_FREE(select_ikfs)
    4272                 :          26 :    call cwtime_report(" phgamma_setup_qpoint", cpu, wall, gflops)
    4273                 :          26 :    return
    4274                 :             :  end if
    4275                 :             : 
    4276                 :             :  ! Tetrahedron method:
    4277                 :             :  !   1) Compute weights for double delta integration.
    4278                 :             :  !   2) Filter k-points according to the weights (k must be in FS window with non-zero weight)
    4279                 :             :  !   3) Distribute effective k-points assuming all procs have all FS k-points.
    4280                 :             : 
    4281   [ +  +  +  +  :       33845 :  fs%dbldelta_tetra_weights_kfs = zero
                   +  + ]
    4282                 :             : 
    4283         [ -  + ]:          35 :  ABI_CHECK(isdiagmat(ebands%kptrlatt), "kptrlatt must be diagonal when tetra is used.")
    4284         [ -  + ]:          35 :  ABI_CHECK(ebands%nshiftk == 1, "nshiftk must be 1 when tetra is used")
    4285                 :          35 :  nge = get_diag(ebands%kptrlatt); ngw = nge
    4286         [ +  + ]:         140 :  nkbz = product(nge(1:3))
    4287                 :             : 
    4288                 :             :  ! TODO: Handle symmetries in a cleaner way. Change API of krank_new to pass symafm and kptopt
    4289                 :             :  call ibz_krank%init(ebands%nkpt, ebands%kptns, nsym=cryst%nsym, symrec=cryst%symrec, &
    4290                 :          35 :                      time_reversal=kpts_timrev_from_kptopt(ebands%kptopt) == 1)
    4291                 :             : 
    4292                 :             :  ! Compute eig_k and eig_kq in full BZ for the relevant bands around Ef.
    4293                 :          35 :  nb = fs%maxnb
    4294   [ -  +  +  -  :         105 :  ABI_MALLOC(kbz, (3, nkbz))
          +  -  +  -  -  
                +  -  + ]
    4295   [ -  +  +  -  :         105 :  ABI_MALLOC(indkpt, (nkbz))
          +  -  +  -  -  
                +  -  + ]
    4296   [ -  +  +  -  :         140 :  ABI_MALLOC(eig_k, (nb, nkbz))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    4297   [ -  +  +  -  :         105 :  ABI_MALLOC(eig_kq, (nb, nkbz))
          -  +  +  -  -  
                +  -  + ]
    4298   [ -  +  +  -  :          70 :  ABI_MALLOC(kbz2fs, (nkbz))
             -  +  -  + ]
    4299                 :             : 
    4300         [ +  + ]:       17955 :  kbz2fs = -1; ierr = 0; ik_bz = 0
    4301         [ +  + ]:         315 :  do i3=0,nge(3) - 1
    4302         [ +  + ]:        2555 :    do i2=0,nge(2) - 1
    4303         [ +  + ]:       20440 :      do i1=0,nge(1) - 1
    4304                 :       17920 :        ik_bz = ik_bz + 1
    4305                 :       17920 :        indkpt(ik_bz) = ik_bz
    4306                 :             : 
    4307                 :             :        ! Find correspondence between libtetra mesh and the IBZ.
    4308         [ +  + ]:       71680 :        kk = ([i1, i2, i3] + ebands%shiftk(:, 1)) / nge(:)
    4309         [ +  + ]:       71680 :        kbz(:, ik_bz) = kk
    4310                 :             : 
    4311                 :       17920 :        ik_fs = fs%krank%get_index(kk)
    4312         [ +  + ]:       17920 :        if (ik_fs /= -1) then
    4313                 :        4830 :          kbz2fs(ik_bz) = ik_fs
    4314                 :             :        else
    4315                 :             :          !ABI_ERROR(sjoin('kpt:', trim(ktoa(kk)), 'is not in FS!!'))
    4316                 :             :        end if
    4317                 :             : 
    4318                 :       17920 :        ik_ibz = ibz_krank%get_index(kk)
    4319         [ -  + ]:       17920 :        if (ik_ibz < 1) then
    4320         [ #  # ]:           0 :          if (ierr <= enough) then
    4321         [ #  # ]:           0 :            ABI_WARNING(sjoin('kpt:', trim(ktoa(kk)), 'has no symmetric among the k-points!'))
    4322                 :             :          end if
    4323                 :           0 :          ierr = ierr + 1; cycle
    4324                 :             :        end if
    4325                 :             : 
    4326         [ +  + ]:       53760 :        eig_k(:, ik_bz) = ebands%eig(fs%bmin:fs%bmax, ik_ibz, spin)
    4327                 :             : 
    4328                 :             :        ! Find correspondence between k+q in the BZ and the IBZ image.
    4329         [ +  + ]:       71680 :        kq = kk + qpt
    4330                 :       17920 :        ikq_ibz = ibz_krank%get_index(kq)
    4331                 :             : 
    4332         [ -  + ]:       17920 :        if (ikq_ibz < 1) then
    4333         [ #  # ]:           0 :          if (ierr <= enough) then
    4334         [ #  # ]:           0 :            ABI_WARNING(sjoin('kpt + qpt:', trim(ktoa(kq)), 'has no symmetric among the k-points!'))
    4335                 :             :          end if
    4336                 :           0 :          ierr = ierr + 1; cycle
    4337                 :             :        end if
    4338                 :             : 
    4339         [ +  + ]:       56000 :        eig_kq(:, ik_bz) = ebands%eig(fs%bmin:fs%bmax, ikq_ibz, spin)
    4340                 :             :      end do
    4341                 :             :    end do
    4342                 :             :  end do
    4343                 :             : 
    4344         [ -  + ]:          35 :  ABI_CHECK(ierr == 0, "See above warnings")
    4345                 :          35 :  call ibz_krank%free()
    4346                 :             : 
    4347                 :          70 :  select case (ltetra)
    4348                 :             :  case (1, 2)
    4349                 :             :    ! Use libtetra routines.
    4350                 :             :    ! Compute weights for double delta integration. Note that libtetra assumes Ef set to zero.
    4351                 :             :    ! TODO: Average weights over degenerate states?
    4352         [ -  + ]:          35 :    if (ltetra == 1) call wrtout(std_out, " Using linear tetrahedron method from libtetrabz (ltetra: 1)")
    4353         [ +  - ]:          35 :    if (ltetra == 2) call wrtout(std_out, " Using optimized tetrahedron method from libtetrabz (ltetra: 2)")
    4354   [ +  +  +  +  :      107555 :    eig_k = eig_k - ebands%fermie; eig_kq = eig_kq - ebands%fermie
             +  +  +  + ]
    4355   [ -  +  +  -  :         175 :    ABI_MALLOC(wght_bz, (nb, nb, nkbz))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    4356                 :          35 :    call libtetrabz_dbldelta(ltetra, cryst%gprimd, nb, nge, eig_k, eig_kq, ngw, wght_bz, comm=comm)
    4357                 :             :    ! Revert changes to eig arrays
    4358   [ +  +  +  + ]:       53795 :    eig_k = eig_k + ebands%fermie !; eig_kq = eig_kq + ebands%fermie
    4359                 :             : 
    4360                 :             :    ! Reindex from full BZ to fs% kpoints.
    4361         [ +  + ]:       17955 :    do ik_bz=1,nkbz
    4362                 :       17920 :      ik_fs = kbz2fs(ik_bz)
    4363         [ +  + ]:       17955 :      if (ik_fs /= -1) then
    4364   [ +  +  +  + ]:       33810 :        fs%dbldelta_tetra_weights_kfs(:,:,ik_fs) = wght_bz(:,:,ik_bz)
    4365                 :             :      else
    4366                 :             :        !write(std_out,*)"should be zero :", wght_bz(:,:,ik_bz)
    4367                 :             :      end if
    4368                 :             :    end do
    4369         [ -  + ]:          35 :    ABI_FREE(wght_bz)
    4370                 :             : 
    4371                 :             :  case (3)
    4372                 :             :    ! Tetrahedron method with Allen's approach for double delta.
    4373                 :             :    ! WARNING: wrong results maybe bug somewhere.
    4374                 :           0 :    call wrtout(std_out, " Calling Allen's version for q-point")
    4375                 :           0 :    nene = 3
    4376                 :           0 :    enemin = ebands%fermie - tol6
    4377                 :           0 :    enemax = ebands%fermie + tol6
    4378                 :             : 
    4379   [ #  #  #  #  :           0 :    ABI_MALLOC(dtweightde, (nkbz, nene, nene))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4380   [ #  #  #  #  :           0 :    ABI_MALLOC(tweight, (nkbz, nene, nene))
          #  #  #  #  #  
                #  #  # ]
    4381   [ #  #  #  #  :           0 :    ABI_MALLOC(work_k, (nkbz))
          #  #  #  #  #  
                #  #  # ]
    4382   [ #  #  #  #  :           0 :    ABI_MALLOC(work_kq, (nkbz))
             #  #  #  # ]
    4383                 :             : 
    4384                 :           0 :    call init_tetra(indkpt, cryst%gprimd, fs%klatt, kbz, nkbz, tetra, ierr, errorstring, comm)
    4385         [ #  # ]:           0 :    ABI_CHECK(ierr == 0, "init_tetra returned ierr /= 0")
    4386                 :             : 
    4387   [ #  #  #  #  :           0 :    fs%dbldelta_tetra_weights_kfs = zero
                   #  # ]
    4388         [ #  # ]:           0 :    do ib2=1,nb
    4389   [ #  #  #  # ]:           0 :      work_k = eig_k(ib2, :)
    4390         [ #  # ]:           0 :      do ib1=1,nb
    4391   [ #  #  #  # ]:           0 :       work_kq = eig_kq(ib1, :)
    4392                 :             :       ! TODO: Average weights over degenerate states?
    4393                 :             :       call get_dbl_tetra_weight(work_k, work_kq, enemin, enemax, enemin, enemax, &
    4394                 :           0 :                                 max_occ1, nene, nene, nkbz, tetra, tweight, dtweightde, ierr)
    4395         [ #  # ]:           0 :       ABI_CHECK(ierr == 0, "get_dbldelta_weights returned ierr /= 0")
    4396                 :             : 
    4397                 :             :       ! Reindex from full BZ to fs% kpoints.
    4398         [ #  # ]:           0 :       do ik_bz=1,nkbz
    4399                 :           0 :         ik_fs = kbz2fs(ik_bz)
    4400         [ #  # ]:           0 :         if (ik_fs /= -1) then
    4401                 :           0 :           fs%dbldelta_tetra_weights_kfs(ib1,ib2,ik_fs) = dtweightde(ik_bz, 2, 2) ! / nkbz
    4402                 :             :         else
    4403                 :             :           !write(std_out,*)"should be zero :", wght_bz(:,:,ik_bz)
    4404                 :             :         end if
    4405                 :             :       end do
    4406                 :             :      end do
    4407                 :             :    end do
    4408                 :             : 
    4409                 :           0 :    call destroy_tetra(tetra)
    4410         [ #  # ]:           0 :    ABI_FREE(work_k)
    4411         [ #  # ]:           0 :    ABI_FREE(work_kq)
    4412         [ #  # ]:           0 :    ABI_FREE(dtweightde)
    4413         [ #  # ]:           0 :    ABI_FREE(tweight)
    4414                 :             : 
    4415                 :             :  case default
    4416      [ +  -  - ]:          35 :    ABI_ERROR(sjoin("Invalid value of ltetra:", itoa(ltetra)))
    4417                 :             :  end select
    4418                 :             : 
    4419                 :             :  ! Now we can filter the k-points according to the tetra weights and distribute them inside comm.
    4420                 :             :  ! Assuming all procs in comm have all k-points in the IBZ.
    4421                 :             :  ! nkfs_q is the total number of BZ k-points on the FS contributing for this q-point.
    4422   [ -  +  +  -  :         105 :  ABI_MALLOC(select_ikfs, (fs%nkfs))
          +  -  +  -  -  
                +  -  + ]
    4423                 :          35 :  nkfs_q = 0
    4424         [ +  + ]:        4865 :  do ik_fs=1,fs%nkfs
    4425   [ +  +  +  +  :        6079 :    if (any(abs(fs%dbldelta_tetra_weights_kfs(:,:,ik_fs)) > zero)) then
             +  +  +  + ]
    4426                 :        4668 :      nkfs_q = nkfs_q + 1; select_ikfs(nkfs_q) = ik_fs
    4427                 :             :    end if
    4428                 :             :  end do
    4429                 :             : 
    4430                 :             :  ! Here we compute my_ifsk_q.
    4431         [ +  - ]:          35 :  ABI_SFREE(gams%my_ifsk_q)
    4432         [ -  + ]:          35 :  call xmpi_split_list(nkfs_q, select_ikfs, comm, gams%my_nfsk_q, gams%my_ifsk_q)
    4433         [ -  + ]:          35 :  ABI_FREE(select_ikfs)
    4434                 :             : 
    4435                 :             :  !write(std_out,"(2(a,i0),/)")" Treating ", gams%my_nfsk_q, " my k-points in the FS window over total nkfs: ", fs%nkfs
    4436                 :             : 
    4437                 :             :  write(msg, "(2(a,i0),a)") &
    4438                 :          35 :   " Number of k-points in the FS window treated by me: ", gams%my_nfsk_q, " over: ", nkfs_q, ch10
    4439                 :             :   !" Number of MPI procs in kpt_comm: ", gams%kpt_comm%nproc
    4440                 :          35 :  call wrtout(std_out, msg)
    4441                 :             : 
    4442         [ -  + ]:          35 :  ABI_FREE(kbz2fs)
    4443         [ -  + ]:          35 :  ABI_FREE(indkpt)
    4444         [ -  + ]:          35 :  ABI_FREE(kbz)
    4445         [ -  + ]:          35 :  ABI_FREE(eig_k)
    4446         [ -  + ]:          35 :  ABI_FREE(eig_kq)
    4447                 :             : 
    4448                 :          35 :  call cwtime_report(sjoin(" phgamma_setup_qpoint for spin:", itoa(spin)), cpu, wall, gflops)
    4449                 :             : 
    4450   [ -  +  -  +  :         122 : end subroutine phgamma_setup_qpoint
          -  +  -  +  -  
          +  -  +  -  +  
                   -  + ]
    4451                 :             : !!***
    4452                 :             : 
    4453                 :             : !----------------------------------------------------------------------
    4454                 :             : 
    4455                 :             : !!****f* m_phgamma/find_ewin
    4456                 :             : !! NAME
    4457                 :             : !! find_ewin
    4458                 :             : !!
    4459                 :             : !! FUNCTION
    4460                 :             : !!  Use bisection to find the optimal energy window around the Fermi level
    4461                 :             : !!
    4462                 :             : !! SOURCE
    4463                 :             : 
    4464                 :           0 : subroutine find_ewin(nqibz, qibz, cryst, ebands, ltetra, fs_ewin, comm)
    4465                 :             : 
    4466                 :             : !Arguments ------------------------------------
    4467                 :             :  integer,intent(in) :: nqibz
    4468                 :             :  type(crystal_t),intent(in) :: cryst
    4469                 :             :  type(ebands_t),intent(in) :: ebands
    4470                 :             :  integer,intent(in) :: ltetra, comm
    4471                 :             :  real(dp),intent(out) :: fs_ewin
    4472                 :             : !arrays
    4473                 :             :  real(dp),intent(in) :: qibz(3, nqibz)
    4474                 :             : 
    4475                 :             : !Local variables-------------------------------
    4476                 :             : !scalars
    4477                 :             :  integer,parameter :: master = 0
    4478                 :             :  integer :: my_rank, iq_ibz, spin, ii, unt
    4479                 :             :  real(dp) :: cpu, wall, gflops
    4480                 :             :  character(len=500) :: msg
    4481                 :             : !arrays
    4482                 :             :  integer :: bstarts(3), bstops(3)
    4483                 :             :  real(dp) :: elows(3), ehighs(3), ewins(3), qsums(3)
    4484                 :           0 :  real(dp), allocatable :: wtqs(:,:,:)
    4485                 :             : ! *************************************************************************
    4486                 :             : 
    4487                 :           0 :  call cwtime(cpu, wall, gflops, "start")
    4488                 :           0 :  my_rank = xmpi_comm_rank(comm)
    4489                 :             : 
    4490                 :           0 :  unt = -1
    4491         [ #  # ]:           0 :  if (xmpi_comm_rank(comm) == master) then
    4492         [ #  # ]:           0 :    if (open_file("tetra.dat", msg, newunit=unt, action="write", form="formatted", status="unknown") /= 0) then
    4493                 :           0 :      ABI_ERROR(msg)
    4494                 :             :    end if
    4495                 :             :  end if
    4496                 :             : 
    4497                 :             :  ! 1 is low, 2 is high, 3 is for the workspace
    4498   [ #  #  #  #  :           0 :  ABI_MALLOC(wtqs, (nqibz, ebands%nsppol, 3))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    4499                 :           0 :  ewins(1) = half * eV_Ha; elows(1) = ebands%fermie - ewins(1); ehighs(1) = ebands%fermie + ewins(1)
    4500                 :           0 :  call ebands%get_bands_from_erange(elows(1), ehighs(1), bstarts(1), bstops(1))
    4501                 :           0 :  call calc_dbldelta(cryst, ebands, ltetra, bstarts(1), bstops(1), nqibz, qibz, wtqs(:,:,1), comm)
    4502         [ #  # ]:           0 :  if (unt /= -1) write(unt, *) wtqs(:,:,1)
    4503                 :             : 
    4504                 :             :  !ewins(2) = five * eV_Ha; elows(2) = ebands%fermie - ewins(2); ehighs(2) = ebands%fermie + ewins(2)
    4505                 :             :  ewins(2) = two * eV_Ha; elows(2) = ebands%fermie - ewins(2); ehighs(2) = ebands%fermie + ewins(2)
    4506                 :           0 :  ewins(2) = one * eV_Ha; elows(2) = ebands%fermie - ewins(2); ehighs(2) = ebands%fermie + ewins(2)
    4507                 :           0 :  call ebands%get_bands_from_erange(elows(2), ehighs(2), bstarts(2), bstops(2))
    4508                 :           0 :  call calc_dbldelta(cryst, ebands, ltetra, bstarts(2), bstops(2), nqibz, qibz, wtqs(:,:,2), comm)
    4509         [ #  # ]:           0 :  if (unt /= -1) write(unt, *) wtqs(:,:,2)
    4510                 :             : 
    4511   [ #  #  #  #  :           0 :  if (abs(sum(abs(wtqs(:,:,1)) - sum(abs(wtqs(:,:,2))))) / sum(abs(wtqs(:,:,2))) < tol2) then
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    4512                 :           0 :    fs_ewin = ewins(1)
    4513                 :           0 :    call print_weights_index(1); goto 100
    4514                 :             :  end if
    4515                 :             : 
    4516                 :             :  ! Bisection part.
    4517                 :           0 :  do
    4518                 :           0 :    ewins(3) = (ewins(1) + ewins(2)) / two; elows(3) = ebands%fermie - ewins(3); ehighs(3) = ebands%fermie + ewins(3)
    4519                 :           0 :    call ebands%get_bands_from_erange(elows(3), ehighs(3), bstarts(3), bstops(3))
    4520                 :           0 :    call calc_dbldelta(cryst, ebands, ltetra, bstarts(3), bstops(3), nqibz, qibz, wtqs(:,:,3), comm)
    4521         [ #  # ]:           0 :    if (unt /= -1) write(unt, *) wtqs(:,:,3)
    4522                 :             : 
    4523         [ #  # ]:           0 :    do ii=1,3
    4524   [ #  #  #  # ]:           0 :      qsums(ii) = sum(abs(wtqs(:,:,ii))) / nqibz
    4525                 :             :    end do
    4526                 :             : 
    4527                 :           0 :    write(std_out,*)qsums(1), ", for ewins(1)_eV", ewins(1) * Ha_eV, " bstart(1)", bstarts(1), " bstopt(1)", bstops(1)
    4528                 :           0 :    write(std_out,*)qsums(2), ", for ewins(2)_eV", ewins(2) * Ha_eV, " bstart(1)", bstarts(2), " bstopt(1)", bstops(2)
    4529                 :           0 :    write(std_out,*)qsums(3), ", for ewins(3)_eV", ewins(3) * Ha_eV, " bstart(1)", bstarts(3), " bstopt(1)", bstops(3)
    4530                 :             : 
    4531                 :             :    !if (abs(sum(abs(wtqs(:,:,3)) - sum(abs(wtqs(:,:,2))))) / sum(abs(wtqs(:,:,2))) < tol3) then
    4532                 :             :    !  !  If 3 is close to 2, try to reduce the window by moving towards 1
    4533                 :             :    !  ewins(2) = ewins(3); elows(2) = elows(3); ehighs(2) = ehighs(3)
    4534                 :             : 
    4535         [ #  # ]:           0 :    if (abs(qsums(3) - qsums(2)) / qsums(2) < tol2) then
    4536                 :           0 :      fs_ewin = ewins(3)
    4537                 :           0 :      call print_weights_index(3)
    4538                 :           0 :      exit
    4539                 :             : 
    4540                 :             :    else
    4541                 :           0 :     ewins(1) = ewins(3); elows(1) = elows(3); ehighs(1) = ehighs(3)
    4542                 :             :    end if
    4543                 :             : 
    4544                 :             :  end do
    4545                 :             : 
    4546                 :             : 100 continue
    4547         [ #  # ]:           0 :  ABI_FREE(wtqs)
    4548         [ #  # ]:           0 :  if (unt /= -1) close(unt)
    4549                 :             : 
    4550                 :           0 :  call cwtime_report(" find_ewin", cpu, wall, gflops)
    4551                 :             : 
    4552                 :             : contains
    4553                 :             : 
    4554                 :           0 : subroutine print_weights_index(ind)
    4555                 :             : 
    4556                 :             :  integer,intent(in) :: ind
    4557                 :             : 
    4558         [ #  # ]:           0 :  if (my_rank == master) then
    4559                 :           0 :    write(std_out, "(a, f8.3, a)")" Optimal FS energy window: ", fs_ewin * Ha_eV, " (eV)"
    4560         [ #  # ]:           0 :    do iq_ibz=1,nqibz
    4561         [ #  # ]:           0 :      write(std_out, "(2a)")" For q-point:", trim(ktoa(qibz(:, iq_ibz)))
    4562         [ #  # ]:           0 :      do spin=1,ebands%nsppol
    4563                 :           0 :        write(std_out, *) wtqs(iq_ibz, spin, ind)
    4564                 :             :      end do
    4565                 :             :    end do
    4566                 :             :  end if
    4567                 :             : 
    4568                 :           0 : end subroutine print_weights_index
    4569                 :             : 
    4570                 :             : end subroutine find_ewin
    4571                 :             : !!***
    4572                 :             : 
    4573                 :             : !----------------------------------------------------------------------
    4574                 :             : 
    4575                 :             : !!****f* m_phgamma/calc_dbldelta
    4576                 :             : !! NAME
    4577                 :             : !! calc_dbldelta
    4578                 :             : !!
    4579                 :             : !! FUNCTION
    4580                 :             : !!  Compute Tetrahedron weights for the double delta.
    4581                 :             : !!
    4582                 :             : !! SOURCE
    4583                 :             : 
    4584                 :           0 : subroutine calc_dbldelta(cryst, ebands, ltetra, bstart, bstop, nqibz, qibz, wtqs, comm)
    4585                 :             : 
    4586                 :             : !Arguments ------------------------------------
    4587                 :             :  type(crystal_t),intent(in) :: cryst
    4588                 :             :  type(ebands_t),intent(in) :: ebands
    4589                 :             :  integer,intent(in) :: ltetra, bstart, bstop, nqibz, comm
    4590                 :             : !arrays
    4591                 :             :  real(dp),intent(in) :: qibz(3,nqibz)
    4592                 :             :  real(dp),intent(out) :: wtqs(nqibz, ebands%nsppol)
    4593                 :             : 
    4594                 :             : !Local variables-------------------------------
    4595                 :             : !scalars
    4596                 :             :  integer,parameter :: enough = 50
    4597                 :             :  integer :: nkbz, ierr, nb, ik_bz, ik_ibz, ikq_ibz, i1, i2, i3, nene, spin, iq_ibz
    4598                 :             :  integer :: ib1, ib2, my_rank, nproc, cnt
    4599                 :             :  real(dp),parameter :: max_occ1 = one
    4600                 :             :  real(dp) :: enemin, enemax !cpu, wall, gflops,
    4601                 :             :  !character(len=500) :: msg
    4602                 :           0 :  type(krank_t) :: ibz_krank
    4603                 :           0 :  type(t_tetrahedron) :: tetra
    4604                 :             :  !character(len=80) :: errorstring
    4605                 :             : !arrays
    4606                 :             :  integer :: nge(3), ngw(3)
    4607                 :           0 :  integer,allocatable :: indkpt(:) !, symrecfm(:,:,:)
    4608                 :             :  real(dp) :: qpt(3), kk(3), kq(3)
    4609                 :           0 :  real(dp),allocatable :: eig_k(:,:), eig_kq(:,:), wght_bz(:,:,:), kbz(:,:)
    4610                 :           0 :  real(dp),allocatable :: work_k(:), work_kq(:), dtweightde(:,:,:), tweight(:,:,:)
    4611                 :             : ! *************************************************************************
    4612                 :             : 
    4613                 :           0 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
    4614                 :             :  !call cwtime(cpu, wall, gflops, "start")
    4615                 :             : 
    4616         [ #  # ]:           0 :  ABI_CHECK(nqibz > 1, "Need more that 1 q-point")
    4617         [ #  # ]:           0 :  ABI_CHECK(isdiagmat(ebands%kptrlatt), "kptrlatt must be diagonal when tetra is used.")
    4618         [ #  # ]:           0 :  ABI_CHECK(ebands%nshiftk == 1, "nshiftk must be 1 when tetra is used")
    4619                 :           0 :  nge = get_diag(ebands%kptrlatt); ngw = nge
    4620         [ #  # ]:           0 :  nkbz = product(nge(1:3))
    4621                 :             : 
    4622                 :             :  ! TODO: Handle symmetries in a cleaner way. Change API of krank_new to pass symafm and kptopt
    4623                 :             :  call ibz_krank%init(ebands%nkpt, ebands%kptns, nsym=cryst%nsym, symrec=cryst%symrec, &
    4624                 :           0 :                     time_reversal=kpts_timrev_from_kptopt(ebands%kptopt) == 1)
    4625                 :             : 
    4626                 :           0 :  nb = bstop - bstart + 1
    4627   [ #  #  #  #  :           0 :  ABI_MALLOC(kbz, (3, nkbz))
          #  #  #  #  #  
                #  #  # ]
    4628   [ #  #  #  #  :           0 :  ABI_MALLOC(indkpt, (nkbz))
          #  #  #  #  #  
                #  #  # ]
    4629   [ #  #  #  #  :           0 :  ABI_MALLOC(eig_k, (nb, nkbz))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4630   [ #  #  #  #  :           0 :  ABI_MALLOC(eig_kq, (nb, nkbz))
          #  #  #  #  #  
                #  #  # ]
    4631                 :             : 
    4632   [ #  #  #  # ]:           0 :  wtqs = zero; cnt = 0
    4633         [ #  # ]:           0 :  do spin=1,ebands%nsppol
    4634         [ #  # ]:           0 :    do iq_ibz=1,nqibz
    4635         [ #  # ]:           0 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism.
    4636         [ #  # ]:           0 :      qpt = qibz(:, iq_ibz)
    4637                 :             : 
    4638                 :             :      ! The double delta is ill-defined for q == 0
    4639   [ #  #  #  #  :           0 :      if (all(abs(qpt) < tol12)) cycle
                   #  # ]
    4640                 :             : 
    4641                 :           0 :      ierr = 0; ik_bz = 0
    4642         [ #  # ]:           0 :      do i3=0,nge(3) - 1
    4643         [ #  # ]:           0 :        do i2=0,nge(2) - 1
    4644         [ #  # ]:           0 :          do i1=0,nge(1) - 1
    4645                 :           0 :            ik_bz = ik_bz + 1
    4646                 :           0 :            indkpt(ik_bz) = ik_bz
    4647                 :             : 
    4648                 :             :            ! Find correspondence between the grid and the IBZ
    4649         [ #  # ]:           0 :            kk = ([i1, i2, i3] + ebands%shiftk(:, 1)) / nge(:)
    4650         [ #  # ]:           0 :            kbz(:, ik_bz) = kk
    4651                 :             : 
    4652                 :           0 :            ik_ibz = ibz_krank%get_index(kk)
    4653         [ #  # ]:           0 :            if (ik_ibz < 1) then
    4654         [ #  # ]:           0 :              if (ierr <= enough) then
    4655         [ #  # ]:           0 :                ABI_WARNING(sjoin('kpt:', trim(ktoa(kk)), 'has no symmetric among the k-points!'))
    4656                 :             :              end if
    4657                 :           0 :              ierr = ierr + 1; cycle
    4658                 :             :            end if
    4659                 :             : 
    4660         [ #  # ]:           0 :            eig_k(:, ik_bz) = ebands%eig(bstart:bstop, ik_ibz, spin)
    4661                 :             : 
    4662                 :             :            ! Find correspondence between the BZ grid and the IBZ.
    4663         [ #  # ]:           0 :            kq = kk + qpt
    4664                 :           0 :            ikq_ibz = ibz_krank%get_index(kq)
    4665                 :             : 
    4666         [ #  # ]:           0 :            if (ikq_ibz < 1) then
    4667         [ #  # ]:           0 :              if (ierr <= enough) then
    4668         [ #  # ]:           0 :                ABI_WARNING(sjoin('kpt + qpt:', trim(ktoa(kq)), 'has no symmetric among the k-points!'))
    4669                 :             :              end if
    4670                 :           0 :              ierr = ierr + 1; cycle
    4671                 :             :            end if
    4672                 :             : 
    4673         [ #  # ]:           0 :            eig_kq(:, ik_bz) = ebands%eig(bstart:bstop, ikq_ibz, spin)
    4674                 :             :          end do
    4675                 :             :        end do
    4676                 :             :      end do
    4677         [ #  # ]:           0 :      ABI_CHECK(ierr == 0, "See above warnings")
    4678                 :             : 
    4679         [ #  # ]:           0 :      if (any(ltetra == [1, 2])) then
    4680                 :             :        ! Compute weights for double delta integration. Note that libtetra assumes Ef set to zero.
    4681                 :             :        ! TODO: Average weights over degenerate states?
    4682                 :             :        !write(std_out,"(a,i0,2a)")" Calling libtetrabz_dbldelta with ltetra: ", ltetra, " for q-point:", trim(ktoa(qpt))
    4683   [ #  #  #  #  :           0 :        eig_k = eig_k - ebands%fermie; eig_kq = eig_kq - ebands%fermie
             #  #  #  # ]
    4684   [ #  #  #  #  :           0 :        ABI_MALLOC(wght_bz, (nb, nb, nkbz))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    4685                 :           0 :        call libtetrabz_dbldelta(ltetra, cryst%gprimd, nb, nge, eig_k, eig_kq, ngw, wght_bz, comm=comm)
    4686   [ #  #  #  # ]:           0 :        eig_k = eig_k + ebands%fermie !; eig_kq = eig_kq + ebands%fermie
    4687                 :             : 
    4688   [ #  #  #  #  :           0 :        wtqs(iq_ibz, spin) = sum(abs(wght_bz))
                   #  # ]
    4689         [ #  # ]:           0 :        ABI_FREE(wght_bz)
    4690                 :             : 
    4691         [ #  # ]:           0 :      else if (ltetra == 3) then
    4692                 :             :        ! Tetrahedron method with Allen's approach for double delta.
    4693                 :             :        !write(std_out,"(2a)")" Calling Allen's version for q-point: ", trim(ktoa(qpt))
    4694                 :           0 :        nene = 3
    4695                 :           0 :        enemin = ebands%fermie - tol6
    4696                 :           0 :        enemax = ebands%fermie + tol6
    4697                 :             : 
    4698   [ #  #  #  #  :           0 :        ABI_MALLOC(dtweightde, (nkbz, nene, nene))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4699   [ #  #  #  #  :           0 :        ABI_MALLOC(tweight, (nkbz, nene, nene))
          #  #  #  #  #  
                #  #  # ]
    4700   [ #  #  #  #  :           0 :        ABI_MALLOC(work_k, (nkbz))
          #  #  #  #  #  
                #  #  # ]
    4701   [ #  #  #  #  :           0 :        ABI_MALLOC(work_kq, (nkbz))
             #  #  #  # ]
    4702                 :             : 
    4703                 :             :        ! TODO
    4704                 :           0 :        ABI_ERROR("Not Implemented")
    4705                 :             :        !call init_tetra(indkpt, cryst%gprimd, fs%klatt, kbz, nkbz, tetra, ierr, errorstring, comm)
    4706         [ #  # ]:           0 :        ABI_CHECK(ierr == 0, "init_tetra returned ierr /= 0")
    4707                 :             : 
    4708                 :             :        !fs%dbldelta_tetra_weights_kfs = zero
    4709         [ #  # ]:           0 :        do ib2=1,nb
    4710   [ #  #  #  # ]:           0 :          work_k = eig_k(ib2, :)
    4711         [ #  # ]:           0 :          do ib1=1,nb
    4712   [ #  #  #  # ]:           0 :           work_kq = eig_kq(ib1, :)
    4713                 :             :           ! TODO: Average weights over degenerate states?
    4714                 :             :           call get_dbl_tetra_weight(work_k, work_kq, enemin, enemax, enemin, enemax, &
    4715                 :           0 :                                     max_occ1, nene, nene, nkbz, tetra, tweight, dtweightde, ierr)
    4716         [ #  # ]:           0 :           ABI_CHECK(ierr == 0, "get_dbldelta_weights returned ierr /= 0")
    4717                 :             : 
    4718         [ #  # ]:           0 :           wtqs(iq_ibz, spin) = wtqs(iq_ibz, spin) + sum(abs(dtweightde(:, 2, 2)))
    4719                 :             :          end do
    4720                 :             :        end do
    4721                 :             : 
    4722                 :           0 :        call destroy_tetra(tetra)
    4723         [ #  # ]:           0 :        ABI_FREE(work_k)
    4724         [ #  # ]:           0 :        ABI_FREE(work_kq)
    4725         [ #  # ]:           0 :        ABI_FREE(dtweightde)
    4726         [ #  # ]:           0 :        ABI_FREE(tweight)
    4727                 :             :      else
    4728                 :           0 :        ABI_ERROR(sjoin("Invalid value of ltetra:", itoa(ltetra)))
    4729                 :             :      end if
    4730                 :             :    end do ! iq_ibz
    4731                 :             :  end do ! spin
    4732                 :             : 
    4733         [ #  # ]:           0 :  ABI_FREE(indkpt)
    4734         [ #  # ]:           0 :  ABI_FREE(kbz)
    4735         [ #  # ]:           0 :  ABI_FREE(eig_k)
    4736         [ #  # ]:           0 :  ABI_FREE(eig_kq)
    4737                 :             : 
    4738                 :           0 :  call ibz_krank%free()
    4739                 :           0 :  call xmpi_sum(wtqs, comm, ierr)
    4740                 :             :  !call cwtime_report(" calc_dbldelta", cpu, wall, gflops)
    4741                 :             : 
    4742   [ #  #  #  #  :           0 : end subroutine calc_dbldelta
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4743                 :             : !!***
    4744                 :             : 
    4745   [ -  +  -  -  :          75 : end module m_phgamma
          +  +  -  +  +  
          -  -  +  -  +  
          +  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                   -  + ]
    4746                 :             : !!***
        

Generated by: LCOV version 2.3-1