LCOV - code coverage report
Current view: top level - src/78_eph - m_ephwg.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.0 % 236 177
Test Date: 2026-09-20 18:56:22 Functions: 75.0 % 12 9

            Line data    Source code
       1              : !!****m* ABINIT/m_ephwg
       2              : !! NAME
       3              : !! m_ephwg
       4              : !!
       5              : !! FUNCTION
       6              : !!  Tools and objects to compute the weights used for the BZ integration of EPH quantities.
       7              : !!  More specifically the integration of quantities such as the imaginary part of the self-energy
       8              : !!  involving delta functions. Different approaches are available.
       9              : !!
      10              : !! COPYRIGHT
      11              : !!  Copyright (C) 2008-2026 ABINIT group (MG, HM)
      12              : !!  This file is distributed under the terms of the
      13              : !!  GNU General Public License, see ~abinit/COPYING
      14              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      15              : !!
      16              : !! SOURCE
      17              : 
      18              : #if defined HAVE_CONFIG_H
      19              : #include "config.h"
      20              : #endif
      21              : 
      22              : #include "abi_common.h"
      23              : 
      24              : module m_ephwg
      25              : 
      26              :  use defs_basis
      27              :  use m_abicore
      28              :  use m_errors
      29              :  use m_xmpi
      30              :  use m_copy
      31              :  use m_dtset
      32              :  use m_htetra
      33              :  use m_nctk
      34              :  use netcdf
      35              :  use m_crystal
      36              :  use m_ifc
      37              :  use m_lgroup
      38              :  use m_ebands
      39              :  use m_eph_double_grid
      40              :  use m_krank
      41              : 
      42              :  use m_time,            only : cwtime, cwtime_report
      43              :  use m_matrix,          only : matr3inv
      44              :  use m_numeric_tools,   only : arth, inrange, wrap2_pmhalf
      45              :  use m_special_funcs,   only : gaussian
      46              :  use m_fstrings,        only : strcat, ltoa, itoa, ftoa, ktoa, sjoin
      47              :  use m_simtet,          only : sim0onei, SIM0TWOI
      48              :  use m_kpts,            only : kpts_timrev_from_kptopt, kpts_ibz_from_kptrlatt, kpts_map
      49              :  use m_occ,             only : occ_fd, occ_be
      50              : 
      51              :  implicit none
      52              : 
      53              :  private
      54              : !!***
      55              : 
      56              : !----------------------------------------------------------------------
      57              : 
      58              : !!****t* m_ephwg/ephwg_t
      59              : !! NAME
      60              : !! ephwg_t
      61              : !!
      62              : !! FUNCTION
      63              : !!  Stores electron eigevalues and phonon frequencies in the IBZ (assume same mesh for e and ph).
      64              : !!  Provides tools to compute (e_{k+q} - w{q}) in the IBZ(k)
      65              : !!  and integrate the delta functions for phonon emission/absorption with the tetrahedron method.
      66              : !!
      67              : !! SOURCE
      68              : 
      69              : type, public :: ephwg_t
      70              : 
      71              :   integer :: natom3
      72              :   ! 3 * natom
      73              : 
      74              :   integer :: nsppol
      75              :   ! Number of independent spin polarizations.
      76              : 
      77              :   integer :: nbcount
      78              :   ! Number of bands treated.
      79              : 
      80              :   integer :: bstart
      81              :   ! The fist band (global index) starts at bstart.
      82              :   ! Used to select bands around the Fermi level.
      83              : 
      84              :   integer :: kptopt
      85              :   ! Option for k-point generation.
      86              : 
      87              :   integer :: timrev
      88              :   ! 1 if the use of time-reversal is allowed; 0 otherwise
      89              : 
      90              :   integer :: nibz, nbz
      91              :   ! Number of q-points in IBZ and full BZ.
      92              : 
      93              :   integer :: nq_k
      94              :   ! Number of points in IBZ(k) i.e. the irreducible wedge
      95              :   ! defined by the operations of the little group of k.
      96              : 
      97              :   !real(dp) :: max_phfrq
      98              :   ! Max Phonon frequency, computed from phfrq_ibz
      99              : 
     100              :   integer :: kptrlatt(3,3)
     101              :    ! Value of kptrlatt after inkpts. So one shift
     102              : 
     103              :   integer, allocatable :: kq2ibz(:)
     104              :   ! kq2ibz(nq_k)
     105              :   ! Mapping (k + q) --> initial IBZ array
     106              : 
     107              :   real(dp),allocatable :: ibz(:,:)
     108              :   ! ibz(3, nibz)
     109              :   ! The initial IBZ.
     110              : 
     111              :   real(dp),allocatable :: bz(:,:)
     112              :   ! bz(3, nbz)
     113              :   ! points in full BZ.
     114              : 
     115              :   real(dp) :: klatt(3, 3)
     116              :   ! Reciprocal of lattice vectors for full kpoint grid. Used by init_tetra
     117              : 
     118              :   integer,allocatable :: lgk2ibz(:)
     119              :   ! lgk2ibz(nq_k)
     120              :   ! Mapping Little-group IBZ_k --> initial IBZ
     121              :   ! TODO: This should be generalized to have the symmetry indices as well so
     122              :   ! that we can use it in sigmaph but then we have to implement similar algo for double grid.
     123              : 
     124              :   real(dp),allocatable :: phfrq_ibz(:,:)
     125              :   ! (nibz, natom3)
     126              :   ! Phonon frequencies in the IBZ
     127              : 
     128              :   real(dp),allocatable :: eigkbs_ibz(:, :, :)
     129              :   ! (nibz, nbcount, nsppol)
     130              :   ! Electron eigenvalues in the IBZ for nbcount states
     131              :   ! (not necessarily equal to global nband, see also bstart and bcount)
     132              : 
     133              :   type(crystal_t), pointer :: cryst => null()
     134              :   ! Pointer to input structure (does not own memory)
     135              : 
     136              :   type(lgroup_t) :: lgk
     137              :   ! Little group of the k-point
     138              : 
     139              :   type(htetra_t) :: tetra_k
     140              :   ! Used to evaluate delta(w - e_{k+q} +/- phw_q) with tetrahedron method.
     141              : 
     142              :  contains
     143              : 
     144              :      procedure :: setup_kpoint => ephwg_setup_kpoint
     145              :      ! Prepare tetrahedron method for given external k-point.
     146              : 
     147              :      procedure :: double_grid_setup_kpoint => ephwg_double_grid_setup_kpoint
     148              :      ! Prepare tetrahedron method for given external k-point using double grid routines.
     149              : 
     150              :      procedure :: report_stats => ephwg_report_stats
     151              :      ! Report how much memory is being used by this object
     152              : 
     153              :      procedure :: get_deltas => ephwg_get_deltas
     154              :      ! Compute weights for $ \int \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $
     155              : 
     156              :      procedure :: get_deltas_wvals => ephwg_get_deltas_wvals
     157              :      ! Compute weights for $ \int \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $
     158              : 
     159              :      procedure :: get_deltas_qibzk => ephwg_get_deltas_qibzk
     160              :      ! Compute weights for $ \delta(\omega - \omega_{q\nu}} $ using IBZ(k) ordering
     161              : 
     162              :      procedure :: get_zinv_weights => ephwg_get_zinv_weights
     163              :      ! Compute weights for $ \int 1 / (\omega - \ee_{k+q, b} \pm \omega_{q\nu} $
     164              : 
     165              :      procedure :: free => ephwg_free
     166              :      ! Free memory
     167              :  end type ephwg_t
     168              : 
     169              :  public :: ephwg_new             ! Basic Constructor
     170              :  public :: ephwg_from_ebands     ! Build object from ebands_t
     171              : 
     172              : contains
     173              : !!***
     174              : 
     175              : !----------------------------------------------------------------------
     176              : 
     177              : !!****f* m_ephwg/ephwg_new
     178              : !! NAME
     179              : !! ephwg_new
     180              : !!
     181              : !! FUNCTION
     182              : !!  Initialize the object from the electronic eigenvalues given in the IBZ.
     183              : !!
     184              : !! INPUTS
     185              : !!  cryst<cryst_t>=Crystalline structure.
     186              : !!  ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
     187              : !!  bstart=Index of the first band to be included.
     188              : !!  nbcount=Number of bands included
     189              : !!  kptopt=Option for the k-point generation.
     190              : !!  kptrlatt(3,3)=k-point lattice specification
     191              : !!  nshiftk= number of shift vectors.
     192              : !!  shiftk(3,nshiftk)=shift vectors for k point generation
     193              : !!  nkibz=Number of points in the IBZ
     194              : !!  kibz(3,nkibz)=Reduced coordinates of the k-points in the IBZ.
     195              : !!  nsppol=Number of independent spin polarizations.
     196              : !!  eig_ibz(nbcount, nkibz, nsppol) = Electron eigenvalues for nbcount states
     197              : !!
     198              : !! OUTPUT
     199              : !!
     200              : !! SOURCE
     201              : 
     202           23 : type(ephwg_t) function ephwg_new( &
     203           23 :    cryst, ifc, bstart, nbcount, kptopt, kptrlatt, nshiftk, shiftk, nkibz, kibz, nsppol, eig_ibz, comm) result(new)
     204              : 
     205              : !Arguments ------------------------------------
     206              : !scalars
     207              :  integer,intent(in) :: kptopt, nshiftk, nkibz, bstart, nbcount, nsppol, comm
     208              :  type(crystal_t),target,intent(in) :: cryst
     209              :  type(ifc_type),intent(in) :: ifc
     210              : !arrays
     211              :  integer,intent(in) :: kptrlatt(3,3)
     212              :  real(dp),intent(in) :: shiftk(3, nshiftk), kibz(3, nkibz)
     213              :  real(dp),intent(in) :: eig_ibz(nbcount, nkibz, nsppol)
     214              : 
     215              : !Local variables-------------------------------
     216              : !scalars
     217              :  integer :: nprocs, my_rank, ik, ierr, out_nkibz
     218              :  real(dp) :: cpu, wall, gflops
     219              : !arrays
     220              :  real(dp) :: rlatt(3,3)
     221              :  integer :: out_kptrlatt(3,3)
     222           46 :  real(dp) :: displ_cart(2,3,cryst%natom,3*cryst%natom), phfrq(3*cryst%natom)
     223           23 :  real(dp),allocatable :: out_kibz(:,:), out_wtk(:)
     224              : !----------------------------------------------------------------------
     225              : 
     226           23 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     227              : 
     228           23 :  new%natom3 = ifc%natom * 3
     229           23 :  new%nsppol = nsppol
     230           23 :  new%nbcount = nbcount
     231           23 :  new%bstart = bstart
     232           23 :  new%kptopt = kptopt
     233           23 :  new%timrev = kpts_timrev_from_kptopt(new%kptopt)
     234           23 :  new%nibz = nkibz
     235           23 :  new%cryst => cryst
     236           23 :  call alloc_copy(kibz, new%ibz)
     237              : 
     238           23 :  call cwtime(cpu, wall, gflops, "start")
     239              : 
     240              :  ! Get full BZ (new%nbz, new%bz) and new kptrlatt for tetra.
     241              :  call kpts_ibz_from_kptrlatt(cryst, kptrlatt, kptopt, nshiftk, shiftk, out_nkibz, out_kibz, out_wtk, new%nbz, new%bz, &
     242           23 :                              new_kptrlatt=out_kptrlatt)
     243           23 :  call cwtime_report(" ephwg_new: kpts_ibz_from_kptrlatt", cpu, wall, gflops)
     244              : 
     245          299 :  new%kptrlatt = out_kptrlatt
     246          299 :  rlatt = out_kptrlatt; call matr3inv(rlatt, new%klatt)
     247              : 
     248           23 :  ABI_CHECK(size(out_kibz, dim=2) == new%nibz, "mismatch in nkibz!")
     249           23 :  ABI_FREE(out_kibz)
     250           23 :  ABI_FREE(out_wtk)
     251              : 
     252              :  ! Copy eigenvalues in IBZ. Change shape for better performance in other routines.
     253          115 :  ABI_MALLOC(new%eigkbs_ibz, (new%nibz, new%nbcount, new%nsppol))
     254         6087 :  do ik=1,new%nibz
     255        20350 :    new%eigkbs_ibz(ik, :, :) = eig_ibz(:, ik, :)
     256              :  end do
     257              : 
     258              :  ! Fourier interpolate phonon frequencies on the same mesh.
     259        36176 :  ABI_CALLOC(new%phfrq_ibz, (new%nibz, new%natom3))
     260              : 
     261         6087 :  do ik=1,new%nibz
     262         6064 :    if (mod(ik, nprocs) /= my_rank) cycle ! mpi-parallelism
     263         6064 :    call ifc%fourq(cryst, new%ibz(:, ik), phfrq, displ_cart)
     264        42036 :    new%phfrq_ibz(ik, :) = phfrq
     265              :  end do
     266              : 
     267              :  ! Collect results on each rank
     268           23 :  call xmpi_sum(new%phfrq_ibz, comm, ierr)
     269              : 
     270              :  !new%max_phfrq = maxval(phfrq_ibz)
     271              : 
     272           23 :  call cwtime_report(" ephwg_new: ifc_fourq", cpu, wall, gflops)
     273              : 
     274           92 : end function ephwg_new
     275              : !!***
     276              : 
     277              : !----------------------------------------------------------------------
     278              : 
     279              : !!****f* m_ephwg/ephwg_from_ebands
     280              : !! NAME
     281              : !! ephwg_from_ebands
     282              : !!
     283              : !! FUNCTION
     284              : !!  Convenience constructor to initialize the object from an ebands_t object
     285              : 
     286           23 : type(ephwg_t) function ephwg_from_ebands(cryst, ifc, ebands, bstart, nbcount, comm) result(new)
     287              : 
     288              : !Arguments ------------------------------------
     289              : !scalars
     290              :  integer,intent(in) ::  bstart, nbcount, comm
     291              :  type(crystal_t),intent(in) :: cryst
     292              :  type(ifc_type),intent(in) :: ifc
     293              :  type(ebands_t),intent(in) :: ebands
     294              : 
     295              : !Local variables-------------------------------
     296           23 :  real(dp),allocatable :: eig_ibz(:, :, :)
     297              : !----------------------------------------------------------------------
     298              : 
     299           12 :  if (bstart == 1 .and. nbcount == ebands%mband) then
     300              :    new = ephwg_new(cryst, ifc, bstart, nbcount, ebands%kptopt, ebands%kptrlatt, ebands%nshiftk, ebands%shiftk, ebands%nkpt, &
     301            1 :       ebands%kptns, ebands%nsppol, ebands%eig, comm)
     302              :  else
     303           66 :    ABI_CHECK(inrange(bstart, [1, ebands%mband]), "Wrong bstart")
     304           66 :    ABI_CHECK(inrange(bstart + nbcount - 1, [1, ebands%mband]), "Wrong nbcount")
     305              :    ! Copy submatrix of eigenvalues
     306          110 :    ABI_MALLOC(eig_ibz, (nbcount, ebands%nkpt, ebands%nsppol))
     307        13889 :    eig_ibz = ebands%eig(bstart:bstart+nbcount-1, : , :)
     308              :    new = ephwg_new(cryst, ifc, bstart, nbcount, ebands%kptopt, ebands%kptrlatt, ebands%nshiftk, ebands%shiftk, ebands%nkpt, &
     309           22 :       ebands%kptns, ebands%nsppol, eig_ibz, comm)
     310           22 :    ABI_FREE(eig_ibz)
     311              :  end if
     312              : 
     313           23 : end function ephwg_from_ebands
     314              : !!***
     315              : 
     316              : !!****f* m_ephwg/ephwg_setup_kpoint
     317              : !! NAME
     318              : !! ephwg_setup_kpoint
     319              : !!
     320              : !! FUNCTION
     321              : !!  Set internal tables and object required to compute integration weights for a given k-point.
     322              : !!
     323              : !! INPUTS
     324              : !!  kpoint(3): k-point in reduced coordinates.
     325              : !!  prtvol: Verbosity level
     326              : !!  comm: MPI communicator
     327              : !!
     328              : !! OUTPUT
     329              : !!
     330              : !! SOURCE
     331              : 
     332           62 : subroutine ephwg_setup_kpoint(self, kpoint, prtvol, comm, skip_mapping)
     333              : 
     334              : !Arguments ------------------------------------
     335              : !scalars
     336              :  class(ephwg_t),target,intent(inout) :: self
     337              :  integer,intent(in) :: prtvol, comm
     338              :  logical,optional,intent(in) :: skip_mapping
     339              : !arrays
     340              :  real(dp),intent(in) :: kpoint(3)
     341              : 
     342              : !Local variables-------------------------------
     343              : !scalars
     344              :  integer :: ierr,ii
     345              :  logical :: do_mapping
     346              :  real(dp) :: cpu, wall, gflops
     347              :  character(len=80) :: errorstring
     348              :  !character(len=500) :: msg
     349              :  type(crystal_t),pointer :: cryst
     350           62 :  type(krank_t) :: krank
     351              : !arrays
     352           62 :  integer,allocatable :: indkk(:,:)
     353              : !----------------------------------------------------------------------
     354              : 
     355           62 :  do_mapping = .true.; if (present(skip_mapping)) do_mapping = .not. skip_mapping
     356           62 :  cryst => self%cryst
     357           62 :  call cwtime(cpu, wall, gflops, "start")
     358              : 
     359              :  ! Get little group of the (external) kpoint.
     360           62 :  call self%lgk%free()
     361           62 :  call self%lgk%init(self%cryst, kpoint, self%timrev, self%nbz, self%bz, self%nibz, self%ibz, comm)
     362              : 
     363           68 :  if (prtvol > 0) call self%lgk%print([std_out])
     364           62 :  self%nq_k = self%lgk%nibz
     365              : 
     366           62 :  call cwtime_report(" lgroup_new", cpu, wall, gflops)
     367              : 
     368           62 :  if (do_mapping) then
     369              :    ! TODO: Use symrec conventions although this means that we cannot reuse these tables
     370              :    ! to symmetrize wavefunctions and potentials that require S-1 i.e. the symrel convention.
     371              : 
     372              :    ! Get mapping IBZ_k --> initial IBZ (self%lgk%ibz --> self%ibz)
     373            0 :    ABI_MALLOC(indkk, (6, self%nq_k))
     374              : 
     375            0 :    call krank%from_kptrlatt(self%nibz, self%ibz, self%kptrlatt, compute_invrank=.False.)
     376              : 
     377            0 :    if (kpts_map("symrel", self%kptopt, cryst, krank, self%nq_k, self%lgk%ibz, indkk) /= 0) then
     378            0 :      ABI_ERROR("At least one of the points in IBZ(k) could not be generated from a symmetrical one.")
     379              :    end if
     380              : 
     381            0 :    call krank%free()
     382              : 
     383            0 :    ABI_SFREE(self%lgk2ibz)
     384            0 :    call alloc_copy(indkk(1, :), self%lgk2ibz)
     385            0 :    ABI_FREE(indkk)
     386            0 :    call cwtime_report(" listkk1", cpu, wall, gflops)
     387              : 
     388              :    ! Get mapping (k + q) --> initial IBZ.
     389            0 :    do ii=1,self%nq_k
     390            0 :      self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) + kpoint
     391              :    end do
     392            0 :    ABI_MALLOC(indkk, (6, self%nq_k))
     393              : 
     394            0 :    call krank%from_kptrlatt(self%nibz, self%ibz, self%kptrlatt, compute_invrank=.False.)
     395              : 
     396            0 :    if (kpts_map("symrel", self%kptopt, cryst, krank, self%nq_k, self%lgk%ibz, indkk) /= 0) then
     397            0 :      ABI_ERROR("At least one of the points in IBZ(k) + q could not be generated from a symmetrical one.")
     398              :    end if
     399            0 :    call krank%free()
     400              : 
     401            0 :    call cwtime_report(" listkk2", cpu, wall, gflops)
     402              : 
     403            0 :    ABI_SFREE(self%kq2ibz)
     404            0 :    call alloc_copy(indkk(1, :), self%kq2ibz)
     405            0 :    ABI_FREE(indkk)
     406              : 
     407              :    ! Revert changes
     408            0 :    do ii=1,self%nq_k
     409            0 :      self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) - kpoint
     410              :    end do
     411              :  end if
     412              : 
     413              :  ! Get mapping BZ --> IBZ_k (self%bz --> self%lgrp%ibz) required for tetrahedron method
     414          186 :  ABI_MALLOC(indkk, (self%nbz, 1))
     415       429950 :  indkk(:, 1) = self%lgk%bz2ibz_smap(1, :)
     416              : 
     417              :  ! Build tetrahedron object using IBZ(k) as the effective IBZ
     418              :  ! This means that input data for tetra routines must be provided in lgk%kibz_q
     419           62 :  call self%tetra_k%free()
     420              :  call self%tetra_k%init(indkk(:, 1), cryst%gprimd, self%klatt, self%bz, self%nbz, &
     421           62 :                         self%lgk%ibz, self%nq_k, ierr, errorstring, comm)
     422              :  !call tetra_write(self%tetra_k, self%lgk%nibz, self%lgk%ibz, strcat("tetrak_", ktoa(kpoint)))
     423           62 :  ABI_CHECK(ierr == 0, errorstring)
     424              : 
     425           62 :  if (xmpi_comm_rank(comm) == 0) call self%tetra_k%print(std_out)
     426           62 :  ABI_FREE(indkk)
     427              : 
     428           62 :  call cwtime_report(" init_tetra", cpu, wall, gflops)
     429              : 
     430          186 : end subroutine ephwg_setup_kpoint
     431              : !!***
     432              : 
     433              : !!****f* m_ephwg/ephwg_double_grid_setup_kpoint
     434              : !! NAME
     435              : !! ephwg_setup_kpoint
     436              : !!
     437              : !! FUNCTION
     438              : !!  Set internal tables and object required to compute integration weights for a given k-point
     439              : !!  using the double grid routines to map the different k-points.
     440              : !!  This version should be more efficient than its counterpart without the double grid.
     441              : !!
     442              : !! INPUTS
     443              : !!  kpoint(3): k-point in reduced coordinates.
     444              : !!  prtvol: Verbosity level
     445              : !!  comm: MPI communicator
     446              : !!
     447              : !! OUTPUT
     448              : !!
     449              : !! SOURCE
     450              : 
     451           19 : subroutine ephwg_double_grid_setup_kpoint(self, eph_doublegrid, kpoint, prtvol, comm)
     452              : 
     453              : !Arguments ------------------------------------
     454              : !scalars
     455              :  class(ephwg_t),target,intent(inout) :: self
     456              :  type(eph_double_grid_t),intent(inout) :: eph_doublegrid
     457              :  integer,intent(in) :: prtvol, comm
     458              : !arrays
     459              :  real(dp),intent(in) :: kpoint(3)
     460              : 
     461              : !Local variables-------------------------------
     462              : !scalars
     463              :  integer,parameter :: timrev0 = 0
     464              :  integer :: ierr,ii,ik_idx
     465              :  character(len=80) :: errorstring
     466              :  !character(len=500) :: msg
     467              :  type(crystal_t),pointer :: cryst
     468              : !arrays
     469           19 :  integer,allocatable :: lgkibz2bz(:) !indkk(:,:),
     470           19 :  integer,allocatable :: bz2lgkibz(:), bz2lgkibzkq(:) !, bz2bz(:), mapping(:,:)
     471              :  !real(dp) :: kpt(3), wrap_kpt(3), shift
     472              : !----------------------------------------------------------------------
     473              : 
     474           19 :  cryst => self%cryst
     475              : 
     476              :  ! Get little group of the (external) kpoint.
     477           19 :  call self%lgk%free()
     478           19 :  call self%lgk%init(self%cryst, kpoint, self%timrev, self%nbz, self%bz, self%nibz, self%ibz, comm)
     479           19 :  if (prtvol > 0) call self%lgk%print([std_out])
     480           19 :  self%nq_k = self%lgk%nibz
     481              : 
     482              :  ! get dg%bz --> self%lgrp%ibz
     483           57 :  ABI_REMALLOC(eph_doublegrid%bz2lgkibz, (eph_doublegrid%dense_nbz))
     484              : 
     485              :  ! Old version using all crystal symmetries
     486              :  !call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,&
     487              :  !                            cryst%symrel, cryst%nsym, &
     488              :  !                            eph_doublegrid%bz2lgkibz, has_timrev=1)
     489              :  call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,&
     490              :                             self%lgk%symrec_lg, self%lgk%nsym_lg, &
     491           19 :                             eph_doublegrid%bz2lgkibz, timrev0, use_symrec=.true.)
     492              : 
     493              :  ! self%lgrp%ibz --> dg%bz
     494        80998 :  ABI_ICALLOC(lgkibz2bz, (self%lgk%nibz))
     495       339987 :  do ii=1,self%nbz
     496       339968 :    ik_idx = eph_doublegrid%bz2lgkibz(ii)
     497       339987 :    lgkibz2bz(ik_idx) = ii
     498              :  enddo
     499              : 
     500              :  ! get self%lgrp%ibz --> dg%bz --> self%ibz
     501           57 :  ABI_REMALLOC(self%lgk2ibz, (self%nq_k))
     502        80960 :  do ii=1,self%nq_k
     503        80941 :    ik_idx = lgkibz2bz(ii)
     504        80960 :    self%lgk2ibz(ii) = eph_doublegrid%bz2ibz_dense(ik_idx)
     505              :  enddo
     506              : 
     507              :  ! calculate k+q
     508        80960 :  do ii=1,self%nq_k
     509       323783 :    self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) + kpoint
     510              :  end do
     511              : 
     512              :  ! get dg%bz --> lgk%ibz (k+q)
     513           57 :  ABI_MALLOC(bz2lgkibzkq, (eph_doublegrid%dense_nbz))
     514              :  ! Old version using all crystal symmetries
     515              :  !call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,&
     516              :  !                            cryst%symrel, cryst%nsym, &
     517              :  !                            bz2lgkibzkq, has_timrev=1)
     518              :  call eph_doublegrid%bz2ibz(self%lgk%ibz, self%lgk%nibz,&
     519              :                             self%lgk%symrec_lg, self%lgk%nsym_lg, &
     520           19 :                             bz2lgkibzkq, timrev0, use_symrec=.true.)
     521              : 
     522              :  ! self%lgrp%ibz (k+q) --> dg%bz
     523       339987 :  do ii=1,self%nbz
     524       339968 :    ik_idx = bz2lgkibzkq(ii)
     525       339987 :    lgkibz2bz(ik_idx) = ii
     526              :  enddo
     527           19 :  ABI_FREE(bz2lgkibzkq)
     528              : 
     529              :  ! get self%lgrp%ibz (k+q) --> dg%bz --> self%ibz
     530           57 :  ABI_REMALLOC(self%kq2ibz, (self%nq_k))
     531        80960 :  do ii=1,self%nq_k
     532        80941 :    ik_idx = lgkibz2bz(ii)
     533        80960 :    self%kq2ibz(ii) = eph_doublegrid%bz2ibz_dense(ik_idx)
     534              :  enddo
     535           19 :  ABI_FREE(lgkibz2bz)
     536              : 
     537              :  ! revert change
     538        80960 :  do ii=1,self%nq_k
     539       323783 :    self%lgk%ibz(:, ii) = self%lgk%ibz(:, ii) - kpoint
     540              :  end do
     541              : 
     542              :  ! get self%bz --> dg%bz --> self%lgrp%ibz
     543           57 :  ABI_MALLOC(bz2lgkibz, (self%nbz))
     544              : 
     545       339987 :  do ii=1,self%nbz
     546              :     ! get self%bz --> dg%bz
     547       339968 :     ik_idx = eph_doublegrid%get_index(self%bz(:,ii),2)
     548              :     ! dg%bz --> self%lgrp%ibz
     549       339987 :     bz2lgkibz(ii) = eph_doublegrid%bz2lgkibz(ik_idx)
     550              :  end do
     551              : 
     552              :  ! Build tetrahedron object using IBZ(k) as the effective IBZ
     553              :  ! This means that input data for tetra routines must be provided in lgk%kibz_q
     554           19 :  call self%tetra_k%free()
     555              :  call self%tetra_k%init(bz2lgkibz, cryst%gprimd, self%klatt, self%bz, self%nbz, &
     556           19 :                         self%lgk%ibz, self%nq_k, ierr, errorstring, comm)
     557           19 :  if (ierr /= 0) then
     558            0 :    ABI_ERROR(errorstring)
     559              :  end if
     560           19 :  ABI_FREE(bz2lgkibz)
     561              : 
     562           19 : end subroutine ephwg_double_grid_setup_kpoint
     563              : !!***
     564              : 
     565              : !----------------------------------------------------------------------
     566              : 
     567              : !!****f* m_ephwg/ephwg_report_stats
     568              : !! NAME
     569              : !! ephwg_report_stats
     570              : !!
     571              : !! FUNCTION
     572              : !!
     573              : !! INPUTS
     574              : !!
     575              : !! OUTPUT
     576              : !!
     577              : !! SOURCE
     578              : 
     579           81 : subroutine ephwg_report_stats(self)
     580              : 
     581              : !Arguments ------------------------------------
     582              : !scalars
     583              :  class(ephwg_t),intent(in) :: self
     584              : 
     585              : !Variables
     586              :  real(dp) :: mem_tot
     587              : !----------------------------------------------------------------------
     588              : 
     589              :  ! IBZ qpoints
     590           81 :  mem_tot = 3 * self%nibz * dp
     591              :  ! BZ qpoints
     592           81 :  mem_tot = mem_tot + 3 * self%nbz * dp
     593              :  ! lgk2ibz and kq2ibz
     594           81 :  mem_tot = mem_tot + self%nq_k * 2 * 4
     595              :  ! phonon frequencies
     596           81 :  mem_tot = mem_tot + self%nibz * self%natom3 * dp
     597              :  ! eigenvalues
     598           81 :  mem_tot = mem_tot + self%nibz * self%nbcount * self%nsppol * dp
     599              : 
     600           81 :  write(std_out,"(a,f8.1,a)") " Memory allocated for ephwg weights:", mem_tot * b2Mb, " [Mb] <<< MEM"
     601              : 
     602           81 : end subroutine ephwg_report_stats
     603              : !!***
     604              : 
     605              : !----------------------------------------------------------------------
     606              : 
     607              : !!****f* m_ephwg/ephwg_get_deltas
     608              : !! NAME
     609              : !! ephwg_get_deltas
     610              : !!
     611              : !! FUNCTION
     612              : !! Compute weights for $ \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $
     613              : !! for a given (band, spin) and phonon mode nu.
     614              : !!
     615              : !! INPUTS
     616              : !! band=band index (global index i.e. unshifted)
     617              : !! spin=Spin index
     618              : !! nu=Phonon branch.
     619              : !! nene=number of energies for DOS
     620              : !! eminmax=min and  energy in delta (linear mesh)
     621              : !! bcorr=1 to include Blochl correction else 0.
     622              : !! comm=MPI communicator
     623              : !! [broad]=Gaussian broadening
     624              : !!
     625              : !! OUTPUT
     626              : !!  deltaw_pm(nene, nq_k, 2)  (plus, minus) including the weights for BZ integration.
     627              : !   These arrays have the same order as the little group used in sigmaph.
     628              : !!
     629              : !! SOURCE
     630              : 
     631            0 : subroutine ephwg_get_deltas(self, band, spin, nu, nene, eminmax, bcorr, deltaw_pm, comm, &
     632              :                             broad)  ! optional
     633              : 
     634              : !Arguments ------------------------------------
     635              : !scalars
     636              :  integer,intent(in) :: band, spin, nu, nene, bcorr, comm
     637              :  class(ephwg_t),intent(in) :: self
     638              :  real(dp),optional,intent(in) :: broad
     639              : !arrays
     640              :  real(dp),intent(in) :: eminmax(2)
     641              :  real(dp),intent(out) :: deltaw_pm(nene, self%nq_k, 2)
     642              : 
     643              : !Local variables-------------------------------
     644              : !scalars
     645              :  integer :: iq,iq_ibz,ikpq_ibz,ib,ie
     646              :  real(dp),parameter :: max_occ1 = one
     647              :  real(dp) :: omega_step
     648              : !arrays
     649            0 :  real(dp) :: wme0(nene)
     650            0 :  real(dp),allocatable :: thetaw(:,:), pme_k(:,:)
     651              : !----------------------------------------------------------------------
     652              : 
     653            0 :  ib = band - self%bstart + 1
     654              : 
     655            0 :  ABI_MALLOC(thetaw, (nene, self%nq_k))
     656            0 :  ABI_MALLOC(pme_k, (self%nq_k, 2))
     657              : 
     658              :  ! Fill array for e_{k+q, b} +- w_{q,nu)
     659            0 :  do iq=1,self%nq_k
     660            0 :    iq_ibz = self%lgk2ibz(iq)   ! IBZ_k --> IBZ
     661            0 :    ikpq_ibz = self%kq2ibz(iq)  ! k + q --> IBZ
     662            0 :    pme_k(iq, 1) = self%eigkbs_ibz(ikpq_ibz, ib, spin) - self%phfrq_ibz(iq_ibz, nu)
     663            0 :    pme_k(iq, 2) = self%eigkbs_ibz(ikpq_ibz, ib, spin) + self%phfrq_ibz(iq_ibz, nu)
     664              :  end do
     665              : 
     666            0 :  if (present(broad)) then
     667            0 :    omega_step = (eminmax(2) - eminmax(1)) / (nene - 1)
     668              :    ! Use thetaw as workspace array
     669            0 :    thetaw(:, 1) = arth(eminmax(1), omega_step, nene)
     670            0 :    do iq=1,self%nq_k
     671            0 :      do ie=1,2
     672            0 :        wme0 = thetaw(:, 1) - pme_k(iq, ie)
     673            0 :        deltaw_pm(:, iq, ie) = gaussian(wme0, broad)
     674              :      end do
     675              :    end do
     676              : 
     677              :    ! Multiply by weights
     678            0 :    do ie=1,nene
     679            0 :      deltaw_pm(ie, :, 1) = deltaw_pm(ie, :, 1) * self%lgk%weights
     680            0 :      deltaw_pm(ie, :, 2) = deltaw_pm(ie, :, 2) * self%lgk%weights
     681              :    end do
     682              : 
     683              :  else
     684              :    ! TODO Add routine to compute only delta
     685              :    call self%tetra_k%blochl_weights(pme_k(:,1), eminmax(1), eminmax(2), max_occ1, nene, self%nq_k, &
     686            0 :      bcorr, thetaw, deltaw_pm(:,:,1), comm)
     687              :    call self%tetra_k%blochl_weights(pme_k(:,2), eminmax(1), eminmax(2), max_occ1, nene, self%nq_k, &
     688            0 :      bcorr, thetaw, deltaw_pm(:,:,2), comm)
     689              :  end if
     690              : 
     691            0 :  ABI_FREE(thetaw)
     692            0 :  ABI_FREE(pme_k)
     693              : 
     694            0 : end subroutine ephwg_get_deltas
     695              : !!***
     696              : 
     697              : !----------------------------------------------------------------------
     698              : 
     699              : !!****f* m_ephwg/ephwg_get_deltas_wvals
     700              : !! NAME
     701              : !! ephwg_get_deltas_wvals
     702              : !!
     703              : !! FUNCTION
     704              : !! Compute weights for $ \delta(\omega - \ee_{k+q, b} \pm \omega_{q\nu} $
     705              : !! for a given (band, spin) and phonon mode nu.
     706              : !!
     707              : !! INPUTS
     708              : !! band=band index (global index i.e. unshifted)
     709              : !! spin=Spin index
     710              : !! nu=Phonon branch.
     711              : !! nene=number of energies for DOS
     712              : !! eminmax=min and  energy in delta (linear mesh)
     713              : !! bcorr=1 to include Blochl correction else 0.
     714              : !! comm=MPI communicator
     715              : !! [broad]=Gaussian broadening
     716              : !!
     717              : !! OUTPUT
     718              : !!  deltaw_pm(nene, nq_k, 2)  (plus, minus) including the weights for BZ integration.
     719              : !   These arrays have the same order as the little group used in sigmaph.
     720              : !!
     721              : !! SOURCE
     722              : 
     723        15108 : subroutine ephwg_get_deltas_wvals(self, band, spin, nu, neig, eig, bcorr, deltaw_pm, comm, &
     724              :                                   broad)  ! optional
     725              : 
     726              : !Arguments ------------------------------------
     727              : !scalars
     728              :  integer,intent(in) :: band, spin, nu, neig, bcorr, comm
     729              :  real(dp),intent(in) :: eig(neig)
     730              :  class(ephwg_t),intent(in) :: self
     731              :  real(dp),optional,intent(in) :: broad
     732              : !arrays
     733              :  real(dp),intent(out) :: deltaw_pm(neig,self%nq_k, 2)
     734              : 
     735              : !Local variables-------------------------------
     736              : !scalars
     737              :  real(dp),parameter :: max_occ1 = one
     738              :  integer :: iq, iq_ibz, ikpq_ibz, ib, nprocs, my_rank
     739        30216 :  real(dp) :: wme0(neig)
     740              : !arrays
     741        15108 :  real(dp),allocatable :: pme_k(:,:)
     742              : !----------------------------------------------------------------------
     743              : 
     744        15108 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     745        15108 :  ib = band - self%bstart + 1
     746     13081836 :  deltaw_pm = zero
     747              : 
     748        45324 :  ABI_MALLOC(pme_k, (self%nq_k, 2))
     749              : 
     750              :  ! Fill array for e_{k+q, b} +- w_{q,nu)
     751      3274236 :  do iq=1,self%nq_k
     752      3259128 :    iq_ibz = self%lgk2ibz(iq)   ! IBZ_k --> IBZ
     753      3259128 :    ikpq_ibz = self%kq2ibz(iq)  ! k + q --> IBZ
     754      3259128 :    pme_k(iq, 1) = self%eigkbs_ibz(ikpq_ibz, ib, spin) - self%phfrq_ibz(iq_ibz, nu)
     755      3274236 :    pme_k(iq, 2) = self%eigkbs_ibz(ikpq_ibz, ib, spin) + self%phfrq_ibz(iq_ibz, nu)
     756              :  end do
     757              : 
     758              :  ! Compute the tetrahedron or gaussian weights
     759        15108 :  if (present(broad)) then
     760            0 :    do iq_ibz=1,self%nq_k
     761            0 :      if (mod(iq_ibz, nprocs) /= my_rank) cycle ! MPI parallelism
     762            0 :      wme0 = eig - pme_k(iq_ibz, 1)
     763            0 :      deltaw_pm(:,iq_ibz,1) = gaussian(wme0, broad) * self%lgk%weights(iq_ibz)
     764            0 :      wme0 = eig - pme_k(iq_ibz, 2)
     765            0 :      deltaw_pm(:,iq_ibz,2) = gaussian(wme0, broad) * self%lgk%weights(iq_ibz)
     766              :    end do
     767              :  else
     768        15108 :    call self%tetra_k%wvals_weights_delta(pme_k(:, 1), neig, eig, max_occ1, self%nq_k, bcorr, deltaw_pm(:,:,1), comm)
     769        15108 :    call self%tetra_k%wvals_weights_delta(pme_k(:, 2), neig, eig, max_occ1, self%nq_k, bcorr, deltaw_pm(:,:,2), comm)
     770              :  end if
     771              : 
     772        15108 :  ABI_FREE(pme_k)
     773              : 
     774        15108 : end subroutine ephwg_get_deltas_wvals
     775              : !!***
     776              : 
     777              : !----------------------------------------------------------------------
     778              : 
     779              : !!****f* m_ephwg/ephwg_get_deltas_qibzk
     780              : !! NAME
     781              : !! ephwg_get_deltas_qibzk
     782              : !!
     783              : !! FUNCTION
     784              : !! Compute weights for $ \delta(\omega - \omega_{q\nu} $ for given nu, using q-opints in the IBZ(k)
     785              : !!
     786              : !! INPUTS
     787              : !! nu=Phonon branch.
     788              : !! nene=number of energies for DOS
     789              : !! eminmax=min and  energy in delta (linear mesh)
     790              : !! bcorr=1 to include Blochl correction else 0.
     791              : !! comm=MPI communicator
     792              : !! [with_qweights]= .False. if q-point weights should not be included in dt_weights
     793              : !!
     794              : !! OUTPUT
     795              : !!  dt_weights(nene, nq_k, 2)  weights for BZ integration (delta and theta function)
     796              : !   These arrays have the same order as the q-points in the little group of the k-point.
     797              : !!
     798              : !! SOURCE
     799              : 
     800          114 : subroutine ephwg_get_deltas_qibzk(self, nu, nene, eminmax, bcorr, dt_weights, comm, with_qweights)
     801              : 
     802              : !Arguments ------------------------------------
     803              : !scalars
     804              :  integer,intent(in) :: nu, nene, bcorr, comm
     805              :  class(ephwg_t),intent(in) :: self
     806              :  logical,optional,intent(in) :: with_qweights
     807              : !arrays
     808              :  real(dp),intent(in) :: eminmax(2)
     809              :  real(dp),intent(out) :: dt_weights(nene, self%nq_k, 2)
     810              : 
     811              : !Local variables-------------------------------
     812              : !scalars
     813              :  integer :: iq, iq_ibz, ie, ii
     814              :  real(dp),parameter :: max_occ1 = one
     815              : !arrays
     816          114 :  real(dp),allocatable :: eigen_in(:)
     817              : !----------------------------------------------------------------------
     818              : 
     819          342 :  ABI_MALLOC(eigen_in, (self%nq_k))
     820              : 
     821              :  ! Fill eigen_in
     822         5874 :  do iq=1,self%nq_k
     823         5760 :    iq_ibz = self%lgk2ibz(iq)  ! IBZ_k --> IBZ
     824         5874 :    eigen_in(iq) = self%phfrq_ibz(iq_ibz, nu)
     825              :  end do
     826              : 
     827              :  call self%tetra_k%blochl_weights(eigen_in, eminmax(1), eminmax(2), max_occ1, nene, self%nq_k, &
     828          114 :    bcorr, dt_weights(:,:,2), dt_weights(:,:,1), comm)
     829              : 
     830          114 :  if (present(with_qweights)) then
     831          114 :   if (.not. with_qweights) then
     832            0 :     do ii=1,2
     833            0 :       do ie=1,nene
     834            0 :         dt_weights(ie, :, ii) = dt_weights(ie, :, ii) * self%lgk%weights
     835              :       end do
     836              :     end do
     837              :    end if
     838              :  end if
     839              : 
     840          114 :  ABI_FREE(eigen_in)
     841              : 
     842          114 : end subroutine ephwg_get_deltas_qibzk
     843              : !!***
     844              : 
     845              : !----------------------------------------------------------------------
     846              : 
     847              : !!****f* m_ephwg/ephwg_get_zinv_weights
     848              : !! NAME
     849              : !! ephwg_get_zinv_weights
     850              : !!
     851              : !! FUNCTION
     852              : !! Compute weights for a given (kpoint, qpoint, spin) for all phonon modes.
     853              : !!
     854              : !! INPUTS
     855              : !! nz: Number of frequencies
     856              : !! nbcalc=Number of bands in self-energy matrix elements.
     857              : !! zvals(nw): z-values
     858              : !! iband_sum = band index in self-energy sum. (global index i.e. unshifted)
     859              : !! spin=Spin index
     860              : !! nu=Phonon branch index
     861              : !! zinv_opt:
     862              : !!   1 for S. Kaprzyk routines,
     863              : !!   2 for Lambin-Vigneron.
     864              : !! comm=MPI communicator
     865              : !! [use_bzsum]= By default the weights are multiplied by the Nstar(q) / Nq where
     866              : !!   Nstar(q) is the number of points in the star of the q-point (using the symmetries of the little group of k)
     867              : !!   If use_bzsum is set to True, the Nstar(q) coefficient is removed so that the caller can
     868              : !!   integrate over the BZ without using symmetries.
     869              : !!  [erange(2)]: if present, weights are computed with an approximated asyntotic expression if
     870              : !!   real(z) is outside of this interval and with tetra if inside.
     871              : 
     872              : !! OUTPUT
     873              : !!  cweights(nz, 2, nbcalc, %nq_k)  (plus, minus)
     874              : !!  include weights for BZ integration.
     875              : !!
     876              : !! SOURCE
     877              : 
     878         1128 : subroutine ephwg_get_zinv_weights(self, nz, nbcalc, zvals, iband_sum, spin, nu, zinv_opt, cweights, comm, use_bzsum, erange)
     879              : 
     880              : !Arguments ------------------------------------
     881              : !scalars
     882              :  integer,intent(in) :: iband_sum, spin, nu, nz, nbcalc, zinv_opt, comm
     883              :  class(ephwg_t),intent(in) :: self
     884              :  logical, optional, intent(in) :: use_bzsum
     885              : !arrays
     886              :  complex(dp),intent(in) :: zvals(nz, nbcalc)
     887              :  complex(dp),intent(out) :: cweights(nz, 2, nbcalc, self%nq_k)
     888              :  real(dp),optional,intent(in) :: erange(2)
     889              : 
     890              : !Local variables-------------------------------
     891              : !scalars
     892              :  integer,parameter :: master = 0
     893              :  integer :: iq_ibz, ikpq_ibz, ib, ii, iq, nprocs, my_rank !, ierr
     894              :  real(dp),parameter :: max_occ1 = one
     895              :  !real(dp) :: emin, emax
     896              :  logical :: use_bzsum_
     897              : !arrays
     898              :  real(dp) :: my_erange(2)
     899         1128 :  real(dp),allocatable :: pme_k(:,:)
     900         1128 :  complex(dp),allocatable :: cweights_tmp(:,:)
     901              : !----------------------------------------------------------------------
     902              : 
     903         1128 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     904              : 
     905         1128 :  use_bzsum_ = .False.; if (present(use_bzsum)) use_bzsum_ = use_bzsum
     906         1128 :  my_erange = [-huge(one), huge(one)]; if (present(erange)) my_erange = erange
     907              : 
     908              :  ! Allocate array for e_{k+q, b} +- w_{q,nu)
     909         3384 :  ABI_MALLOC(pme_k, (self%nq_k, 2))
     910              : 
     911         1128 :  ib = iband_sum - self%bstart + 1
     912        12972 :  do iq=1,self%nq_k
     913        11844 :    iq_ibz = self%lgk2ibz(iq)   ! IBZ_k --> IBZ
     914        11844 :    ikpq_ibz = self%kq2ibz(iq)  ! k + q --> IBZ
     915        11844 :    pme_k(iq, 1) = self%eigkbs_ibz(ikpq_ibz, ib, spin) - self%phfrq_ibz(iq_ibz, nu)
     916        12972 :    pme_k(iq, 2) = self%eigkbs_ibz(ikpq_ibz, ib, spin) + self%phfrq_ibz(iq_ibz, nu)
     917              :  end do
     918              : 
     919              :  ! As this part is quite demanding, especially when nz is large, use input z-mesh
     920              :  ! when we are inside the window in which the denominator can blow up (+- some tolerance)
     921              :  ! Outside the window, downsample the mesh use to compute the weights and spline the results.
     922              :  !if (zinv_opt == 2) then
     923              :  !  emin = minval(self%eigkbs_ibz(:, ib, spin))
     924              :  !  emax = maxval(self%eigkbs_ibz(:, ib, spin))
     925              :  !  !my_erange = [emin - half * abs(emin), emax + half * abs(emax)]
     926              :  !  my_erange = [emin - tol2 * abs(emin), emax + tol2 * abs(emax)]
     927              :  !end if
     928              : 
     929      8631372 :  cweights = zero
     930         4512 :  ABI_MALLOC(cweights_tmp, (nz, self%nq_k))
     931              : 
     932        10152 :  do ib=1,nbcalc
     933        28200 :    do ii=1,2
     934              :      call self%tetra_k%weights_wvals_zinv(pme_k(:, ii), nz, zvals(:, ib), max_occ1, self%nq_k, zinv_opt, &
     935        18048 :                                           cweights_tmp, comm, erange=my_erange)
     936       216576 :      do iq=1,self%nq_k
     937      8541696 :        cweights(:, ii, ib, iq) = cweights_tmp(:, iq)
     938              :      end do
     939              :    end do
     940              :  end do
     941              : 
     942         1128 :  ABI_FREE(cweights_tmp)
     943              : 
     944              :  ! Rescale weights so that the caller can sum over the full BZ.
     945              :  !if (use_bzsum_) cweights = cweights / ( self%lgk%weights(iqlk) * self%nbz )
     946              : 
     947         1128 :  ABI_FREE(pme_k)
     948              :  !call xmpi_sum(cweights, comm, ierr)
     949              : 
     950         1128 : end subroutine ephwg_get_zinv_weights
     951              : !!***
     952              : 
     953              : !!****f* m_ephwg/ephwg_free
     954              : !! NAME
     955              : !! ephwg_free
     956              : !!
     957              : !! FUNCTION
     958              : !!  Deallocate memory
     959              : !!
     960              : !! INPUTS
     961              : !!
     962              : !! OUTPUT
     963              : !!
     964              : !! SOURCE
     965              : 
     966          131 : subroutine ephwg_free(self)
     967              : 
     968              : !Arguments ------------------------------------
     969              :  class(ephwg_t),intent(inout) :: self
     970              : !----------------------------------------------------------------------
     971              : 
     972              :  ! integer
     973          131 :  ABI_SFREE(self%kq2ibz)
     974              : 
     975              :  ! Real
     976          131 :  ABI_SFREE(self%ibz)
     977          131 :  ABI_SFREE(self%bz)
     978          131 :  ABI_SFREE(self%lgk2ibz)
     979          131 :  ABI_SFREE(self%phfrq_ibz)
     980          131 :  ABI_SFREE(self%eigkbs_ibz)
     981              : 
     982              :  ! types
     983          131 :  call self%tetra_k%free()
     984          131 :  call self%lgk%free()
     985              : 
     986              :  ! nullify pointers
     987          131 :  self%cryst => null()
     988              : 
     989          131 : end subroutine ephwg_free
     990              : !!***
     991              : 
     992            0 : end module m_ephwg
     993              : !!***
        

Generated by: LCOV version 2.3-1