TABLE OF CONTENTS


ABINIT/m_sigtk [ Modules ]

[ Top ] [ Modules ]

NAME

  m_sigtk

FUNCTION

  Helper functions common to electron self-energy calculations. Provides tools to:

      - Define list of k-points and bands in sel-energy matrix elements from input variables.

COPYRIGHT

  Copyright (C) 2008-2024 ABINIT group (MG)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

18 #if defined HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include "abi_common.h"
23 
24 module m_sigtk
25 
26  use defs_basis
27  use m_abicore
28  use m_errors
29  use m_ebands
30  use m_crystal
31  use m_xmpi
32 #ifdef HAVE_NETCDF
33  use netcdf
34 #endif
35  use m_nctk
36  use m_hdr
37  use m_dtset
38  use m_krank
39 
40  use m_build_info,   only : abinit_version
41  use m_fstrings,     only : sjoin, ltoa, strcat, itoa, ftoa
42  use m_io_tools,     only : open_file
43  use defs_datatypes, only : ebands_t, pseudopotential_type
44  use defs_wvltypes,  only : wvl_internal_type
45  use m_pawtab,       only : pawtab_type
46  use m_kpts,         only : kpts_ibz_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map
47 
48  implicit none
49 
50  private
51 
52  public :: sigtk_kcalc_from_nkptgw
53  public :: sigtk_kcalc_from_qprange
54  public :: sigtk_kcalc_from_gaps
55  public :: sigtk_kcalc_from_erange
56  public :: sigtk_kpts_in_erange
57  public :: sigtk_sigma_tables

m_sigmaph/sigtk_kpts_in_erange [ Functions ]

[ Top ] [ m_sigmaph ] [ Functions ]

NAME

  sigtk_kpts_in_erange

FUNCTION

  Use star functions interpolation and [[einterp]] to interpolate KS energies onto dense k-mesh
  defined by [[sigma_ngkpt]] and [[sigma_shiftk]].
  find k-points inside (electron/hole) pockets according to the values specifed by [[sigma_erange]].
  write kerange.nc file with the tables required by abinit to automate nscf band structure calculations
  mainly used to prepare eph calculations in which only selected k-points are nededed (imaginary part of self-energies).

INPUTS

  dtset <dataset_type>=all input variables for this dataset
  cryst<crystal_t>=Crystalline structure
  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
  psps <pseudopotential_type>=all the information about psps
  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
  prefix=Prefix for output file.
  comm: MPI communicator.

SOURCE

