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-11-06 10:48:53 Functions: 93.3 % 15 14
Branches: 56.6 % 640 362

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