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-11-08 00:10:28 Functions: 75.0 % 12 9
Branches: 43.4 % 558 242

             Branch data     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