559 subroutine sigtk_kpts_in_erange(dtset, cryst, ebands, psps, pawtab, prefix, comm)
560 
561 !Arguments ------------------------------------
562 !scalars
563  type(dataset_type),intent(in) :: dtset
564  type(crystal_t),intent(in) :: cryst
565  type(ebands_t),intent(in) :: ebands
566  type(pseudopotential_type),intent(in) :: psps
567  character(len=*),intent(in) :: prefix
568  integer,intent(in) :: comm
569 !arrays
570  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw)
571 
572 !Local variables ------------------------------
573 !scalars
574  integer,parameter :: master = 0, pertcase0 = 0, image1 = 1
575  integer :: ii, my_rank, nprocs, spin, ikf_ibz, band, nkpt_inerange, gap_err, unt, ncid, cnt, ncerr
576  logical :: assume_gap
577  real(dp) :: ee, cmin, vmax
578  character(len=500) :: msg
579  character(len=fnlen) :: path
580  type(ebands_t) :: fine_ebands
581  type(gaps_t) :: gaps, fine_gaps
582  type(wvl_internal_type) :: dummy_wvl
583  type(hdr_type) :: fine_hdr
584 !arrays
585  integer :: fine_kptrlatt(3,3), band_block(2), unts(2)
586  integer,allocatable :: kshe_mask(:,:,:), krange2ibz(:)
587  real(dp) :: params(4)
588 
589 ! *************************************************************************
590 
591  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
592 
593  ! (-num, -num) activate treatment of metals with energy window around Efermi.
594  assume_gap = .not. all(dtset%sigma_erange < zero)
595  unts = [std_out, ab_out]
596 
597  if (my_rank == master) then
598    call wrtout(unts, sjoin(ch10, repeat("=", 92)))
599    call wrtout(unts, " Using SKW interpolation to interpolate KS energies onto dense k-mesh.")
600    call wrtout(unts, sjoin(" defined by sigma_ngkpt:", trim(ltoa(dtset%sigma_ngkpt))))
601    ABI_CHECK(allocated(dtset%sigma_shiftk), "sigma_nshiftk must be specified in input.")
602    write(std_out, "(2a)") " and sigma_shiftk shifts:"
603    do ii=1,dtset%nshiftk
604      call wrtout(unts, sjoin(itoa(ii), ltoa(dtset%sigma_shiftk(:, ii))))
605    end do
606 
607    if (assume_gap) then
608      call wrtout(unts, " Finding k-points inside (electron/hole) pockets (assuming semiconductor).")
609    else
610      call wrtout(unts, " Finding k-points inside energy window around Fermi level (assuming metal).")
611    end if
612    write(msg, "(a, 2(f6.3, 1x), a)")" Using sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
613    call wrtout(unts, msg)
614    call wrtout(unts, sjoin(" SKW parameters (einterp): ", ltoa(dtset%einterp)))
615    call wrtout(unts, sjoin(repeat("=", 92), ch10))
616    !call ebands_print(ebands, header, unit=std_out, prtvol=dtset%prtvol)
617 
618    ! Consistency check.
619    if (all(dtset%sigma_erange == zero)) then
620      ABI_ERROR("sigma_erange must be specified in input when calling sigtk_kpts_in_erange.")
621    end if
622    if (all(dtset%sigma_ngkpt == 0)) then
623      ABI_ERROR("sigma_ngkpt must be specified in input when calling sigtk_kpts_in_erange.")
624    end if
625  end if
626 
627  if (assume_gap) then
628    ! Compute gaps using input ebands.
629    gaps = ebands_get_gaps(ebands, gap_err)
630    if (gap_err /= 0) then
631      ABI_ERROR("Cannot compute fundamental and direct gap (likely metal).")
632    end if
633 
634    if (my_rank == master) then
635      call gaps%print(header="Gaps from input WFK", unit=std_out)
636      call gaps%print(header="Gaps from input WFK", unit=ab_out)
637    end if
638    call gaps%free()
639  else
640    call wrtout(unts, sjoin("Using Fermi level:", ftoa(ebands%fermie * Ha_eV, fmt="f6.2"), " (eV)"))
641  end if
642 
643  ! Interpolate band energies with star functions.
644  ! In the EPH code, we will need eigens in the IBZ to compute efermi not just energies inside pockets.
645  fine_kptrlatt = 0
646  do ii=1,3
647    fine_kptrlatt(ii, ii) = dtset%sigma_ngkpt(ii)
648  end do
649  band_block = [1, ebands%mband]
650  params = 0; params(1) = 1; params(2) = 5; if (nint(dtset%einterp(1)) == 1) params = dtset%einterp
651 
652  fine_ebands = ebands_interp_kmesh(ebands, cryst, params, fine_kptrlatt, &
653                                    dtset%sigma_nshiftk, dtset%sigma_shiftk, band_block, comm)
654  fine_ebands%istwfk = 1
655 
656  call ebands_update_occ(fine_ebands, dtset%spinmagntarget, prtvol=dtset%prtvol)
657  call ebands_print(fine_ebands, header="FINE EBANDS", unit=std_out, prtvol=dtset%prtvol)
658 
659  if (assume_gap) then
660    ! Compute gaps using fine_ebands.
661    fine_gaps = ebands_get_gaps(fine_ebands, gap_err)
662    if (gap_err /= 0) then
663      ABI_ERROR("Cannot compute fundamental and direct gap (likely metal).")
664    end if
665 
666    if (my_rank == master) then
667      call fine_gaps%print(header="Gaps from SKW interpolated eigenvalues", unit=std_out)
668      call fine_gaps%print(header="Gaps from SKW interpolated eigenvalues", unit=ab_out)
669    end if
670  end if
671 
672  ! Build new header with fine k-mesh (note kptrlatt_orig == kptrlatt)
673  call hdr_init_lowlvl(fine_hdr, fine_ebands, psps, pawtab, dummy_wvl, abinit_version, pertcase0, &
674    dtset%natom, dtset%nsym, dtset%nspden, dtset%ecut, dtset%pawecutdg, dtset%ecutsm, dtset%dilatmx, &
675    dtset%intxc, dtset%ixc, dtset%stmbias, dtset%usewvl, dtset%pawcpxocc, dtset%pawspnorb, dtset%ngfft, dtset%ngfftdg, &
676    dtset%so_psp, dtset%qptn, cryst%rprimd, cryst%xred, cryst%symrel, cryst%tnons, cryst%symafm, cryst%typat, &
677    dtset%amu_orig(:, image1), dtset%icoulomb, &
678    dtset%kptopt, dtset%nelect, dtset%ne_qFD, dtset%nh_qFD, dtset%ivalence, dtset%cellcharge(1), &
679    fine_kptrlatt, fine_kptrlatt, dtset%sigma_nshiftk, dtset%sigma_nshiftk, dtset%sigma_shiftk, dtset%sigma_shiftk)
680 
681  ! Find k-points inside sigma_erange energy window.
682  ! Set entry to the number of states inside the pocket at (ikpt, spin)
683  ! (last index discerns between hole and electron pockets)
684  ABI_ICALLOC(kshe_mask, (fine_ebands%nkpt, ebands%nsppol, 2))
685 
686  do spin=1,ebands%nsppol
687    ! Get CBM and VBM with some tolerance.
688    if (assume_gap) then
689      vmax = fine_gaps%vb_max(spin) + tol2 * eV_Ha
690      cmin = fine_gaps%cb_min(spin) - tol2 * eV_Ha
691    else
692      ! Note that we use the Fermi level from ebands instead of fine_ebands.
693      vmax = ebands%fermie
694      cmin = ebands%fermie
695    end if
696 
697    do ikf_ibz=1,fine_ebands%nkpt
698      do band=1,ebands%mband
699        ee = fine_ebands%eig(band, ikf_ibz, spin)
700        ! Check whether the interpolated eigenvalue is inside the sigma_erange window.
701        if (abs(dtset%sigma_erange(1)) > zero) then
702          if (ee <= vmax .and. vmax - ee <= abs(dtset%sigma_erange(1))) then
703            kshe_mask(ikf_ibz, spin, 1) = kshe_mask(ikf_ibz, spin, 1) + 1; exit
704          end if
705        end if
706        if (abs(dtset%sigma_erange(2)) > zero) then
707          if (ee >= cmin .and. ee - cmin <= abs(dtset%sigma_erange(2))) then
708            kshe_mask(ikf_ibz, spin, 2) = kshe_mask(ikf_ibz, spin, 2) + 1; exit
709          end if
710        end if
711      end do
712    end do
713  end do
714 
715  ! Build list of k-points inside pockets. Use over dimensioned array.
716  cnt = count(kshe_mask /= 0)
717  ABI_MALLOC(krange2ibz, (cnt))
718  cnt = 0
719  do ikf_ibz=1,fine_ebands%nkpt
720    if (any(kshe_mask(ikf_ibz,:,:) /= 0)) then
721      cnt = cnt + 1
722      krange2ibz(cnt) = ikf_ibz
723    end if
724  end do
725  nkpt_inerange = cnt
726 
727  ! Possible extensions that may be implemented at this level:
728  !     1. Find image points in the BZ?
729  !     2. Compute tetra and q-points for EPH calculation or use +/- wmax window and heuristic approach in sigmaph at runtime?
730  !     3. Compute SKW 1st and 2nd derivatives needed to treat Frohlich?
731 
732  ! Write output files with k-point list.
733  if (my_rank == master .and. len_trim(prefix) /= 0) then
734    write(std_out, "(a,i0,a,f5.1,a)")" Found: ",  nkpt_inerange, " kpoints in sigma_erange energy windows. (nkeff / nkibz): ", &
735        (100.0_dp * nkpt_inerange) / fine_ebands%nkpt, " [%]"
736 
737    ! Write text file with Abinit input variables (mainly for testing purposes).
738    path = strcat(prefix, "_KERANGE")
739    if (open_file(path, msg, newunit=unt, form="formatted") /= 0) then
740      ABI_ERROR(msg)
741    end if
742    write(unt, "(a)")"kptopt 0"
743    write(unt, "(a, i0)")"nkpt ", nkpt_inerange
744    write(unt, "(a)")"kpt"
745    do ii=1,nkpt_inerange
746      write(unt, "(3(es16.8,1x))") fine_ebands%kptns(:, krange2ibz(ii))
747    end do
748    write(unt, "(a, i0)")"wtk"
749    do ii=1,nkpt_inerange
750      write(unt, "(es16.8)") fine_ebands%wtk(krange2ibz(ii))
751    end do
752    close(unt)
753 
754    ! Write netcdf file used to perform NSCF run and EPH calculations with eph_task = -4.
755    path = strcat(prefix, "_KERANGE.nc")
756 #ifdef HAVE_NETCDF
757    NCF_CHECK(nctk_open_create(ncid, path, xmpi_comm_self))
758    ! Write crystalline structure, fine_hdr and fine_ebands defined on the fine k-mesh.
759    ! fine_ebands will be used to compare with the ab-initio NSCF eigenvalues.
760    !
761    ! TODO: The size of the KERANGE.nc quickly increases with the k-mesh.
762    ! It is ~700 Mb for a ~ 300^3 grid due to occ and eigens
763    ! But these quantities are now used in inkpts so it may be possible to avoid writing them to disk.
764    !
765    NCF_CHECK(fine_hdr%ncwrite(ncid, fform_from_ext("KERANGE.nc"), nc_define=.True.))
766    NCF_CHECK(cryst%ncwrite(ncid))
767    NCF_CHECK(ebands_ncwrite(fine_ebands, ncid))
768    NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("nkpt_inerange", nkpt_inerange)], defmode=.True.))
769    ! Define extra arrays.
770    ncerr = nctk_def_arrays(ncid, [ &
771      nctkarr_t("kshe_mask", "int", "number_of_kpoints, number_of_spins, two"), &
772      nctkarr_t("krange2ibz", "int", "nkpt_inerange"), &
773      nctkarr_t("sigma_erange", "dp", "two"), &
774      nctkarr_t("einterp", "dp", "four") &
775    ], defmode=.True.)
776    NCF_CHECK(ncerr)
777    ! Write extra arrays.
778    NCF_CHECK(nctk_set_datamode(ncid))
779    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kshe_mask"), kshe_mask))
780    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "krange2ibz"), krange2ibz(1:nkpt_inerange)))
781    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_erange"), dtset%sigma_erange))
782    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "einterp"), params))
783    NCF_CHECK(nf90_close(ncid))
784 #endif
785  end if
786 
787  ABI_FREE(kshe_mask)
788  ABI_FREE(krange2ibz)
789 
790  call fine_gaps%free()
791  call ebands_free(fine_ebands)
792  call fine_hdr%free()
793 
794 end subroutine sigtk_kpts_in_erange

