LCOV - code coverage report
Current view: top level - src/67_common - m_sigtk.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.6 % 395 334
Test Date: 2026-09-19 17:42:43 Functions: 71.4 % 14 10

            Line data    Source code
       1              : !!****m* ABINIT/m_sigtk
       2              : !! NAME
       3              : !!  m_sigtk
       4              : !!
       5              : !! FUNCTION
       6              : !!  Helper functions common to electron self-energy calculations. Provides tools to:
       7              : !!  Define list of k-points and bands in sel-energy matrix elements from input variables.
       8              : !!
       9              : !! COPYRIGHT
      10              : !!  Copyright (C) 2008-2026 ABINIT group (MG)
      11              : !!  This file is distributed under the terms of the
      12              : !!  GNU General Public License, see ~abinit/COPYING
      13              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      14              : !!
      15              : !! SOURCE
      16              : 
      17              : #if defined HAVE_CONFIG_H
      18              : #include "config.h"
      19              : #endif
      20              : 
      21              : #include "abi_common.h"
      22              : 
      23              : module m_sigtk
      24              : 
      25              :  use defs_basis
      26              :  use m_abicore
      27              :  use m_errors
      28              :  use m_ebands
      29              :  use m_crystal
      30              :  use m_xmpi
      31              :  use netcdf
      32              :  use m_nctk
      33              :  use m_hdr
      34              :  use m_dtset
      35              :  use m_krank
      36              : 
      37              :  use m_build_info,   only : abinit_version
      38              :  use m_fstrings,     only : sjoin, ltoa, strcat, itoa, ftoa
      39              :  use m_io_tools,     only : open_file
      40              :  use defs_datatypes, only : pseudopotential_type
      41              :  use defs_wvltypes,  only : wvl_internal_type
      42              :  use m_gwdefs,       only : sigijtab_t, sigijtab_free
      43              :  use m_esymm,        only : esymm_t
      44              :  use m_pawtab,       only : pawtab_type
      45              :  use m_kpts,         only : kpts_ibz_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map
      46              : 
      47              :  implicit none
      48              : 
      49              :  private
      50              : 
      51              :  public :: sigtk_kcalc_from_nkptgw
      52              :  public :: sigtk_kcalc_from_qprange
      53              :  public :: sigtk_kcalc_from_gaps
      54              :  public :: sigtk_kcalc_from_erange
      55              :  public :: sigtk_kpts_in_erange
      56              :  public :: sigtk_sigma_tables
      57              :  public :: sigtk_multiply_by_vc_sqrt
      58              :  public :: sigtk_dw_tpp_red
      59              : !!***
      60              : 
      61              :  ! Tables for degenerated KS states.
      62              :  type, public :: bids_t
      63              :    integer, allocatable :: vals(:)
      64              :  end type bids_t
      65              : 
      66              :  type, public :: degtab_t
      67              :    type(bids_t), allocatable :: bids(:)
      68              :    contains
      69              :    procedure :: free => degtab_free
      70              :  end type degtab_t
      71              : 
      72              :  public :: degtab_array_free   ! Free array of degtab_t objects.
      73              : !!***
      74              : 
      75              : contains  !=====================================================
      76              : !!***
      77              : 
      78              : !!****f* m_sigtk/sigtk_kcalc_from_nkptgw
      79              : !! NAME
      80              : !!  sigtk_kcalc_from_nkptgw
      81              : !!
      82              : !! FUNCTION
      83              : !!  Initialize list of k-points and bands for self-energy matrix elements from nkptgw.
      84              : !!
      85              : !! INPUT
      86              : !!  dtset<dataset_type>=All input variables for this dataset.
      87              : !!  mband: Max number of bands.
      88              : !!
      89              : !! OUTPUT
      90              : !!  nkcalc: Number of k-points in self-energy matrix elements.
      91              : !!  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
      92              : !!  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
      93              : !!  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
      94              : !!
      95              : !! SOURCE
      96              : 
      97           27 : subroutine sigtk_kcalc_from_nkptgw(dtset, mband, nkcalc, kcalc, bstart_ks, nbcalc_ks)
      98              : 
      99              : !Arguments ------------------------------------
     100              :  type(dataset_type),intent(in) :: dtset
     101              :  integer,intent(in) :: mband
     102              :  integer,intent(out) :: nkcalc
     103              : !arrays
     104              :  real(dp),allocatable,intent(out) :: kcalc(:,:)
     105              :  integer,allocatable,intent(out) :: bstart_ks(:,:)
     106              :  integer,allocatable,intent(out) :: nbcalc_ks(:,:)
     107              : 
     108              : !Local variables ------------------------------
     109              : !scalars
     110              :  integer :: spin, ierr, ikcalc
     111              :  character(len=500) :: msg
     112              : ! *************************************************************************
     113              : 
     114           27 :  call wrtout(std_out, " Generating list of k-points for self-energy from kptgw and bdgw.")
     115              : 
     116           27 :  nkcalc = dtset%nkptgw
     117           81 :  ABI_MALLOC(kcalc, (3, nkcalc))
     118          108 :  ABI_MALLOC(bstart_ks, (nkcalc, dtset%nsppol))
     119           81 :  ABI_MALLOC(nbcalc_ks, (nkcalc, dtset%nsppol))
     120              : 
     121          222 :  kcalc = dtset%kptgw(:,1:nkcalc)
     122           54 :  do spin=1,dtset%nsppol
     123           69 :    bstart_ks(:,spin) = dtset%bdgw(1,1:nkcalc,spin)
     124           96 :    nbcalc_ks(:,spin) = dtset%bdgw(2,1:nkcalc,spin) - dtset%bdgw(1,1:nkcalc,spin) + 1
     125              :  end do
     126              : 
     127              :  ! Consistency check on bdgw and mband
     128           27 :  ierr = 0
     129           54 :  do spin=1,dtset%nsppol
     130           96 :    do ikcalc=1,nkcalc
     131           69 :      if (dtset%bdgw(2,ikcalc,spin) > mband) then
     132            0 :        ierr = ierr + 1
     133              :        write(msg,'(a,2(i0,1x),2(a,i0))')&
     134            0 :         "For (k, s) ",ikcalc,spin," bdgw= ",dtset%bdgw(2,ikcalc,spin), " > mband = ",mband
     135            0 :        ABI_WARNING(msg)
     136              :      end if
     137              :    end do
     138              :  end do
     139           27 :  ABI_CHECK(ierr == 0, "Not enough bands in WFK file. See messages above. Aborting now.")
     140              : 
     141           27 : end subroutine sigtk_kcalc_from_nkptgw
     142              : !!***
     143              : 
     144              : !!****f* m_sigtk/sigtk_kcalc_from_qprange
     145              : !! NAME
     146              : !!  sigtk_kcalc_from_qprange
     147              : !!
     148              : !! FUNCTION
     149              : !! Use qprange to select the interesting k-points and the corresponding bands.
     150              : !!
     151              : !!    0 --> Compute the QP corrections only for the fundamental and the direct gap.
     152              : !! +num --> Compute the QP corrections for all the k-points in the irreducible zone and include `num`
     153              : !!           bands above and below the Fermi level.
     154              : !! -num --> Compute the QP corrections for all the k-points in the irreducible zone.
     155              : !!          Include all occupied states and `num` empty states.
     156              : !!
     157              : !! INPUT
     158              : !!  dtset<dataset_type>=All input variables for this dataset.
     159              : !!  cryst<crystal_t>=Crystalline structure
     160              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     161              : !!  qprange: See above description
     162              : !!
     163              : !! OUTPUT
     164              : !!  nkcalc: Number of k-points in self-energy matrix elements.
     165              : !!  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
     166              : !!  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
     167              : !!  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
     168              : !!
     169              : !! SOURCE
     170              : 
     171           11 : subroutine sigtk_kcalc_from_qprange(dtset, cryst, ebands, qprange, nkcalc, kcalc, bstart_ks, nbcalc_ks)
     172              : 
     173              : !Arguments ------------------------------------
     174              :  type(dataset_type),intent(in) :: dtset
     175              :  type(crystal_t),intent(in) :: cryst
     176              :  type(ebands_t),intent(in) :: ebands
     177              :  integer,intent(in) :: qprange
     178              :  integer,intent(out) :: nkcalc
     179              : !arrays
     180              :  real(dp),allocatable,intent(out) :: kcalc(:,:)
     181              :  integer,allocatable,intent(out) :: bstart_ks(:,:), nbcalc_ks(:,:)
     182              : 
     183              : !Local variables ------------------------------
     184              : !scalars
     185              :  integer :: spin, ik, bstop, mband, sigma_nkbz
     186              : !arrays
     187           22 :  integer :: kptrlatt(3,3), val_indices(ebands%nkpt, ebands%nsppol)
     188           11 :  real(dp),allocatable :: sigma_wtk(:),sigma_kbz(:,:)
     189              : ! *************************************************************************
     190              : 
     191           11 :  mband = ebands%mband
     192              : 
     193           11 :  val_indices = ebands%get_valence_idx()
     194              : 
     195           32 :  if (any(dtset%sigma_ngkpt /= 0)) then
     196            4 :     call wrtout(std_out, " Generating list of k-points for self-energy from sigma_ngkpt and qprange.")
     197            4 :     ABI_CHECK(qprange /= 0, "qprange must be != 0")
     198              :     ! Get %kcalc from sigma_ngkpt
     199            4 :     kptrlatt = 0
     200            4 :     kptrlatt(1,1) = dtset%sigma_ngkpt(1); kptrlatt(2,2) = dtset%sigma_ngkpt(2); kptrlatt(3,3) = dtset%sigma_ngkpt(3)
     201              :     call kpts_ibz_from_kptrlatt(cryst, kptrlatt, dtset%kptopt, dtset%sigma_nshiftk, dtset%sigma_shiftk, &
     202            4 :                                 nkcalc, kcalc, sigma_wtk, sigma_nkbz, sigma_kbz)
     203            4 :     ABI_FREE(sigma_kbz)
     204            4 :     ABI_FREE(sigma_wtk)
     205              :  else
     206              :     ! Include all the k-points in the IBZ.
     207              :     ! Note that kcalc == ebands%kptns so we can use a single ik index in the loop over k-points.
     208              :     ! No need to map kcalc onto ebands%kptns.
     209            7 :     call wrtout(std_out, " nkptgw set to 0 ==> Include all k-points in the IBZ for Sigma_nk.")
     210            7 :     nkcalc = ebands%nkpt
     211           21 :     ABI_MALLOC(kcalc, (3, nkcalc))
     212          238 :     kcalc = ebands%kptns
     213              :  end if
     214              : 
     215           44 :  ABI_MALLOC(bstart_ks, (nkcalc, dtset%nsppol))
     216           33 :  ABI_MALLOC(nbcalc_ks, (nkcalc, dtset%nsppol))
     217              : 
     218           11 :  if (qprange > 0) then
     219           11 :    call wrtout(std_out, " Using buffer of bands above and below the Fermi level.")
     220           22 :    do spin=1,dtset%nsppol
     221           90 :      do ik=1,nkcalc
     222           68 :        bstart_ks(ik,spin) = max(val_indices(ik,spin) - qprange, 1)
     223           68 :        bstop = min(val_indices(ik,spin) + qprange, mband)
     224           79 :        nbcalc_ks(ik,spin) = bstop - bstart_ks(ik,spin) + 1
     225              :      end do
     226              :    end do
     227              : 
     228              :  else
     229            0 :    call wrtout(std_out, " Including all occupied states and -qprange empty states.")
     230            0 :    bstart_ks = 1
     231            0 :    do spin=1,dtset%nsppol
     232            0 :      do ik=1,nkcalc
     233            0 :        nbcalc_ks(ik,spin) = min(val_indices(ik,spin) - qprange, mband)
     234              :      end do
     235              :    end do
     236              :  end if
     237              : 
     238           11 : end subroutine sigtk_kcalc_from_qprange
     239              : !!***
     240              : 
     241              : !!****f* m_sigtk/sigtk_kcalc_from_gaps
     242              : !! NAME
     243              : !!  sigtk_kcalc_from_gaps
     244              : !!
     245              : !! FUNCTION
     246              : !!  Select list of k-points and bands for self-energy matrix elements so that fundamental and direct gaps are included.
     247              : !!
     248              : !! INPUT
     249              : !!  dtset<dataset_type>=All input variables for this dataset.
     250              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     251              : !!  gaps<gaps_t>=Store location of gaps.
     252              : !!
     253              : !! OUTPUT
     254              : !!  nkcalc: Number of k-points in self-energy matrix elements.
     255              : !!  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
     256              : !!  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
     257              : !!  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
     258              : !!
     259              : !! SOURCE
     260              : 
     261           14 : subroutine sigtk_kcalc_from_gaps(dtset, ebands, gaps, nkcalc, kcalc, bstart_ks, nbcalc_ks)
     262              : 
     263              : !Arguments ------------------------------------
     264              :  type(dataset_type),intent(in) :: dtset
     265              :  type(ebands_t),intent(in) :: ebands
     266              :  type(gaps_t) :: gaps
     267              :  integer,intent(out) :: nkcalc
     268              : !arrays
     269              :  real(dp),allocatable,intent(out) :: kcalc(:,:)
     270              :  integer,allocatable,intent(out) :: bstart_ks(:,:)
     271              :  integer,allocatable,intent(out) :: nbcalc_ks(:,:)
     272              : 
     273              : !Local variables ------------------------------
     274              : !scalars
     275              :  integer :: spin, nsppol, ii, ik_ibz, nk_found, ifo, jj, ib_min, ib_max
     276              :  logical :: found, changed
     277              : !arrays
     278           28 :  integer :: val_indices(ebands%nkpt, ebands%nsppol), kpos(6)
     279              : ! *************************************************************************
     280              : 
     281              :  ABI_UNUSED((/dtset%natom/))
     282              : 
     283           14 :  call wrtout(std_out, " Including direct and fundamental KS gap in Sigma_nk")
     284           28 :  ABI_CHECK(maxval(gaps%ierr) == 0, "qprange 0 cannot be used because I cannot find the gap (gap_err !=0)")
     285              : 
     286           14 :  nsppol = ebands%nsppol
     287           14 :  val_indices = ebands%get_valence_idx()
     288              : 
     289              :  ! Include the direct and the fundamental KS gap.
     290              :  ! The problem here is that kptgw and nkptgw do not depend on the spin and therefore
     291              :  ! we have compute the union of the k-points where the fundamental and the direct gaps are located.
     292           14 :  nk_found = 1; kpos(1) = gaps%fo_kpos(1,1)
     293              : 
     294              :  ! Find the list of `interesting` kpoints.
     295           28 :  do spin=1,nsppol
     296           70 :    do ifo=1,3
     297           42 :      ik_ibz = gaps%fo_kpos(ifo, spin)
     298           42 :      found = .False.; jj = 0
     299           84 :      do while (.not. found .and. jj < nk_found)
     300           42 :        jj = jj + 1; found = (kpos(jj) == ik_ibz)
     301              :      end do
     302           56 :      if (.not. found) then
     303           10 :        nk_found = nk_found + 1; kpos(nk_found) = ik_ibz
     304              :      end if
     305              :    end do
     306              :  end do
     307              : 
     308              :  ! Now we can define the list of k-points and the bands range.
     309           14 :  nkcalc = nk_found
     310           42 :  ABI_MALLOC(kcalc, (3, nkcalc))
     311           56 :  ABI_MALLOC(bstart_ks, (nkcalc, nsppol))
     312           42 :  ABI_MALLOC(nbcalc_ks, (nkcalc, nsppol))
     313              : 
     314           38 :  do ii=1,nkcalc
     315           24 :    ik_ibz = kpos(ii)
     316           96 :    kcalc(:,ii) = ebands%kptns(:,ik_ibz)
     317           62 :    do spin=1,nsppol
     318              :      ! Enlarge initial band range to include degenerate states.
     319           24 :      ib_min = val_indices(ik_ibz, spin)
     320           24 :      ib_max = ib_min + 1
     321           24 :      call ebands%enclose_degbands(ik_ibz, spin, ib_min, ib_max, changed, dtset%symsigma_de)
     322           24 :      bstart_ks(ii,spin) = ib_min
     323           48 :      nbcalc_ks(ii,spin) = ib_max - ib_min + 1
     324              :    end do
     325              :  end do
     326              : 
     327           14 : end subroutine sigtk_kcalc_from_gaps
     328              : !!***
     329              : 
     330              : !!****f* m_sigtk/sigtk_kcalc_from_erange
     331              : !! NAME
     332              : !!  sigtk_kcalc_from_erange
     333              : !!
     334              : !! FUNCTION
     335              : !!  Select list of k-points and bands for self-energy matrix elements on the basis of their positions
     336              : !!  wrt to the (band edges|fermi level) and the value of sigma_erange.
     337              : !!  Useful when computing electron-lifetimes for transport calculations.
     338              : !!
     339              : !! INPUT
     340              : !!  dtset<dataset_type>=All input variables for this dataset.
     341              : !!  cryst<crystal_t>=Crystalline structure
     342              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     343              : !!  gaps<gaps_t>=Store location of gaps.
     344              : !!  comm: MPI communicator.
     345              : !!
     346              : !! OUTPUT
     347              : !!  nkcalc: Number of k-points in self-energy matrix elements.
     348              : !!  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
     349              : !!  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
     350              : !!  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
     351              : !!
     352              : !! SOURCE
     353              : 
     354           14 : subroutine sigtk_kcalc_from_erange(dtset, cryst, ebands, gaps, nkcalc, kcalc, bstart_ks, nbcalc_ks, comm)
     355              : 
     356              : !Arguments ------------------------------------
     357              :  type(dataset_type),intent(in) :: dtset
     358              :  type(crystal_t),intent(in) :: cryst
     359              :  type(ebands_t),intent(in) :: ebands
     360              :  type(gaps_t),intent(in) :: gaps
     361              :  integer,intent(in) :: comm
     362              :  integer,intent(out) :: nkcalc
     363              : !arrays
     364              :  real(dp),allocatable,intent(out) :: kcalc(:,:)
     365              :  integer,allocatable,intent(out) :: bstart_ks(:,:)
     366              :  integer,allocatable,intent(out) :: nbcalc_ks(:,:)
     367              : 
     368              : !Local variables ------------------------------
     369              : !scalars
     370              :  integer,parameter :: master = 0
     371              :  integer :: spin, ik, band, ii, ic, nsppol, tmp_nkpt, sigma_nkbz, my_rank
     372              :  logical :: found
     373              :  real(dp) :: cmin, vmax, ee
     374              :  logical :: assume_gap
     375              :  character(len=500) :: msg
     376           14 :  type(krank_t) :: krank
     377              : !arrays
     378           28 :  integer :: kptrlatt(3,3), units(1), kpos(ebands%nkpt)
     379           14 :  integer,allocatable :: ib_work(:,:,:), sigmak2ebands(:), indkk(:,:)
     380           14 :  real(dp),allocatable :: sigma_wtk(:),sigma_kbz(:,:),tmp_kcalc(:,:)
     381              : ! *************************************************************************
     382              : 
     383           14 :  my_rank = xmpi_comm_rank(comm) !; nprocs = xmpi_comm_size(comm)
     384           28 :  units = [std_out]
     385           16 :  assume_gap = .not. all(dtset%sigma_erange < zero)
     386              : 
     387           14 :  if (my_rank == master) then
     388           14 :    write(std_out, "(a)")" Selecting k-points and bands according to their position wrt the band edges (sigma_erange)."
     389           42 :    write(std_out, "(a, 2(f6.3, 1x), a)")" sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
     390           14 :    if (assume_gap) then
     391           26 :      call gaps%print([std_out])
     392           26 :      ABI_CHECK(maxval(gaps%ierr) == 0, "sigma_erange 0 cannot be used because I cannot find the gap (gap_err !=0)")
     393              :    end if
     394              :  end if
     395              : 
     396           50 :  if (any(dtset%sigma_ngkpt /= 0)) then
     397            2 :     call wrtout(std_out, sjoin(" Generating initial list of k-points from sigma_nkpt:", ltoa(dtset%sigma_ngkpt)))
     398              :     ! Get tentative tmp_nkpt and tmp_kcalc from sigma_ngkpt.
     399            2 :     kptrlatt = 0
     400            2 :     kptrlatt(1,1) = dtset%sigma_ngkpt(1); kptrlatt(2,2) = dtset%sigma_ngkpt(2); kptrlatt(3,3) = dtset%sigma_ngkpt(3)
     401              :     call kpts_ibz_from_kptrlatt(cryst, kptrlatt, dtset%kptopt, dtset%sigma_nshiftk, dtset%sigma_shiftk, &
     402            2 :                                 tmp_nkpt, tmp_kcalc, sigma_wtk, sigma_nkbz, sigma_kbz)
     403              : 
     404            2 :     ABI_FREE(sigma_kbz)
     405            2 :     ABI_FREE(sigma_wtk)
     406              : 
     407              :     ! Map tmp_kcalc to ebands%kpts
     408              : 
     409            6 :     ABI_MALLOC(indkk, (6, tmp_nkpt))
     410              : 
     411            2 :     call krank%from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.)
     412              : 
     413            2 :     if (kpts_map("symrec", ebands%kptopt, cryst, krank, tmp_nkpt, tmp_kcalc, indkk) /= 0) then
     414              :       write(msg, '(3a)' )&
     415            0 :         "At least one of the k-points could not be generated from a symmetrical one in the WFK.",ch10,&
     416            0 :         'Action: check your WFK file and the value of sigma_nkpt, sigma_shiftk in the input file.'
     417            0 :       ABI_ERROR(msg)
     418              :     end if
     419              : 
     420            2 :     call krank%free()
     421              : 
     422            6 :     ABI_MALLOC(sigmak2ebands, (tmp_nkpt))
     423           10 :     sigmak2ebands = indkk(1, :)
     424            2 :     ABI_FREE(tmp_kcalc)
     425            2 :     ABI_FREE(indkk)
     426              : 
     427              :  else
     428              :    ! Include all the k-points in the IBZ in the initial list.
     429           12 :    call wrtout(std_out, " Generating initial list of k-points from input ebands%kptns.")
     430           12 :    tmp_nkpt = ebands%nkpt
     431              :    ! Trivial map
     432           36 :    ABI_MALLOC(sigmak2ebands, (tmp_nkpt))
     433        10506 :    sigmak2ebands = [(ii, ii=1, ebands%nkpt)]
     434              :  end if
     435              : 
     436           14 :  nsppol = ebands%nsppol
     437           56 :  ABI_MALLOC(ib_work, (2, tmp_nkpt, nsppol))
     438              : 
     439           28 :  do spin=1,nsppol
     440              : 
     441           14 :    if (assume_gap) then
     442              :      ! Get CBM and VBM with some tolerance
     443           13 :      vmax = gaps%vb_max(spin) + tol2 * eV_Ha
     444           13 :      cmin = gaps%cb_min(spin) - tol2 * eV_Ha
     445              :    else
     446            1 :      vmax = ebands%fermie
     447            1 :      cmin = ebands%fermie
     448              :    end if
     449              : 
     450         3528 :    do ii=1,tmp_nkpt
     451              :      ! Index of k-point in ebands.
     452         3500 :      ik = sigmak2ebands(ii)
     453              :      ! Will use this initial values to understand if k-point is in energy window.
     454         3500 :      ib_work(1, ii, spin) = huge(1)
     455         3500 :      ib_work(2, ii, spin) = -huge(1)
     456        33688 :      do band=1,ebands%nband(ik + (spin-1) * ebands%nkpt)
     457        30174 :         ee = ebands%eig(band, ik, spin)
     458        30174 :         if (abs(dtset%sigma_erange(1)) > zero) then
     459         3582 :           if (ee <= vmax .and. vmax - ee <= abs(dtset%sigma_erange(1))) then
     460           38 :             ib_work(1, ii, spin) = min(ib_work(1, ii, spin), band)
     461           38 :             ib_work(2, ii, spin) = max(ib_work(2, ii, spin), band)
     462              :             !write(std_out, *), "Adding valence band", band, " with ee [eV]: ", ee * Ha_eV
     463              :           end if
     464              :         end if
     465        33674 :         if (abs(dtset%sigma_erange(2)) > zero) then
     466        30174 :           if (ee >= cmin .and. ee - cmin <= abs(dtset%sigma_erange(2))) then
     467           44 :             ib_work(1, ii, spin) = min(ib_work(1, ii, spin), band)
     468           44 :             ib_work(2, ii, spin) = max(ib_work(2, ii, spin), band)
     469              :             !write(std_out, *)"Adding conduction band", band, " with ee [eV]: ", ee * Ha_eV
     470              :           end if
     471              :         end if
     472              :      end do
     473              :    end do
     474              :  end do
     475              : 
     476              :  ! Now we can define the list of k-points and the bands range.
     477              :  ! The main problem here is that kptgw and nkptgw do not depend on the spin and therefore
     478              :  ! we have to compute the union of the k-points.
     479           14 :  nkcalc = 0
     480         3514 :  do ii=1,tmp_nkpt
     481         6940 :    found = .False.
     482         6940 :    do spin=1,nsppol
     483         6940 :       if (ib_work(1, ii, spin) <= ib_work(2, ii, spin)) then
     484              :         found = .True.; exit
     485              :       end if
     486              :    end do
     487         3514 :    if (found) then
     488           60 :      nkcalc = nkcalc + 1
     489           60 :      kpos(nkcalc) = ii
     490              :    end if
     491              :  end do
     492              : 
     493           42 :  ABI_MALLOC(kcalc, (3, nkcalc))
     494           56 :  ABI_MALLOC(bstart_ks, (nkcalc, nsppol))
     495           42 :  ABI_MALLOC(nbcalc_ks, (nkcalc, nsppol))
     496              : 
     497           74 :  do ic=1,nkcalc
     498              :    ! Index in the ib_work array
     499           60 :    ii = kpos(ic)
     500              :    ! Index in ebands.
     501           60 :    ik = sigmak2ebands(ii)
     502          240 :    kcalc(:,ic) = ebands%kptns(:,ik)
     503          134 :    do spin=1,nsppol
     504           60 :      bstart_ks(ic, spin) = 0
     505           60 :      nbcalc_ks(ic, spin) = 0
     506           60 :      if (ib_work(1, ii, spin) <= ib_work(2, ii, spin)) then
     507           60 :        bstart_ks(ic, spin) = ib_work(1, ii, spin)
     508           60 :        nbcalc_ks(ic, spin) = ib_work(2, ii, spin) - ib_work(1, ii, spin) + 1
     509              :      end if
     510          120 :      if (nbcalc_ks(ic, spin) == 0) then
     511            0 :        ABI_WARNING("Spin-polarized case with nbcalc_ks == 0, don't know if code can handle it!")
     512              :      end if
     513              :    end do
     514              :  end do
     515              : 
     516           14 :  if (my_rank == master) then
     517              :    ! Write info about k-points used in the calculation.
     518              :    write(msg, "(a, i0, a, 2(f6.3, 1x), a)") &
     519           42 :      " Found ", nkcalc, " k-points within sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
     520           14 :    call wrtout(units, msg)
     521           50 :    if (any(dtset%sigma_ngkpt /= 0)) then
     522            2 :      call wrtout(units, sjoin(" These k-points belong to the sigma_ngkpt k-mesh:", ltoa(dtset%sigma_ngkpt)))
     523              :    end if
     524          162 :    write(msg, "(2(a, i0))")" min(nbcalc_ks): ", minval(nbcalc_ks), " Max(nbcalc_ks): ", maxval(nbcalc_ks)
     525           14 :    call wrtout(units, msg)
     526              :  end if
     527              : 
     528           14 :  ABI_FREE(ib_work)
     529           14 :  ABI_FREE(sigmak2ebands)
     530              : 
     531           14 : end subroutine sigtk_kcalc_from_erange
     532              : !!***
     533              : 
     534              : !!****f* m_sigmaph/sigtk_kpts_in_erange
     535              : !! NAME
     536              : !!  sigtk_kpts_in_erange
     537              : !!
     538              : !! FUNCTION
     539              : !!  Use star functions interpolation and [[einterp]] to interpolate KS energies onto dense k-mesh
     540              : !!  defined by [[sigma_ngkpt]] and [[sigma_shiftk]].
     541              : !!  find k-points inside (electron/hole) pockets according to the values specified by [[sigma_erange]].
     542              : !!  write kerange.nc file with the tables required by abinit to automate nscf band structure calculations
     543              : !!  mainly used to prepare eph calculations in which only selected k-points are nededed (imaginary part of self-energies).
     544              : !!
     545              : !! INPUTS
     546              : !!  dtset <dataset_type>=all input variables for this dataset
     547              : !!  cryst<crystal_t>=Crystalline structure
     548              : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     549              : !!  psps <pseudopotential_type>=all the information about psps
     550              : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
     551              : !!  prefix=Prefix for output file.
     552              : !!  comm: MPI communicator.
     553              : !!
     554              : !! SOURCE
     555              : 
     556            2 : subroutine sigtk_kpts_in_erange(dtset, cryst, ebands, psps, pawtab, prefix, comm)
     557              : 
     558              : !Arguments ------------------------------------
     559              : !scalars
     560              :  type(dataset_type),intent(in) :: dtset
     561              :  type(crystal_t),intent(in) :: cryst
     562              :  type(ebands_t),intent(in) :: ebands
     563              :  type(pseudopotential_type),intent(in) :: psps
     564              :  character(len=*),intent(in) :: prefix
     565              :  integer,intent(in) :: comm
     566              : !arrays
     567              :  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw)
     568              : 
     569              : !Local variables ------------------------------
     570              : !scalars
     571              :  integer,parameter :: master = 0, pertcase0 = 0, image1 = 1
     572              :  integer :: ii, my_rank, nprocs, spin, ikf_ibz, band, nkpt_inerange, gap_err, unt, ncid, cnt, ncerr
     573              :  logical :: assume_gap
     574              :  real(dp) :: ee, cmin, vmax
     575              :  character(len=500) :: msg
     576              :  character(len=fnlen) :: path
     577            2 :  type(ebands_t) :: fine_ebands
     578            2 :  type(gaps_t) :: gaps, fine_gaps
     579            2 :  type(wvl_internal_type) :: dummy_wvl
     580            2 :  type(hdr_type) :: fine_hdr
     581              : !arrays
     582              :  integer :: fine_kptrlatt(3,3), band_block(2), units(2)
     583            2 :  integer,allocatable :: kshe_mask(:,:,:), krange2ibz(:)
     584              :  real(dp) :: params(4)
     585              : ! *************************************************************************
     586              : 
     587            2 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
     588              : 
     589              :  ! (-num, -num) activate treatment of metals with energy window around Efermi.
     590            4 :  assume_gap = .not. all(dtset%sigma_erange < zero)
     591            6 :  units = [std_out, ab_out]
     592              : 
     593            2 :  if (my_rank == master) then
     594            2 :    call wrtout(units, sjoin(ch10, repeat("=", 92)))
     595            2 :    call wrtout(units, " Using SKW interpolation to interpolate KS energies onto dense k-mesh.")
     596            2 :    call wrtout(units, sjoin(" defined by sigma_ngkpt:", trim(ltoa(dtset%sigma_ngkpt))))
     597            2 :    ABI_CHECK(allocated(dtset%sigma_shiftk), "sigma_nshiftk must be specified in input.")
     598            2 :    write(std_out, "(2a)") " and sigma_shiftk shifts:"
     599            4 :    do ii=1,dtset%nshiftk
     600            4 :      call wrtout(units, sjoin(itoa(ii), ltoa(dtset%sigma_shiftk(:, ii))))
     601              :    end do
     602              : 
     603            2 :    if (assume_gap) then
     604            1 :      call wrtout(units, " Finding k-points inside (electron/hole) pockets (assuming semiconductor).")
     605              :    else
     606            1 :      call wrtout(units, " Finding k-points inside energy window around Fermi level (assuming metal).")
     607              :    end if
     608            6 :    write(msg, "(a, 2(f6.3, 1x), a)")" Using sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
     609            2 :    call wrtout(units, msg)
     610            2 :    call wrtout(units, sjoin(" SKW parameters (einterp): ", ltoa(dtset%einterp)))
     611            2 :    call wrtout(units, sjoin(repeat("=", 92), ch10))
     612              :    !call ebands%print([std_out], header, prtvol=dtset%prtvol)
     613              : 
     614              :    ! Consistency check.
     615            2 :    if (all(dtset%sigma_erange == zero)) then
     616            0 :      ABI_ERROR("sigma_erange must be specified in input when calling sigtk_kpts_in_erange.")
     617              :    end if
     618            2 :    if (all(dtset%sigma_ngkpt == 0)) then
     619            0 :      ABI_ERROR("sigma_ngkpt must be specified in input when calling sigtk_kpts_in_erange.")
     620              :    end if
     621              :  end if
     622              : 
     623            2 :  if (assume_gap) then
     624              :    ! Compute gaps using input ebands.
     625            1 :    gaps = ebands%get_gaps(gap_err)
     626            1 :    if (gap_err /= 0) then
     627            0 :      ABI_ERROR("Cannot compute fundamental and direct gap (likely metal).")
     628              :    end if
     629              : 
     630            1 :    if (my_rank == master) call gaps%print(units, header="Gaps from input WFK")
     631            1 :    call gaps%free()
     632              :  else
     633            1 :    call wrtout(units, sjoin("Using Fermi level:", ftoa(ebands%fermie * Ha_eV, fmt="f6.2"), " (eV)"))
     634              :  end if
     635              : 
     636              :  ! Interpolate band energies with star functions.
     637              :  ! In the EPH code, we will need eigens in the IBZ to compute efermi not just energies inside pockets.
     638            2 :  fine_kptrlatt = 0
     639            8 :  do ii=1,3
     640            8 :    fine_kptrlatt(ii, ii) = dtset%sigma_ngkpt(ii)
     641              :  end do
     642            6 :  band_block = [1, ebands%mband]
     643           10 :  params = 0; params(1) = 1; params(2) = 5; if (nint(dtset%einterp(1)) == 1) params = dtset%einterp
     644              : 
     645              :  fine_ebands = ebands%interp_kmesh(cryst, params, fine_kptrlatt, &
     646            2 :                                    dtset%sigma_nshiftk, dtset%sigma_shiftk, band_block, comm)
     647          176 :  fine_ebands%istwfk = 1
     648              : 
     649            2 :  call fine_ebands%update_occ(dtset%spinmagntarget, prtvol=dtset%prtvol)
     650            4 :  call fine_ebands%print([std_out], header="FINE EBANDS", prtvol=dtset%prtvol)
     651              : 
     652            2 :  if (assume_gap) then
     653              :    ! Compute gaps using fine_ebands.
     654            1 :    fine_gaps = fine_ebands%get_gaps(gap_err)
     655            1 :    if (gap_err /= 0) then
     656            0 :      ABI_ERROR("Cannot compute fundamental and direct gap (likely metal).")
     657              :    end if
     658              : 
     659            1 :    if (my_rank == master) call fine_gaps%print(units, header="Gaps from SKW interpolated eigenvalues")
     660              :  end if
     661              : 
     662              :  ! Build new header with fine k-mesh (note kptrlatt_orig == kptrlatt)
     663              :  call fine_hdr%init_lowlvl(fine_ebands, psps, pawtab, dummy_wvl, abinit_version, pertcase0, &
     664              :    dtset%natom, dtset%nsym, dtset%nspden, dtset%ecut, dtset%pawecutdg, dtset%ecutsm, dtset%dilatmx, &
     665              :    dtset%intxc, dtset%ixc, dtset%stmbias, dtset%usewvl, dtset%pawcpxocc, dtset%pawspnorb, dtset%ngfft, dtset%ngfftdg, &
     666              :    dtset%so_psp, dtset%qptn, cryst%rprimd, cryst%xred, cryst%symrel, cryst%tnons, cryst%symafm, cryst%typat, &
     667              :    dtset%amu_orig(:, image1), dtset%icoulomb, &
     668              :    dtset%kptopt, dtset%nelect, dtset%ne_qFD, dtset%nh_qFD, dtset%ivalence, dtset%cellcharge(1), &
     669            2 :    fine_kptrlatt, fine_kptrlatt, dtset%sigma_nshiftk, dtset%sigma_nshiftk, dtset%sigma_shiftk, dtset%sigma_shiftk)
     670              : 
     671              :  ! Find k-points inside sigma_erange energy window.
     672              :  ! Set entry to the number of states inside the pocket at (ikpt, spin)
     673              :  ! (last index discerns between hole and electron pockets)
     674          366 :  ABI_ICALLOC(kshe_mask, (fine_ebands%nkpt, ebands%nsppol, 2))
     675              : 
     676            4 :  do spin=1,ebands%nsppol
     677              :    ! Get CBM and VBM with some tolerance.
     678            2 :    if (assume_gap) then
     679            1 :      vmax = fine_gaps%vb_max(spin) + tol2 * eV_Ha
     680            1 :      cmin = fine_gaps%cb_min(spin) - tol2 * eV_Ha
     681              :    else
     682              :      ! Note that we use the Fermi level from ebands instead of fine_ebands.
     683            1 :      vmax = ebands%fermie
     684            1 :      cmin = ebands%fermie
     685              :    end if
     686              : 
     687          178 :    do ikf_ibz=1,fine_ebands%nkpt
     688         3111 :      do band=1,ebands%mband
     689         2952 :        ee = fine_ebands%eig(band, ikf_ibz, spin)
     690              :        ! Check whether the interpolated eigenvalue is inside the sigma_erange window.
     691         2952 :        if (abs(dtset%sigma_erange(1)) > zero) then
     692         2952 :          if (ee <= vmax .and. vmax - ee <= abs(dtset%sigma_erange(1))) then
     693           11 :            kshe_mask(ikf_ibz, spin, 1) = kshe_mask(ikf_ibz, spin, 1) + 1; exit
     694              :          end if
     695              :        end if
     696         3098 :        if (abs(dtset%sigma_erange(2)) > zero) then
     697         2941 :          if (ee >= cmin .and. ee - cmin <= abs(dtset%sigma_erange(2))) then
     698            6 :            kshe_mask(ikf_ibz, spin, 2) = kshe_mask(ikf_ibz, spin, 2) + 1; exit
     699              :          end if
     700              :        end if
     701              :      end do
     702              :    end do
     703              :  end do
     704              : 
     705              :  ! Build list of k-points inside pockets. Use over dimensioned array.
     706          358 :  cnt = count(kshe_mask /= 0)
     707            6 :  ABI_MALLOC(krange2ibz, (cnt))
     708          176 :  cnt = 0
     709          176 :  do ikf_ibz=1,fine_ebands%nkpt
     710          816 :    if (any(kshe_mask(ikf_ibz,:,:) /= 0)) then
     711           17 :      cnt = cnt + 1; krange2ibz(cnt) = ikf_ibz
     712              :    end if
     713              :  end do
     714            2 :  nkpt_inerange = cnt
     715              : 
     716              :  ! Possible extensions that may be implemented at this level:
     717              :  !     1. Find image points in the BZ?
     718              :  !     2. Compute tetra and q-points for EPH calculation or use +/- wmax window and heuristic approach in sigmaph at runtime?
     719              :  !     3. Compute SKW 1st and 2nd derivatives needed to treat Frohlich?
     720              : 
     721              :  ! Write output files with k-point list.
     722            2 :  if (my_rank == master .and. len_trim(prefix) /= 0) then
     723            2 :    write(std_out, "(a,i0,a,f5.1,a)")" Found: ",  nkpt_inerange, " kpoints in sigma_erange energy windows. (nkeff / nkibz): ", &
     724            4 :        (100.0_dp * nkpt_inerange) / fine_ebands%nkpt, " [%]"
     725              : 
     726              :    ! Write text file with Abinit input variables (mainly for testing purposes).
     727            2 :    path = strcat(prefix, "_KERANGE")
     728            2 :    if (open_file(path, msg, newunit=unt, form="formatted") /= 0) then
     729            0 :      ABI_ERROR(msg)
     730              :    end if
     731            2 :    write(unt, "(a)")"kptopt 0"
     732            2 :    write(unt, "(a, i0)")"nkpt ", nkpt_inerange
     733            2 :    write(unt, "(a)")"kpt"
     734           19 :    do ii=1,nkpt_inerange
     735           19 :      write(unt, "(3(es16.8,1x))") fine_ebands%kptns(:, krange2ibz(ii))
     736              :    end do
     737            2 :    write(unt, "(a, i0)")"wtk"
     738           19 :    do ii=1,nkpt_inerange
     739           19 :      write(unt, "(es16.8)") fine_ebands%wtk(krange2ibz(ii))
     740              :    end do
     741            2 :    close(unt)
     742              : 
     743              :    ! Write netcdf file used to perform NSCF run and EPH calculations with eph_task = -4.
     744            2 :    path = strcat(prefix, "_KERANGE.nc")
     745            2 :    NCF_CHECK(nctk_open_create(ncid, path, xmpi_comm_self))
     746              :    ! Write crystalline structure, fine_hdr and fine_ebands defined on the fine k-mesh.
     747              :    ! fine_ebands will be used to compare with the ab-initio NSCF eigenvalues.
     748              :    !
     749              :    ! TODO: The size of the KERANGE.nc quickly increases with the k-mesh.
     750              :    ! It is ~700 Mb for a ~ 300^3 grid due to occ and eigens
     751              :    ! But these quantities are now used in inkpts so it may be possible to avoid writing them to disk.
     752              :    !
     753            2 :    NCF_CHECK(fine_hdr%ncwrite(ncid, fform_from_ext("KERANGE.nc"), nc_define=.True.))
     754            2 :    NCF_CHECK(cryst%ncwrite(ncid))
     755            2 :    NCF_CHECK(fine_ebands%ncwrite(ncid))
     756            4 :    NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("nkpt_inerange", nkpt_inerange)], defmode=.True.))
     757              :    ! Define extra arrays.
     758              :    ncerr = nctk_def_arrays(ncid, [ &
     759              :      nctkarr_t("kshe_mask", "int", "number_of_kpoints, number_of_spins, two"), &
     760              :      nctkarr_t("krange2ibz", "int", "nkpt_inerange"), &
     761              :      nctkarr_t("sigma_erange", "dp", "two"), &
     762              :      nctkarr_t("einterp", "dp", "four") &
     763           10 :    ], defmode=.True.)
     764            2 :    NCF_CHECK(ncerr)
     765              :    ! Write extra arrays.
     766            2 :    NCF_CHECK(nctk_set_datamode(ncid))
     767            2 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kshe_mask"), kshe_mask))
     768            2 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "krange2ibz"), krange2ibz(1:nkpt_inerange)))
     769            2 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_erange"), dtset%sigma_erange))
     770            2 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "einterp"), params))
     771            2 :    NCF_CHECK(nf90_close(ncid))
     772              :  end if
     773              : 
     774            2 :  ABI_FREE(kshe_mask)
     775            2 :  ABI_FREE(krange2ibz)
     776              : 
     777            2 :  call fine_gaps%free(); call fine_ebands%free(); call fine_hdr%free()
     778              : 
     779            2 : end subroutine sigtk_kpts_in_erange
     780              : !!***
     781              : 
     782           12 : subroutine degtab_free(degtab)
     783              :  class(degtab_t),intent(inout) :: degtab
     784              :  integer :: ii
     785           46 :  do ii=1,size(degtab%bids)
     786           46 :    ABI_SFREE(degtab%bids(ii)%vals)
     787              :  end do
     788           46 :  ABI_FREE(degtab%bids)
     789           12 : end subroutine degtab_free
     790              : 
     791           56 : subroutine degtab_array_free(degtab)
     792              :  class(degtab_t),intent(inout) :: degtab(:,:)
     793              : 
     794              :  integer :: jj, ii, ideg
     795              : 
     796          112 :  do jj=1,size(degtab, dim=2)
     797          284 :    do ii=1,size(degtab, dim=1)
     798          172 :      if (.not. allocated(degtab(ii, jj)%bids)) cycle
     799          630 :      do ideg=1,size(degtab(ii, jj)%bids)
     800          630 :        ABI_SFREE(degtab(ii, jj)%bids(ideg)%vals)
     801              :      end do
     802          686 :      ABI_SFREE(degtab(ii, jj)%bids)
     803              :    end do
     804              :  end do
     805              : 
     806           56 : end subroutine degtab_array_free
     807              : !!***
     808              : 
     809              : !----------------------------------------------------------------------
     810              : 
     811              : !!****f* m_sigtk/sigtk_sigma_tables
     812              : !! NAME
     813              : !!  sigtk_sigma_tables
     814              : !!
     815              : !! FUNCTION
     816              : !!  Build tables with the band indices used to compute the matrix elements of sigma_x and sigma_c
     817              : !!  taking into account the kind of self-energies and symmetries from esymm.
     818              : !!
     819              : !! INPUTS
     820              : !!  nkcalc: Number of k-points to compute.
     821              : !!  nkibz: Number of k-points in the IBZ.
     822              : !!  nsppol: Number of spins.
     823              : !!  bstart_ks, bstop_ks: First and last band for each (ikcalc, spin).
     824              : !!  kcalc2ibz: Mapping kcalc --> IBZ.
     825              : !!  only_diago: True if only diagonal matrix elements are wanted.
     826              : !!  sigc_is_herm: True is Sigma_c is Hermitian.
     827              : !!  [esymm]: Band symmetries
     828              : !!
     829              : !! OUTPUT
     830              : !!  sigxij_tab, sigcij_tab
     831              : !!
     832              : !! SOURCE
     833              : 
     834          402 : subroutine sigtk_sigma_tables(nkcalc, nkibz, nsppol, bstart_ks, bstop_ks, kcalc2ibz, &
     835            0 :                               only_diago, sigc_is_herm, sigxij_tab, sigcij_tab, esymm)
     836              : 
     837              : !Arguments ------------------------------------
     838              :  integer,intent(in) :: nkcalc, nkibz, nsppol
     839              :  integer,intent(in) :: bstart_ks(nkcalc, nsppol), bstop_ks(nkcalc, nsppol)
     840              :  logical,intent(in) :: only_diago, sigc_is_herm
     841              :  integer,intent(in) :: kcalc2ibz(nkcalc)
     842              :  type(sigijtab_t),allocatable,intent(inout) :: Sigxij_tab(:,:), Sigcij_tab(:,:)
     843              :  type(esymm_t),optional,intent(in) :: esymm(nkibz, nsppol)
     844              : 
     845              : !Local variables-------------------------------
     846              : !scalars
     847              :  integer :: spin,ikcalc,ik_ibz,bmin,bmax,bcol,brow
     848              :  integer :: ii,idx_x,idx_c,irr_idx1,irr_idx2
     849              : !arrays
     850          201 :  integer,allocatable :: sigc_bidx(:), sigx_bidx(:)
     851          402 :  logical :: use_sym_at(nkibz, nsppol)
     852              : ! *************************************************************************
     853              : 
     854          201 :  if (allocated(Sigxij_tab)) then
     855            0 :    call sigijtab_free(Sigxij_tab)
     856            0 :    ABI_FREE(Sigxij_tab)
     857              :  end if
     858          201 :  if (allocated(Sigcij_tab)) then
     859            0 :    call sigijtab_free(Sigcij_tab)
     860            0 :    ABI_FREE(Sigcij_tab)
     861              :  end if
     862              : 
     863         1656 :  ABI_MALLOC(Sigcij_tab, (nkcalc, nsppol))
     864         1455 :  ABI_MALLOC(Sigxij_tab, (nkcalc, nsppol))
     865              : 
     866         1638 :  use_sym_at = .FALSE.
     867          201 :  if (present(esymm)) then
     868              :    ! Create the Sig_ij tables taking advantage of the classification of the bands.
     869            0 :    do spin=1,nsppol
     870            0 :      do ikcalc=1,nkcalc
     871            0 :       ik_ibz = kcalc2ibz(ikcalc)
     872            0 :       use_sym_at(ik_ibz, spin) = .not. esymm(ik_ibz, spin)%failed()
     873              :      end do
     874              :    end do
     875              :  end if
     876              : 
     877          406 :  do spin=1,nsppol
     878         1053 :    do ikcalc=1,nkcalc
     879          647 :      ik_ibz = kcalc2ibz(ikcalc)
     880              : 
     881          852 :      if (use_sym_at(ik_ibz, spin)) then
     882            0 :        if (only_diago) then
     883            0 :          ABI_ERROR("You should not be here!")
     884              :        end if
     885              : 
     886            0 :        bmin = bstart_ks(ikcalc, spin); bmax = bstop_ks(ikcalc, spin)
     887            0 :        ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col, (bmin:bmax))
     888            0 :        ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col, (bmin:bmax))
     889              : 
     890            0 :        do bcol=bmin,bmax
     891            0 :          ABI_MALLOC(sigc_bidx, (bmax - bmin + 1))
     892            0 :          ABI_MALLOC(sigx_bidx, (bmax - bmin + 1))
     893              : 
     894            0 :          if (esymm(ik_ibz,spin)%err_status /= 0) then
     895              :            ! Band classification failed.
     896            0 :            sigc_bidx = [(ii, ii=bmin, bmax)]
     897            0 :            idx_c = bmax - bmin + 1
     898            0 :            sigx_bidx = [(ii,ii=bmin,bcol)] ! Hermitian
     899            0 :            idx_x = bcol - bmin + 1
     900              :          else
     901            0 :            irr_idx2 = esymm(ik_ibz,spin)%b2irrep(bcol)
     902            0 :            idx_c = 0
     903            0 :            do brow=bmin,bmax
     904            0 :              irr_idx1 = esymm(ik_ibz,spin)%b2irrep(brow)
     905            0 :              if (sigc_is_herm .and. bcol < brow) CYCLE  ! Only the upper triangle for HF, SEX, or COHSEX.
     906            0 :              if (irr_idx1 == irr_idx2) then ! same character, add this row to the list.
     907            0 :                idx_c = idx_c + 1
     908            0 :                sigc_bidx(idx_c) = brow
     909              :              end if
     910              :            end do
     911              :            idx_x = 0
     912            0 :            do brow=bmin,bcol
     913            0 :              irr_idx1 = esymm(ik_ibz,spin)%b2irrep(brow)
     914              :              if (bcol<brow) CYCLE  ! Sig_x is always Hermitian.
     915            0 :              if (irr_idx1 == irr_idx2) then ! same character, add this row to the list.
     916            0 :                idx_x = idx_x +1
     917            0 :                sigx_bidx(idx_x) = brow
     918              :              end if
     919              :            end do
     920              :          end if
     921              : 
     922              :          ! Table for Sigma_x matrix elements taking into account symmetries of the bands.
     923            0 :          ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (idx_x))
     924              : 
     925            0 :          Sigxij_tab(ikcalc, spin)%col(bcol)%size1 = idx_x
     926            0 :          Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigx_bidx(1:idx_x)
     927              :          !write(std_out,*)" Sigxij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol
     928              :          !write(std_out,*)" size: ",idx_x,(Sigxij_tab(ikcalc,spin)%col(bcol)%bidx(ii),ii=1,idx_x)
     929              :          !
     930              :          ! Table for Sigma_c matrix elements taking into account symmetries of the bands.
     931            0 :          ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx, (idx_c))
     932              : 
     933            0 :          Sigcij_tab(ikcalc, spin)%col(bcol)%size1= idx_c
     934            0 :          Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigc_bidx(1:idx_c)
     935              :          !write(std_out,*)" Sigcij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol
     936              :          !write(std_out,*)" size: ",idx_c,(Sigcij_tab(ikcalc,spin)%col(bcol)%bidx(ii), ii=1,idx_c)
     937              : 
     938            0 :          ABI_FREE(sigx_bidx)
     939            0 :          ABI_FREE(sigc_bidx)
     940              :        end do ! bcol
     941              : 
     942              :      else
     943              :        ! Symmetries cannot be used for this (k,s).
     944          647 :        bmin = bstart_ks(ikcalc, spin); bmax = bstop_ks(ikcalc, spin)
     945         7392 :        ABI_MALLOC(Sigcij_tab (ikcalc, spin)%col, (bmin:bmax))
     946         6745 :        ABI_MALLOC(Sigxij_tab (ikcalc, spin)%col, (bmin:bmax))
     947              : 
     948          647 :        if (only_diago) then
     949              :          ! QP wavefunctions == KS, therefore only diagonal elements are calculated.
     950         1837 :          do bcol=bmin,bmax
     951         1571 :            ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx, (1:1))
     952         1571 :            Sigcij_tab(ikcalc, spin)%col(bcol)%size1= 1
     953         1571 :            Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(1) = bcol
     954              : 
     955         1571 :            ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (1:1))
     956         1571 :            Sigxij_tab(ikcalc, spin)%col(bcol)%size1 = 1
     957         1837 :            Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(1) = bcol
     958              :          end do
     959              :        else
     960              :          ! Use QP wavefunctions, Sigma_ij matrix is sparse but we have to classify the states in sigma.
     961              :          ! The only thing we can do here is filling the entire matrix taking advantage of Hermiticity (if any).
     962         4261 :          do bcol=bmin,bmax
     963        11640 :            ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (bcol-bmin+1))
     964         3880 :            Sigxij_tab(ikcalc, spin)%col(bcol)%size1= bcol-bmin+1
     965        50520 :            Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(:) = [(ii, ii=bmin,bcol)] ! Sigma_x is Hermitian.
     966              :            !write(std_out,*)"Sigxij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol,Sigxij_tab(ikcalc,spin)%col(bcol)%bidx(:)
     967              : 
     968        11640 :            ABI_MALLOC(sigc_bidx, (bmax-bmin+1))
     969        46640 :            idx_c = 0
     970        46640 :            do brow=bmin,bmax
     971        42760 :              if (sigc_is_herm .and. bcol < brow) CYCLE  ! Only the upper triangle of Sigc_ij is needed (SEX, COHSEX).
     972        30860 :              idx_c = idx_c +1
     973        46640 :              sigc_bidx(idx_c) = brow
     974              :            end do
     975        11640 :            ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx,(idx_c))
     976         3880 :            Sigcij_tab(ikcalc, spin)%col(bcol)%size1= idx_c
     977        34740 :            Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigc_bidx(1:idx_c)
     978         4261 :            ABI_FREE(sigc_bidx)
     979              :            !write(std_out,*)"Sigcij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol,Sigcij_tab(ikcalc,spin)%col(bcol)%bidx(:)
     980              :          end do
     981              :        end if
     982              :      end if
     983              : 
     984              :    end do !ikcalc
     985              :  end do !spin
     986              : 
     987          201 : end subroutine sigtk_sigma_tables
     988              : !!***
     989              : 
     990              : !!****f* m_sigtk/sigtk_multiply_by_vc_sqrt
     991              : !! NAME
     992              : !!  sigtk_multiply_by_vc_sqrt
     993              : !!
     994              : !! FUNCTION
     995              : !! Multiply rhotwg vector by the square root of the Coulomb term taking into account nspinor.
     996              : !!
     997              : !! INPUTS
     998              : !!  trans="C" to take the complex conjugate of rhotwg. "N" to use rhotwg directly.
     999              : !!  npw=Number of PWs.
    1000              : !!  nspinor: Number of spinor components.
    1001              : !!  ndat=Number of bands in rhotwh.
    1002              : !!  vc_sqrt: square root of the Coulomb interaction vc(q,g).
    1003              : !!
    1004              : !! SIDE EFFECTS
    1005              : !!  rhotgw:
    1006              : !!  In input:  <k+q|e^{-i(q+g)r|k>
    1007              : !!  In output: <k+q|e^{-i(q+g)r|k> * vc_sqrt(q, g)
    1008              : !!
    1009              : !! SOURCE
    1010              : 
    1011       779968 : subroutine sigtk_multiply_by_vc_sqrt(trans, npw, nspinor, ndat, vc_sqrt, rhotwg)
    1012              : 
    1013              :  character(len=1),intent(in) :: trans
    1014              :  integer,intent(in) :: npw, nspinor, ndat
    1015              :  complex(gwp),intent(in) :: vc_sqrt(npw)
    1016              :  complex(gwp),intent(inout) :: rhotwg(npw*nspinor, ndat)
    1017              : 
    1018              : !Local variables ------------------------------
    1019              :  integer :: ii, spad, idat
    1020              : !************************************************************************
    1021              : 
    1022              :  select case (trans)
    1023              :  case ("N")
    1024       472192 :    do idat=1, ndat
    1025       708288 :      do ii=1,nspinor
    1026       236096 :        spad = (ii-1) * npw
    1027     92831424 :        rhotwg(spad+1:spad+npw, idat) = rhotwg(spad+1:spad+npw, idat) * vc_sqrt(1:npw)
    1028              :      end do
    1029              :    end do
    1030              : 
    1031              :  case ("C")
    1032              :    ! Take the complex conjugate of rhotwg.
    1033      1087744 :    do idat=1, ndat
    1034      1631616 :      do ii=1,nspinor
    1035       543872 :        spad = (ii-1) * npw
    1036    228971904 :        rhotwg(spad+1:spad+npw, idat) = GWPC_CONJG(rhotwg(spad+1:spad+npw, idat)) * vc_sqrt(1:npw)
    1037              :      end do
    1038              :    end do
    1039              : 
    1040              :  case default
    1041       779968 :    ABI_ERROR(sjoin("Invalid trans", trans))
    1042              :  end select
    1043              : 
    1044       779968 : end subroutine sigtk_multiply_by_vc_sqrt
    1045              : !!***
    1046              : 
    1047              : !!****f* m_sigtk/sigtk_dw_tpp_red
    1048              : !! NAME
    1049              : !!  sigtk_dw_tpp_red
    1050              : !!
    1051              : !! FUNCTION
    1052              : !!  Compute T_pp'(q,nu) matrix in reduced coordinates.
    1053              : !!
    1054              : !! INPUTS
    1055              : !!
    1056              : !! OUTPUTS
    1057              : !!
    1058              : !! SOURCE
    1059              : 
    1060         7118 : pure subroutine sigtk_dw_tpp_red(natom, displ_red, tpp_red)
    1061              : 
    1062              :  integer,intent(in) :: natom
    1063              :  real(dp),intent(in) :: displ_red(2, 3, natom)
    1064              :  complex(dp),intent(out) :: tpp_red(3*natom,3*natom)
    1065              : 
    1066              : !Local variables ------------------------------
    1067              :  integer :: ip1, ip2, idir1, idir2, ipert1, ipert2
    1068              :  complex(dp) :: dka, dkap, dkpa, dkpap
    1069              : !************************************************************************
    1070              : 
    1071        49826 :  do ip2=1,natom*3
    1072        42708 :    idir2 = mod(ip2-1, 3) + 1; ipert2 = (ip2 - idir2) / 3 + 1
    1073       306074 :    do ip1=1,natom*3
    1074       256248 :      idir1 = mod(ip1-1, 3) + 1; ipert1 = (ip1 - idir1) / 3 + 1
    1075              :      ! (k,a) (k,a')* + (k',a) (k',a')*
    1076       256248 :      dka   = dcmplx(displ_red(1, idir1, ipert1), displ_red(2, idir1, ipert1))
    1077       256248 :      dkap  = dcmplx(displ_red(1, idir2, ipert1), displ_red(2, idir2, ipert1))
    1078       256248 :      dkpa  = dcmplx(displ_red(1, idir1, ipert2), displ_red(2, idir1, ipert2))
    1079       256248 :      dkpap = dcmplx(displ_red(1, idir2, ipert2), displ_red(2, idir2, ipert2))
    1080       298956 :      tpp_red(ip1, ip2) = dka * dconjg(dkap) + dkpa * dconjg(dkpap)
    1081              :    end do
    1082              :  end do
    1083              : 
    1084         7118 : end subroutine sigtk_dw_tpp_red
    1085              : !!***
    1086              : 
    1087            0 : end module m_sigtk
    1088              : !!***
        

Generated by: LCOV version 2.3-1