LCOV - code coverage report
Current view: top level - src/70_gw - m_gwrdm.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.3 % 403 364
Test Date: 2026-09-19 17:42:43 Functions: 93.3 % 15 14

            Line data    Source code
       1              : !!****m* ABINIT/m_gwrdm
       2              : !! NAME
       3              : !!  m_gwrdm
       4              : !!
       5              : !! FUNCTION
       6              : !!  Compute density matrix correction Galitskii-Migdal Ecorr, G = Go + Go Sigma Go (imaginary freqs. are used in Sigma_c)
       7              : !!  and associated quantities (natural orbitals, matrix elements, etc.).
       8              : !!
       9              : !! SOURCE
      10              : 
      11              : #if defined HAVE_CONFIG_H
      12              : #include "config.h"
      13              : #endif
      14              : 
      15              : #include "abi_common.h"
      16              : 
      17              : module m_gwrdm
      18              : 
      19              :  use defs_basis
      20              :  use m_gwdefs
      21              :  use m_abicore
      22              :  use m_xmpi
      23              :  use m_errors
      24              :  use m_hide_blas
      25              :  use m_time
      26              :  use m_wfd
      27              :  use m_hdr
      28              :  use m_dtset
      29              : 
      30              :  use m_fstrings,       only : sjoin, itoa
      31              :  use m_melemts,        only : melements_t
      32              :  use m_bz_mesh,        only : kmesh_t
      33              :  use m_ebands,         only : ebands_t
      34              :  use m_sigma,          only : sigma_t
      35              :  use m_xctk,           only : xcden
      36              :  use m_gaussian_quadrature, only: cgqf
      37              : 
      38              :  implicit none
      39              : 
      40              :  private :: no2ks,ks2no,printrdm_k,rotate_ks_no
      41              : !!***
      42              : 
      43              :  public :: quadrature_sigma_cw,calc_Ec_GM_k,calc_rdmx,calc_rdmc,natoccs,update_hdr_bst,print_tot_occ,change_matrix
      44              :  public :: print_chkprdm,print_total_energy,print_band_energies,get_chkprdm
      45              : !!***
      46              : 
      47              : contains
      48              : !!***
      49              : 
      50              : !!****f* ABINIT/quadrature_sigma_cw
      51              : !! NAME
      52              : !! quadrature_sigma_cw
      53              : !!
      54              : !! FUNCTION
      55              : !!  Quadrature frequencies used for Sigma_c(iw) integration
      56              : !!
      57              : !! INPUTS
      58              : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
      59              : !! Sr=sigma_t (see the definition of this structured datatype)
      60              : !! weights=real quadrature weights.
      61              : !!
      62              : !! OUTPUT
      63              : !! Update Sigp and Sr imaginary frequencies with iw, and weights with the quadrature weights
      64              : !!
      65              : !! SOURCE
      66              : 
      67            5 : subroutine quadrature_sigma_cw(Sigp,Sr,weights)
      68              : !Arguments ------------------------------------
      69              : !scalars
      70              :  type(sigparams_t),intent(inout) :: Sigp
      71              :  type(sigma_t),intent(inout) :: Sr
      72              : !arrays
      73              :  real(dp),intent(inout) :: weights(:)
      74              : 
      75              : !Local variables ------------------------------
      76              : !scalars
      77              :  integer :: ifreqs,order_int,gaussian_kind,units(2)
      78              :  real(dp) :: gwalpha,gwbeta,wmin,wmax
      79              :  character(len=500) :: msg
      80              : !arrays
      81            5 :  real(dp),allocatable :: freqs(:)
      82              : !************************************************************************
      83              : 
      84           15 :  units = [std_out, ab_out]
      85              : 
      86            5 :  order_int=Sigp%nomegasi
      87            5 :  write(msg,'(a45,i9)')' number of imaginary frequencies for Sigma_c ',order_int
      88            5 :  call wrtout(units, msg)
      89            5 :  write(msg,'(a1)')' '
      90            5 :  call wrtout(units, msg)
      91            5 :  order_int=Sigp%nomegasi
      92           15 :  ABI_MALLOC(freqs,(order_int))
      93            5 :  gaussian_kind=1
      94            5 :  gwalpha=zero
      95            5 :  gwbeta=zero
      96            5 :  wmin=zero
      97            5 :  wmax=one
      98            5 :  call cgqf(order_int,gaussian_kind,gwalpha,gwbeta,wmin,wmax,freqs,weights)
      99              :  ! From  0 to 1 -> 0 to infinity
     100          165 :  weights(:)=weights(:)/(one-freqs(:))**two
     101          165 :  freqs(:)=freqs(:)/(one-freqs(:))
     102              :  ! Form complex frequencies from 0 to iInf and print them in the log file
     103            5 :  write(msg,'(a52)')'           Re(iw)           Im(iw)           Weight  '
     104            5 :  call wrtout(std_out,msg)
     105            5 :  write(msg,'(a52)')'          --------         --------         -------- '
     106            5 :  call wrtout(std_out,msg)
     107          165 :  do ifreqs=1,order_int
     108          160 :    Sigp%omegasi(ifreqs)=cmplx(zero,freqs(ifreqs))
     109          160 :    Sr%omega_i(ifreqs)=Sigp%omegasi(ifreqs)
     110          160 :    write(msg,'(3f17.5)') Sr%omega_i(ifreqs),weights(ifreqs)
     111          165 :    call wrtout(std_out,msg)
     112              :  enddo
     113            5 :  ABI_FREE(freqs)
     114              : 
     115            5 : end subroutine quadrature_sigma_cw
     116              : !!***
     117              : 
     118              : !!****f* ABINIT/Calc_Ec_GM_k
     119              : !! NAME
     120              : !! calc_Ec_GM_k
     121              : !!
     122              : !! FUNCTION
     123              : !! Calculate Galitskii-Migdal corr. energy integrated in the Imaginary axis Ec = 1/pi \sum_i \int Gii(iv)*Sigma_c,ii(iv) + cc. dv
     124              : !!
     125              : !! INPUTS
     126              : !! ib1=min band for given k
     127              : !! ib2=max band for given k.
     128              : !! ik_ibz= the label of k-point in the IBZ whose Galitskii-Migdal contribution is accounted.
     129              : !! weights=array containing the weights used in the quadrature.
     130              : !! sigcme_k=array containing Sigma(iw) as Sigma(iw,ib1:ib2,ib1:ib2,nspin)
     131              : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
     132              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     133              : !!  eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
     134              : !!  occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
     135              : !! Sr=sigma_t (see the definition of this structured datatype)
     136              : !!
     137              : !! OUTPUT
     138              : !! Compute the Galitskii-Migdal corr energy contribution of this k-point:
     139              : !! Ec ^k = 1/(4*pi) * fact_spin * int _{ -Inf }^{ +Inf } dv Sigma_c ^k (iv) * G0(iv)
     140              : !!       = 1/(4*pi) * fact_spin * int _{   0  }^{ +Inf } dv 2 * Re{ Sigma_c ^k (iv) * G0(iv) }
     141              : !!
     142              : !! SOURCE
     143              : 
     144            0 : function calc_Ec_GM_k(ib1,ib2,ik_ibz,Sr,weights,sigcme_k,ebands) result(Ec_GM_k)
     145              : 
     146              : !Arguments ------------------------------------
     147              : !scalars
     148              :  real(dp) :: Ec_GM_k
     149              :  integer,intent(in) :: ib1,ib2,ik_ibz
     150              :  type(ebands_t),target,intent(in) :: ebands
     151              :  type(sigma_t),intent(in) :: Sr
     152              : !arrays
     153              :  real(dp),intent(in) :: weights(:)
     154              :  complex(dp),intent(in) :: sigcme_k(:,:,:,:)
     155              : !Local variables ------------------------------
     156              : !scalars
     157              :  integer :: ibdm!,unitt
     158              :  real(dp) :: ec_integrated,spin_fact,fact
     159              :  character(len=500) :: msg
     160              : !arrays
     161              : !************************************************************************
     162              : 
     163            0 :  ec_integrated=zero
     164            0 :  spin_fact=two
     165            0 :  fact=spin_fact*(one/(two_pi*two))
     166              : 
     167            0 :  if (ib1/=1) then
     168              :    msg="Unable to compute the Galitskii-Migdal correlation energy because the first band was " // &
     169            0 :      & "not included in bdgw interval. Restart the calculation starting bdgw from 1."
     170            0 :    ABI_WARNING(msg)
     171              :  else
     172              :    ! WARNING: Sigma_c(iv) produced from a previous integration at the screening stage, is numerically not much stable and introduces bumps.
     173              :    ! Unfortunately, the Green's function times Sigma_c(iv) does not decay fast enough with iv to overcome the bumps. These bumps are
     174              :    ! not pronouced for the linearized density matrix update, as two Green's functions are multiplied making the decay much faster with iv.
     175              :    ! If a better way to produce more stable Sigma_c(iv) values is found, this subroutine can be use to evaluate GM Ecorr in the future. TODO
     176            0 :    do ibdm=1,ib2
     177              :      ! Sigma_pp(iv)/[(iv - e_ibdm,k)] + [Sigma_pp(iv)/[(iv - e_ibdm,k)]]^* = 2 Re [Sigma_pp(iv)/(iv - e_ibdm,k)]
     178            0 :      ec_integrated=ec_integrated+two*real( sum(weights(:)*sigcme_k(:,ibdm,ibdm,1)/(Sr%omega_i(:)-ebands%eig(ibdm,ik_ibz,1)) ) )
     179              :    end do
     180              :  endif
     181              : 
     182            0 :  Ec_GM_k=fact*ec_integrated
     183              : 
     184            0 : end function calc_Ec_GM_k
     185              : !!***
     186              : 
     187              : !!****f* ABINIT/calc_rdmx
     188              : !! NAME
     189              : !! calc_rdmx
     190              : !!
     191              : !! FUNCTION
     192              : !! Calculate density matrix corrections for G = Go + Go (Sigma_x - alpha*Sigma_x - Vxc) Go
     193              : !!
     194              : !! INPUTS
     195              : !! ib1=min band for given k
     196              : !! ib2=max band for given k.
     197              : !! ik_ibz= the label of k-point in the IBZ.
     198              : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
     199              : !! pot=Self-energy-Potential difference, matrix size (i,j), where i and j belong to k.
     200              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     201              : !!  eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
     202              : !!  occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
     203              : !!
     204              : !! OUTPUT
     205              : !! Updated rdm_k matrix array with Go (Sigma_x - alpha*Sigma_x - Vxc) Go
     206              : !!
     207              : !! SOURCE
     208              : 
     209           27 : subroutine calc_rdmx(ib1,ib2,ik_ibz,pot,rdm_k,ebands)
     210              : 
     211              : !Arguments ------------------------------------
     212              : !scalars
     213              :  integer,intent(in) :: ib1,ib2,ik_ibz
     214              :  type(ebands_t),target,intent(in) :: ebands
     215              : !arrays
     216              :  complex(dp),intent(in) :: pot(:,:)
     217              :  complex(dp),intent(inout) :: rdm_k(:,:)
     218              : 
     219              : !Local variables ------------------------------
     220              : !scalars
     221              :  character(len=500) :: msg
     222              :  integer :: ib1dm,ib2dm, units(2)
     223              :  real(dp) :: spin_fact,tol8
     224              : !************************************************************************
     225              : 
     226           27 :  tol8=1.0e-8
     227           27 :  spin_fact=two
     228           81 :  units = [std_out, ab_out]
     229              : 
     230           27 :  write(msg,'(a58,3f10.5)')' Computing the 1-RDM correction for  Sx-Vxc  and k-point: ',ebands%kptns(:,ik_ibz)
     231           27 :  call wrtout(units, msg)
     232           27 :  write(msg,'(a11,i5,a8,i5)')'from band ',ib1,' to band',ib2
     233           27 :  call wrtout(units, msg)
     234              : 
     235         1709 :  rdm_k(:,:)=czero
     236          196 :  do ib1dm=ib1,ib2-1
     237          841 :    do ib2dm=ib1dm+1,ib2
     238          814 :      if ((ebands%occ(ib1dm,ik_ibz,1)>tol8) .and. (ebands%occ(ib2dm,ik_ibz,1)<tol8)) then
     239              :        rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1))=spin_fact&
     240          236 :             &*pot(1+(ib1dm-ib1),1+(ib2dm-ib1))/(ebands%eig(ib1dm,ik_ibz,1)-ebands%eig(ib2dm,ik_ibz,1)+tol8)
     241              :        ! Dji = Dij^*
     242          236 :        rdm_k(1+(ib2dm-ib1),1+(ib1dm-ib1))=conjg(rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1)))
     243              :      end if
     244              :    end do
     245              :  end do
     246              : 
     247           27 : end subroutine calc_rdmx
     248              : !!***
     249              : 
     250              : !!****f* ABINIT/calc_rdmc
     251              : !! NAME
     252              : !! calc_rdmc
     253              : !!
     254              : !! FUNCTION
     255              : !! Calculate density matrix corrections for G = Go + int Go(iw) Sigma_c(iw) Go(iw) dw
     256              : !!
     257              : !! INPUTS
     258              : !! ib1=min band for given k
     259              : !! ib2=max band for given k.
     260              : !! ik_ibz= the label of k-point in the IBZ.
     261              : !! omega_i=Frequencies along the imaginary axis.
     262              : !! weights=array containing the weights used in the quadrature.
     263              : !! sigcme_k=array containing Sigma(iw) as Sigma(iw,ib1:ib2,ib1:ib2,nspin)
     264              : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
     265              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     266              : !!
     267              : !! OUTPUT
     268              : !! Updated rdm_k matrix array with int Go(iw) Sigma_c(iw) Go(iw) dw
     269              : !!
     270              : !! SOURCE
     271              : 
     272           21 : subroutine calc_rdmc(ib1,ib2,ik_ibz,omega_i,weights,sigcme_k,ebands,rdm_k)
     273              : 
     274              : !Arguments ------------------------------------
     275              : !scalars
     276              :  integer,intent(in) :: ib1,ib2,ik_ibz
     277              :  type(ebands_t),target,intent(in) :: ebands
     278              :  complex(dp),intent(in) :: omega_i(:)
     279              : !arrays
     280              :  real(dp),intent(in) :: weights(:)
     281              :  complex(dp),intent(inout) :: rdm_k(:,:)
     282              :  complex(dp),intent(in) :: sigcme_k(:,:,:,:)
     283              : 
     284              : !Local variables ------------------------------
     285              : !scalars
     286              :  real(dp) :: spin_fact,fact
     287              :  integer :: ib1dm, ib2dm, units(2)
     288              :  character(len=500) :: msg
     289              : !************************************************************************
     290              : 
     291           21 :  spin_fact = two
     292           21 :  fact = spin_fact * (one/two_pi)
     293           63 :  units = [std_out, ab_out]
     294              : 
     295           21 :  write(msg,'(a58,3f10.5)')' Computing the 1-RDM correction for  Sc(iw)  and k-point: ',ebands%kptns(1:,ik_ibz)
     296           21 :  call wrtout(units , msg)
     297           21 :  write(msg,'(a11,i5,a8,i5)')'from band ',ib1,' to band',ib2
     298           21 :  call wrtout(units , msg)
     299              : 
     300         1271 :  rdm_k(:,:)=czero
     301          169 :  do ib1dm=ib1,ib2
     302          794 :    do ib2dm=ib1dm,ib2
     303              :      ! Sigma_pq/[(denominator)] + [Sigma_qp/[(denominator)]]^*
     304              :      rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1))=fact*sum(weights(:)*( sigcme_k(:,1+(ib1dm-ib1),1+(ib2dm-ib1),1)/&
     305              :                  &( (omega_i(:)-ebands%eig(ib1dm,ik_ibz,1))*(omega_i(:)-ebands%eig(ib2dm,ik_ibz,1)) )&
     306              :                                     +conjg( sigcme_k(:,1+(ib2dm-ib1),1+(ib1dm-ib1),1)/&
     307        19605 :                  &( (omega_i(:)-ebands%eig(ib1dm,ik_ibz,1))*(omega_i(:)-ebands%eig(ib2dm,ik_ibz,1)) ) ) ) )
     308              :      ! Dji = Dij^*
     309          773 :      rdm_k(1+(ib2dm-ib1),1+(ib1dm-ib1))=conjg(rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1)))
     310              :    end do
     311              :  end do
     312              : 
     313           21 : end subroutine calc_rdmc
     314              : !!***
     315              : 
     316              : !!****f* ABINIT/natoccs
     317              : !! NAME
     318              : !! natoccs
     319              : !!
     320              : !! FUNCTION
     321              : !! Calculate natural orbitals and occ. numbers for a given k-point
     322              : !!
     323              : !! INPUTS
     324              : !! ib1=min band for given k
     325              : !! ib2=max band for given k.
     326              : !! ik_ibz= the label of k-point in the IBZ.
     327              : !! iinfo=use Sigma_x or Sigma_c phaser
     328              : !! weights=array containing the weights used in the quadrature.
     329              : !! nateigv=array containing the natural eigenvectors in columns (nbands,nband,k-point,nspin)
     330              : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
     331              : !! occs = array containing the occ numbers for a given k-point occs(nband,k-point).
     332              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     333              : !!  eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
     334              : !!  occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
     335              : !! checksij=check the orthonormality of the nat. orbitals
     336              : !!
     337              : !! OUTPUT
     338              : !! Compute the nat. orbitals and occ. numbers from the rdm_k matrix (for exchange and correlations)
     339              : !!
     340              : !! SOURCE
     341              : 
     342           48 : subroutine natoccs(ib1,ib2,rdm_k,nateigv,occs,ebands,ik_ibz,iinfo,checksij)
     343              : !Arguments ------------------------------------
     344              : !scalars
     345              :  integer,intent(in) :: ib1,ib2,ik_ibz,iinfo
     346              :  integer,intent(in),optional :: checksij
     347              :  type(ebands_t),target,intent(in) :: ebands
     348              : !arrays
     349              :  real(dp),intent(inout) :: occs(:,:)
     350              :  complex(dp),intent(inout) :: rdm_k(:,:),nateigv(:,:,:,:)
     351              : !Local variables ------------------------------
     352              : !scalars
     353              :  integer:: ndim,ib1dm,ib2dm,ib3dm,lwork,info
     354              :  logical:: check_Sijmat
     355              :  character(len=500) :: msg
     356              :  real(dp) :: toccs_k,tol10
     357              :  complex(dp) :: Sib1k_ib2k
     358              : !arrays
     359              :  integer :: units(2)
     360           48 :  real(dp),allocatable :: occs_tmp(:),occs_tmp2(:),rwork(:)
     361           48 :  complex(dp),allocatable :: work(:),tmp_mat(:,:),eigenvect(:,:)
     362              : !************************************************************************
     363              : 
     364           48 :  check_Sijmat=.false.; if (present(checksij)) check_Sijmat=.true.
     365          144 :  units = [std_out, ab_out]
     366           48 :  tol10=1.0e-10
     367              : 
     368           48 :  ndim=ib2-ib1+1
     369           48 :  lwork=2*ndim-1
     370          144 :  ABI_MALLOC(occs_tmp,(ndim))
     371           96 :  ABI_MALLOC(occs_tmp2,(ndim))
     372          144 :  ABI_MALLOC(work,(lwork))
     373          192 :  ABI_MALLOC(tmp_mat,(ndim,ndim))
     374          144 :  ABI_MALLOC(eigenvect,(ndim,ndim))
     375          144 :  ABI_MALLOC(rwork,(3*ndim-2))
     376              : 
     377         2980 :  tmp_mat=zero
     378          392 :  do ib2dm=1,ndim
     379         1858 :    do ib1dm=ib2dm,ndim
     380         1466 :      tmp_mat(ib1dm,ib2dm)=rdm_k(ib1dm,ib2dm)
     381              :      ! Dji = Dij^*
     382         1810 :      tmp_mat(ib2dm,ib1dm)=conjg(tmp_mat(ib1dm,ib2dm))
     383              :    end do
     384              :  end do
     385              : 
     386          688 :  work=zero
     387          392 :  occs_tmp=zero
     388           48 :  info=0
     389           48 :  call zheev('v','u',ndim,tmp_mat,ndim,occs_tmp,work,lwork,rwork,info)
     390           48 :  ABI_CHECK(info == 0, sjoin("Failed the diagonalization of the updated GW 1-RDM with info:", itoa(info)))
     391              : 
     392              :  ! Sort in descending order
     393          392 :  do ib1dm=1,ndim
     394          344 :   occs_tmp2(ib1dm)=occs_tmp(ndim-(ib1dm-1))
     395         2932 :   do ib2dm=1,ndim
     396         2932 :    eigenvect(ib2dm,ib1dm)=tmp_mat(ib2dm,(ndim-(ib1dm-1)))
     397              :   end do
     398          392 :   if (abs(occs_tmp2(ib1dm))<tol10) then
     399          106 :     occs_tmp2(ib1dm)=zero
     400              :   end if
     401              :  end do
     402              : 
     403              :  ! Check orthonormality?
     404           48 :  if (check_Sijmat) then
     405            0 :    do ib1dm=1,ndim
     406            0 :      do ib2dm=1,ib1dm
     407              :        Sib1k_ib2k=czero
     408            0 :        do ib3dm=1,ndim
     409            0 :          Sib1k_ib2k=Sib1k_ib2k+conjg(eigenvect(ib3dm,ib1dm))*eigenvect(ib3dm,ib2dm)
     410              :        end do
     411            0 :        if (ib1dm==ib2dm) then
     412            0 :          if(abs(Sib1k_ib2k-cmplx(one,zero))>tol10) then
     413            0 :            write(msg,'(a45,i5,a1,i5,f10.5)') 'Large deviation from identity for bands ',ib1dm,' ',ib2dm,real(Sib1k_ib2k)
     414            0 :            call wrtout(std_out,msg)
     415              :          endif
     416              :        else
     417            0 :          if (abs(Sib1k_ib2k)>tol10) then
     418            0 :            write(msg,'(a45,i5,a1,i5,f10.5)') 'Large deviation from identity for bands ',ib1dm,' ',ib2dm,real(Sib1k_ib2k)
     419            0 :            call wrtout(std_out,msg)
     420              :          end if
     421              :        end if
     422              :      end do
     423              :    end do
     424              :  end if
     425              : 
     426              :  ! Print results
     427           48 :  if (info==0) then
     428           48 :    if (iinfo==0) then
     429           27 :      write(msg,'(a51,3f10.5)') 'Occs. after updating with Sx-Vxc corr. at k-point:',ebands%kptns(1:,ik_ibz)
     430              :    else
     431           21 :      write(msg,'(a51,3f10.5)') 'Occs. after updating with S_c correct. at k-point:',ebands%kptns(1:,ik_ibz)
     432              :    endif
     433           48 :    call wrtout(units, msg)
     434           48 :    ib1dm=ndim-(ndim/10)*10
     435           48 :    do ib2dm=1,(ndim/10)*10,10
     436            0 :      write(msg,'(f11.5,9f10.5)') occs_tmp2(ib2dm:ib2dm+9)
     437           48 :      call wrtout(units, msg)
     438              :    end do
     439           48 :    ib1dm=(ndim/10)*10+1
     440           48 :    write(msg,'(f11.5,*(f10.5))') occs_tmp2(ib1dm:)
     441           48 :    call wrtout(units, msg)
     442              :  else
     443            0 :    write(msg,'(a36,3f10.5)') 'Error computing occs. for k-point: ',ebands%kptns(1:,ik_ibz)
     444            0 :    call wrtout(units, msg)
     445              :  end if
     446              : 
     447              :  ! Store natural orbital eigenvectors matrix and occs. Also compute total number of electrons for this k-point
     448           48 :  toccs_k=zero
     449          392 :  do ib1dm=1,ndim
     450         2932 :    do ib2dm=1,ndim
     451         2932 :      nateigv(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=eigenvect(ib1dm,ib2dm)
     452              :    end do
     453          344 :    occs(ib1+(ib1dm-1),ik_ibz)=occs_tmp2(ib1dm)  ! Overwrite the initial KS-DFT occs from ib1 to ib2
     454          392 :    toccs_k=toccs_k+occs_tmp2(ib1dm)
     455              :  end do
     456              : 
     457           48 :  write(msg,'(a22,i5,a3,i5,a21,f10.5)') ' Total occ. from band ',ib1,' to', ib2,' at current k-point: ',toccs_k
     458           48 :  call wrtout(units, msg)
     459           48 :  write(msg,'(a5)') ' '
     460           48 :  call wrtout(units, msg)
     461              : 
     462           48 :  ABI_FREE(rwork)
     463           48 :  ABI_FREE(work)
     464           48 :  ABI_FREE(tmp_mat)
     465           48 :  ABI_FREE(eigenvect)
     466           48 :  ABI_FREE(occs_tmp)
     467           48 :  ABI_FREE(occs_tmp2)
     468              : 
     469           48 : end subroutine natoccs
     470              : !!***
     471              : 
     472              : !!****f* ABINIT/update_hdr_bst
     473              : !! NAME
     474              : !! update_hdr_bst
     475              : !!
     476              : !! FUNCTION
     477              : !! Update the Hdr for the WFK and DEN files and the occ. numbers in the ebands file for a given k-point
     478              : !!
     479              : !! INPUTS
     480              : !! Wfd<wfd_t>=Datatype gathering data on QP amplitudes.
     481              : !! ngfft_in(18)=information on the fine FFT grid used for densities and potentials.
     482              : !! b1gw=min band for given k in the interval where we update.
     483              : !! b2gw=max band for given k in the interval where we update.
     484              : !! occs= array containing the occ numbers for a given k-point occs_ks(nband,k-point).
     485              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     486              : !!  eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
     487              : !!  occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
     488              : !!
     489              : !! OUTPUT
     490              : !! Updated Hdr and ebands information
     491              : !!
     492              : !! SOURCE
     493              : 
     494            5 : subroutine update_hdr_bst(Wfd,occs,b1gw,b2gw,ebands,Hdr,ngfft_in)
     495              : 
     496              : !Arguments ------------------------------------
     497              : !scalars
     498              :  integer,intent(in) :: b1gw,b2gw
     499              :  integer,intent(in),dimension(3) :: ngfft_in
     500              :  type(ebands_t),target,intent(inout) :: ebands
     501              :  type(Hdr_type),intent(inout) :: Hdr
     502              :  class(wfd_t),intent(in) :: Wfd
     503              : !arrays
     504              :  real(dp),intent(in) :: occs(:,:)
     505              : !Local variables ------------------------------
     506              : !scalars
     507              :  integer :: ib1dm,ib2dm,dim_bands,ikpoint
     508              : !arrays
     509              : !************************************************************************
     510              : 
     511              :  ! ebands occ (QP_ebands ones) are changed and never recoverd
     512           35 :  do ikpoint=1,ebands%nkpt
     513          269 :    ebands%occ(b1gw:b2gw,ikpoint,1) = occs(b1gw:b2gw,ikpoint) ! Spins summed, occ in [0:2]
     514              :  enddo
     515            5 :  ABI_COMMENT("QP_ebands: occupancies were updated with nat. orb. ones")
     516            5 :  if ((size(Hdr%occ(:))/ebands%nkpt) < (b2gw-b1gw+1)) then
     517              :    !Actually, we should never reach this point because the code should stop during Wfd initialization in m_sigma_driver
     518            0 :    ABI_ERROR("Impossible to use the existing read WFK to build a new one!")
     519              :  end if
     520              : 
     521              :  ! Update occ in Hdr before printing
     522            5 :  ib1dm=1
     523           35 :  do ikpoint=1,ebands%nkpt
     524           30 :    dim_bands=size(ebands%occ(:,ikpoint,1))
     525          275 :    do ib2dm=1,dim_bands
     526          240 :      Hdr%occ(ib1dm)=ebands%occ(ib2dm,ikpoint,1) ! Because Hdr%occ is a 1-D array
     527          270 :      ib1dm=ib1dm+1
     528              :    end do
     529              :  end do
     530              : 
     531           35 :  Hdr%npwarr(:)=Wfd%npwarr(:)                                   ! Use the npw and ngfft = ones used in GW calc
     532           20 :  Hdr%ngfft(1:3)=ngfft_in(1:3)
     533            5 :  ABI_COMMENT("Hdr_sigma: occupancies, npw, and ngfft were updated")
     534              : 
     535            5 : end subroutine update_hdr_bst
     536              : !!***
     537              : 
     538              : !!****f* ABINIT/print_tot_occ
     539              : !! NAME
     540              : !! print_tot_occ
     541              : !!
     542              : !! FUNCTION
     543              : !! Compute and print the total (averaged) occ. from all k-points
     544              : !!
     545              : !! INPUTS
     546              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     547              : !!  eig(Sigp%nbnds,%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
     548              : !!  occ(Sigp%nbnds,%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
     549              : !!
     550              : !! OUTPUT
     551              : !! Print the total (averaged) occ. = sum_k weight_k * Nelec_k
     552              : !!
     553              : !! SOURCE
     554              : 
     555            5 : subroutine print_tot_occ(ebands)
     556              : 
     557              : !Arguments ------------------------------------
     558              :  type(ebands_t),intent(in) :: ebands
     559              : 
     560              : !Local variables-------------------------------
     561              : !scalars
     562              :  character(len=500) :: msg
     563              :  integer :: ik,spin, units(2)
     564              :  real(dp) :: wtk,occ_bks,tot_occ
     565              : ! *************************************************************************
     566              : 
     567           15 :  units = [std_out, ab_out]
     568              : 
     569            5 :  tot_occ=zero
     570              : 
     571           10 :  do spin=1,ebands%nsppol
     572           40 :    do ik=1,ebands%nkpt
     573           30 :      wtk = ebands%wtk(ik)
     574          270 :      occ_bks = sum(ebands%occ(:,ik,spin))
     575              :      !if (sigma%nsig_ab==1) then ! Only closed-shell restricted is programed
     576           35 :      tot_occ=tot_occ+occ_bks*wtk
     577              :      !end if
     578              :    end do
     579              :  end do
     580              : 
     581            5 :  write(msg,'(a1)') ' '
     582            5 :  call wrtout(units, msg)
     583            5 :  write(msg,'(a39,f10.5)') ' Total averaged occ. from all k-points: ',tot_occ
     584            5 :  call wrtout(units, msg)
     585            5 :  write(msg,'(a1)') ' '
     586            5 :  call wrtout(units, msg)
     587              : 
     588            5 : end subroutine print_tot_occ
     589              : !!***
     590              : 
     591              : !!****f* ABINIT/get_chkprdm
     592              : !! NAME
     593              : !! get_chkprdm
     594              : !!
     595              : !! FUNCTION
     596              : !!  Read all checkpoint files built on previous runs
     597              : !!
     598              : !! INPUTS
     599              : !! Wfd<wfd_t>=Wave function descriptor see file 69_wfd/m_wfd.F90
     600              : !! Kmesh <kmesh_t>=Structure describing the k-point sampling.
     601              : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
     602              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     603              : !!  eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
     604              : !!  occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
     605              : !! occs = occ. numbers array occs(Wfd%mband,Wfd%nkibz)
     606              : !! nateigv = natural orbital eigenvectors nateigv(Wfd%mband,Wfd%mband,Wfd%nkibz,Sigp%nsppol))
     607              : !! sigmak_todo = integer array initialized to 1 and its components are set to 0 if the kpoint
     608              : !! is read from the checkpoint sigmak_todo(Wfd%nkibz)
     609              : !! my_rank = rank of the mpi process.
     610              : !!
     611              : !! OUTPUT
     612              : !! occ are updated if they are read from any checkpoint file
     613              : !! nateigv are stored if they are read from any checkpoint file
     614              : !! sigmak_todo components set to 1 if the kpoint is read from any checkpoint file
     615              : !!
     616              : !! SOURCE
     617              : 
     618            1 : subroutine get_chkprdm(Wfd,Kmesh,Sigp,ebands,occs,nateigv,sigmak_todo,my_rank,gw1rdm_fname_in)
     619              : !Arguments ------------------------------------
     620              : !scalars
     621              :  integer,intent(in) :: my_rank
     622              :  class(wfd_t),intent(in) :: Wfd
     623              :  type(kmesh_t),intent(in) :: Kmesh
     624              :  type(sigparams_t),intent(in) :: Sigp
     625              :  type(ebands_t),intent(in) :: ebands
     626              :  character(len=fnlen),intent(in) :: gw1rdm_fname_in
     627              : !arrays
     628              :  integer,intent(inout) :: sigmak_todo(:)
     629              :  real(dp),intent(inout) :: occs(:,:)
     630              :  complex(dp),intent(inout) :: nateigv(:,:,:,:)
     631              : !Local variables-------------------------------
     632              : !scalars
     633              :  integer,parameter :: master=0,iunit=666314
     634              :  integer :: ierr,ib1,ib2,ib3,ikcalc,istat,ik_ibz,ik_ibz_read,iread,iread_eigv
     635              :  real(dp) :: auxl_read
     636              :  character(len=fnlen) :: gw1rdm_fname
     637              :  character(len=500) :: msg
     638              : !arrays
     639            1 :  real(dp),allocatable :: occ_tmp(:),eigvect_tmp(:)
     640              : ! *************************************************************************
     641              : 
     642            1 :  if (my_rank==master) then
     643            1 :    iread_eigv=Wfd%mband
     644            1 :    iread_eigv=iread_eigv*(2*iread_eigv)
     645            3 :    ABI_MALLOC(occ_tmp,(Wfd%mband))
     646            3 :    ABI_MALLOC(eigvect_tmp,(iread_eigv))
     647              : 
     648            7 :    do ikcalc=1,Sigp%nkptgw
     649            6 :      ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Irred k-point for GW
     650            6 :      if(ik_ibz<10) then
     651            6 :        write(gw1rdm_fname,"(a,i1)") trim(gw1rdm_fname_in),ik_ibz
     652            0 :      else if(ik_ibz<100 .and. ik_ibz>=10) then
     653            0 :        write(gw1rdm_fname,"(a,i2)") trim(gw1rdm_fname_in),ik_ibz
     654            0 :      else if(ik_ibz<1000 .and. ik_ibz>=100) then
     655            0 :        write(gw1rdm_fname,"(a,i3)") trim(gw1rdm_fname_in),ik_ibz
     656              :      else
     657            0 :        ABI_ERROR("The maximum k-point label for the checkpoint file to read is 999.")
     658              :      end if
     659            6 :      write(msg,'(a1)')' '
     660            6 :      call wrtout(std_out,msg)
     661            6 :      write(msg,'(a25,a)')' Reading checkpoint file ',trim(gw1rdm_fname)
     662            6 :      call wrtout(std_out,msg)
     663            6 :      write(msg,'(a1)')' '
     664            6 :      call wrtout(std_out,msg)
     665          822 :      occ_tmp(:)=zero;eigvect_tmp(:)=zero;
     666            6 :      open(unit=iunit,form='unformatted',file=gw1rdm_fname,iostat=istat,status='old')
     667            6 :      iread=0;ik_ibz_read=0;
     668            6 :      if (istat==0) then
     669              :        do
     670          414 :          if (iread<Wfd%mband) then
     671           27 :            iread=iread+1
     672           27 :            read(iunit,iostat=istat) auxl_read
     673           27 :            if (istat==0) then
     674           24 :              occ_tmp(iread)=auxl_read
     675              :            end if
     676          387 :          else if (iread<(iread_eigv+Wfd%mband)) then
     677          384 :            iread=iread+1
     678          384 :            read(iunit,iostat=istat) auxl_read
     679          384 :            if (istat==0) then
     680          384 :              eigvect_tmp(iread-Wfd%mband)=auxl_read
     681              :            end if
     682              :          else
     683            3 :            read(iunit,iostat=istat) ik_ibz_read
     684            3 :            if (istat==0 .and. ik_ibz_read/=0) then
     685            3 :             iread=0
     686            3 :             sigmak_todo(ik_ibz_read)=0
     687            3 :             ib3=1
     688           27 :             do ib1=1,Wfd%mband
     689           24 :               occs(ib1,ik_ibz_read)=occ_tmp(ib1)
     690          219 :               do ib2=1,Wfd%mband
     691          192 :                 nateigv(ib1,ib2,ik_ibz_read,1)=cmplx(eigvect_tmp(ib3),eigvect_tmp(ib3+1))
     692          216 :                 ib3=ib3+2
     693              :               end do
     694              :             end do
     695            3 :             ik_ibz_read=0
     696          411 :             occ_tmp=zero;eigvect_tmp=zero;
     697              :            end if
     698              :          end if
     699          414 :          if(istat/=0) then
     700              :            exit
     701              :          end if
     702              :        end do
     703              :      end if
     704            7 :      close(iunit)
     705              :    end do
     706            1 :    write(msg,'(a1)')' '
     707            1 :    call wrtout(std_out,msg)
     708            1 :    write(msg,'(a49)')' List of k-points read from all checkpoint files '
     709            1 :    call wrtout(std_out,msg)
     710            7 :    do ikcalc=1,Sigp%nkptgw
     711            6 :      ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Irred k-point for GW
     712            7 :      if (sigmak_todo(ik_ibz)==0) then
     713            3 :        write(msg,'(3f10.5)') ebands%kptns(1:,ik_ibz)
     714            3 :        call wrtout(std_out,msg)
     715              :      end if
     716              :    enddo
     717            1 :    write(msg,'(a1)')' '
     718            1 :    call wrtout(std_out,msg)
     719            1 :    ABI_FREE(occ_tmp)
     720            1 :    ABI_FREE(eigvect_tmp)
     721              :  end if
     722              : 
     723              : ! Broadcast from master the information stored in occs and nateigv to all processes.
     724            1 :  call xmpi_barrier(Wfd%comm)
     725              :  ierr=0
     726            1 :  call xmpi_bcast(sigmak_todo(:),master,Wfd%comm,ierr)
     727            1 :  if(ierr/=0) then
     728            0 :    ABI_ERROR("Error distributing the sigmak_todo table.")
     729              :  endif
     730            1 :  call xmpi_bcast(occs(:,:),master,Wfd%comm,ierr)
     731            1 :  if(ierr/=0) then
     732            0 :    ABI_ERROR("Error distributing the occs read from checkpoint file(s).")
     733              :  endif
     734            1 :  call xmpi_bcast(nateigv(:,:,:,:),master,Wfd%comm,ierr)
     735            1 :  if(ierr/=0) then
     736            0 :    ABI_ERROR("Error distributing the natural orbital eigenvectors read from checkpoint file(s).")
     737              :  endif
     738              : 
     739            1 : end subroutine get_chkprdm
     740              : !!***
     741              : 
     742              : !!****f* ABINIT/print_chkprdm
     743              : !! NAME
     744              : !! print_chkprdm
     745              : !!
     746              : !! FUNCTION
     747              : !!  Write the checkpoint file for a given k-point
     748              : !!
     749              : !! INPUTS
     750              : !! Wfd<wfd_t>=Wave function descriptor see file 69_wfd/m_wfd.F90
     751              : !! occs = occ. numbers array occs(Wfd%mband,Wfd%nkibz)
     752              : !! nateigv = natural orbital eigenvectors nateigv(Wfd%mband,Wfd%mband,Wfd%nkibz,Sigp%nsppol))
     753              : !! my_rank = rank of the mpi process.
     754              : !! gw1rdm_fname_out = name of the gw1rdm checkpoint out without k-point extension
     755              : !!
     756              : !! OUTPUT
     757              : !!
     758              : !! SOURCE
     759              : 
     760            6 : subroutine print_chkprdm(Wfd,occs,nateigv,ik_ibz,my_rank,gw1rdm_fname_out)
     761              : !Arguments ------------------------------------
     762              : !scalars
     763              :  integer,intent(in) :: ik_ibz,my_rank
     764              :  class(wfd_t),intent(in) :: Wfd
     765              :  character(len=fnlen),intent(in) :: gw1rdm_fname_out
     766              : !arrays
     767              :  real(dp),intent(in) :: occs(:,:)
     768              :  complex(dp),intent(in) :: nateigv(:,:,:,:)
     769              : !Local variables-------------------------------
     770              : !scalars
     771              :  integer,parameter :: master=0,iunit=666314
     772              :  integer :: iwrite,iwrite2
     773              :  character(len=fnlen) :: gw1rdm_fname
     774              :  character(len=500) :: msg
     775              : !arrays
     776              : ! *************************************************************************
     777              : 
     778            6 :  if (my_rank==master) then
     779            6 :    if(ik_ibz<10) then
     780            6 :      write(gw1rdm_fname,"(a,i1)") trim(gw1rdm_fname_out),ik_ibz
     781            0 :    else if(ik_ibz<100 .and. ik_ibz>=10) then
     782            0 :      write(gw1rdm_fname,"(a,i2)") trim(gw1rdm_fname_out),ik_ibz
     783            0 :    else if(ik_ibz<1000 .and. ik_ibz>=100) then
     784            0 :      write(gw1rdm_fname,"(a,i3)") trim(gw1rdm_fname_out),ik_ibz
     785              :    else
     786            0 :      ABI_ERROR("The maximum k-point label for the checkpoint file to write is 999.")
     787              :    end if
     788            6 :    write(msg,'(a1)')' '
     789            6 :    call wrtout(std_out,msg)
     790            6 :    write(msg,'(a25,a)')' Writing checkpoint file ',trim(gw1rdm_fname)
     791            6 :    call wrtout(std_out,msg)
     792            6 :    write(msg,'(a1)')' '
     793            6 :    call wrtout(std_out,msg)
     794            6 :    open(unit=iunit,form='unformatted',file=gw1rdm_fname)
     795           54 :    do iwrite=1,Wfd%mband
     796           54 :      write(iunit) occs(iwrite,ik_ibz)
     797              :    end do
     798           54 :    do iwrite=1,Wfd%mband
     799          438 :      do iwrite2=1,Wfd%mband
     800          384 :        write(iunit) real(nateigv(iwrite,iwrite2,ik_ibz,1))
     801          432 :        write(iunit) aimag(nateigv(iwrite,iwrite2,ik_ibz,1))
     802              :      end do
     803              :    end do
     804            6 :    write(iunit) ik_ibz
     805            6 :    close(iunit)
     806              :  end if
     807              : 
     808            6 :  call xmpi_barrier(Wfd%comm)
     809              : 
     810            6 : end subroutine print_chkprdm
     811              : !!***
     812              : 
     813              : !!****f* ABINIT/change_matrix
     814              : !! NAME
     815              : !! change_matrix
     816              : !!
     817              : !! FUNCTION
     818              : !!  Transform integrals from KS -> NO and NO -> KS orbitals
     819              : !!
     820              : !!   Transform <NO_i|K[NO]|NO_j> -> <KS_i|K[NO]|KS_j>,
     821              : !!             <KS_i|J[NO]|KS_j> -> <NO_i|J[NO]|NO_j>,
     822              : !!   and         <KS_i|T|KS_j>   ->   <NO_i|T|NO_j>
     823              : !!
     824              : !!
     825              : !! INPUTS
     826              : !! Kmesh <kmesh_t>=Structure describing the k-point sampling.
     827              : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
     828              : !! nateigv = natural orbital eigenvectors nateigv(Wfd%mband,Wfd%mband,Wfd%nkibz,Sigp%nsppol))
     829              : !!
     830              : !! OUTPUT
     831              : !!  Mels
     832              : !!   %kinetic=matrix elements of $t$.
     833              : !!   %vhartr =matrix elements of $v_H$.
     834              : !! Sr=sigma_t (see the definition of this structured datatype)
     835              : !!
     836              : !! SOURCE
     837              : 
     838            4 : subroutine change_matrix(Sigp,Sr,Mels,Kmesh,nateigv)
     839              : 
     840              : !Arguments ------------------------------------
     841              : !scalars
     842              :  type(kmesh_t),intent(in) :: Kmesh
     843              :  type(sigparams_t),intent(in) :: Sigp
     844              :  type(sigma_t),intent(inout) :: Sr
     845              :  type(melements_t),intent(inout) :: Mels
     846              : !arrays
     847              :  complex(dp),intent(in) :: nateigv(:,:,:,:)
     848              : !Local variables-------------------------------
     849              : !scalars
     850              :  integer :: ikcalc,ik_ibz,ib1,ib2,ib1dm,ib2dm
     851              : !arrays
     852            4 :  complex(dp),allocatable :: mat2rot(:,:),Umat(:,:)
     853              : ! *************************************************************************
     854              : 
     855           28 :   do ikcalc=1,Sigp%nkptgw
     856           24 :     ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Index of the irreducible k-point for GW
     857           48 :     ib1=MINVAL(Sigp%minbnd(ikcalc,:))       ! min and max band indices for GW corrections (for this k-point)
     858           48 :     ib2=MAXVAL(Sigp%maxbnd(ikcalc,:))
     859           96 :     ABI_MALLOC(mat2rot,(ib2-ib1+1,ib2-ib1+1))
     860           72 :     ABI_MALLOC(Umat,(ib2-ib1+1,ib2-ib1+1))
     861              :     ! <NO_i|K[NO]|NO_j> -> <KS_i|K[NO]|KS_j>
     862          216 :     do ib1dm=1,ib2-ib1+1
     863         1752 :       do ib2dm=1,ib2-ib1+1
     864         1536 :         Umat(ib1dm,ib2dm)=nateigv(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
     865         1728 :         mat2rot(ib1dm,ib2dm)=Sr%x_mat(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
     866              :       end do
     867              :     end do
     868           24 :     call rotate_ks_no(ib1,ib2,mat2rot,Umat,0)
     869          216 :     do ib1dm=1,ib2-ib1+1
     870         1752 :       do ib2dm=1,ib2-ib1+1
     871         1728 :         Sr%x_mat(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=mat2rot(ib1dm,ib2dm)
     872              :       end do
     873              :     end do
     874              :     ! <KS_i|J[NO]|KS_j> -> <NO_i|J[NO]|NO_j>
     875          216 :     do ib1dm=1,ib2-ib1+1
     876         1752 :       do ib2dm=1,ib2-ib1+1
     877         1728 :         mat2rot(ib1dm,ib2dm)=Mels%vhartree(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
     878              :       end do
     879              :     end do
     880           24 :     call rotate_ks_no(ib1,ib2,mat2rot,Umat,1)
     881          216 :     do ib1dm=1,ib2-ib1+1
     882         1752 :       do ib2dm=1,ib2-ib1+1
     883         1728 :         Mels%vhartree(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=mat2rot(ib1dm,ib2dm)
     884              :       end do
     885              :     end do
     886              :     ! <KS_i|T|KS_j> -> <NO_i|T|NO_j>
     887          216 :     do ib1dm=1,ib2-ib1+1
     888         1752 :       do ib2dm=1,ib2-ib1+1
     889         1728 :         mat2rot(ib1dm,ib2dm)=Mels%kinetic(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
     890              :       end do
     891              :     end do
     892           24 :     call rotate_ks_no(ib1,ib2,mat2rot,Umat,1)
     893          216 :     do ib1dm=1,ib2-ib1+1
     894         1752 :       do ib2dm=1,ib2-ib1+1
     895         1728 :         Mels%kinetic(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=mat2rot(ib1dm,ib2dm)
     896              :       end do
     897              :     end do
     898           24 :     ABI_FREE(Umat)
     899           28 :     ABI_FREE(mat2rot)
     900              :   end do
     901            4 : end subroutine change_matrix
     902              : !!***
     903              : 
     904              : !!****f* ABINIT/print_total_energy
     905              : !! NAME
     906              : !! print_total_energy
     907              : !!
     908              : !! FUNCTION
     909              : !!  Print total energy and energy components
     910              : !!
     911              : !! INPUTS
     912              : !! all energy terms are self-explanatory
     913              : !!
     914              : !! OUTPUT
     915              : !!
     916              : !! SOURCE
     917              : 
     918            4 : subroutine print_total_energy(ekin_energy,evext_energy,evextnl_energy,e_corepsp,eh_energy,ex_energy,&
     919              :                               exc_mbb_energy,e_ewald,etot,etot2,den_int)
     920              : !Arguments ------------------------------------
     921              : !scalars
     922              :  real(dp),intent(in) :: ekin_energy,evext_energy,evextnl_energy,e_corepsp,eh_energy,ex_energy
     923              :  real(dp),intent(in) :: exc_mbb_energy,e_ewald,etot,etot2,den_int
     924              : 
     925              : !Local variables-------------------------------
     926              :  character(len=500) :: msg
     927              :  integer :: units(2)
     928              : 
     929              : !************************************************************************
     930              : 
     931           12 :  units = [std_out, ab_out]
     932              : 
     933            4 :  write(msg,'(a1)')' '
     934            4 :  call wrtout(units, msg)
     935              :  write(msg,'(a98)')'---------------------------------------------------------------&
     936            4 :          &----------------------------------'
     937            4 :  call wrtout(units, msg)
     938            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Ekinetic   = : ',ekin_energy,' Ha ,',ekin_energy*Ha_eV,' eV'
     939            4 :  call wrtout(units, msg)
     940            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Evext_l    = : ',evext_energy,' Ha ,',evext_energy*Ha_eV,' eV'
     941            4 :  call wrtout(units, msg)
     942            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Evext_nl   = : ',evextnl_energy,' Ha ,',evextnl_energy*Ha_eV,' eV'
     943            4 :  call wrtout(units, msg)
     944            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Epsp_core  = : ',e_corepsp,' Ha ,',e_corepsp*Ha_eV,' eV'
     945            4 :  call wrtout(units, msg)
     946            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Ehartree   = : ',eh_energy,' Ha ,',eh_energy*Ha_eV,' eV'
     947            4 :  call wrtout(units, msg)
     948            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Ex[SD]     = : ',ex_energy,' Ha ,',ex_energy*Ha_eV,' eV'
     949            4 :  call wrtout(units, msg)
     950            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Exc[MBB]   = : ',exc_mbb_energy,' Ha ,',exc_mbb_energy*Ha_eV,' eV'
     951            4 :  call wrtout(units, msg)
     952            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Enn        = : ',e_ewald,' Ha ,',e_ewald*Ha_eV,' eV'
     953            4 :  call wrtout(units, msg)
     954              :  write(msg,'(a98)')'-----------------------------------------------------------------&
     955            4 :          &--------------------------------'
     956            4 :  call wrtout(units, msg)
     957            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Etot[SD]   = : ',etot,' Ha ,',etot*Ha_eV,' eV'
     958            4 :  call wrtout(units, msg)
     959            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Etot[MBB]  = : ',etot2,' Ha ,',etot2*Ha_eV,' eV'
     960            4 :  call wrtout(units, msg)
     961            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Vee[SD]    = : ',(ex_energy+eh_energy),' Ha ,',(ex_energy+eh_energy)*Ha_eV,' eV'
     962            4 :  call wrtout(units, msg)
     963            4 :  write(msg,'(a,f10.5,a,f10.3,a)')' Vee[MBB]   = : ',(exc_mbb_energy+eh_energy),' Ha ,',&
     964            8 :          &(exc_mbb_energy+eh_energy)*Ha_eV,' eV'
     965            4 :  call wrtout(units, msg)
     966            4 :  write(msg,'(a,f10.5)')  ' Density    = : ',den_int
     967            4 :  call wrtout(units, msg)
     968            4 :  write(msg,'(a)')' Vee[SD] (= Ehartree + Ex[SD]) energy obtained using GW 1-RDM:'
     969            4 :  call wrtout(units, msg)
     970            4 :  write(msg,'(a)')' Vee[MBB] (= Ehartree + Exc[MBB]) energy obtained using GW 1-RDM:'
     971            4 :  call wrtout(units, msg)
     972              :  write(msg,'(a98)')'-------------------------------------------------------------------&
     973            4 :          &------------------------------'
     974            4 :  call wrtout(units, msg)
     975              : 
     976            4 : end subroutine print_total_energy
     977              : !!***
     978              : 
     979              : !!****f* ABINIT/print_band_energies
     980              : !! NAME
     981              : !! print_band_energies
     982              : !!
     983              : !! FUNCTION
     984              : !!  Print updated band energies
     985              : !!
     986              : !!
     987              : !! INPUTS
     988              : !! Kmesh <kmesh_t>=Structure describing the k-point sampling.
     989              : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
     990              : !!  Mels
     991              : !!   %kinetic=matrix elements of $t$.
     992              : !!   %vhartr =matrix elements of $v_H$.
     993              : !! Sr=sigma_t (see the definition of this structured datatype)
     994              : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
     995              : !!  eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
     996              : !!  occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
     997              : !!
     998              : !! OUTPUT
     999              : !!
    1000              : !! SOURCE
    1001              : 
    1002            4 : subroutine print_band_energies(b1gw,b2gw,Sr,Sigp,Mels,Kmesh,ebands,new_hartr,old_purex)
    1003              : !Arguments ------------------------------------
    1004              : !scalars
    1005              :  type(kmesh_t),intent(in) :: Kmesh
    1006              :  type(sigparams_t),intent(in) :: Sigp
    1007              :  type(sigma_t),intent(in) :: Sr
    1008              :  type(ebands_t),intent(in) :: ebands
    1009              :  type(melements_t),intent(in) :: Mels
    1010              :  integer,intent(in) :: b1gw,b2gw
    1011              : !arrays
    1012              :  complex(dp),intent(in) :: old_purex(:,:),new_hartr(:,:)
    1013              : !Local variables-------------------------------
    1014              : !scalars
    1015              :  integer :: ib,ikcalc,ik_ibz, units(2)
    1016              :  real(dp) :: eik_new
    1017              :  complex(dp) :: delta_band_ibik
    1018              :  character(len=500) :: msg
    1019              : !************************************************************************
    1020              : 
    1021           12 :  units = [std_out, ab_out]
    1022              : 
    1023            4 :  write(msg,'(a1)')  ' '
    1024            4 :  call wrtout(units, msg)
    1025            4 :  write(msg,'(a42)')  ' Computing band corrections Delta eik (eV)'
    1026            4 :  call wrtout(units, msg)
    1027            4 :  write(msg,'(a42)')  ' -----------------------------------------'
    1028            4 :  call wrtout(units, msg)
    1029            4 :  write(msg,'(a1)')  ' '
    1030            4 :  call wrtout(units, msg)
    1031            4 :  write(msg,'(a1)')  ' '
    1032            4 :  call wrtout(units, msg)
    1033              :  write(msg,'(a110)') ' Band corrections Delta eik = <KS_i|K[NO]-a*K[KS]+vH[NO]&
    1034            4 :        &-vH[KS]-Vxc[KS]|KS_i> and eik^new = eik^GS + Delta eik'
    1035            4 :  call wrtout(units, msg)
    1036            4 :  write(msg,'(a1)')  ' '
    1037            4 :  call wrtout(units, msg)
    1038           28 :  do ikcalc=1,Sigp%nkptgw
    1039           24 :    ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Index of the irreducible k-point for GW
    1040              :    write(msg,'(a127)')'---------------------------------------------------------&
    1041           24 :            &--------------------------------------------------------------------'
    1042           24 :    call wrtout(units, msg)
    1043              :    write(msg,'(a)')'  k-point  band      eik^GS        eik^new     Delta eik  &
    1044           24 :      &       K[NO]       a*K[KS]         Vxc[KS]       vH[NO]        vH[KS]'
    1045           24 :    call wrtout(units, msg)
    1046          220 :    do ib=b1gw,b2gw
    1047              :      delta_band_ibik=(new_hartr(ib,ikcalc)-Mels%vhartree(ib,ib,ik_ibz,1))&
    1048          192 :      &+Sr%x_mat(ib,ib,ik_ibz,1)-Mels%vxcval(ib,ib,ik_ibz,1)-old_purex(ib,ikcalc)
    1049          192 :      eik_new=real(ebands%eig(ib,ik_ibz,1))+real(delta_band_ibik)
    1050              :      write(msg,'(i5,4x,i5,8(4x,f10.3))') &
    1051          192 :      & ik_ibz,ib,real(ebands%eig(ib,ik_ibz,1))*Ha_eV,eik_new*Ha_eV,real(delta_band_ibik)*Ha_eV,&
    1052          192 :      & real(Sr%x_mat(ib,ib,ik_ibz,1))*Ha_eV,real(old_purex(ib,ikcalc))*Ha_eV,&
    1053          192 :      & real(Mels%vxcval(ib,ib,ik_ibz,1))*Ha_eV,&
    1054          384 :      & real(new_hartr(ib,ikcalc))*Ha_eV,real(Mels%vhartree(ib,ib,ik_ibz,1))*Ha_eV
    1055          216 :      call wrtout(units, msg)
    1056              :    enddo
    1057              :  enddo
    1058              :  write(msg,'(a127)')'---------------------------------------------------------&
    1059            4 :          &--------------------------------------------------------------------'
    1060            4 :  call wrtout(units, msg)
    1061              : 
    1062            4 : end subroutine print_band_energies
    1063              : !!***
    1064              : 
    1065              : !!****f* ABINIT/rotate_ks_no
    1066              : !! NAME
    1067              : !! rotate_ks_no
    1068              : !!
    1069              : !! FUNCTION
    1070              : !! Rotate a matrix from KS to NO basis and vicerversa.
    1071              : !!
    1072              : !! INPUTS
    1073              : !! ib1=min band for given k
    1074              : !! ib2=max band for given k.
    1075              : !! Umat=array containing the eigenvectors in Columns (a unitary matrix)
    1076              : !! Mat=initially an array containing the matrix elements in KS or NO basis
    1077              : !! option=0 rotate from NO -> KS | 1 rotate from KS -> NO
    1078              : !!
    1079              : !! OUTPUT
    1080              : !! Rotate a matrix from KS to NO basis and vicerversa and save the new matrix on Mat.
    1081              : !! Mat=at the end an array containing the matrix elements in NO or KS basis
    1082              : !!
    1083              : !! SOURCE
    1084              : 
    1085           72 : subroutine rotate_ks_no(ib1,ib2,Mat,Umat,option)
    1086              : !Arguments ------------------------------------
    1087              : !scalars
    1088              :  integer,intent(in) :: ib1,ib2,option
    1089              : !arrays
    1090              :  complex(dp),intent(in) :: Umat(:,:)
    1091              :  complex(dp),intent(inout) :: Mat(:,:)
    1092              : !Local variables ------------------------------
    1093              : !scalars
    1094              :  integer:: ndim
    1095              : !arrays
    1096              : !************************************************************************
    1097              : 
    1098           72 :  ndim=ib2-ib1+1
    1099           72 :  if (option==0) then
    1100           24 :    call no2ks(ndim,Mat,Umat)
    1101              :  else
    1102           48 :    call ks2no(ndim,Mat,Umat)
    1103              :  end if
    1104              : 
    1105           72 : end subroutine rotate_ks_no
    1106              : !!***
    1107              : 
    1108              : !!****f* ABINIT/ks2no
    1109              : !! NAME
    1110              : !! ks2no
    1111              : !!
    1112              : !! FUNCTION
    1113              : !! Transform the matrix mat from KS to NO basis
    1114              : !!
    1115              : !! INPUTS
    1116              : !! dim=dimension of the matrices
    1117              : !! mat=array in the KS basis
    1118              : !! rot=unitary matrix containg the eigenvectors in NO basis
    1119              : !!
    1120              : !! OUTPUT
    1121              : !! mat=array in the NO basis
    1122              : !!
    1123              : !! SOURCE
    1124              : 
    1125           48 : subroutine ks2no(ndim,mat,rot)
    1126              : !Arguments ------------------------------------
    1127              : !scalars
    1128              :  integer,intent(in) :: ndim
    1129              : !arrays
    1130              :  complex(dp),dimension(:,:),intent(in) :: rot
    1131              :  complex(dp),dimension(:,:),intent(inout) :: mat
    1132              : !Local variables ------------------------------
    1133              : !scalars
    1134              : !arrays
    1135           48 :  complex(dp),allocatable :: res(:,:)
    1136              : !************************************************************************
    1137              : 
    1138          192 :  ABI_MALLOC(res,(ndim,ndim))
    1139         3504 :  res=czero
    1140              : 
    1141              :  ! <NO|Op|NO> =  (U^t)* <KS|Op|KS> U
    1142        31632 :  res=matmul(conjg(transpose(rot)),mat)
    1143        56208 :  mat=matmul(res,rot)
    1144              : 
    1145           48 :  ABI_FREE(res)
    1146              : 
    1147           48 : end subroutine ks2no
    1148              : !!***
    1149              : 
    1150              : !!****f* ABINIT/no2ks
    1151              : !! NAME
    1152              : !! no2ks
    1153              : !!
    1154              : !! FUNCTION
    1155              : !! Transform the matrix mat from NO to KS basis
    1156              : !!
    1157              : !! INPUTS
    1158              : !! dim=dimension of the matrices
    1159              : !! mat=array in the KS basis
    1160              : !! rot=unitary matrix containg the eigenvectors in NO basis
    1161              : !!
    1162              : !! OUTPUT
    1163              : !! mat=array in the KS basis
    1164              : !!
    1165              : !! SOURCE
    1166              : 
    1167           24 : subroutine no2ks(ndim,mat,rot)
    1168              : !Arguments ------------------------------------
    1169              : !scalars
    1170              :  integer,intent(in) :: ndim
    1171              : !arrays
    1172              :  complex(dp),dimension(:,:),intent(in) :: rot
    1173              :  complex(dp),dimension(:,:),intent(inout) :: mat
    1174              : !Local variables ------------------------------
    1175           24 :  complex(dp),allocatable :: res(:,:)
    1176              : !************************************************************************
    1177              : 
    1178           96 :  ABI_MALLOC(res,(ndim,ndim))
    1179         1752 :  res=czero
    1180              : 
    1181              :  ! <KS|Op|KS> = U <NO|Op|NO> (U^t)*
    1182        15816 :  res=matmul(rot,mat)
    1183        28104 :  mat=matmul(res,conjg(transpose(rot)))
    1184              : 
    1185           24 :  ABI_FREE(res)
    1186              : 
    1187           24 : end subroutine no2ks
    1188              : !!***
    1189              : 
    1190              : !!****f* ABINIT/printrdm_k
    1191              : !! NAME
    1192              : !! printrdm_k
    1193              : !!
    1194              : !! FUNCTION
    1195              : !! Print the DM1 matrix
    1196              : !!
    1197              : !! INPUTS
    1198              : !! ib1=min band.
    1199              : !! ib2=max band.
    1200              : !! rdm_k=array containing the 1-RDM matrix
    1201              : !!
    1202              : !! OUTPUT
    1203              : !! Print the 1-RDM matrix
    1204              : !! SOURCE
    1205              : 
    1206              : subroutine printrdm_k(ib1,ib2,rdm_k) ! Only used for debug on this file, do not use it with large arrays!
    1207              : !Arguments ------------------------------------
    1208              : !scalars
    1209              :  integer,intent(in) :: ib1,ib2
    1210              : !arrays
    1211              :  complex(dp),intent(in) :: rdm_k(:,:)
    1212              : !Local variables ------------------------------
    1213              : !scalars
    1214              :  integer::ib1dm
    1215              :  character(len=500) :: msg
    1216              : !arrays
    1217              : !************************************************************************
    1218              : 
    1219              :  do ib1dm=ib1,ib2
    1220              :    write(msg,'(*(f12.5))') real(rdm_k(ib1dm,ib1:ib2))
    1221              :    call wrtout(std_out, msg)
    1222              :  end do
    1223              : 
    1224              : end subroutine printrdm_k
    1225              : !!***
    1226              : 
    1227              : end module m_gwrdm
    1228              : !!***
        

Generated by: LCOV version 2.3-1