m_sigtk/sigtk_kcalc_from_erange [ Functions ]

[ Top ] [ m_sigtk ] [ Functions ]

NAME

  sigtk_kcalc_from_erange

FUNCTION

  Select list of k-points and bands for self-energy matrix elements on the basis of their positions
  wrt to the (band edges|fermi level) and the value of sigma_erange.
  Useful when computing electron-lifetimes for transport calculations.

 INPUT
  dtset<dataset_type>=All input variables for this dataset.
  cryst<crystal_t>=Crystalline structure
  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
  gaps<gaps_t>=Store location of gaps.
  comm: MPI communicator.

OUTPUT

  nkcalc: Number of k-points in self-energy matrix elements.
  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.

SOURCE

354 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, timrev, sigma_nkbz, my_rank
372  logical :: found
373  real(dp) :: cmin, vmax, ee
374  logical :: assume_gap
375  character(len=500) :: msg
376  type(krank_t) :: krank
377 !arrays
378  integer :: kptrlatt(3,3), unts(1)
379  integer,allocatable :: ib_work(:,:,:), sigmak2ebands(:), indkk(:,:)
380  integer :: kpos(ebands%nkpt)
381  real(dp),allocatable :: sigma_wtk(:),sigma_kbz(:,:),tmp_kcalc(:,:)
382 
383 ! *************************************************************************
384 
385  my_rank = xmpi_comm_rank(comm) !; nprocs = xmpi_comm_size(comm)
386  unts = [std_out]
387  assume_gap = .not. all(dtset%sigma_erange < zero)
388 
389  if (my_rank == master) then
390    write(std_out, "(a)")" Selecting k-points and bands according to their position wrt the band edges (sigma_erange)."
391    write(std_out, "(a, 2(f6.3, 1x), a)")" sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
392    if (assume_gap) then
393      call gaps%print(unit=std_out)
394      ABI_CHECK(maxval(gaps%ierr) == 0, "sigma_erange 0 cannot be used because I cannot find the gap (gap_err !=0)")
395    end if
396  end if
397 
398  if (any(dtset%sigma_ngkpt /= 0)) then
399     call wrtout(std_out, sjoin(" Generating initial list of k-points from sigma_nkpt:", ltoa(dtset%sigma_ngkpt)))
400     ! Get tentative tmp_nkpt and tmp_kcalc from sigma_ngkpt.
401     kptrlatt = 0
402     kptrlatt(1,1) = dtset%sigma_ngkpt(1); kptrlatt(2,2) = dtset%sigma_ngkpt(2); kptrlatt(3,3) = dtset%sigma_ngkpt(3)
403     call kpts_ibz_from_kptrlatt(cryst, kptrlatt, dtset%kptopt, dtset%sigma_nshiftk, dtset%sigma_shiftk, &
404                                 tmp_nkpt, tmp_kcalc, sigma_wtk, sigma_nkbz, sigma_kbz)
405 
406     ABI_FREE(sigma_kbz)
407     ABI_FREE(sigma_wtk)
408 
409     ! Map tmp_kcalc to ebands%kpts
410     timrev = kpts_timrev_from_kptopt(ebands%kptopt)
411 
412     ABI_MALLOC(indkk, (6, tmp_nkpt))
413 
414     krank = krank_from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.)
415 
416     if (kpts_map("symrec", timrev, cryst, krank, tmp_nkpt, tmp_kcalc, indkk) /= 0) then
417       write(msg, '(3a)' )&
418         "At least one of the k-points could not be generated from a symmetrical one in the WFK.",ch10,&
419         'Action: check your WFK file and the value of sigma_nkpt, sigma_shiftk in the input file.'
420       ABI_ERROR(msg)
421     end if
422 
423     call krank%free()
424 
425     ABI_MALLOC(sigmak2ebands, (tmp_nkpt))
426     sigmak2ebands = indkk(1, :)
427     ABI_FREE(tmp_kcalc)
428     ABI_FREE(indkk)
429 
430  else
431    ! Include all the k-points in the IBZ in the initial list.
432    call wrtout(std_out, " Generating initial list of k-points from input ebands%kptns.")
433    tmp_nkpt = ebands%nkpt
434    ! Trivial map
435    ABI_MALLOC(sigmak2ebands, (tmp_nkpt))
436    sigmak2ebands = [(ii, ii=1, ebands%nkpt)]
437  end if
438 
439  nsppol = ebands%nsppol
440  ABI_MALLOC(ib_work, (2, tmp_nkpt, nsppol))
441 
442  do spin=1,nsppol
443 
444    if (assume_gap) then
445      ! Get CBM and VBM with some tolerance
446      vmax = gaps%vb_max(spin) + tol2 * eV_Ha
447      cmin = gaps%cb_min(spin) - tol2 * eV_Ha
448    else
449      vmax = ebands%fermie
450      cmin = ebands%fermie
451    end if
452 
453    do ii=1,tmp_nkpt
454      ! Index of k-point in ebands.
455      ik = sigmak2ebands(ii)
456      ! Will use this initial values to understand if k-point is in energy window.
457      ib_work(1, ii, spin) = huge(1)
458      ib_work(2, ii, spin) = -huge(1)
459      do band=1,ebands%nband(ik + (spin-1) * ebands%nkpt)
460         ee = ebands%eig(band, ik, spin)
461         if (abs(dtset%sigma_erange(1)) > zero) then
462           if (ee <= vmax .and. vmax - ee <= abs(dtset%sigma_erange(1))) then
463             ib_work(1, ii, spin) = min(ib_work(1, ii, spin), band)
464             ib_work(2, ii, spin) = max(ib_work(2, ii, spin), band)
465             !write(std_out, *), "Adding valence band", band, " with ee [eV]: ", ee * Ha_eV
466           end if
467         end if
468         if (abs(dtset%sigma_erange(2)) > zero) then
469           if (ee >= cmin .and. ee - cmin <= abs(dtset%sigma_erange(2))) then
470             ib_work(1, ii, spin) = min(ib_work(1, ii, spin), band)
471             ib_work(2, ii, spin) = max(ib_work(2, ii, spin), band)
472             !write(std_out, *)"Adding conduction band", band, " with ee [eV]: ", ee * Ha_eV
473           end if
474         end if
475      end do
476    end do
477  end do
478 
479  ! Now we can define the list of k-points and the bands range.
480  ! The main problem here is that kptgw and nkptgw do not depend on the spin and therefore
481  ! we have to compute the union of the k-points.
482  nkcalc = 0
483  do ii=1,tmp_nkpt
484    found = .False.
485    do spin=1,nsppol
486       if (ib_work(1, ii, spin) <= ib_work(2, ii, spin)) then
487         found = .True.; exit
488       end if
489    end do
490    if (found) then
491      nkcalc = nkcalc + 1
492      kpos(nkcalc) = ii
493    end if
494  end do
495 
496  ABI_MALLOC(kcalc, (3, nkcalc))
497  ABI_MALLOC(bstart_ks, (nkcalc, nsppol))
498  ABI_MALLOC(nbcalc_ks, (nkcalc, nsppol))
499 
500  do ic=1,nkcalc
501    ! Index in the ib_work array
502    ii = kpos(ic)
503    ! Index in ebands.
504    ik = sigmak2ebands(ii)
505    kcalc(:,ic) = ebands%kptns(:,ik)
506    do spin=1,nsppol
507      bstart_ks(ic, spin) = 0
508      nbcalc_ks(ic, spin) = 0
509      if (ib_work(1, ii, spin) <= ib_work(2, ii, spin)) then
510        bstart_ks(ic, spin) = ib_work(1, ii, spin)
511        nbcalc_ks(ic, spin) = ib_work(2, ii, spin) - ib_work(1, ii, spin) + 1
512      end if
513      if (nbcalc_ks(ic, spin) == 0) then
514        ABI_WARNING("Spin-polarized case with nbcalc_ks == 0, don't know if code can handle it!")
515      end if
516    end do
517  end do
518 
519  if (my_rank == master) then
520    ! Write info about k-points used in the calculation.
521    write(msg, "(a, i0, a, 2(f6.3, 1x), a)") &
522      " Found ", nkcalc, " k-points within sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
523    call wrtout(unts, msg)
524    if (any(dtset%sigma_ngkpt /= 0)) then
525      call wrtout(unts, sjoin(" These k-points belong to the sigma_ngkpt k-mesh:", ltoa(dtset%sigma_ngkpt)))
526    end if
527    write(msg, "(2(a, i0))")" min(nbcalc_ks): ", minval(nbcalc_ks), " Max(nbcalc_ks): ", maxval(nbcalc_ks)
528    call wrtout(unts, msg)
529  end if
530 
531  ABI_FREE(ib_work)
532  ABI_FREE(sigmak2ebands)
533 
534 end subroutine sigtk_kcalc_from_erange

