TABLE OF CONTENTS


ABINIT/m_chi0tk [ Modules ]

[ Top ] [ Modules ]

NAME

  m_chi0tk

FUNCTION

  This module provides tools for the computation of the irreducible polarizability.

COPYRIGHT

 Copyright (C) 1999-2024 ABINIT group (MG, FB)
 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

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 MODULE m_chi0tk
23 
24  use defs_basis
25  use m_abicore
26  use m_errors
27  use m_xmpi
28  use m_xomp
29  use m_sort
30 
31  use defs_datatypes, only : ebands_t
32  use m_gwdefs,   only : GW_TOL_DOCC, czero_gw, cone_gw, one_gw, em1params_t, j_gw
33  use m_fstrings, only : sjoin, itoa
34  use m_hide_blas,only : xgerc, xgemm, xherk, xher
35  use m_crystal,  only : crystal_t
36  use m_gsphere,  only : gsphere_t
37  use m_bz_mesh,  only : littlegroup_t, kmesh_t
38  use m_wfd,      only : wfdgw_t
39 
40  implicit none
41 
42  private
43 
44  public :: assemblychi0_sym
45  public :: symmetrize_afm_chi0
46  public :: accumulate_chi0_q0
47  public :: accumulate_head_wings_imagw
48  public :: accumulate_sfchi0_q0
49  public :: assemblychi0sf
50  public :: approxdelta
51  public :: setup_spectral
52  public :: hilbert_transform
53  public :: hilbert_transform_headwings
54  public :: completechi0_deltapart
55  public :: output_chi0sumrule
56  public :: accumulate_chi0sumrule
57  public :: make_transitions
58  public :: chi0_bbp_mask

m_chi0tk/accumulate_chi0_q0 [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 accumulate_chi0_q0

FUNCTION

 Update the independent particle susceptibility at q==0 for the contribution
 of one pair of occupied-unoccupied band, for each frequency.
 This routine takes advantage of the symmetries of the little group of the external q-point
 to symmetrize the contribution arising from the input k-point located in the IBZ_q.
 It computes:

   $ \chi_0(G1,G2,io) = \chi_0(G1,G2,io)+\sum_S (rhotwg(G1)*rhotwg^\dagger(G2))*green_w(io) $

 where S is a symmetry in reciprocal space.
 The matrix elements of the gradient operator and [V_{nl},r] are symmetrized as well.

INPUTS

  ik_bz=Index of the k-point whose contribution has to be added to chi0.
  isym_kbz=Index of the symmetry such that k_bz = IS k_ibz
  itim_kbz=2 if time-reversal has to be used to obtain k_bz, 1 otherwise.
  npwepG0=Maximum number of G vectors
  rhotwg(npwepG0)=Oscillator matrix elements corresponding to an occupied-unoccupied pair of states.
  rhotwx(3,nspinor**2)=Matrix element of the operator $-i[H,r]/(e1-e2) = -i r$ in reciprocal lattice units.
  green_w(nomega)=Frequency dependent part of the Green function.
  Ltg_q<littlegroup_t_type>=Info on the little group associated to the external q-point.
    %timrev=2 it time-reversal is used, 1 otherwise.
    %nsym_sg=Number of space group symmetries.
    %wtksym(2,nsym,nkbz)=1 if the symmetry (with or without time-reversal) must be considered for this k-point.
  Gsph_epsG0<gsphere_t> Information on the "enlarged" G-sphere used for chi0, it contains umklapp G0 vectors
    %ng=number of G vectors in the enlarged sphere, actually MUST be equal to the size of rhotwg.
    %rottbm1(ng,2,nsym)=index of (IR)^{-1} G where I is the identity or the inversion.
    %phmGt(ng,nsym)=phase factors associated to non-simmorphic operations.
  Cryst<crystal_t>=Structure defining the unit cell and its symmetries
    %nsym=Number of symmetries.
    %symrec(3,3,nsym)=Symmetry operation in reciprocal space (reduced coordinates)
  Ep<em1params_t>=Parameters of the chi0 calculation.
     %npwe=number of plane waves in chi0.
     %symchi=1 if symmetrization has to be performed.
     %nomega=number of frequencies in chi0.

SIDE EFFECTS

  chi0(npwe,npwe,nomega)= Updated independent-particle susceptibility matrix in reciprocal space at q==0.
  chi0_head(3,3,Ep%nomega)=Head.
  chi0_lwing(Ep%npwe*Ep%nI,Ep%nomega,3)=Lower wing.
  chi0_uwing(Ep%npwe*Ep%nJ,Ep%nomega,3)=Upper wing.

NOTES

  1) Symmetrization of the oscilator matrix elements.
    If  Sq = q then  M_G( Sk,q)= e^{-i(q+G).\tau} M_{ S^-1G}  (k,q)
    If -Sq = q then  M_G(-Sk,q)= e^{-i(q+G).\tau} M_{-S^-1G}^*(k,q)

    In the case of umklapps:
    If  Sq = q+G0 then  M_G( Sk,q)= e^{-i(q+G).\tau} M_{ S^-1(G-G0}   (k,q)
    If -Sq = q+G0 then  M_G(-Sk,q)= e^{-i(q+G).\tau} M_{-S^-1(G-G0)}^*(k,q)

  In the equation below there is no need to take into account the phases due to q.t
  as they cancel each other in the scalar product ==> only phmGt(G,isym)=e^{-iG.\tau} is needed.

  2) Symmetrization of the matrix elements of the position operator.

    <Sk,b|\vec r| Sk,b'> = <k b| R\vec r + \tau|k b'>

     where S is one of the symrec operation, R and \tau is the corresponding
     operation in real space. The term involving the fractional translation is zero provided that b /= b'.

SOURCE