m_sigtk/sigtk_kcalc_from_gaps [ Functions ]

[ Top ] [ m_sigtk ] [ Functions ]

NAME

  sigtk_kcalc_from_gaps

FUNCTION

  Select list of k-points and bands for self-energy matrix elements so that fundamental and direct gaps are included.

 INPUT
  dtset<dataset_type>=All input variables for this dataset.
  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
  gaps<gaps_t>=Store location of gaps.

OUTPUT

  nkcalc: Number of k-points in self-energy matrix elements.
  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.

SOURCE

263 subroutine sigtk_kcalc_from_gaps(dtset, ebands, gaps, nkcalc, kcalc, bstart_ks, nbcalc_ks)
264 
265 !Arguments ------------------------------------
266  type(dataset_type),intent(in) :: dtset
267  type(ebands_t),intent(in) :: ebands
268  type(gaps_t) :: gaps
269  integer,intent(out) :: nkcalc
270 !arrays
271  real(dp),allocatable,intent(out) :: kcalc(:,:)
272  integer,allocatable,intent(out) :: bstart_ks(:,:)
273  integer,allocatable,intent(out) :: nbcalc_ks(:,:)
274 
275 !Local variables ------------------------------
276 !scalars
277  integer :: spin, nsppol, ii, ik, nk_found, ifo, jj
278  logical :: found
279 !arrays
280  integer :: val_indices(ebands%nkpt, ebands%nsppol)
281  integer :: kpos(6)
282 
283 ! *************************************************************************
284 
285  ABI_UNUSED((/dtset%natom/))
286 
287  call wrtout(std_out, " Including direct and fundamental KS gap in Sigma_nk")
288  ABI_CHECK(maxval(gaps%ierr) == 0, "qprange 0 cannot be used because I cannot find the gap (gap_err !=0)")
289 
290  nsppol = ebands%nsppol
291  val_indices = ebands_get_valence_idx(ebands)
292 
293  ! Include the direct and the fundamental KS gap.
294  ! The problem here is that kptgw and nkptgw do not depend on the spin and therefore
295  ! we have compute the union of the k-points where the fundamental and the direct gaps are located.
296  nk_found = 1; kpos(1) = gaps%fo_kpos(1,1)
297 
298  ! Find the list of `interesting` kpoints.
299  do spin=1,nsppol
300    do ifo=1,3
301      ik = gaps%fo_kpos(ifo, spin)
302      found = .False.; jj = 0
303      do while (.not. found .and. jj < nk_found)
304        jj = jj + 1; found = (kpos(jj) == ik)
305      end do
306      if (.not. found) then
307        nk_found = nk_found + 1; kpos(nk_found) = ik
308      end if
309    end do
310  end do
311 
312  ! Now we can define the list of k-points and the bands range.
313  nkcalc = nk_found
314  ABI_MALLOC(kcalc, (3, nkcalc))
315  ABI_MALLOC(bstart_ks, (nkcalc, nsppol))
316  ABI_MALLOC(nbcalc_ks, (nkcalc, nsppol))
317 
318  do ii=1,nkcalc
319    ik = kpos(ii)
320    kcalc(:,ii) = ebands%kptns(:,ik)
321    do spin=1,nsppol
322      bstart_ks(ii,spin) = val_indices(ik,spin)
323      nbcalc_ks(ii,spin) = 2
324    end do
325  end do
326 
327 end subroutine sigtk_kcalc_from_gaps

m_sigtk/sigtk_kcalc_from_nkptgw [ Functions ]

[ Top ] [ m_sigtk ] [ Functions ]

NAME

  sigtk_kcalc_from_nkptgw

FUNCTION

  Initialize list of k-points and bands for self-energy matrix elements from nkptgw.

 INPUT
  dtset<dataset_type>=All input variables for this dataset.
  mband: Max number of bands.

OUTPUT

  nkcalc: Number of k-points in self-energy matrix elements.
  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.

SOURCE

 95 subroutine sigtk_kcalc_from_nkptgw(dtset, mband, nkcalc, kcalc, bstart_ks, nbcalc_ks)
 96 
 97 !Arguments ------------------------------------
 98  type(dataset_type),intent(in) :: dtset
 99  integer,intent(in) :: mband
100  integer,intent(out) :: nkcalc
101 !arrays
102  real(dp),allocatable,intent(out) :: kcalc(:,:)
103  integer,allocatable,intent(out) :: bstart_ks(:,:)
104  integer,allocatable,intent(out) :: nbcalc_ks(:,:)
105 
106 !Local variables ------------------------------
107 !scalars
108  integer :: spin, ierr, ikcalc
109  character(len=500) :: msg
110 
111 ! *************************************************************************
112 
113  call wrtout(std_out, " Generating list of k-points for self-energy from kptgw and bdgw.")
114 
115  nkcalc = dtset%nkptgw
116  ABI_MALLOC(kcalc, (3, nkcalc))
117  ABI_MALLOC(bstart_ks, (nkcalc, dtset%nsppol))
118  ABI_MALLOC(nbcalc_ks, (nkcalc, dtset%nsppol))
119 
120  kcalc = dtset%kptgw(:,1:nkcalc)
121  do spin=1,dtset%nsppol
122    bstart_ks(:,spin) = dtset%bdgw(1,1:nkcalc,spin)
123    nbcalc_ks(:,spin) = dtset%bdgw(2,1:nkcalc,spin) - dtset%bdgw(1,1:nkcalc,spin) + 1
124  end do
125 
126  ! Consistency check on bdgw and mband
127  ierr = 0
128  do spin=1,dtset%nsppol
129    do ikcalc=1,nkcalc
130      if (dtset%bdgw(2,ikcalc,spin) > mband) then
131        ierr = ierr + 1
132        write(msg,'(a,2(i0,1x),2(a,i0))')&
133         "For (k, s) ",ikcalc,spin," bdgw= ",dtset%bdgw(2,ikcalc,spin), " > mband = ",mband
134        ABI_WARNING(msg)
135      end if
136    end do
137  end do
138  ABI_CHECK(ierr == 0, "Not enough bands in WFK file. See messages above. Aborting now.")
139 
140 end subroutine sigtk_kcalc_from_nkptgw