617 subroutine accumulate_chi0_q0(is_metallic,ik_bz,isym_kbz,itim_kbz,gwcomp,nspinor,npwepG0,Ep,Cryst,Ltg_q,Gsph_epsG0,&
618                               chi0,rhotwx,rhotwg,green_w,green_enhigh_w,deltaf_b1b2,chi0_head,chi0_lwing,chi0_uwing)
619 
620 !Arguments ------------------------------------
621 !scalars
622  logical,intent(in) :: is_metallic
623  integer,intent(in) :: ik_bz,isym_kbz,itim_kbz,npwepG0,nspinor,gwcomp
624  real(dp),intent(in) :: deltaf_b1b2
625  type(littlegroup_t),intent(in) :: Ltg_q
626  type(gsphere_t),target,intent(in) :: Gsph_epsG0
627  type(crystal_t),intent(in) :: Cryst
628  type(em1params_t),intent(in) :: Ep
629 !arrays
630  complex(gwpc),intent(in) :: rhotwg(npwepG0)
631  complex(gwpc),intent(in) :: rhotwx(3, nspinor**2)
632  complex(gwpc),intent(inout) :: chi0(Ep%npwe*Ep%nI, Ep%npwe*Ep%nJ, Ep%nomega)
633  complex(dpc),intent(in) :: green_w(Ep%nomega), green_enhigh_w(Ep%nomega)
634  complex(dpc),intent(inout) :: chi0_head(3, 3, Ep%nomega)
635  complex(dpc),intent(inout) :: chi0_lwing(Ep%npwe*Ep%nI, Ep%nomega, 3)
636  complex(dpc),intent(inout) :: chi0_uwing(Ep%npwe*Ep%nJ, Ep%nomega, 3)
637 
638 !Local variables-------------------------------
639 !scalars
640  integer :: itim,io,isym,idir,jdir,isymop,nsymop,npwe,nomega
641  real(gwp) :: dr
642  complex(gwpc) :: dd
643  !character(len=500) :: msg
644 !arrays
645  integer,ABI_CONTIGUOUS pointer :: Sm1G(:)
646  complex(dpc) :: mir_kbz(3)
647  complex(gwpc),allocatable :: rhotwg_sym(:,:)
648  complex(gwpc), ABI_CONTIGUOUS pointer :: phmGt(:)
649 
650 !************************************************************************
651 
652  ABI_UNUSED(deltaf_b1b2)
653 
654  npwe = ep%npwe; nomega = ep%nomega
655 
656  select case (Ep%symchi)
657  case (0)
658    ! Do not use symmetries.
659    ! Symmetrize rhotwg in the full BZ and accumulate over the full BZ i.e.
660    !   chi0(G1,G2,io) = chi0(G1,G2,io) + (rhotwg(G1)*conjg(rhotwg(G2)))*green_w(io)
661    !
662    ! The non-analytic term is symmetrized for this k-point in the BZ according to:
663    !    rhotwg(1) =  S^-1q * rhotwx_ibz
664    !    rhotwg(1) = -S^-1q * conjg(rhotwx_ibz) if time-reversal is used.
665 
666    ! Multiply elements G1,G2 of rhotwg by green_w(io) and accumulate in chi0(G1,G2,io)
667 
668 !$OMP PARALLEL DO PRIVATE(dr, dd) IF (nomega > 2)
669    do io=1,nomega
670      ! Check if green_w(io) is real (=> pure imaginary omega)
671      ! and that it is not a metal
672      ! then the corresponding chi0(io) is hermitian
673      if (ABS(AIMAG(green_w(io))) < 1.0e-6_dp .and. .not. is_metallic) then
674        dr = green_w(io)
675        call xher('U', npwe, dr, rhotwg, 1, chi0(:,:,io), npwe)
676      else
677        dd = green_w(io)
678        call xgerc(npwe, npwe, dd, rhotwg, 1, rhotwg, 1, chi0(:,:,io), npwe)
679      endif
680    end do
681 
682    ! === Accumulate heads and wings for each small q ===
683    ! FIXME extrapolar method should be checked!!
684    ! Symmetrize <r> in full BZ: <Sk b|r|Sk b'> = R <k b|r|k b'> + \tau \delta_{bb'}
685    if (nspinor == 1) then
686      mir_kbz = (3-2*itim_kbz) * matmul(Cryst%symrec(:,:,isym_kbz), rhotwx(:,1))
687    else
688      mir_kbz = (3-2*itim_kbz) * matmul(Cryst%symrec(:,:,isym_kbz), sum(rhotwx(:,1:2), dim=2))
689    end if
690    if (itim_kbz == 2) mir_kbz = conjg(mir_kbz)
691 
692    ! here we might take advantage of Hermiticity along Im axis in RPA (see mkG0w)
693    do idir=1,3
694      do io=1,nomega
695        chi0_uwing(:,io,idir) = chi0_uwing(:,io,idir) + green_w(io) * mir_kbz(idir)*conjg(rhotwg)
696        chi0_lwing(:,io,idir) = chi0_lwing(:,io,idir) + green_w(io) * rhotwg*conjg(mir_kbz(idir))
697        if (gwcomp == 1) then
698          ! Add contribution due to extrapolar technique.
699          chi0_uwing(:,io,idir) = chi0_uwing(:,io,idir) + green_enhigh_w(io) * mir_kbz(idir)*conjg(rhotwg)
700          chi0_lwing(:,io,idir) = chi0_lwing(:,io,idir) + green_enhigh_w(io) * rhotwg*conjg(mir_kbz(idir))
701        end if
702      end do
703    end do
704 
705    ! Accumulate the head.
706    do io=1,nomega
707      do jdir=1,3
708        do idir=1,3
709          chi0_head(idir,jdir,io) = chi0_head(idir,jdir,io) + green_w(io) * mir_kbz(idir)*conjg(mir_kbz(jdir))
710          if (gwcomp == 1) then
711            ! Add contribution due to extrapolar technique.
712            chi0_head(idir,jdir,io) = chi0_head(idir,jdir,io) + green_enhigh_w(io) * mir_kbz(idir)*conjg(mir_kbz(jdir))
713          end if
714        end do
715      end do
716    end do
717 
718  case (1)
719    ! Use symmetries to reconstruct the integrand.
720 
721    nsymop = count(Ltg_q%wtksym(:,:,ik_bz) == 1)
722    ABI_MALLOC(rhotwg_sym, (npwe, nsymop))
723    isymop = 0
724 
725    ! Loop over symmetries of the space group and time-reversal.
726    do isym=1,Ltg_q%nsym_sg
727      do itim=1,Ltg_q%timrev
728 
729        if (Ltg_q%wtksym(itim, isym, ik_bz) == 1) then
730          ! This operation belongs to the little group and has to be considered to reconstruct the BZ.
731          phmGt => Gsph_epsG0%phmGt  (1:npwe, isym) ! In the 2 lines below note the slicing (1:npwe)
732          Sm1G  => Gsph_epsG0%rottbm1(1:npwe, itim, isym)
733 
734          isymop = isymop + 1
735          select case (itim)
736          case (1)
737            rhotwg_sym(1:npwe, isymop) = rhotwg(Sm1G(1:npwe)) * phmGt(1:npwe)
738          case (2)
739            rhotwg_sym(1:npwe,isymop) = conjg(rhotwg(Sm1G(1:npwe))) * phmGt(1:npwe)
740          case default
741            ABI_BUG(sjoin('Wrong value of itim:', itoa(itim)))
742          end select
743 
744          ! === Accumulate heads and wings for each small q ===
745          ! FIXME extrapolar method should be checked!!
746 
747          ! Symmetrize <r> in full BZ: <Sk b|r|Sk b'> = R <k b|r|k b'> + \tau \delta_{bb'}
748          if (nspinor == 1) then
749            mir_kbz = (3-2*itim) * matmul(Cryst%symrec(:,:,isym), rhotwx(:,1))
750          else
751            mir_kbz = (3-2*itim) * matmul(Cryst%symrec(:,:,isym), sum(rhotwx(:,1:2), dim=2))
752          end if
753 
754          if (itim == 2) mir_kbz = conjg(mir_kbz)
755 
756          ! here we might take advantage of Hermiticity along Im axis in RPA (see mkG0w)
757          do idir=1,3
758            do io=1,nomega
759              chi0_uwing(:,io,idir) = chi0_uwing(:,io,idir) + green_w(io) * mir_kbz(idir) * conjg(rhotwg_sym(:,isymop))
760              chi0_lwing(:,io,idir) = chi0_lwing(:,io,idir) + green_w(io) * rhotwg_sym(:,isymop) * conjg(mir_kbz(idir))
761              if (gwcomp == 1) then
762                ! Add contribution due to extrapolar technique.
763                chi0_uwing(:,io,idir) = chi0_uwing(:,io,idir) + green_enhigh_w(io) * mir_kbz(idir) * conjg(rhotwg_sym(:,isymop))
764                chi0_lwing(:,io,idir) = chi0_lwing(:,io,idir) + green_enhigh_w(io) * rhotwg_sym(:,isymop) * conjg(mir_kbz(idir))
765              end if
766            end do
767          end do
768 
769          ! Accumulate the head.
770          do io=1,nomega
771            do jdir=1,3
772              do idir=1,3
773                 chi0_head(idir,jdir,io) = chi0_head(idir,jdir,io) + green_w(io) * mir_kbz(idir) * conjg(mir_kbz(jdir))
774                 if (gwcomp == 1) then
775                   ! Add contribution due to extrapolar technique.
776                   chi0_head(idir,jdir,io) = chi0_head(idir,jdir,io) + green_enhigh_w(io)*mir_kbz(idir) * conjg(mir_kbz(jdir))
777                 end if
778              end do
779            end do
780          end do
781 
782        end if !wtksym
783      end do !itim
784    end do !isym
785 
786    ! Multiply rhotwg_sym by green_w(io) and accumulate in chi0(G,Gp,io)
787 !$OMP PARALLEL DO PRIVATE(dr, dd) IF (nomega > 2)
788    do io=1,nomega
789      ! Check if green_w(io) is real (=> pure imaginary omega) and that it is not a metal
790      ! then the corresponding chi0(io) is hermitian
791      if (ABS(AIMAG(green_w(io))) < 1.0e-6_dp .and. .not. is_metallic) then
792        dr = green_w(io)
793        call xherk('U', 'N', npwe, nsymop, dr, rhotwg_sym, npwe, one_gw, chi0(:,:,io), npwe)
794      else
795        dd = green_w(io)
796        call xgemm('N', 'C', npwe, npwe, nsymop, dd, rhotwg_sym, npwe, rhotwg_sym, npwe, cone_gw, chi0(:,:,io), npwe)
797      endif
798    end do
799 
800    ABI_FREE(rhotwg_sym)
801 
802  case default
803    ABI_BUG(sjoin('Wrong value of symchi:', itoa(Ep%symchi)))
804  end select
805 
806 end subroutine accumulate_chi0_q0

m_chi0tk/accumulate_chi0sumrule [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 accumulate_chi0sumrule

FUNCTION

  Accumulate the contribution to the sum rule for Im chi0
  arising from a single transition. Eventually symmetrize
  it using the symmetry operations of the little group of q.

INPUTS

  ik_bz=Index of the k-point in the full BZ whose contribution has to be added and symmetrized.
  symchi=1 if we are summing over IBZ_q and symmetrization has to be performed.
  npwe=Number of G vectors in chi0.
  npwepG0=Number of G vectors in the "enlarged" sphere to treat umklapp.
  factor=factor entering the expression.
  delta_ene=Transition energy.
  Ltg_q=<littlegroup_t>= Structure gathering information on the little group of the external q.
  Gsph_epsG0=<gsphere_t>=Info on the G-sphere for chi0.
  rhotwg(npwepG0)=Fouriet transform of u_{b1 k-q} u_{b2 k} in the "enlarged" sphere.

OUTPUT

  See SIDES EFFECTS

 SIDES EFFECTS
  chi0sumrule(npwe)= In input the sum rule calculated so far,
  In output the contribution of this transition is accounted for, and, eventually, symmetrized.
  using the symmetry operations of the little group of the external q.

SOURCE

2103 subroutine accumulate_chi0sumrule(ik_bz,symchi,npwe,factor,delta_ene,&
2104 & Ltg_q,Gsph_epsG0,npwepG0,rhotwg,chi0sumrule)
2105 
2106 !Arguments ------------------------------------
2107 !scalars
2108  integer,intent(in) :: ik_bz,npwe,npwepG0,symchi
2109  real(dp),intent(in) :: delta_ene,factor
2110  type(gsphere_t),intent(in) :: Gsph_epsG0
2111  type(littlegroup_t),target,intent(in) :: Ltg_q
2112 !arrays
2113  real(dp),intent(inout) :: chi0sumrule(npwe)
2114  complex(gwpc),intent(in) :: rhotwg(npwepG0)
2115 
2116 !Local variables-------------------------------
2117 !scalars
2118  integer :: isym,itim
2119  !character(len=500) :: msg
2120 !arrays
2121  integer,allocatable :: Sm1_gmG0(:)
2122  integer, ABI_CONTIGUOUS pointer :: gmG0(:)
2123  complex(gwpc),allocatable :: rhotwg_sym(:)
2124 
2125 !************************************************************************
2126 
2127  ! Accumulating the sum rule on chi0.
2128  ! Eq.(5.284) in G. D. Mahan Many-Particle Physics 3rd edition [[cite:Mahan2000]]
2129 
2130  SELECT CASE (symchi)
2131  CASE (0)
2132    ! Do not use symmetries, sum is performed in the full BZ.
2133    chi0sumrule(:)=chi0sumrule(:) + factor*delta_ene*ABS(rhotwg(1:npwe))**2
2134 
2135  CASE (1)
2136    ! Symmetrize the contribution in the full BZ.
2137    ABI_MALLOC(rhotwg_sym,(npwe))
2138    ABI_MALLOC(Sm1_gmG0,(npwe))
2139 
2140    do itim=1,Ltg_q%timrev
2141      do isym=1,Ltg_q%nsym_sg
2142        if (Ltg_q%wtksym(itim,isym,ik_bz)==1) then
2143         ! This operation belongs to the little group and has to be used to reconstruct the BZ ===
2144         ! In the following 2 lines mind the slicing (1:npwe)
2145         gmG0  => Ltg_q%igmG0(1:npwe,itim,isym)
2146         Sm1_gmG0(1:npwe)=Gsph_epsG0%rottbm1(gmG0(1:npwe),itim,isym)
2147         rhotwg_sym(1:npwe)=rhotwg(Sm1_gmG0)
2148 
2149         chi0sumrule(:)=chi0sumrule(:) + factor*delta_ene*ABS(rhotwg_sym(1:npwe))**2
2150        end if
2151      end do !isym
2152    end do !itim
2153 
2154    ABI_FREE(rhotwg_sym)
2155    ABI_FREE(Sm1_gmG0)
2156 
2157  CASE DEFAULT
2158    ABI_BUG(sjoin('Wrong value for symchi:', itoa(symchi)))
2159  END SELECT
2160 
2161 end subroutine accumulate_chi0sumrule

m_chi0tk/accumulate_head_wings_imagw [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 accumulate_head_wings_imagw

FUNCTION


m_chi0tk/accumulate_sfchi0_q0 [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 accumulate_sfchi0_q0

FUNCTION

 Update the spectral function of the independent particle susceptibility at q==0 for the contribution
 of one pair of occupied-unoccupied band, for each frequency.
 If symchi==1, the symmetries belonging to the little group of the external point q are used
 to reconstruct the contributions in the full Brillouin zone. In this case, the equation implented is:

  $ chi0(G1,G2,io)=chi0(G1,G2,io)+\sum_S (rhotwg(G1)*rhotwg^\dagger(G2))* \delta(\omega -trans) $

 where S is a symmetry belonging to the little group of q.
 The subroutine also performs the symmetrization of the matrix elements of the
 gradient operator and of the commutator [V_{nl},r] with the position operator.

INPUTS

  ikbz=Index in the BZ of the k-point whose contribution to chi0 has to be added,
   if we use symmetries, the contribution to chi0 by this k-point has to be symmetrized.
  isym_kbz=Index of the symmetry such as k_bz = IS k_ibz
  itim_kbz=2 if time-reversal has to be used to obtain k_bz, 1 otherwise.
  my_wl,my_wr=min and Max frequency index treated by this processor.
  npwe=Number of plane waves used to describe chi0.
  npwepG0=Maximum number of G vectors to account for umklapps.
  nomega=Number of frequencies in the imaginary part.
  rhotwg(npwepG0)=Oscillator matrix elements corresponding to an occupied-unoccupied pair of states.
  rhotwx(3,nspinor**2)=Matrix elements of the gradient and of the commutator of the non-local operator with
    the position operator. The second term is present only if inclvkb=1,2.
  Gsph_epsG0<gsphere_t> Information on the "enlarged" G-sphere used for chi0, it contains umklapp G0 vectors
    %ng=number of G vectors in the enlarged sphere. It MUST be equal to the size of rhotwg
    %rottbm1(ng,2,nsym)=index of (IR)^{-1} G where I is the identity or the inversion
    %phmGt(ng,nsym)=phase factors associated to non-symmorphic operations
  Ltg_q<littlegroup_t_type>=Info on the little group associated to the external q-point.
    %timrev=2 it time-reversal is used, 1 otherwise
    %nsym_sg=Number of space group symmetries
    %wtksym(2,nsym,nkbz)=1 if the symmetry (with or without time-reversal) must be considered for this k-point
    %flag_umklp(timrev,nsym)= flag for umklapp processes
     if 1 that the particular operation (IS) requires a G_o to preserve Q, 0 otherwise
 Cryst<crystal_t>=Info on unit cell and it symmetries
    %nsym=Number of symmetry operations.
    %symrec(3,3,nsym)=Symmetry operations in reciprocal space (reduced coordinates).

OUTPUT

  (see side effects)

SIDE EFFECTS

  sf_chi0(npwe,npwe,my_wl:my_wr)=Updated spectral function at q==0.
  sf_lwing(npwe,my_wl:my_wr,3)=Updated lower wing of the spectral function.
  sf_uwing(npwe,mw_wl:my_wr,3)=Updated upper wing of the spectral function.
  sf_head(3,3,my_wl:my_wr)=Updated head of the spectral function.

SOURCE

1013 subroutine accumulate_sfchi0_q0(ikbz,isym_kbz,itim_kbz,nspinor,symchi,npwepG0,npwe,Cryst,Ltg_q,Gsph_epsG0,&
1014 & factocc,my_wl,iomegal,wl,my_wr,iomegar,wr,rhotwx,rhotwg,nomegasf,sf_chi0,sf_head,sf_lwing,sf_uwing)
1015 
1016 !Arguments ------------------------------------
1017 !scalars
1018  integer,intent(in) :: ikbz,my_wl,my_wr,nomegasf,npwe,npwepG0,nspinor
1019  integer,intent(in) :: isym_kbz,itim_kbz,symchi,iomegal,iomegar
1020  real(dp),intent(in) :: factocc,wl,wr
1021  type(littlegroup_t),intent(in) :: Ltg_q
1022  type(gsphere_t),target,intent(in) :: Gsph_epsG0
1023  type(crystal_t),intent(in) :: Cryst
1024 !arrays
1025  complex(gwpc),intent(in) :: rhotwg(npwepG0)
1026  complex(gwpc),intent(in) :: rhotwx(3,nspinor**2)
1027  complex(gwpc),intent(inout) :: sf_chi0(npwe,npwe,my_wl:my_wr)
1028  complex(dpc),intent(inout) :: sf_head(3,3,my_wl:my_wr)
1029  complex(dpc),intent(inout) :: sf_lwing(npwe,my_wl:my_wr,3)
1030  complex(dpc),intent(inout) :: sf_uwing(npwe,my_wl:my_wr,3)
1031 
1032 !Local variables-------------------------------
1033 !scalars
1034  integer :: itim,isym,idir,jdir
1035  complex(gwpc) :: num
1036  character(len=500) :: msg
1037 !arrays
1038  integer, ABI_CONTIGUOUS pointer :: Sm1G(:)
1039  complex(dpc) :: mir_kbz(3)
1040  complex(gwpc), ABI_CONTIGUOUS pointer :: phmGt(:)
1041  complex(gwpc),allocatable :: rhotwg_sym(:)
1042 
1043 !************************************************************************
1044 
1045  if (iomegal<my_wl .or. iomegar>my_wr) then
1046    write(msg,'(3a,2(a,i0,a,i0,a))')ch10,&
1047 &    'Indices out of boundary ',ch10,&
1048 &    '  my_wl = ',my_wl,' iomegal = ',iomegal,ch10,&
1049 &    '  my_wr = ',my_wr,' iomegar = ',iomegar,ch10
1050    ABI_BUG(msg)
1051  end if
1052 
1053  SELECT CASE (symchi)
1054  CASE (0)
1055    !
1056    ! Calculation without symmetries
1057    ! rhotwg(1)= R^-1q*rhotwx_ibz
1058    ! rhotwg(1)=-R^-1q*conjg(rhotwx_ibz) for inversion
1059    if (wl<huge(zero)*1.d-11) then
1060      !this is awful but it is still a first coding
1061      ! Num is single precision needed for cgerc check factocc
1062      num=-wl*factocc
1063      call XGERC(npwe,npwe,num,rhotwg,1,rhotwg,1,sf_chi0(:,:,iomegal),npwe)
1064    end if
1065    ! Last point, must accumulate left point but not the right one
1066    if (iomegar/=nomegasf+1 .and. wr<huge(zero)*1.d-11) then
1067      num=-wr*factocc
1068      call XGERC(npwe,npwe,num,rhotwg,1,rhotwg,1,sf_chi0(:,:,iomegar),npwe)
1069    end if
1070 
1071    ! ================================
1072    ! ==== Update heads and wings ====
1073    ! ================================
1074 
1075    ! Symmetrize <r> in full BZ: <Sk b|r|Sk b'> = R <k b|r|k b'> + \tau \delta_{bb'}
1076    if (nspinor == 1) then
1077       mir_kbz =(3-2*itim_kbz) * MATMUL(Cryst%symrec(:,:,isym_kbz),rhotwx(:,1))
1078     else
1079       mir_kbz = (3-2*itim_kbz) * MATMUL(Cryst%symrec(:,:,isym_kbz), sum(rhotwx(:,1:2), dim=2))
1080     end if
1081    if (itim_kbz==2) mir_kbz=conjg(mir_kbz)
1082 
1083    do jdir=1,3
1084      if (wl<huge(zero)*1.d-11) then
1085        ! this is awful but it is still a first coding
1086        ! Num is single precision needed for cgerc check factocc
1087        num=-wl*factocc
1088        sf_uwing(:,iomegal,jdir) = sf_uwing(:,iomegal,jdir) + num * mir_kbz(jdir) * conjg(rhotwg(1:npwepG0))
1089        sf_lwing(:,iomegal,jdir) = sf_lwing(:,iomegal,jdir) + num * rhotwg(1:npwepG0) * conjg(mir_kbz(jdir))
1090        do idir=1,3
1091          sf_head(idir,jdir,iomegal) = sf_head(idir,jdir,iomegal) + num * mir_kbz(idir) * conjg(mir_kbz(jdir))
1092        end do
1093      end if
1094 
1095      ! Last point, must accumulate left point but not the right one
1096      if (iomegar/=nomegasf+1 .and. wr<huge(zero)*1.d-11) then
1097        num=-wr*factocc
1098        sf_uwing(:,iomegar,jdir) = sf_uwing(:,iomegar,jdir) + num * mir_kbz(jdir) * conjg(rhotwg(1:npwepG0))
1099        sf_lwing(:,iomegar,jdir) = sf_lwing(:,iomegar,jdir) + num * rhotwg(1:npwepG0) * conjg(mir_kbz(jdir))
1100        do idir=1,3
1101          sf_head(idir,jdir,iomegar) = sf_head(idir,jdir,iomegar) + num * mir_kbz(idir) * conjg(mir_kbz(jdir))
1102        end do
1103      end if
1104    end do ! jdir
1105 
1106  CASE (1)
1107    ! === Notes on the symmetrization of oscillator matrix elements ===
1108    ! If  Sq = q then  M_G( Sk,q)= e^{-i(q+G)\cdot t} M_{ S^-1G}  (k,q)
1109    ! If -Sq = q then  M_G(-Sk,q)= e^{-i(q+G)\cdot t} M_{-S^-1G}^*(k,q)
1110    !
1111    ! In case of an umklapp process
1112    ! If  Sq = q+G_o then  M_G( Sk,q)= e^{-i(q+G)\cdot t} M_{ S^-1(G-G_o}   (k,q)
1113    ! If -Sq = q+G_o then  M_G(-Sk,q)= e^{-i(q+G)\cdot t} M_{-S^-1(G-G-o)}^*(k,q)
1114    !
1115    ! rhotwg(1)= R^-1q*rhotwx_ibz
1116    ! rhotwg(1)=-R^-1q*conjg(rhotwx_ibz) for inversion
1117 
1118    ABI_MALLOC(rhotwg_sym,(npwe))
1119 
1120    ! Loop over symmetries of the space group and time-reversal
1121    do isym=1,Ltg_q%nsym_sg
1122      do itim=1,Ltg_q%timrev
1123 
1124        if (Ltg_q%wtksym(itim,isym,ikbz)==1) then
1125          ! This operation belongs to the little group and has to be considered to reconstruct the BZ
1126          phmGt => Gsph_epsG0%phmGt(1:npwe,isym) ! In these 2 lines mind the slicing (1:npwe)
1127          Sm1G  => Gsph_epsG0%rottbm1(1:npwe,itim,isym)
1128 
1129          SELECT CASE (itim)
1130          CASE (1)
1131            rhotwg_sym(1:npwe)=rhotwg(Sm1G(1:npwe))*phmGt(1:npwe)
1132          CASE (2)
1133            rhotwg_sym(1:npwe)=conjg(rhotwg(Sm1G(1:npwe)))*phmGt(1:npwe)
1134          CASE DEFAULT
1135            ABI_BUG(sjoin('Wrong value of itim:', itoa(itim)))
1136          END SELECT
1137 
1138          ! Multiply elements G,Gp of rhotwg_sym*num and accumulate in sf_chi0(G,Gp,io)
1139          if (wl<huge(zero)*1.d-11) then
1140            num=-wl*factocc
1141            call XGERC(npwe,npwe,num,rhotwg_sym,1,rhotwg_sym,1,sf_chi0(:,:,iomegal),npwe)
1142          end if
1143 
1144          ! Last point, must accumulate left point but not the right one
1145          if (iomegar/=nomegasf+1 .and. wr<huge(zero)*1.d-11) then
1146            num=-wr*factocc
1147            call XGERC(npwe,npwe,num,rhotwg_sym,1,rhotwg_sym,1,sf_chi0(:,:,iomegar),npwe)
1148          end if
1149 
1150          ! Accumulate heads and wings.
1151          ! Symmetrize <r> in full BZ: <Sk b|r|Sk b'> = R <k b|r|k b'> + \tau \delta_{bb'}
1152          if (nspinor == 1) then
1153            mir_kbz =(3-2*itim) * MATMUL(Cryst%symrec(:,:,isym),rhotwx(:,1))
1154          else
1155            mir_kbz = (3-2*itim) * MATMUL(Cryst%symrec(:,:,isym), sum(rhotwx(:,1:2), dim=2))
1156          end if
1157          if (itim==2) mir_kbz=conjg(mir_kbz)
1158 
1159          do jdir=1,3
1160            if (wl<huge(zero)*1.d-11) then
1161              ! this is awful but it is still a first coding
1162              ! Num is single precision needed for cgerc check factocc
1163              num=-wl*factocc
1164              sf_uwing(:,iomegal,jdir) = sf_uwing(:,iomegal,jdir) + num * mir_kbz(jdir) * conjg(rhotwg_sym(1:npwe))
1165              sf_lwing(:,iomegal,jdir) = sf_lwing(:,iomegal,jdir) + num * rhotwg_sym(1:npwe) * conjg(mir_kbz(jdir))
1166              do idir=1,3
1167                sf_head(idir,jdir,iomegal) = sf_head(idir,jdir,iomegal) + num * mir_kbz(idir) * conjg(mir_kbz(jdir))
1168              end do
1169            end if
1170 
1171            ! Last point, must accumulate left point but not the right one
1172            if (iomegar/=nomegasf+1 .and. wr<huge(zero)*1.d-11) then
1173              num=-wr*factocc
1174              sf_uwing(:,iomegar,jdir) = sf_uwing(:,iomegar,jdir) + num * mir_kbz(jdir) * conjg(rhotwg_sym(1:npwe))
1175              sf_lwing(:,iomegar,jdir) = sf_lwing(:,iomegar,jdir) + num * rhotwg_sym(1:npwe) * conjg(mir_kbz(jdir))
1176              do idir=1,3
1177                sf_head(idir,jdir,iomegar) = sf_head(idir,jdir,iomegar) + num * mir_kbz(idir) * conjg(mir_kbz(jdir))
1178              end do
1179            end if
1180          end do ! jdir
1181 
1182        end if !wtksym
1183      end do !inv
1184    end do !isym
1185    ABI_FREE(rhotwg_sym)
1186 
1187  CASE DEFAULT
1188    ABI_BUG(sjoin('Wrong value of symchi:', itoa(symchi)))
1189  END SELECT
1190 
1191 end subroutine accumulate_sfchi0_q0

m_chi0tk/approxdelta [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

  approxdelta

FUNCTION

  Approximate the Dirac function using two methods:
  method 1) a triangular funtion centered at the value egwdiff_re, Eq 17 of PRB 74, 035101 (2006) [[cite:Shishkin2006]]
  method 2) a gaussian of witdth ep%spsmear expandended in Taylor series
  (at the moment only the 0-th moments)

  Subroutine needed to implement the calculation
  of the polarizability using the spectral representation as proposed in:
  PRB 74, 035101 (2006) [[cite:Shishkin2006]]
  and PRB 61, 7172 (2000) [[cite:Miyake2000]]

INPUTS

  nomegasf=number of frequencies in the grid for Im \chi_0
  omegasf(0:nomega+1)= frequencies (real)
  egwdiff_re = transition energy where the delta function is centered

  method= 1: a triangular shaped function used to approximated the delta
          2: gaussian approximation with standard deviation (smear)
 smear= used only in case of method==2, defines the width of the gaussian

OUTPUT

  wl = weight associated to omegal (last omega wich is smaller than egwdiff_re
  wr = weight associate to omegar  (first omega larger than egwdff_re
  iomegal= index in the array omegasf of the last frequency < egwdiff
  iomegar= index in the array omegasf of the first frequency > egwdiff

SOURCE

1433 subroutine approxdelta(nomegasf,omegasf,egwdiff_re,smear,iomegal,iomegar,wl,wr,spmeth)
1434 
1435 !Arguments ------------------------------------
1436 !scalars
1437  integer,intent(in) :: nomegasf,spmeth
1438  integer,intent(out) :: iomegal,iomegar
1439  real(dp),intent(in) :: egwdiff_re,smear
1440  real(dp),intent(out) :: wl,wr
1441 !arrays
1442  real(dp),intent(in) :: omegasf(nomegasf)
1443 
1444 !Local variables-------------------------------
1445  integer :: io,iomega
1446  real(dp) :: omegal,omegar,deltal,deltar
1447  !character(len=500) :: msg
1448 ! *************************************************************************
1449 
1450  iomega=-999
1451  do io=nomegasf,1,-1
1452    if (omegasf(io)<egwdiff_re) then
1453     iomega=io; EXIT
1454    end if
1455  end do
1456 
1457  iomegal=iomega   ; omegal=omegasf(iomegal)
1458  iomegar=iomegal+1; omegar=omegasf(iomegar)
1459 
1460  SELECT CASE (spmeth)
1461  CASE (1)
1462    ! Weights for triangular shaped function
1463    wr=  (egwdiff_re-omegal)/(omegar-omegal)
1464    wl= -(egwdiff_re-omegar)/(omegar-omegal)
1465 
1466  CASE (2)
1467    ! Weights for gaussian method (0-th moment)
1468    deltal=(egwdiff_re-omegal)/smear
1469    deltar=(omegar-egwdiff_re)/smear
1470    if (deltar>=deltal) then
1471      wl=EXP(-deltal*deltal)
1472      ! this value is used to avoid double counting and speed-up
1473      wr=huge(one)*1.d-10
1474    else
1475      wl=huge(one)*1.d-10
1476      wr=exp(-deltal*deltal)
1477    end if
1478 
1479  CASE DEFAULT
1480    ABI_BUG(sjoin('Wrong value for spmeth:', itoa(spmeth)))
1481  END SELECT
1482 
1483 end subroutine approxdelta

m_chi0tk/assemblychi0_sym [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 assemblychi0_sym

FUNCTION

 Update the independent particle susceptibility for the contribution
 of one pair of occupied-unoccupied band, for each frequency.
 If symchi=1 the expression is symmetrized taking into account the symmetries
 of the little group associated to the external q-point.
 Compute chi0(G1,G2,io)=chi0(G1,G2,io)+\sum_S \hat S (rhotwg(G1)*rhotwg*(G2))*green_w(io)
 where S are the symmetries of the little group associated to the external q-point.

INPUTS

  nspinor=Number of spinorial components.
  ik_bz=Index of the k-point in the BZ array whose contribution has to be symmetrized and added to cchi0
  npwepG0=Maximum number of G vectors taking into account possible umklapp G0, ie enlarged sphere G-G0
  rhotwg(npwe)=Oscillator matrix elements for this k-point and the transition that has to be summed
  green_w(nomega)=frequency dependent part coming from the green function
  Gsph_epsG0<gsphere_t> Information on the "enlarged" G-sphere used for chi0, it contains umklapp G0 vectors
    %ng=number of G vectors in the enlarged sphere, actually MUST be equal to the size of rhotwg
    %rottbm1(ng,2,nsym)=index of (IR)^{-1} G where I is the identity or the inversion
    %phmGt(ng,nsym)=phase factors associated to non-simmorphic operations
  Ltg_q<littlegroup_t_type>=Info on the little group associated to the external q-point.
    %timrev=2 it time-reversal is used, 1 otherwise
    %nsym_sg=Number of space group symmetries
    %wtksym(2,nsym,nkbz)=1 if the symmetry (with or without time-reversal) must be considered for this k-point
    %flag_umklp(timrev,nsym)= flag for umklapp processes
      if 1 that the particular operation (IS) requires a G_o to preserve Q, 0 otherwise
    %igmG0(npwepG0,timrev,nsym) index of G-G0 in the array gvec
  Ep<em1params_t>=Parameters related to the calculation of chi0/epsilon^-1
    %symchi
    %nomega=number of frequencies
    %npwe=number of plane waves for epsilon (input variable)

OUTPUT

  (see side effects)

SIDE EFFECTS

  chi0(npwe,npwe,nomega)=independent-particle susceptibility matrix in reciprocal space

SOURCE

109 subroutine assemblychi0_sym(is_metallic,ik_bz,nspinor,Ep,Ltg_q,green_w,npwepG0,rhotwg,Gsph_epsG0,chi0)
110 
111 !Arguments ------------------------------------
112 !scalars
113  logical,intent(in) :: is_metallic
114  integer,intent(in) :: ik_bz,npwepG0,nspinor
115  type(gsphere_t),intent(in) :: Gsph_epsG0
116  type(littlegroup_t),intent(in) :: Ltg_q
117  type(em1params_t),intent(in) :: Ep
118 !arrays
119  complex(gwpc),intent(in) :: rhotwg(npwepG0)
120  complex(dpc),intent(in) :: green_w(Ep%nomega)
121  complex(gwpc),intent(inout) :: chi0(Ep%npwe*Ep%nI,Ep%npwe*Ep%nJ,Ep%nomega)
122 
123 !Local variables-------------------------------
124 !scalars
125  integer :: itim,io,isym,nthreads
126  integer :: isymop,nsymop
127  real(gwp) :: dr
128  complex(gwpc) :: dd
129  !character(len=500) :: msg
130 !arrays
131  integer :: Sm1_gmG0(Ep%npwe)
132  complex(gwpc),allocatable :: rhotwg_sym(:,:)
133 
134 ! *************************************************************************
135 
136  ABI_UNUSED(nspinor)
137 
138  nthreads = xomp_get_max_threads()
139 
140  SELECT CASE (Ep%symchi)
141  CASE (0)
142    ! Do not use symmetries
143 
144    ! note that single precision is faster (sometimes factor ~2).
145    ! Rely on MKL threads for OPENMP parallelization
146 
147    do io=1,Ep%nomega
148      ! Check if green_w(io) is real (=> pure imaginary omega)
149      ! and that it is not a metal
150      ! then the corresponding chi0(io) is hermitian
151      if( ABS(AIMAG(green_w(io))) < 1.0e-6_dp .and. .not. is_metallic ) then
152        dr=green_w(io)
153        call xher('U',Ep%npwe,dr,rhotwg,1,chi0(:,:,io),Ep%npwe)
154      else
155        dd=green_w(io)
156        call xgerc(Ep%npwe,Ep%npwe,dd,rhotwg,1,rhotwg,1,chi0(:,:,io),Ep%npwe)
157      endif
158    end do
159 
160  CASE (1)
161    ! Use symmetries to reconstruct the integrand in the BZ.
162    !
163    ! Notes on the symmetrization of the oscillator matrix elements
164    !  If  Sq = q then  M_G^( Sk,q)= e^{-i(q+G).t} M_{ S^-1G}  (k,q)
165    !  If -Sq = q then  M_G^(-Sk,q)= e^{-i(q+G).t} M_{-S^-1G}^*(k,q)
166    !
167    ! In case of an umklapp process
168    !  If  Sq = q+G0 then  M_G( Sk,q)= e^{-i(q+G).t} M_{ S^-1(G-G0}   (k,q)
169    !  If -Sq = q+G0 then  M_G(-Sk,q)= e^{-i(q+G).t} M_{-S^-1(G-G0)}^*(k,q)
170    !
171    ! Ltg_q%igmG0(ig,itim,isym) contains the index of G-G0 where ISq=q+G0
172    ! Note that there is no need to take into account the phases due to q,
173    ! They cancel in the scalar product ==> phmGt(G,isym)=e^{-iG\cdot t}
174    !
175    ! Mind the slicing of %rottbm1(npwepG0,timrev,nsym) and %phmGt(npwepG0,nsym) as
176    ! these arrays, usually, do not conform to rho_twg_sym(npw) !
177    !
178    ! Loop over symmetries of the space group and time-reversal.
179    nsymop = count(Ltg_q%wtksym(:,:,ik_bz)==1)
180    ABI_MALLOC(rhotwg_sym,(Ep%npwe,nsymop))
181    isymop = 0
182 
183    ! Prepare all the rhotwg at once to use BLAS level 3 routines
184    do isym=1,Ltg_q%nsym_sg
185      do itim=1,Ltg_q%timrev
186        if (Ltg_q%wtksym(itim,isym,ik_bz)==1) then
187          ! This operation belongs to the little group and has to be used to reconstruct the BZ ===
188          ! * In the following 3 lines mind the slicing (1:npwe)
189          ! TODO this is a hot-spot, should add a test on the umklapp
190          !
191          !gmG0 => Ltg_q%igmG0(1:Ep%npwe,itim,isym)
192          Sm1_gmG0(1:Ep%npwe) = Gsph_epsG0%rottbm1( Ltg_q%igmG0(1:Ep%npwe,itim,isym), itim,isym)
193 
194          isymop = isymop + 1
195          SELECT CASE (itim)
196          CASE (1)
197            rhotwg_sym(1:Ep%npwe,isymop) = rhotwg(Sm1_gmG0) * Gsph_epsG0%phmGt(1:Ep%npwe,isym)
198          CASE (2)
199            rhotwg_sym(1:Ep%npwe,isymop) = GWPC_CONJG(rhotwg(Sm1_gmG0))*Gsph_epsG0%phmGt(1:Ep%npwe,isym)
200          CASE DEFAULT
201            ABI_BUG(sjoin('Wrong itim:', itoa(itim)))
202          END SELECT
203        end if
204      end do
205    end do
206 
207    ! Multiply rhotwg_sym by green_w(io) and accumulate in chi0(G,Gp,io)
208    ! note that single precision is faster (sometimes factor ~2).
209    ! Rely on MKL threads for OPENMP parallelization
210    do io=1,Ep%nomega
211      ! Check if green_w(io) is real (=> pure imaginary omega)
212      ! and that it is not a metal
213      ! then the corresponding chi0(io) is hermitian
214      if( ABS(AIMAG(green_w(io))) < 1.0e-6_dp .and. .not. is_metallic ) then
215        dr=green_w(io)
216        call xherk('U','N',Ep%npwe,nsymop,dr,rhotwg_sym,Ep%npwe,one_gw,chi0(:,:,io),Ep%npwe)
217      else
218        dd=green_w(io)
219        call xgemm('N','C',Ep%npwe,Ep%npwe,nsymop,dd,rhotwg_sym,Ep%npwe,rhotwg_sym,Ep%npwe,cone_gw,chi0(:,:,io),Ep%npwe)
220      endif
221    end do
222 
223    ABI_FREE(rhotwg_sym)
224 
225  CASE DEFAULT
226    ABI_BUG(sjoin('Wrong symchi:', itoa(Ep%symchi)))
227  END SELECT
228 
229 end subroutine assemblychi0_sym

m_chi0tk/assemblychi0sf [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 assemblychi0sf

FUNCTION

 Update the spectral function of the irreducible polarizability for the contribution
 of one pair of occupied-unoccupied states, for each frequency.
 If symchi==1, the symmetries of the little group of the external q-point are used
 to symmetrize the contribution in the full Brillouin zone. In this case, the routine computes:

   $ chi0(G1,G2,io)=chi0(G1,G2,io)+\sum_S (rhotwg(G1)*rhotwg^\dagger(G2))*\delta(w - trans) $

 where S are the symmetries of the little group of the external q-point.

INPUTS

  ik_bz=Index of the k-point in the BZ whose contribution has to be added to the spectral function of chi0
    If symchi=1, the contribution is symmetrized.
  my_wl,my_wr=min and Max frequency index treated by this processor.
  npwe=Number of plane waves used to describe chi0.
  npwepG0=Maximum number of G vectors taking into account umklapp vectors.
  nomegasf=Number of frequencies for the spectral function.
  nspinor=Number of spinorial components.
  symchi=1 if symmetries are used, 0 otherwise
  rhotwg(npwepG0)=Oscillator matrix elements corresponding to an occupied-unoccupied pair of states.
  timrev=if 2, time reversal has to be used to obtain k_bz; 1 otherwise.
  Gsph_epsG0<gsphere_t> Information on the "enlarged" G-sphere used for chi0, it contains umklapp G0 vectors
    %ng=number of G vectors in the enlarged sphere, actually MUST be equal to the size of rhotwg
    %rottbm1(ng,2,nsym)=index of (IR)^{-1} G where I is the identity or the inversion
    %phmGt(ng,nsym)=phase factors associated to non-simmorphic operations
  Ltg_q<littlegroup_t_type>=Info on the little group associated to the external q-point.
    %timrev=2 it time-reversal is used, 1 otherwise
    %nsym_sg=Number of space group symmetries
    %wtksym(2,nsym,nkbz)=1 if the symmetry (with or without time-reversal) must be considered for this k-point
    %flag_umklp(timrev,nsym)= flag for umklapp processes
      if 1 that the particular operation (IS) requires a G_o to preserve Q, 0 otherwise
    %igmG0(npwepG0,timrev,nsym) index of G-G0 in the array gvec
  factocc=occupation factor=f_occ*(ockp-occk) (see cchi0.F90)
  wl,wr=Weights used to approximate the delta function.

OUTPUT

  (see side effects)

SIDE EFFECTS

  chi0sf(npwe,npwe,my_wl:my_wr)= updated spectral function.

NOTES

  Umklapp processes are not yet implemented

SOURCE

1246 subroutine assemblychi0sf(ik_bz,symchi,Ltg_q,npwepG0,npwe,rhotwg,Gsph_epsG0,&
1247 & factocc,my_wl,iomegal,wl,my_wr,iomegar,wr,nomegasf,chi0sf)
1248 
1249 !Arguments ------------------------------------
1250 !scalars
1251  integer,intent(in) :: ik_bz,iomegal,iomegar,my_wl,my_wr,nomegasf,npwe,npwepG0
1252  integer,intent(in) :: symchi
1253  real(dp),intent(in) :: factocc,wl,wr
1254  type(gsphere_t),intent(in) :: Gsph_epsG0
1255  type(littlegroup_t),intent(in) :: Ltg_q
1256 !arrays
1257  complex(gwpc),intent(in) :: rhotwg(npwepG0)
1258  complex(gwpc),intent(inout) :: chi0sf(npwe,npwe,my_wl:my_wr)
1259 
1260 !Local variables-------------------------------
1261 !scalars
1262  integer :: isym,itim,ig1,ig2
1263  complex(gwpc) :: num
1264  character(len=500) :: msg
1265 !arrays
1266  integer :: Sm1_gmG0(npwe)
1267  complex(gwpc) :: rhotwg_sym(npwe)
1268 
1269 ! *************************************************************************
1270 
1271  if (iomegal < my_wl .or. iomegar > my_wr) then
1272    write(msg,'(3a,2(a,i0,a,i0,a))')ch10,&
1273 &    ' Indices out of boundary ',ch10,&
1274 &    '  my_wl = ',my_wl,' iomegal = ',iomegal,ch10,&
1275 &    '  my_wr = ',my_wr,' iomegar = ',iomegar,ch10
1276    ABI_BUG(msg)
1277  end if
1278 
1279  SELECT CASE (symchi)
1280  CASE (0)
1281     ! Do not use symmetries.
1282 
1283 ! MG: This is the best I can do for this part.
1284 !$omp PARALLEL private(num)
1285 !$omp SECTIONS
1286 !$omp SECTION
1287    if (wl<huge(zero)*1.d-11) then !FIXME this is awful
1288      num=-wl*factocc
1289      call XGERC(npwe,npwe,num,rhotwg,1,rhotwg,1,chi0sf(:,:,iomegal),npwe)
1290    end if
1291 
1292    ! Last point, must accumulate left point but not the right one
1293 !$omp SECTION
1294    if (iomegar/=nomegasf+1 .and. wr<huge(zero)*1.d-11) then
1295      num=-wr*factocc
1296      call XGERC(npwe,npwe,num,rhotwg,1,rhotwg,1,chi0sf(:,:,iomegar),npwe)
1297    end if
1298 !$omp end SECTIONS
1299 !$omp end PARALLEL
1300 
1301  CASE (1)
1302    ! Use symmetries to reconstruct oscillator matrix elements
1303    ! Notes on the symmetrization of the oscillator maxtri elements:
1304    !
1305    ! If  Sq=q then  M_G^( Sk,q)= e^{-i(q+G)\cdot t} M_{ S^-1G}  (k,q)
1306    ! If -Sq=q then  M_G^(-Sk,q)= e^{-i(q+G)\cdot t} M_{-S^-1G}^*(k,q)
1307    !
1308    ! In case of an umklapp process
1309    ! If  Sq=q+G_o then  M_G( Sk,q)= e^{-i(q+G)\cdot t} M_{ S^-1(G-G_o}   (k,q)
1310    ! If -Sq=q+G_o then  M_G(-Sk,q)= e^{-i(q+G)\cdot t} M_{-S^-1(G-G_o)}^*(k,q)
1311    !
1312    ! Ltg_q%igmG0(ig,itim,isym) contains the index of G-G0 where ISq=q+G0
1313    ! Note that there is no need to take into account the phases due to q,
1314    ! They cancel in the scalar product ==> phmGt(G,isym)=e^{-iG\cdot t}
1315    !
1316    ! Mind the slicing of %rottbm1(npwepG0,timrev,nsym) and %phgt(npwepG0,nsym) as
1317    ! these arrays, usually, do not conform to rho_twg_sym(npw) !
1318    !
1319    !ABI_MALLOC(rhotwg_sym,(npwe))
1320    !
1321    ! Loop over symmetries of the space group and time-reversal
1322    do isym=1,Ltg_q%nsym_sg
1323      do itim=1,Ltg_q%timrev
1324 
1325        if (Ltg_q%wtksym(itim,isym,ik_bz)==1) then
1326          ! This operation belongs to the little group and has to be used to reconstruct BZ.
1327          ! TODO this is a hot-spot, should add a test on the umklapp
1328          !
1329          ! In these 3 lines mind the slicing (1:npwe)
1330          Sm1_gmG0(1:npwe)=Gsph_epsG0%rottbm1( Ltg_q%igmG0(1:npwe,itim,isym), itim,isym)
1331 
1332          SELECT CASE (itim)
1333          CASE (1)
1334            rhotwg_sym(1:npwe)=rhotwg(Sm1_gmG0(1:npwe)) * Gsph_epsG0%phmGt(1:npwe,isym)
1335          CASE (2)
1336            rhotwg_sym(1:npwe)=conjg(rhotwg(Sm1_gmG0(1:npwe))) * Gsph_epsG0%phmGt(1:npwe,isym)
1337          CASE DEFAULT
1338            ABI_BUG(sjoin('Wrong value for itim:', itoa(itim)))
1339          END SELECT
1340 
1341 #if 0
1342 !! MG: This is the best I can do, at present.
1343 !$omp PARALLEL private(num)
1344 !$omp SECTIONS
1345 
1346 !$omp SECTION
1347          if (wl<huge(zero)*1.d-11) then
1348            num=-wl*factocc
1349            call XGERC(npwe,npwe,num,rhotwg_sym,1,rhotwg_sym,1,chi0sf(:,:,iomegal),npwe)
1350          end if
1351 !$omp SECTION
1352          !
1353          ! Last point, must accumulate left point but not the right one
1354          if (iomegar/=nomegasf+1 .and. wr<huge(zero)*1.d-11) then
1355            num=-wr*factocc
1356            call XGERC(npwe,npwe,num,rhotwg_sym,1,rhotwg_sym,1,chi0sf(:,:,iomegar),npwe)
1357          end if
1358 !$omp end SECTIONS
1359 !$omp end PARALLEL
1360 #else
1361 
1362          if (wl<huge(zero)*1.d-11) then
1363            !call XGERC(npwe,npwe,num,rhotwg_sym,1,rhotwg_sym,1,chi0sf(:,:,iomegal),npwe)
1364            num=-wl*factocc
1365 !$omp parallel do
1366            do ig2=1,npwe
1367              do ig1=1,npwe
1368                chi0sf(ig1,ig2,iomegal) = chi0sf(ig1,ig2,iomegal) + num * rhotwg_sym(ig1) * conjg(rhotwg_sym(ig2))
1369              end do
1370            end do
1371          end if
1372 
1373          ! Last point, must accumulate left point but not the right one
1374          if (iomegar/=nomegasf+1 .and. wr<huge(zero)*1.d-11) then
1375            !call XGERC(npwe,npwe,num,rhotwg_sym,1,rhotwg_sym,1,chi0sf(:,:,iomegar),npwe)
1376            num=-wr*factocc
1377 !$omp parallel do
1378            do ig2=1,npwe
1379              do ig1=1,npwe
1380                !call XGERC(npwe,npwe,num,rhotwg_sym,1,rhotwg_sym,1,chi0sf(:,:,iomegal),npwe)
1381                chi0sf(ig1,ig2,iomegar) = chi0sf(ig1,ig2,iomegar) + num * rhotwg_sym(ig1) * conjg(rhotwg_sym(ig2))
1382              end do
1383            end do
1384          end if
1385 #endif
1386        end if !wtksym
1387 
1388      end do !inv
1389    end do !isym
1390    !ABI_FREE(rhotwg_sym)
1391 
1392  CASE DEFAULT
1393    ABI_BUG(sjoin('Wrong value for symchi:', itoa(symchi)))
1394  END SELECT
1395 
1396 end subroutine assemblychi0sf

m_chi0tk/calc_kkweight [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

  calc_kkweight

FUNCTION

  Calculate frequency dependent weights needed to perform the Hilbert transform

  Subroutine needed to implement the calculation
  of the polarizability using the spectral representation as proposed in:
  PRB 74, 035101 (2006) [[cite:Shishkin2006]]
  and PRB 61, 7172 (2000) [[cite:Miyake2000]]

INPUTS

 nsp=number of frequencies where the imaginary part of the polarizability is evaluated
 ne=number of frequencies for the polarizability (same as in epsilon^-1)
 omegasp(nsp)=real frequencies for the imaginary part of the polarizability
 omegae(ne)= imaginary frequencies for the polarizability
 delta=small imaginary part used to avoid poles, input variables

OUTPUT

 kkweight(nsp,ne)=frequency dependent weights Eq A1 PRB 74, 035101 (2006) [[cite:Shishkin2006]]

SOURCE

1513 subroutine calc_kkweight(ne,omegae,nsp,omegasp,delta,omegamax,kkw)
1514 
1515 !Arguments ------------------------------------
1516 !scalars
1517  integer,intent(in) :: ne,nsp
1518  real(dp),intent(in) :: delta,omegamax
1519 !arrays
1520  real(dp),intent(in) :: omegasp(nsp)
1521  complex(dpc),intent(in) :: omegae(ne)
1522  complex(dpc),intent(out) :: kkw(nsp,ne)
1523 
1524 !Local variables-------------------------------
1525 !scalars
1526  integer :: isp,je
1527  real(dp) :: eta,xx1,xx2,den1,den2
1528  complex(dpc) :: c1,c2,wt
1529 !************************************************************************
1530 
1531  DBG_ENTER("COLL")
1532 
1533  kkw(:,:)=czero
1534 
1535  do je=1,ne
1536    eta=delta
1537    wt=omegae(je)
1538    ! Not include shift at omega==0, what about metallic systems?
1539    if (abs(real(omegae(je)))<tol6 .and. abs(aimag(wt))<tol6) eta=tol12
1540    !  Not include shift along the imaginary axis
1541    if (abs(aimag(wt))>tol6) eta=zero
1542    do isp=1,nsp
1543      if (isp==1) then
1544        ! Skip negative point, should check that this would not lead to spurious effects
1545        c1=czero
1546        den1=one
1547      else
1548        xx1=omegasp(isp-1)
1549        xx2=omegasp(isp)
1550        den1= xx2-xx1
1551        c1= -(wt-xx1+j_dpc*eta)*log( (wt-xx2+j_dpc*eta)/(wt-xx1+j_dpc*eta) )&
1552 &          +(wt+xx1-j_dpc*eta)*log( (wt+xx2-j_dpc*eta)/(wt+xx1-j_dpc*eta) )
1553        c1= c1/den1
1554      end if
1555      xx1=omegasp(isp)
1556      if (isp==nsp) then
1557        ! Skip last point should check that this would not lead to spurious effects
1558        xx2=omegamax
1559      else
1560        xx2=omegasp(isp+1)
1561      end if
1562      den2=xx2-xx1
1563      c2=  (wt-xx2+j_dpc*eta)*log( (wt-xx2+j_dpc*eta)/(wt-xx1+j_dpc*eta) )&
1564 &        -(wt+xx2-j_dpc*eta)*log( (wt+xx2-j_dpc*eta)/(wt+xx1-j_dpc*eta) )
1565      c2= c2/den2
1566      kkw(isp,je)=  c1/den1 + c2/den2
1567    end do
1568  end do
1569 
1570  DBG_EXIT("COLL")
1571 
1572 end subroutine calc_kkweight

m_chi0tk/chi0_bbp_mask [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

  chi0_bbp_mask

FUNCTION

INPUTS

OUTPUT

SOURCE

2338 subroutine chi0_bbp_mask(ikmq_ibz, ik_ibz, spin, spin_fact, use_tr, &
2339                          gwcomp, spmeth, chi_nband, mband, ebands, bbp_mask)
2340 
2341 !Arguments ------------------------------------
2342 !scalars
2343  integer,intent(in) :: spin,ik_ibz,ikmq_ibz,mband,gwcomp, spmeth, chi_nband
2344  real(dp),intent(in) :: spin_fact
2345  logical,intent(in) :: use_tr
2346  type(ebands_t),target,intent(in) :: ebands
2347 !arrays
2348  logical,intent(out) :: bbp_mask(mband, mband)
2349 
2350 !Local variables-------------------------------
2351 !scalars
2352  integer :: ib1, ib2
2353  real(dp) :: deltaeGW_b1kmq_b2k,deltaf_b1kmq_b2k,e_b1_kmq,f_b1_kmq
2354 !arrays
2355  real(dp), ABI_CONTIGUOUS pointer :: qp_eig(:,:,:),qp_occ(:,:,:)
2356 
2357 !************************************************************************
2358 
2359  qp_eig => ebands%eig; qp_occ => ebands%occ
2360  bbp_mask = .FALSE.
2361 
2362  select case (gwcomp)
2363  case (0)
2364    ! Loop over "conduction" states.
2365    do ib1=1,chi_nband
2366      e_b1_kmq = qp_eig(ib1, ikmq_ibz, spin)
2367      f_b1_kmq = qp_occ(ib1, ikmq_ibz, spin)
2368 
2369      ! Loop over "valence" states.
2370      do ib2=1,chi_nband
2371        deltaf_b1kmq_b2k   = spin_fact * (f_b1_kmq - qp_occ(ib2,ik_ibz,spin))
2372        deltaeGW_b1kmq_b2k = e_b1_kmq - qp_eig(ib2,ik_ibz,spin)
2373 
2374        select case (spmeth)
2375        case (0)
2376          ! Standard Adler-Wiser expression.
2377          if (ABS(deltaf_b1kmq_b2k) >= GW_TOL_DOCC) then
2378            bbp_mask(ib1, ib2) = .TRUE.
2379            if (use_tr .and. ib1 < ib2) bbp_mask(ib1,ib2) = .FALSE. ! GAIN a factor ~2 thanks to time-reversal.
2380          end if
2381 
2382        case (1,2)
2383          ! Spectral method, WARNING time-reversal here is always assumed!
2384          if (ABS(deltaf_b1kmq_b2k) >= GW_TOL_DOCC) then
2385            bbp_mask(ib1,ib2)=.TRUE.
2386            if (deltaeGW_b1kmq_b2k<zero) bbp_mask(ib1,ib2)=.FALSE. ! Only positive frequencies are needed for the Hilbert transform.
2387            !$if (use_tr .and. ib1<ib2) bbp_mask(ib1,ib2)=.FALSE. ! GAIN a factor ~2 thanks to time-reversal.
2388          end if
2389 
2390        case default
2391          ABI_ERROR(sjoin("Wrong value for spmeth:", itoa(spmeth)))
2392        end select
2393        !write(std_out,*) "bbp_mask(ib1,ib2)",bbp_mask(ib1,ib2)
2394      end do !ib2
2395    end do !ib1
2396 
2397  case (1)
2398    ! Extrapolar technique
2399    ABI_CHECK(spmeth == 0, "Hilbert transform and extrapolar method are not compatible")
2400 
2401    ! Loop over "conduction" states.
2402    do ib1=1,chi_nband
2403      e_b1_kmq=qp_eig(ib1,ikmq_ibz,spin)
2404      f_b1_kmq=   qp_occ(ib1,ikmq_ibz,spin)
2405 
2406      ! Loop over "valence" states.
2407      do ib2=1,chi_nband
2408        deltaf_b1kmq_b2k  = spin_fact*(f_b1_kmq-qp_occ(ib2,ik_ibz,spin))
2409        deltaeGW_b1kmq_b2k= e_b1_kmq-qp_eig(ib2,ik_ibz,spin)
2410 
2411        ! When the completeness correction is used,
2412        ! we need to also consider transitions with vanishing deltaf
2413        ! Rangel: This is to compute chi in metals correctly with the extrapolar method.
2414        bbp_mask(ib1,ib2)=.TRUE.
2415        !if (qp_occ(ib2,ik_ibz,is) < GW_TOL_DOCC) CYCLE
2416        if (qp_occ(ib2,ik_ibz,spin) < GW_TOL_DOCC .and. (ABS(deltaf_b1kmq_b2k) < GW_TOL_DOCC .or. ib1<ib2)) then
2417          bbp_mask(ib1,ib2)=.FALSE.
2418        end if
2419      end do
2420    end do
2421 
2422   case default
2423     ABI_ERROR(sjoin("Wrong value of gwcomp:", itoa(gwcomp)))
2424   end select
2425 
2426 end subroutine chi0_bbp_mask

m_chi0tk/completechi0_deltapart [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 completechi0_deltapart

FUNCTION

  Apply the delta part of the completeness correction to chi0

INPUTS

  ik_bz=Index of the k-point in the full BZ whose contribution has to be added and symmetrized.
  qzero=.TRUE. is long wave-length limit.
  symchi=1 if we are summing over IBZ_q and symmetrization has to be performed.
  npwe=Number of G vectors in chi0.
  npwvec=MAX number of G.
  nomega=Number of frequencies.
  nspinor=Number of spinorial components.
  nfftot=Total Number of points in the FFT
  ngfft(18)=Info on the FFT.
  igfft0(npwvec)=Index of each G in the FFT array.
  Gsph_FFT=<gsphere_t>=Info on the largest G-sphere contained in the FFT box used for wavefunctions.
  Ltg_q=<littlegroup_t>= Structure gathering information on the little group of the external q.
  green_enhigh_w=Approximated frequency dependent part of the Green function entering equation (TODO put reference)
  wfwfg=Fourier components of u_{kb1}.u_{kb2}

OUTPUT

  See SIDES EFFECTS

 SIDES EFFECTS
  chi0(npwe,npwe,nomega)= In input chi0 calculated so far,
  In output the "delta part" of the completeness correction is added.

SOURCE

1911 subroutine completechi0_deltapart(ik_bz,qzero,symchi,npwe,npwvec,nomega,nspinor,&
1912 & nfftot,ngfft,igfft0,Gsph_FFT,Ltg_q,green_enhigh_w,wfwfg,chi0)
1913 
1914 !Arguments ------------------------------------
1915 !scalars
1916  integer,intent(in) :: ik_bz,nfftot,nomega,npwe,npwvec,nspinor,symchi
1917  logical,intent(in) :: qzero
1918  type(gsphere_t),intent(in) :: Gsph_FFT
1919  type(littlegroup_t),intent(in) :: Ltg_q
1920 !arrays
1921  integer,intent(in) :: igfft0(npwvec),ngfft(18)
1922  complex(dpc),intent(in) :: green_enhigh_w(nomega)
1923  complex(gwpc),intent(in) :: wfwfg(nfftot*nspinor**2)
1924  complex(gwpc),intent(inout) :: chi0(npwe,npwe,nomega)
1925 
1926 !Local variables ------------------------------
1927 !scalars
1928  integer,save :: enough=0
1929  integer :: iSm1_g1mg2,iSm1_g1mg2_fft,ig,gmg_sph,gmg_fft
1930  integer :: igp,igstart,isym,itim,outofbox_wfn
1931  complex(gwpc) :: phmGt
1932  !character(len=500) :: msg
1933 
1934 !************************************************************************
1935 
1936  igstart=1; if (qzero) igstart=2
1937  outofbox_wfn=0
1938 
1939  SELECT CASE (symchi)
1940 
1941  CASE (0) ! Do not use symmetries.
1942    ! MG: One has to make sure G1-G2 is still in the FFT mesh for each G1 and G2 in chi0 (not always true)
1943    ! MODULO wraps G1-G2 in the FFT box but the Fourier components are not periodic!
1944    do igp=igstart,npwe
1945      do ig=igstart,npwe
1946        gmg_fft = Gsph_FFT%gmg_fftidx(ig,igp,ngfft)
1947        if (gmg_fft==0) then
1948          outofbox_wfn=outofbox_wfn+1; CYCLE
1949        end if
1950        chi0(ig,igp,:) = chi0(ig,igp,:) + wfwfg(gmg_fft)*green_enhigh_w(:)
1951      end do
1952    end do
1953 
1954  CASE (1)
1955    ! Symmetrize the integrand in the full BZ.
1956    ! * <Sk b|e^{-i(G1-G2}.r}|b Sk> = e^{-i(G1-G2).\tau} <k b|e^{-i(S^{-1}(G1-G2).r)|b k>
1957    ! * green_enhigh_w in invariant under symmetry
1958    ! * We symmetrize using the operations of the little group of q since this routine
1959    !   is called inside a sum over IBZ_q, it would be possible to symmetrize
1960    !   this term by just summing over the IBZ and rotating the matrix elements.
1961    ! * Time-reversal does not lead to a complex conjugated since bra and ket are the same.
1962    !
1963    do igp=igstart,npwe
1964      do ig=igstart,npwe
1965 
1966       ! Get the index of G1-G2.
1967       gmg_sph = Gsph_FFT%gmg_idx(ig,igp)
1968       if (gmg_sph==0) then
1969         outofbox_wfn=outofbox_wfn+1; CYCLE
1970       end if
1971 
1972       do itim=1,Ltg_q%timrev
1973         do isym=1,Ltg_q%nsym_sg
1974           if (Ltg_q%wtksym(itim,isym,ik_bz)==1) then
1975             ! * This operation belongs to the little group and has to be used to reconstruct the BZ.
1976             ! * Time-reversal in not used to rotate (G1-G2) see comment above.
1977             phmGt          = Gsph_FFT%phmGt  (gmg_sph,isym)
1978             iSm1_g1mg2     = Gsph_FFT%rottbm1(gmg_sph,1,isym)
1979             iSm1_g1mg2_fft = igfft0(iSm1_g1mg2)
1980 
1981             chi0(ig,igp,:) = chi0(ig,igp,:) + phmGt*wfwfg(iSm1_g1mg2_fft)*green_enhigh_w(:)
1982           end if
1983         end do !isym
1984       end do !itim
1985 
1986      end do !igp
1987    end do !ig
1988 
1989  CASE DEFAULT
1990    ABI_BUG("Wrong value of symchi")
1991  END SELECT
1992 
1993  if (outofbox_wfn/=0) then
1994    enough=enough+1
1995    if (enough<=50) then
1996      ABI_WARNING(sjoin(' Number of G1-G2 pairs outside the G-sphere for Wfns: ', itoa(outofbox_wfn)))
1997      if (enough==50) then
1998        call wrtout(std_out,' ========== Stop writing Warnings ==========')
1999      end if
2000    end if
2001  end if
2002 
2003 end subroutine completechi0_deltapart

m_chi0tk/hilbert_transform [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

  hilbert_transform

FUNCTION

  Compute the hilbert transform.

INPUTS

 nomegasf=number of points for the imaginary part of $\chi0(q,\omega)$
 nomega=number of frequencies in $\chi0(q,\omega)$.
 max_rest,min_res=max and min resonant transition energy (for this q-point)
 my_max_rest,my_min_rest=max and min resonant transition energy treated by this processor

OUTPUT

SOURCE

1746 subroutine hilbert_transform(npwe,nomega,nomegasf,my_wl,my_wr,kkweight,sf_chi0,chi0,spmeth)
1747 
1748 !Arguments ------------------------------------
1749 !scalars
1750  integer,intent(in) :: spmeth,nomega,nomegasf,my_wl,my_wr,npwe
1751 !arrays
1752  complex(dpc),intent(in) :: kkweight(nomegasf,nomega)
1753  complex(gwpc),intent(inout) :: sf_chi0(npwe,npwe,my_wl:my_wr)
1754  complex(gwpc),intent(inout) :: chi0(npwe,npwe,nomega)
1755 
1756 !Local variables-------------------------------
1757 !scalars
1758  integer :: ig2,my_nwp
1759  character(len=500) :: msg
1760 !arrays
1761  complex(gwpc),allocatable :: A_g1wp(:,:),H_int(:,:),my_kkweight(:,:)
1762 
1763 !************************************************************************
1764 
1765 #ifdef HAVE_OPENMP
1766  write(msg,'(2a,i3,a)')ch10,' Performing Hilbert transform (with OpenMP) using method ',spmeth,' It might take some time...'
1767 #else
1768  write(msg,'(2a,i3,a)')ch10,' Performing Hilbert transform using method ',spmeth,' It might take some time...'
1769 #endif
1770  call wrtout(std_out, msg, do_flush=.True.)
1771 
1772  my_nwp = my_wr - my_wl +1
1773 
1774 !$omp parallel private(my_kkweight, A_g1wp, H_int, ig2)
1775  ABI_MALLOC(my_kkweight, (my_wl:my_wr,nomega))
1776  my_kkweight = kkweight(my_wl:my_wr,:)
1777 
1778  ABI_MALLOC(A_g1wp, (npwe, my_nwp))
1779  ABI_MALLOC(H_int, (npwe, nomega))
1780 
1781 !$omp do
1782  do ig2=1,npwe
1783    A_g1wp = sf_chi0(:,ig2,:)
1784 
1785    ! Compute H_int = MATMUL(A_g1wp,my_kkweight)
1786    call XGEMM('N','N',npwe,nomega,my_nwp,cone_gw,A_g1wp,npwe,my_kkweight,my_nwp,czero_gw,H_int,npwe)
1787    chi0(:,ig2,:) = H_int
1788  end do
1789 
1790  ABI_FREE(my_kkweight)
1791  ABI_FREE(A_g1wp)
1792  ABI_FREE(H_int)
1793 !$omp end parallel
1794 
1795 end subroutine hilbert_transform

m_chi0tk/hilbert_transform_headwings [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

  hilbert_transform_headwings

FUNCTION

  Compute the hilbert transform the heads and wings of the polarizability.

INPUTS

 nomegasf=number of points for the imaginary part of $\chi0(q,\omega)$
 nomega=number of frequencies in $\chi0(q,\omega)$.
 max_rest,min_res=max and min resonant transition energy (for this q-point)
 my_max_rest,my_min_rest=max and min resonant transition energy treated by this processor

OUTPUT

SOURCE

1817 subroutine hilbert_transform_headwings(npwe,nomega,nomegasf,my_wl,my_wr,kkweight, &
1818 & sf_lwing,sf_uwing,sf_head,chi0_lwing,chi0_uwing,chi0_head,spmeth)
1819 
1820 !Arguments ------------------------------------
1821 !scalars
1822  integer,intent(in) :: spmeth,nomega,nomegasf,my_wl,my_wr,npwe
1823 !arrays
1824  complex(dpc),intent(in) :: kkweight(nomegasf,nomega)
1825  complex(dpc),intent(inout) :: sf_lwing(npwe,my_wl:my_wr,3)
1826  complex(dpc),intent(inout) :: sf_uwing(npwe,my_wl:my_wr,3)
1827  complex(dpc),intent(inout) :: sf_head(3,3,my_wl:my_wr)
1828  complex(dpc),intent(inout) :: chi0_lwing(npwe,nomega,3)
1829  complex(dpc),intent(inout) :: chi0_uwing(npwe,nomega,3)
1830  complex(dpc),intent(inout) :: chi0_head(3,3,nomega)
1831 
1832 !Local variables-------------------------------
1833 !scalars
1834  integer :: ig1,idir,io,iw
1835  complex(dpc) :: kkw
1836  character(len=500) :: msg
1837 !************************************************************************
1838 
1839 #ifdef HAVE_OPENMP
1840  write(msg,'(2a,i3,a)')ch10,' Performing Hilbert transform (with OpenMP) using method ',spmeth,' It might take some time...'
1841 #else
1842  write(msg,'(2a,i3,a)')ch10,' Performing Hilbert transform using method ',spmeth,' It might take some time...'
1843 #endif
1844  call wrtout(std_out,msg, do_flush=.True.)
1845 
1846  ! Hilbert transform of the head.
1847  do io=1,nomega
1848    chi0_head(1,1,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(1,1,my_wl:my_wr))
1849    chi0_head(2,1,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(2,1,my_wl:my_wr))
1850    chi0_head(3,1,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(3,1,my_wl:my_wr))
1851    chi0_head(1,2,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(1,2,my_wl:my_wr))
1852    chi0_head(2,2,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(2,2,my_wl:my_wr))
1853    chi0_head(3,2,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(3,2,my_wl:my_wr))
1854    chi0_head(1,3,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(1,3,my_wl:my_wr))
1855    chi0_head(2,3,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(2,3,my_wl:my_wr))
1856    chi0_head(3,3,io) = SUM(kkweight(my_wl:my_wr,io)*sf_head(3,3,my_wl:my_wr))
1857  end do
1858 
1859  ! Hilbert transform for wings.
1860  ! Partial contributions to chi0 will be summed afterwards.
1861 !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(kkw)
1862  do idir=1,3
1863    do io=1,nomega
1864      do iw=my_wl,my_wr
1865        kkw = kkweight(iw,io)
1866        do ig1=1,npwe
1867          chi0_lwing(ig1,io,idir) = chi0_lwing(ig1,io,idir) + kkw*sf_lwing(ig1,iw,idir)
1868          chi0_uwing(ig1,io,idir) = chi0_uwing(ig1,io,idir) + kkw*sf_uwing(ig1,iw,idir)
1869        end do
1870      end do
1871    end do
1872  end do  !idir
1873 
1874 end subroutine hilbert_transform_headwings

m_chi0tk/make_transitions [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 make_transitions

FUNCTION

  Calculate transition energies entering the espression for the irreducible polarizability.

INPUTS

  nsspol=1 for spin unpolarized, 2 for spin polarized calculations
  nbnds=total number of bands
  kmesh<kmesh_t>=datatype gathering info on the k-mesh:
   | %nbz=number of k-points in the full BZ
   | %nibz=number of k-points in the IBZ
   | %tab(nkbz)=table giving for each k-point in the BZ, the corresponding irreducible point in the IBZ array
   | %bz(3,nkbz)=reduced coordinated of k-points
  TOL_DELTA_OCC=tolerance on the difference of the occupation numbers
  gw_energy(nbnds,kmesh%nkibz,nsppol)=quasi-particle energies energies
  occ(nbnds,kmesh%nkibz,nsppol)=occupation numbers
  chi0alg=integer defining the method used to calculate chi0
   0 ==> calculate chi0 using the Adler-Wiser expression
   1 ==> use spectral method
  timrev=if 2, time-reversal symmetry is considered; 1 otherwise

OUTPUT

 my_max_rest,my_min_rest=Maximum and minimum resonant (posite) transition energy.
 max_rest,min_rest=Maximun and minimum resonant (posite) transition energy treated by this node.

SOURCE

2193 subroutine make_transitions(Wfd,chi0alg,nbnds,nbvw,nsppol,symchi,timrev,TOL_DELTA_OCC,&
2194                             max_rest,min_rest,my_max_rest,my_min_rest,Kmesh,Ltg_q,gw_energy,occ,qpoint,bbp_ks_distrb)
2195 
2196 !Arguments ------------------------------------
2197 !scalars
2198  integer,intent(in) :: chi0alg,nbnds,nbvw,nsppol,symchi,timrev
2199  real(dp),intent(in) :: TOL_DELTA_OCC
2200  real(dp),intent(out) :: max_rest,min_rest, my_max_rest,my_min_rest
2201  type(kmesh_t),intent(in) :: Kmesh
2202  type(littlegroup_t),intent(in) :: Ltg_q
2203  type(wfdgw_t),intent(in) :: Wfd
2204 !arrays
2205  real(dp),intent(in) :: gw_energy(nbnds,Kmesh%nibz,nsppol)
2206  real(dp),intent(in) :: occ(nbnds,Kmesh%nibz,nsppol),qpoint(3)
2207  integer,intent(in) :: bbp_ks_distrb(Wfd%mband,Wfd%mband,Kmesh%nbz,Wfd%nsppol)
2208 
2209 !Local variables-------------------------------
2210 !scalars
2211  integer :: ib1,ib2,ii,ik_bz,ik_ibz,ikmq_bz,ikmq_ibz,is,nt,ntrans,my_ntrans,iloop
2212  real(dp) :: delta_ene,delta_occ,spin_fact
2213  character(len=500) :: msg
2214 !arrays
2215  integer :: G0(3)
2216  real(dp) :: kmq(3)
2217 
2218 !************************************************************************
2219 
2220  DBG_ENTER("COLL")
2221 
2222  if (chi0alg < 0 .or. chi0alg >= 2) then
2223    ABI_BUG(sjoin('chi0alg:', itoa(chi0alg),' not allowed'))
2224  end if
2225  if (timrev /= 1 .and. timrev /= 2) then
2226    ABI_BUG(sjoin('timrev:', itoa(timrev),' not allowed'))
2227  end if
2228 
2229  ABI_UNUSED(nbvw)
2230  !
2231  ! In the first loop, we calculate total number of transitions for this q-point
2232  ! as well the min and max transition without taking into account distribution of bands.
2233  ! In the second iteration, we calculate the min and Max transition treated by this processor.
2234  !
2235  spin_fact =half; if (nsppol == 2) spin_fact = one
2236 
2237  my_max_rest=smallest_real; my_min_rest=greatest_real
2238     max_rest=smallest_real;    min_rest=greatest_real
2239 
2240  do iloop=1,2
2241    nt=0
2242    do ik_bz=1,Kmesh%nbz
2243      ik_ibz=Kmesh%tab(ik_bz)
2244      kmq(:)=Kmesh%bz(:,ik_bz)-qpoint(:)
2245 
2246      if (symchi == 1) then
2247        if (Ltg_q%ibzq(ik_bz) /= 1) cycle ! This point does not belong to the IBZ defined by the little group
2248      end if
2249 
2250      ! Find kp=k-q-G0 and also G0 where kp is in the first BZ
2251      if (.not. kmesh%has_BZ_item(kmq,ikmq_bz,g0)) then
2252        ! Stop as the weight 1.0/nkbz is wrong.
2253        write(msg,'(4a,2(2a,3f12.6),2a)')ch10,&
2254          ' make_transitions : ERROR - ',ch10,&
2255          ' kp  = k-q-G0 not found in the BZ mesh',ch10,&
2256          ' k   = ',(Kmesh%bz(ii,ik_bz),ii=1,3),ch10,&
2257          ' k-q = ',(kmq(ii),ii=1,3),ch10,&
2258          ' weight in cchi0/cchi0q is wrong '
2259        ABI_ERROR(msg)
2260      end if
2261 
2262      ikmq_ibz = Kmesh%tab(ikmq_bz)
2263      do is=1,nsppol
2264        do ib1=1,nbnds
2265          do ib2=1,nbnds
2266 
2267            if (iloop == 2) then
2268              if (bbp_ks_distrb(ib1,ib2,ik_bz,is)/=Wfd%my_rank) cycle
2269            end if
2270 
2271            if (timrev == 2 .and. ib1 < ib2) cycle ! Thanks to time-reversal we gain a factor ~2.
2272 
2273            delta_occ = spin_fact * (occ(ib1,ikmq_ibz,is) - occ(ib2,ik_ibz,is))
2274            delta_ene = gw_energy(ib1,ikmq_ibz,is) - gw_energy(ib2,ik_ibz,is)
2275 
2276            if (chi0alg == 0)  then
2277              ! Adler-Wiser expression. Skip only if factor due to occupation number is smaller than TOL_DELTA_OCC
2278              if (abs(delta_occ) < abs(TOL_DELTA_OCC)) cycle
2279            else if (chi0alg==1) then
2280              ! Spectral method with time-reversal, only resonant transitions
2281              ! This has to be changed to include spectral method without time-reversal
2282              if (delta_ene < -abs(TOL_DELTA_OCC) .or. abs(delta_occ) < abs(TOL_DELTA_OCC)) cycle
2283            end if
2284 
2285            ! We have a new transition
2286            nt=nt+1
2287 
2288            if (iloop==1) then
2289              max_rest=MAX(max_rest,zero,delta_ene)
2290              if (delta_ene>=-tol6) min_rest=MIN(min_rest,delta_ene)
2291            end if
2292            if (iloop==2) then
2293              my_max_rest=MAX(my_max_rest,zero,delta_ene)
2294              if (delta_ene>=-tol6) my_min_rest=MIN(my_min_rest,delta_ene)
2295            end if
2296 
2297          end do
2298        end do
2299      end do
2300    end do
2301    if (iloop==1) ntrans=nt
2302    if (iloop==2) my_ntrans=nt
2303  end do !iloop
2304 
2305  write(msg,'(2a,i9,2a,f8.3,3a,f8.3,a)')ch10,&
2306   ' Total number of transitions = ',ntrans,ch10,&
2307   ' min resonant     = ',min_rest*Ha_eV,' [eV] ',ch10,&
2308   ' Max resonant     = ',max_rest*Ha_eV,' [eV] '
2309  call wrtout(std_out, msg)
2310 
2311  if (Wfd%nproc/=1) then
2312    write(msg,'(2a,i9,2a,f8.3,3a,f8.3,a)')ch10,&
2313     ' Total number of transitions for this processor= ',my_ntrans,ch10,&
2314     ' min resonant     = ',my_min_rest*Ha_eV,' [eV] ',ch10,&
2315     ' Max resonant     = ',my_max_rest*Ha_eV,' [eV] '
2316    call wrtout(std_out, msg)
2317  end if
2318 
2319  DBG_EXIT("COLL")
2320 
2321 end subroutine make_transitions

m_chi0tk/mkrhotwg_sigma [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 mkrhotwg_sigma

FUNCTION

  Helper function used to calculate selected linear combination
  of the oscillator matrix elements in the case of non-collinear magnetism.

INPUTS

  ii=Index selecting the particolar combination of spin components.
  npw=Number of plane-waves in the oscillators.
  nspinor=Number of spinorial components.
  rhotwg(npw*nspinor**2)=OScillator matrix elements.

OUTPUT

  rhotwg_I(npw)=Required linear combination of the oscillator matrix elements.

SOURCE

253 subroutine mkrhotwg_sigma(ii,nspinor,npw,rhotwg,rhotwg_I)
254 
255 !Arguments ------------------------------------
256 !scalars
257  integer,intent(in) :: ii,npw,nspinor
258 !arrays
259  complex(gwpc),intent(in) :: rhotwg(npw*nspinor**2)
260  complex(gwpc),intent(out) :: rhotwg_I(npw)
261 
262 ! *************************************************************************
263 
264  SELECT CASE (ii)
265  CASE (1)
266    ! $ M_0 = M_{\up,\up} + M_{\down,\down} $
267    rhotwg_I(:) = rhotwg(1:npw) + rhotwg(npw+1:2*npw)
268  CASE (2)
269    ! $ M_z = M_{\up,\up} - M_{\down,\down} $
270    rhotwg_I(:) = rhotwg(1:npw) - rhotwg(npw+1:2*npw)
271  CASE (3)
272    ! $ M_x = M_{\up,\down} + M_{\down,\up} $
273    rhotwg_I(:) = ( rhotwg(2*npw+1:3*npw) + rhotwg(3*npw+1:4*npw) )
274  CASE (4)
275    ! $ M_y = i * (M_{\up,\down} -M_{\down,\up}) $
276    rhotwg_I(:) = (rhotwg(2*npw+1:3*npw) - rhotwg(3*npw+1:4*npw) )*j_gw
277  CASE DEFAULT
278    ABI_BUG(sjoin('Wrong ii value:', itoa(ii)))
279  END SELECT
280 
281 end subroutine mkrhotwg_sigma

m_chi0tk/output_chi0sumrule [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 output_chi0sumrule

FUNCTION

  Calculate and output the value of the sum rule for
  the non-interacting polarizability chi0

INPUTS

OUTPUT

  (for writing routines, no output)
  otherwise, should be described

SOURCE

2024 subroutine output_chi0sumrule(qeq0,iq,npwe,omegaplasma,chi0sumrule,epsm1_w0,vc_sqrt)
2025 
2026 !Arguments ------------------------------------
2027 !scalars
2028  integer,intent(in) :: iq,npwe
2029  real(dp),intent(in) :: omegaplasma
2030  logical,intent(in) :: qeq0
2031 !arrays
2032  real(dp),intent(inout) :: chi0sumrule(npwe)
2033  complex(gwpc),intent(in) :: epsm1_w0(npwe,npwe),vc_sqrt(npwe)
2034 
2035 !Local variables ------------------------------
2036 !scalars
2037  integer :: ig,igstart
2038  real(dp) :: average,norm
2039  character(len=500) :: msg
2040 
2041 !************************************************************************
2042 
2043  igstart=1; if (qeq0) igstart=2
2044  !
2045  ! The sumrule reads:
2046  ! $ \int d\omega \omega v * Im[ \chi_0(\omega) ] = \pi/2 * w_p^2 $.
2047  chi0sumrule(igstart:npwe) = chi0sumrule(igstart:npwe) * vc_sqrt(igstart:npwe)**2
2048  !
2049  ! Calculate a weighted average of the fulfilment of the sumrule on epsilon
2050  ! The weight is given according to the significance of each q+G in the
2051  ! subsequent GW calculation: It is proportional to v * (epsm1 -1 )
2052  average = zero; norm = zero
2053  do ig=igstart,npwe
2054    average = average + chi0sumrule(ig) * real( vc_sqrt(ig)**2 * (epsm1_w0(ig,ig) - 1.0_dp ) )
2055    norm    = norm    +                   real( vc_sqrt(ig)**2 * (epsm1_w0(ig,ig) - 1.0_dp ) )
2056    !average = average + chi0sumrule(ig) * real(  (epsm1_w0(ig,ig) - 1.0_dp ) )
2057    !norm    = norm    +                   real(  (epsm1_w0(ig,ig) - 1.0_dp ) )
2058    !write(203,'(i4,8(2x,e12.6))') ig,1.0_dp/vc_sqrt(ig),chi0sumrule(ig)/ (0.5d0*omegaplasma**2*pi)
2059  end do
2060 
2061  if (abs(norm)>tol8) then
2062    write(msg,'(1x,a,i4,a,f10.2,2x,a)')&
2063     ' Average fulfillment of the sum rule on Im[epsilon] for q-point ',&
2064     iq,' :',average/norm/(0.5_dp*omegaplasma**2*pi)*100.0_dp,'[%]'
2065    call wrtout([std_out, ab_out], msg)
2066  end if
2067 
2068 end subroutine output_chi0sumrule

m_chi0tk/setup_spectral [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

  setup_spectral

FUNCTION

 Calculation of \chi_o based on the spectral method as proposed in PRB 74, 035101 (2006) [[cite:Shishkin2006]]
 and PRB 61, 7172 (2000) [[cite:Miyake2000]].
 Setup of the real frequency mesh for $\Im\chi_o$ and of the frequency-dependent weights for
 Hilbert transform. Note that CPU time does not depend dramatically on nomegasf unlike memory.
 spmeth defines the approximant for the delta function:
  ==1 : use Triangular approximant (Kresse method)
  ==2 : use Gaussian method, requiring smearing (Miyake method)

INPUTS

 nomegasf=number of points for the imaginary part of $\chi0(q,\omega)$
 nomega=number of frequencies in $\chi0(q,\omega)$.
 max_rest,min_res=max and min resonant transition energy (for this q-point)
 my_max_rest,my_min_rest=max and min resonant transition energy treated by this processor
 method=integer flag defining the type of frequency mesh used for $\Im chi0$
  | 0 for a linear mesh
  | 1 for a mesh densified around omegaplasma
 omegaplasma=frequency around which the mesh is densifies (usually Drude plasma frequency)
  used only in case of method==1
 zcut=small imaginary shift to avoid pole in chi0

OUTPUT

  kkweight(nomegasf,nomega)=Frequency dependent weight for Hilber transform.
  omegasf(nomegasf+1)=frequencies for imaginary part.

SOURCE

1608 subroutine setup_spectral(nomega,omega,nomegasf,omegasf,max_rest,min_rest,my_max_rest,my_min_rest,&
1609 &  method,zcut,omegaplasma,my_wl,my_wr,kkweight)
1610 
1611 !Arguments ------------------------------------
1612 !scalars
1613  integer,intent(in) :: method,nomega,nomegasf
1614  integer,intent(out) :: my_wl,my_wr
1615  real(dp),intent(in) :: max_rest,min_rest,omegaplasma,zcut
1616  real(dp),intent(in) :: my_max_rest,my_min_rest
1617 !arrays
1618  real(dp),intent(out) :: omegasf(nomegasf)
1619  complex(dpc),intent(in) :: omega(nomega)
1620  complex(dpc),intent(out) :: kkweight(nomegasf,nomega)
1621 
1622 !Local variables-------------------------------
1623 !scalars
1624  integer :: io,ii
1625  real(dp) :: nu_min,nu_max,nu1,nu2,dd,domegasf,wp,deltat
1626  character(len=500) :: msg
1627 !arrays
1628  integer,allocatable :: insort(:)
1629 !************************************************************************
1630 
1631  ! The mesh must enclose the entire range of transitions.
1632  dd=(max_rest-min_rest)/(nomegasf-1)
1633  domegasf=(max_rest-min_rest+2*dd)/(nomegasf-1)
1634 
1635  write(msg,'(4a,f8.3,3a,i5,2a,f8.5,a)')ch10,&
1636   ' === Info on the real frequency mesh for spectral method === ',ch10,&
1637   '  maximum frequency = ',max_rest*Ha_eV,' [eV]',ch10,&
1638   '  nomegasf = ',nomegasf,ch10,&
1639   '  domegasf = ',domegasf*Ha_eV,' [eV]'
1640  call wrtout(std_out,msg)
1641 
1642  if (min_rest<tol6) then
1643    ABI_WARNING("System seems to be metallic")
1644  end if
1645 
1646  ! ======================================================
1647  ! === Setup of the w-mesh for the spectral function ====
1648  ! ======================================================
1649  SELECT CASE (method)
1650  CASE (0)
1651    ! Linear mesh.
1652    call wrtout(std_out, ' Using linear mesh for Im chi0')
1653    do io=1,nomegasf
1654      omegasf(io)=(io-1)*domegasf+min_rest-dd
1655    end do
1656 
1657  CASE (1)
1658    ! Non-homogeneous mesh densified around omega_plasma, do not improve results ===
1659    ! WARNING_ this part has to be checked since I modified omegasf
1660    write(msg,'(a,f7.4,a)')' Using mesh densified around ',omegaplasma*Ha_eV,' [eV] '
1661    call wrtout(std_out, msg)
1662    wp=omegaplasma ; deltat=max_rest-min_rest
1663    nu_min=zero
1664    if (deltat<wp ) then
1665      nu_max = wp/sqrt2 *   ATAN(sqrt2*deltat*wp/(-deltat**2+wp**2))
1666    else
1667      nu_max = wp/sqrt2 * ( ATAN(sqrt2*deltat*wp/(-deltat**2+wp**2)) + pi)
1668    end if
1669    domegasf=(nu_max-nu_min)/(nomegasf+1)
1670    !write(std_out,*)  -(wp/sqrt2) * atan(sqrt2*deltat*wp/(deltat**2-wp**2))
1671    omegasf(1)=zero ; omegasf(nomegasf+1)=deltat
1672    ii=0
1673    do io=2,nomegasf
1674      nu1=domegasf*(io-1) ; nu2=TAN(-sqrt2*nu1/wp)
1675      if (nu2<0) then
1676        omegasf(io) = wp * (one - SQRT(1+2*nu2**2))/(sqrt2*nu2)
1677      else
1678        omegasf(io) = wp * (one + SQRT(1+2*nu2**2))/(sqrt2*nu2)
1679      end if
1680      if (omegasf(io)> deltat ) then
1681        omegasf(io)= deltat-0.1*ii
1682        ii=ii+1
1683      end if
1684      ! write(102,'(i4,2x,3(f9.4,2x))')io,nu1,nu2,ep%omegasf(io)*Ha_eV
1685    end do
1686 
1687    ! Reorder frequencies in ascending order
1688    ABI_MALLOC(insort,(nomegasf+1))
1689    insort(:)=(/ (io,io=1,nomegasf+1) /)
1690    call sort_dp(nomegasf+1,omegasf,insort,tol14)
1691    ABI_FREE(insort)
1692 
1693  CASE DEFAULT
1694    ABI_BUG(sjoin('Wrong value for method:', itoa(method)))
1695  END SELECT
1696  !write(std_out,*)omegasf(1)*Ha_eV,omegasf(nomegasf)*Ha_eV
1697 
1698  ! Find min and max index in omegasf treated by this processor.
1699  my_wr=-999
1700  do io=1,nomegasf
1701    if (omegasf(io)>my_max_rest) then
1702      my_wr=io; EXIT
1703    end if
1704  end do
1705  if (my_wr==nomegasf+2) my_wr=nomegasf+1
1706  my_wl=-999
1707  do io=nomegasf,1,-1
1708    if (omegasf(io)< my_min_rest) then ! Check metals
1709      my_wl=io; EXIT
1710    end if
1711  end do
1712 
1713  write(msg,'(a,2(1x,i0))')' my_wl and my_wr:',my_wl,my_wr
1714  call wrtout(std_out, msg)
1715 
1716  if (my_wl==-999 .or. my_wr==-999) then
1717    write(msg,'(a,2i6)')' wrong value in my_wl and/or my_wr ',my_wl,my_wr
1718    ABI_ERROR(msg)
1719  end if
1720 
1721  ! Calculate weights for Hilbert transform.
1722  call calc_kkweight(nomega,omega,nomegasf,omegasf,zcut,max_rest,kkweight)
1723 
1724 end subroutine setup_spectral

m_chi0tk/symmetrize_afm_chi0tk [ Functions ]

[ Top ] [ m_chi0tk ] [ Functions ]

NAME

 symmetrize_afm_chi0

FUNCTION

  Reconstruct the (down, down) component of the irreducible polarizability
  starting from the (up,up) element in case of systems with AFM symmetries
  (i.e nspden==2 and nsppol=1). Return the trace (up,up)+(down,down) of the
  matrix as required by GW calculations.

INPUTS

  Cryst<crystal_t>= Information on symmetries and unit cell.
  Gsph<gsphere_t>= The G-sphere used to descrive chi0.
  npwe=Number of G-vectors in chi0.
  nomega=number of frequencies.
  Ltg_q<littlegroup_t>=Structure with useful table describing the little group of the q-point.

SIDE EFFECTS

 chi0(npwe,npwe,nomega)= In input the up-up component, in output the trace of chi0.
   The value of matrix elements that should be zero due to AFM symmetry properties are
   forced to be zero (see NOTES below).
 [chi0_lwing(npwe,nomega,3)] = Lower wings, symmetrized in output.
 [chi0_uwing(npwe,nomega,3)] = Upper wings, symmetrized in output.
 [chi0_head(3,3,nomega)    ] = Head of chi0, symmetrized  in output.

NOTES

 In the case of magnetic group Shubnikov type III:
   For each set of paired FM-AFM symmetries, the down-down component of
   a generic response function in reciprocal space can be obtained according to:

    chi^{down,down}_{G1,G2}(q) = chi^{up up}_{G1,G2}(q) e^{iS(G1-G2).(tnonsFM - tnonsAFM)}

   where S is the rotational part common to the FM-AFM pair, tnonsFM and tnonsAFM
   are the fractional translations associated to the ferromagnetic and antiferromagnetic symmetry, respectively.
   Note that, if for a given G1-G2 pair, the phase e^{iS(G1-G2).(tnonsFM - tnonsAFM) depends
   on the FM-AFM symmetry pair, then the corresponding matrix element of chi0 must be zero.
   Actually this is manually enforced in the code because this property might not be
   perfectly satisfied due to round-off errors.

 In the case of magnetic group Shubnikov type III:
   Only the AFM symmetries that preserve the external q-point (with or without time-reversal)
   are used to get the (down, down) component using the fact that:

    chi^{down,down}_{G1,G2}(Sq) = chi^{up up}_{S^{-1}G1,S^{-1}G2}(q) e^{i(G2-G1).tnons_S }

   Actually we perform an average over subset of the little group of q with AFM character in
   order to reduce as much as possible errors due to round off errors. In brief we evaluate:

    1/N_{Ltq} \sum_{S\in Ltg AFM} chi^{up up}_{S^{-1}G1,S^{-1}G2}(q) e^{i(G2-G1).tnons_S }

   where N_{Ltg} is the number of AFM operation in the little group (time reversal included)

TODO

  It is possible to symmetrize chi0 without any the extra allocation for afm_mat.
  More CPU demanding but safer in case of a large chi0 matrix. One might loop over G1 and G2 shells ...

SOURCE

344 subroutine symmetrize_afm_chi0(Cryst,Gsph,Ltg_q,npwe,nomega,chi0,chi0_head,chi0_lwing,chi0_uwing)
345 
346 !Arguments ------------------------------------
347 !scalars
348  integer,intent(in) :: npwe,nomega
349  type(gsphere_t),intent(in) :: Gsph
350  type(crystal_t),intent(in) :: Cryst
351  type(littlegroup_t),intent(in) :: Ltg_q
352 !arrays
353  complex(gwpc),optional,intent(inout) :: chi0(npwe,npwe,nomega)
354  complex(dpc),optional,intent(inout) :: chi0_lwing(npwe,nomega,3)
355  complex(dpc),optional,intent(inout) :: chi0_uwing(npwe,nomega,3)
356  complex(dpc),optional,intent(inout) :: chi0_head(3,3,nomega)
357 
358 !Local variables ------------------------------
359 !scalars
360  integer :: io,ig1,ig2,isymf,isyma,isym,ipair,k0g,kg,npairs,nonzero
361  integer :: iSmg1,iSmg2,itim,shubnikov,ntest
362  complex(gwpc) :: phase,phase_old,sumchi,ctmp
363  logical :: found
364  !character(len=500) :: msg
365 !arrays
366  integer :: rotfm(3,3),rotafm(3,3),pairs2sym(2,Cryst%nsym/2)
367  real(dp) :: tfm(3),tafm(3)
368  complex(gwpc),allocatable :: afm_mat(:),chi0_afm(:,:)
369 
370 !************************************************************************
371 
372  ABI_CHECK(ANY(Cryst%symafm==-1),'Not magnetic space group')
373  !
374  ! ==== Find shubnikov type ====
375  ! TODO This info should be stored in Cryst%
376  shubnikov=4; npairs=0
377 
378  do isymf=1,Cryst%nsym
379    if (Cryst%symafm(isymf)==-1) CYCLE
380    rotfm = Cryst%symrec(:,:,isymf)
381    tfm = Cryst%tnons(:,isymf)
382    found = .FALSE.
383 
384    do isyma=1,Cryst%nsym
385      if (Cryst%symafm(isyma)==1) CYCLE
386      rotafm = Cryst%symrec(:,:,isyma)
387 
388      if (ALL(rotfm==rotafm)) then
389        found=.TRUE.
390        tafm = Cryst%tnons(:,isyma)
391        npairs=npairs+1
392        ABI_CHECK(npairs<=Cryst%nsym/2,'Wrong AFM group')
393        pairs2sym(1,npairs)=isymf
394        pairs2sym(2,npairs)=isyma
395      end if
396    end do !isyma
397 
398    if (.not.found) then
399     shubnikov=3; EXIT !isymf
400    end if
401  end do !isymf
402 
403  select case (shubnikov)
404 
405  case (4)
406    call wrtout(std_out,' Found Magnetic group Shubnikov type IV')
407    ABI_CHECK(npairs==Cryst%nsym/2,'Wrong AFM space group')
408 
409    ABI_MALLOC(afm_mat,(npwe*(npwe+1)/2))
410 
411 ! jmb
412    phase_old=zero
413 
414    do ig2=1,npwe
415      k0g=ig2*(ig2-1)/2
416      do ig1=1,ig2
417        kg=k0g+ig1
418        nonzero=1
419 
420        do ipair=1,Cryst%nsym/2
421          isymf = pairs2sym(1,ipair)
422          isyma = pairs2sym(2,ipair)
423          phase = ( Gsph%phmSGt(ig1,isymf)*conjg(Gsph%phmSGt(ig1,isyma)) ) * &
424 &                ( Gsph%phmSGt(ig2,isymf)*conjg(Gsph%phmSGt(ig2,isyma)) )
425          if (ipair>1 .and. (ABS(phase_old-phase) > tol6)) then
426            nonzero=0; EXIT
427          end if
428          phase_old=phase
429        end do !ipair
430 
431        afm_mat(kg)=nonzero*(cone_gw + phase)
432      end do !ig1
433    end do !ig2
434    !
435    ! =======================================================================
436    ! ==== Symmetrize chi0 constructing chi0^{\up\up} + chi0{\down\down} ====
437    ! =======================================================================
438    !
439    !  head^{\down\down} = head^{\up\up}
440    if (PRESENT(chi0_head)) chi0_head = two * chi0_head
441    !
442    ! w^{\down\down}_{0 G'} =  e^{-iSG'.(tFM-tAFM)} w^{\up\up}_{0 G'}.
443    ! w^{\down\down}_{G 0 } =  e^{+iSG .(tFM-tAFM)} w^{\up\up}_{G 0 }.
444    if (PRESENT(chi0_uwing)) then
445      do io=1,nomega
446        do ig2=1,npwe
447          k0g=ig2*(ig2-1)/2
448          kg=k0g+1
449          chi0_uwing(ig2,io,:)=afm_mat(kg)*chi0_uwing(ig2,io,:)
450        end do
451      end do
452    end if
453 
454    if (PRESENT(chi0_lwing)) then
455      do io=1,nomega
456        do ig1=1,npwe
457          k0g=ig1*(ig1-1)/2
458          kg=k0g+1
459          chi0_lwing(ig1,io,:)=conjg(afm_mat(kg))*chi0_lwing(ig1,io,:)
460        end do
461      end do
462    end if
463 
464    if (PRESENT(chi0)) then
465      do io=1,nomega
466        ! Take care of diagonal.
467        do ig1=1,npwe
468          chi0(ig1,ig1,io)=two*chi0(ig1,ig1,io)
469        end do
470 
471        ! Upper and lower triangle are treated differently:
472        ! We took advantage of the fact the afm_mat is hermitian to reduce memory.
473        do ig2=2,npwe
474          k0g=ig2*(ig2-1)/2
475          do ig1=1,ig2-1
476            kg=k0g+ig1
477            chi0(ig1,ig2,io)=afm_mat(kg)*chi0(ig1,ig2,io)
478          end do
479        end do
480 
481        do ig1=2,npwe
482          k0g=ig1*(ig1-1)/2
483          do ig2=1,ig1-1
484            kg=k0g+ig2
485            chi0(ig1,ig2,io)=conjg(afm_mat(kg))*chi0(ig1,ig2,io)
486          end do
487        end do
488      end do !io
489    end if
490 
491    ABI_FREE(afm_mat)
492 
493  case (3)
494    call wrtout(std_out,' Found Magnetic group Shubnikov type III')
495    ABI_ERROR('Shubnikov type III not implemented')
496 
497    ntest=0
498    do itim=1,ltg_q%timrev
499      do isym=1,ltg_q%nsym_sg
500        ! use only afm sym preserving q with and without time-reversal
501        if ( cryst%symafm(isym)==-1 .and. ltg_q%preserve(itim,isym)==1 ) ntest=ntest+1
502      end do
503    end do
504 
505    if (ntest==0) then
506        ABI_WARNING("no symmetry can be used!")
507    end if
508    !RETURN
509    ABI_MALLOC(chi0_afm,(npwe,npwe))
510 
511    do io=1,nomega
512 
513      do ig2=1,npwe
514        do ig1=1,npwe
515          sumchi=czero_gw
516 
517          do itim=1,ltg_q%timrev
518            do isym=1,ltg_q%nsym_sg
519              ! use only afm sym preserving q with and without time-reversal
520              if ( cryst%symafm(isym)==-1 .and. ltg_q%preserve(itim,isym)==1 ) then
521                phase =  Gsph%phmGt(ig1,isym)*conjg(Gsph%phmGt(ig2,isym))
522                iSmg1=Gsph%rottbm1(ig1,itim,isym)
523                iSmg2=Gsph%rottbm1(ig2,itim,isym)
524                ctmp=chi0(iSmg1,iSmg2,io)*phase !; if (itim==2) ctmp=conjg(ctmp) !check this
525                sumchi=sumchi+ctmp !chi0(iSmg1,iSmg2,io)*phase
526              end if
527            end do ! isym
528          end do !itim
529 
530          chi0_afm(ig1,ig2)=sumchi/Ltg_q%nsym_ltg  !has to be changed in case of time-reversal
531        end do !ig1
532      end do !ig2
533 
534      ! We want chi_{up,up} +chi_{dwn,dwn}.
535      chi0(:,:,io)=chi0(:,:,io)+chi0_afm(:,:)
536    end do !iomega
537 
538    ABI_FREE(chi0_afm)
539 
540  case default
541    ABI_BUG(sjoin('Wrong value for shubnikov= ', itoa(shubnikov)))
542  end select
543 
544 end subroutine symmetrize_afm_chi0