m_sigtk/sigtk_kcalc_from_qprange [ Functions ]

[ Top ] [ m_sigtk ] [ Functions ]

NAME

  sigtk_kcalc_from_qprange

FUNCTION

 Use qprange to select the interesting k-points and the corresponding bands.

    0 --> Compute the QP corrections only for the fundamental and the direct gap.
 +num --> Compute the QP corrections for all the k-points in the irreducible zone and include `num`
           bands above and below the Fermi level.
 -num --> Compute the QP corrections for all the k-points in the irreducible zone.
          Include all occupied states and `num` empty states.

 INPUT
  dtset<dataset_type>=All input variables for this dataset.
  cryst<crystal_t>=Crystalline structure
  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
  qprange: See above description

OUTPUT

  nkcalc: Number of k-points in self-energy matrix elements.
  kcalc(3, nkcalc): List of k-points where the self-energy is computed.
  bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
  nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.

SOURCE

170 subroutine sigtk_kcalc_from_qprange(dtset, cryst, ebands, qprange, nkcalc, kcalc, bstart_ks, nbcalc_ks)
171 
172 !Arguments ------------------------------------
173  type(dataset_type),intent(in) :: dtset
174  type(crystal_t),intent(in) :: cryst
175  type(ebands_t),intent(in) :: ebands
176  integer,intent(in) :: qprange
177  integer,intent(out) :: nkcalc
178 !arrays
179  real(dp),allocatable,intent(out) :: kcalc(:,:)
180  integer,allocatable,intent(out) :: bstart_ks(:,:)
181  integer,allocatable,intent(out) :: nbcalc_ks(:,:)
182 
183 !Local variables ------------------------------
184 !scalars
185  integer :: spin, ik, bstop, mband, sigma_nkbz
186 !arrays
187  integer :: kptrlatt(3,3)
188  integer :: val_indices(ebands%nkpt, ebands%nsppol)
189  real(dp),allocatable :: sigma_wtk(:),sigma_kbz(:,:)
190 
191 ! *************************************************************************
192 
193  mband = ebands%mband
194 
195  val_indices = ebands_get_valence_idx(ebands)
196 
197  if (any(dtset%sigma_ngkpt /= 0)) then
198     call wrtout(std_out, " Generating list of k-points for self-energy from sigma_ngkpt and qprange.")
199     ABI_CHECK(qprange /= 0, "qprange must be != 0")
200     ! Get %kcalc from sigma_ngkpt
201     kptrlatt = 0
202     kptrlatt(1,1) = dtset%sigma_ngkpt(1); kptrlatt(2,2) = dtset%sigma_ngkpt(2); kptrlatt(3,3) = dtset%sigma_ngkpt(3)
203     call kpts_ibz_from_kptrlatt(cryst, kptrlatt, dtset%kptopt, dtset%sigma_nshiftk, dtset%sigma_shiftk, &
204                                 nkcalc, kcalc, sigma_wtk, sigma_nkbz, sigma_kbz)
205     ABI_FREE(sigma_kbz)
206     ABI_FREE(sigma_wtk)
207  else
208     ! Include all the k-points in the IBZ.
209     ! Note that kcalc == ebands%kptns so we can use a single ik index in the loop over k-points.
210     ! No need to map kcalc onto ebands%kptns.
211     call wrtout(std_out, " nkptgw set to 0 ==> Include all k-points in the IBZ for Sigma_nk.")
212     nkcalc = ebands%nkpt
213     ABI_MALLOC(kcalc, (3, nkcalc))
214     kcalc = ebands%kptns
215  end if
216 
217  ABI_MALLOC(bstart_ks, (nkcalc, dtset%nsppol))
218  ABI_MALLOC(nbcalc_ks, (nkcalc, dtset%nsppol))
219 
220  if (qprange > 0) then
221    call wrtout(std_out, " Using buffer of bands above and below the Fermi level.")
222    do spin=1,dtset%nsppol
223      do ik=1,nkcalc
224        bstart_ks(ik,spin) = max(val_indices(ik,spin) - qprange, 1)
225        bstop = min(val_indices(ik,spin) + qprange, mband)
226        nbcalc_ks(ik,spin) = bstop - bstart_ks(ik,spin) + 1
227      end do
228    end do
229 
230  else
231    call wrtout(std_out, " Including all occupied states and -qprange empty states.")
232    bstart_ks = 1
233    do spin=1,dtset%nsppol
234      do ik=1,nkcalc
235        nbcalc_ks(ik,spin) = min(val_indices(ik,spin) - qprange, mband)
236      end do
237    end do
238  end if
239 
240 end subroutine sigtk_kcalc_from_qprange

m_sigtk/sigtk_sigma_tables [ Functions ]

[ Top ] [ m_sigtk ] [ Functions ]

NAME

  sigtk_sigma_tables

FUNCTION

  Build tables with the band indices used to compute the matrix elements of sigma_x and sigma_c
  taking into account the kind of self-energies and symmetries from esymm.

INPUTS

  nkcalc: Number of k-points to compute
  nkibz: Number of k-points in the IBZ
  nsppol: Number of spins
  bstart_ks, bstop_ks: First and last band for each (ikcalc, spin)
  kcalc2ibz: Mapping kcalc --> IBZ
  only_diago: True if only diagonal matrix elements are wanted
  sigc_is_herm: True is Sigma_c is Hermitian
  [esymm]: Band symmetries

OUTPUT

  sigxij_tab, sigcij_tab

SOURCE

840 subroutine sigtk_sigma_tables(nkcalc, nkibz, nsppol, bstart_ks, bstop_ks, kcalc2ibz, &
841                               only_diago, sigc_is_herm, sigxij_tab, sigcij_tab, esymm)
842 
843  use m_gwdefs,        only : sigijtab_t, sigijtab_free
844  use m_esymm,         only : esymm_t, esymm_failed
845 
846 !Arguments ------------------------------------
847  integer,intent(in) :: nkcalc, nkibz, nsppol
848  integer,intent(in) :: bstart_ks(nkcalc, nsppol), bstop_ks(nkcalc, nsppol)
849  logical,intent(in) :: only_diago, sigc_is_herm
850  integer,intent(in) :: kcalc2ibz(nkcalc)
851  type(sigijtab_t),allocatable,intent(inout) :: Sigxij_tab(:,:), Sigcij_tab(:,:)
852  type(esymm_t),optional,intent(in) :: esymm(nkibz, nsppol)
853 
854 !Local variables-------------------------------
855 !scalars
856  integer :: spin,ikcalc,ik_ibz,bmin,bmax,bcol,brow
857  integer :: ii,idx_x,idx_c,irr_idx1,irr_idx2
858 !arrays
859  integer,allocatable :: sigc_bidx(:), sigx_bidx(:)
860  logical :: use_sym_at(nkibz, nsppol)
861 
862 ! *************************************************************************
863 
864  if (allocated(Sigxij_tab)) then
865    call sigijtab_free(Sigxij_tab)
866    ABI_FREE(Sigxij_tab)
867  end if
868  if (allocated(Sigcij_tab)) then
869    call sigijtab_free(Sigcij_tab)
870    ABI_FREE(Sigcij_tab)
871  end if
872 
873  ABI_MALLOC(Sigcij_tab, (nkcalc, nsppol))
874  ABI_MALLOC(Sigxij_tab, (nkcalc, nsppol))
875 
876  use_sym_at = .FALSE.
877  if (present(esymm)) then
878    ! Create the Sig_ij tables taking advantage of the classification of the bands.
879    do spin=1,nsppol
880      do ikcalc=1,nkcalc
881       ik_ibz = kcalc2ibz(ikcalc)
882       use_sym_at(ik_ibz, spin) = .not. esymm_failed(esymm(ik_ibz, spin))
883      end do
884    end do
885  end if
886 
887  do spin=1,nsppol
888    do ikcalc=1,nkcalc
889      ik_ibz = kcalc2ibz(ikcalc)
890 
891      if (use_sym_at(ik_ibz, spin)) then
892        if (only_diago) then
893          ABI_ERROR("You should not be here!")
894        end if
895 
896        bmin = bstart_ks(ikcalc, spin); bmax = bstop_ks(ikcalc, spin)
897        ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col, (bmin:bmax))
898        ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col, (bmin:bmax))
899 
900        do bcol=bmin,bmax
901          ABI_MALLOC(sigc_bidx, (bmax - bmin + 1))
902          ABI_MALLOC(sigx_bidx, (bmax - bmin + 1))
903 
904          if (esymm(ik_ibz,spin)%err_status /= 0) then
905            ! Band classification failed.
906            sigc_bidx = [(ii, ii=bmin, bmax)]
907            idx_c = bmax - bmin + 1
908            sigx_bidx = [(ii,ii=bmin,bcol)] ! Hermitian
909            idx_x = bcol - bmin + 1
910          else
911            irr_idx2 = esymm(ik_ibz,spin)%b2irrep(bcol)
912            idx_c = 0
913            do brow=bmin,bmax
914              irr_idx1 = esymm(ik_ibz,spin)%b2irrep(brow)
915              if (sigc_is_herm .and. bcol < brow) CYCLE  ! Only the upper triangle for HF, SEX, or COHSEX.
916              if (irr_idx1 == irr_idx2) then ! same character, add this row to the list.
917                idx_c = idx_c + 1
918                sigc_bidx(idx_c) = brow
919              end if
920            end do
921            idx_x = 0
922            do brow=bmin,bcol
923              irr_idx1 = esymm(ik_ibz,spin)%b2irrep(brow)
924              if (bcol<brow) CYCLE  ! Sig_x is always Hermitian.
925              if (irr_idx1 == irr_idx2) then ! same character, add this row to the list.
926                idx_x = idx_x +1
927                sigx_bidx(idx_x) = brow
928              end if
929            end do
930          end if
931 
932          ! Table for Sigma_x matrix elements taking into account symmetries of the bands.
933          ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (idx_x))
934 
935          Sigxij_tab(ikcalc, spin)%col(bcol)%size1 = idx_x
936          Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigx_bidx(1:idx_x)
937          !write(std_out,*)" Sigxij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol
938          !write(std_out,*)" size: ",idx_x,(Sigxij_tab(ikcalc,spin)%col(bcol)%bidx(ii),ii=1,idx_x)
939          !
940          ! Table for Sigma_c matrix elements taking into account symmetries of the bands.
941          ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx, (idx_c))
942 
943          Sigcij_tab(ikcalc, spin)%col(bcol)%size1= idx_c
944          Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigc_bidx(1:idx_c)
945          !write(std_out,*)" Sigcij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol
946          !write(std_out,*)" size: ",idx_c,(Sigcij_tab(ikcalc,spin)%col(bcol)%bidx(ii), ii=1,idx_c)
947 
948          ABI_FREE(sigx_bidx)
949          ABI_FREE(sigc_bidx)
950        end do ! bcol
951 
952      else
953        ! Symmetries cannot be used for this (k,s).
954        bmin = bstart_ks(ikcalc, spin); bmax = bstop_ks(ikcalc, spin)
955        ABI_MALLOC(Sigcij_tab (ikcalc, spin)%col, (bmin:bmax))
956        ABI_MALLOC(Sigxij_tab (ikcalc, spin)%col, (bmin:bmax))
957 
958        if (only_diago) then
959          ! QP wavefunctions == KS, therefore only diagonal elements are calculated.
960          do bcol=bmin,bmax
961            ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx, (1:1))
962            Sigcij_tab(ikcalc, spin)%col(bcol)%size1= 1
963            Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(1) = bcol
964 
965            ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (1:1))
966            Sigxij_tab(ikcalc, spin)%col(bcol)%size1 = 1
967            Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(1) = bcol
968          end do
969        else
970          ! Use QP wavefunctions, Sigma_ij matrix is sparse but we have to classify the states in sigma.
971          ! The only thing we can do here is filling the entire matrix taking advantage of Hermiticity (if any).
972          do bcol=bmin,bmax
973            ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (bcol-bmin+1))
974            Sigxij_tab(ikcalc, spin)%col(bcol)%size1= bcol-bmin+1
975            Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(:) = [(ii, ii=bmin,bcol)] ! Sigma_x is Hermitian.
976            !write(std_out,*)"Sigxij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol,Sigxij_tab(ikcalc,spin)%col(bcol)%bidx(:)
977 
978            ABI_MALLOC(sigc_bidx, (bmax-bmin+1))
979            idx_c = 0
980            do brow=bmin,bmax
981              if (sigc_is_herm .and. bcol < brow) CYCLE  ! Only the upper triangle of Sigc_ij is needed (SEX, COHSEX).
982              idx_c = idx_c +1
983              sigc_bidx(idx_c) = brow
984            end do
985            ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx,(idx_c))
986            Sigcij_tab(ikcalc, spin)%col(bcol)%size1= idx_c
987            Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigc_bidx(1:idx_c)
988            ABI_FREE(sigc_bidx)
989            !write(std_out,*)"Sigcij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol,Sigcij_tab(ikcalc,spin)%col(bcol)%bidx(:)
990          end do
991        end if
992      end if
993 
994    end do !ikcalc
995  end do !spin
996 
997 end subroutine sigtk_sigma_tables