LCOV - code coverage report
Current view: top level - src/68_dmft - m_green.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 44.1 % 1756 774
Test Date: 2026-09-19 17:42:43 Functions: 57.6 % 33 19

            Line data    Source code
       1              : !!****m* ABINIT/m_green
       2              : !! NAME
       3              : !!  m_green
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
       9              : !! This file is distributed under the terms of the
      10              : !! GNU General Public License, see ~abinit/COPYING
      11              : !! or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : ! nvtx related macro definition
      23              : #include "nvtx_macros.h"
      24              : 
      25              :  MODULE m_green
      26              : 
      27              :  use, intrinsic :: iso_c_binding, only: c_size_t
      28              :  use defs_basis
      29              :  use m_abicore
      30              :  use m_errors
      31              : 
      32              :  use m_crystal, only : crystal_t
      33              :  use m_fstrings, only : int2char4
      34              :  use m_hide_lapack, only : xginv
      35              :  use m_io_tools, only : open_file
      36              :  use m_lib_four
      37              :  use m_matlu, only : add_matlu,copy_matlu,destroy_matlu,diff_matlu,init_matlu,matlu_type,print_matlu, &
      38              :                    & prod_matlu,shift_matlu,sym_matlu,trace_matlu,trace_prod_matlu,xmpi_matlu,zero_matlu
      39              :  use m_oper, only : copy_oper,copy_oper_from_ndat,copy_oper_to_ndat,destroy_oper,downfold_oper,gather_oper, &
      40              :                   & gather_oper_ks,init_oper,init_oper_ndat,inverse_oper,oper_type,print_oper,prod_oper, &
      41              :                   & trace_oper,trace_prod_oper,upfold_oper
      42              :  use m_paw_dmft, only : construct_nwli_dmft,mpi_distrib_dmft_type,paw_dmft_type
      43              :  use m_self, only : self_type
      44              :  use m_splines
      45              :  use m_time, only : timab
      46              :  use m_xmpi, only : xmpi_barrier,xmpi_sum
      47              :  use m_gputk
      48              :  use m_abi_linalg
      49              : 
      50              : 
      51              : #ifdef HAVE_GPU_MARKERS
      52              :  use m_nvtx_data
      53              : #endif
      54              : 
      55              :  implicit none
      56              : 
      57              :  private
      58              : 
      59              :  public :: init_green
      60              :  public :: destroy_green
      61              :  public :: init_green_tau
      62              :  public :: destroy_green_tau
      63              :  public :: print_green
      64              :  public :: printocc_green
      65              :  public :: compute_green
      66              :  public :: integrate_green
      67              :  public :: icip_green
      68              :  public :: fourier_green
      69              :  public :: check_fourier_green
      70              :  public :: compa_occup_ks
      71              :  public :: copy_green
      72              :  public :: occup_green_tau
      73              :  public :: add_int_fct
      74              :  public :: int_fct
      75              :  public :: fourier_fct
      76              :  public :: spline_fct
      77              :  public :: distrib_paral
      78              :  public :: greendftcompute_green
      79              :  public :: fermi_green
      80              :  public :: newton
      81              :  public :: local_ks_green
      82              :  public :: compute_moments_ks
      83              :  public :: compute_trace_moments_ks
      84              :  public :: compute_moments_loc
      85              :  public :: occup_fd
      86              : !!***
      87              : 
      88              : !!****t* m_green/green_type
      89              : !! NAME
      90              : !!  green_type
      91              : !!
      92              : !! FUNCTION
      93              : !!  This structured datatype contains the necessary data
      94              : !!
      95              : !! SOURCE
      96              : 
      97              :  type, public :: green_type ! for each atom
      98              : 
      99              :   integer :: dmft_nwli
     100              :   ! Linear index of the last imaginary frequency
     101              : 
     102              :   integer :: dmft_nwlo
     103              :   ! Number of imaginary frequencies
     104              : 
     105              :   integer :: dmftqmc_l
     106              :   ! Number of time slices for QMC
     107              : 
     108              :   integer :: fileprt_tau
     109              :   ! 1 if file created
     110              : 
     111              :   integer :: fileprt_w
     112              :   ! 1 if file created
     113              : 
     114              :   integer :: has_charge_matlu
     115              :   ! =2 if calculation of LOCAL CORRELATED occupations is done
     116              : 
     117              :   integer :: has_charge_matlu_prev
     118              :   ! =0 charge_matlu_prev not allocated
     119              :   ! =1 charge_matlu_prev is allocated
     120              :   ! =2 charge_matlu_prev is calculated (ie calculation of LOCAL CORRELATED occupations is done  from
     121              :   ! solver green function)
     122              : 
     123              :   integer :: has_charge_matlu_solver
     124              :   ! =0 charge_matlu_solver not allocated
     125              :   ! =1 charge_matlu_solver is allocated
     126              :   ! =2 charge_matlu_solver is calculated (ie calculation of LOCAL CORRELATED occupations is done from
     127              :   ! solver green function)
     128              : 
     129              :   integer :: has_greenmatlu_xsum
     130              :   ! =1 green%oper%matlu xsum in compute_green
     131              :   ! =0 green%oper%matlu non xsumed in compute_green
     132              :   ! used in integrate_green to checked that green function was computed in
     133              :   ! integrate_green.
     134              : 
     135              :   integer :: has_moments
     136              :   ! =1 if the high-frequency moments are computed
     137              : 
     138              :   integer :: ichargeloc_cv
     139              : 
     140              :   integer :: ifermie_cv
     141              : 
     142              :   integer :: nmoments
     143              :   ! Number of high-frequency moments which will be computed
     144              : 
     145              :   integer :: nw
     146              :   ! Number of frequencies
     147              : 
     148              :   integer :: use_oper_tau_ks
     149              :   ! 0 do not use oper_tau_ks
     150              :   ! 1 use oper_tau_ks
     151              : 
     152              :   character(len=4) :: w_type
     153              :   ! type of frequencies used
     154              : 
     155              :   !character(len=12) :: whichgreen
     156              :   ! describe the type of green function computed (DFT, DMFT, ..)
     157              : 
     158              :   real(dp) :: charge_ks
     159              :   ! Total charge computed from ks orbitals
     160              : 
     161              :   real(dp) :: ekin_imp
     162              :   ! Kinetic energy of the impurity
     163              : 
     164              :   real(dp) :: fband_weiss
     165              :   ! Tr(log(G0))
     166              : 
     167              :   real(dp) :: integral
     168              :   ! Integral of the interaction energy divided by U
     169              : 
     170              :   real(dp) :: trace_log
     171              :   ! Tr(log(G)) in KS space
     172              : 
     173              :   !integer, allocatable :: procb(:,:)
     174              : 
     175              :   !integer, allocatable :: proct(:,:)
     176              : 
     177              :   type(oper_type) :: occup
     178              :   ! Occupation in different basis
     179              : 
     180              :   type(oper_type) :: occup_tau
     181              :   ! Occupation in different basis
     182              : 
     183              :   complex(dp) :: trace_fermie(12)
     184              :   ! Container to store useful quantities for a quick computation
     185              :   ! of the moments during the Fermi level search
     186              : 
     187              :   real(dp), allocatable :: charge_matlu(:,:)
     188              :   ! Total charge on correlated orbitals
     189              : ! todo_ba name of charge_matlu is misleading: should be changed
     190              : 
     191              :   real(dp), allocatable :: charge_matlu_prev(:,:)
     192              :   ! Total charge on correlated orbitals from previous iteration
     193              : 
     194              :   real(dp), allocatable :: charge_matlu_solver(:,:)
     195              :   ! Total charge on correlated orbitals obtained from solver by
     196              :   ! integration over frequencies.
     197              : 
     198              :   real(dp), allocatable :: ecorr_qmc(:)
     199              :   ! Correlation energy for a given atom in qmc
     200              : 
     201              :   real(dp), allocatable :: tau(:)
     202              :   ! Value of time in imaginary space
     203              : 
     204              :   complex(dp), allocatable :: trace_moments_log_ks(:)
     205              :   ! Trace of the moments of log(G)+log(iw*Id) in KS space
     206              : 
     207              :   complex(dp), allocatable :: trace_moments_log_loc(:)
     208              :   ! Trace of the moments of log(G)+log(iw*Id) in local space
     209              : 
     210              :   type(oper_type), allocatable :: moments(:)
     211              :   ! High-frequency moments
     212              : 
     213              :   type(oper_type), allocatable :: oper(:)
     214              :   ! Green's function in different basis
     215              : 
     216              :   type(oper_type), allocatable :: oper_tau(:)
     217              :   ! Green's function in different basis
     218              : 
     219              :   real(dp), ABI_CONTIGUOUS pointer :: omega(:) => null()
     220              :   ! Value of frequencies
     221              : 
     222              :   type(mpi_distrib_dmft_type), pointer :: distrib => null()
     223              :   ! Datastructure for MPI parallelization
     224              : 
     225              :  end type green_type
     226              : 
     227              : !----------------------------------------------------------------------
     228              : 
     229              : 
     230              : CONTAINS
     231              : !!***
     232              : 
     233              : !!****f* m_green/init_green
     234              : !! NAME
     235              : !! init_green
     236              : !!
     237              : !! FUNCTION
     238              : !!  Allocate variables used in type green_type.
     239              : !!
     240              : !! INPUTS
     241              : !!  green  <type(green_type)>= green function data
     242              : !!  energies_dmft  = datastructure for dmft energy
     243              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     244              : !!  opt_oper_ksloc (optional) = option for init_oper
     245              : !!  wtype = "real" Green function will be computed for real frequencies
     246              : !!        = "imag" Green function will be computed for imaginary frequencies
     247              : !!  opt_moments = 1 : to allocate the high frequency moments
     248              : !!  opt_moments_ksloc = option to init green%moments
     249              : !!  opt_occup_ksloc = option to init green%occup
     250              : !!
     251              : !! OUTPUTS
     252              : !! green  = variable of type green_type
     253              : !!
     254              : !! SOURCE
     255              : 
     256          551 : subroutine init_green(green,paw_dmft,opt_oper_ksloc,wtype,opt_moments,opt_moments_ksloc,opt_occup_ksloc)
     257              : 
     258              : !Arguments ------------------------------------
     259              :  type(green_type), intent(inout) :: green
     260              :  type(paw_dmft_type), target, intent(in) :: paw_dmft
     261              :  integer, optional, intent(in) :: opt_moments,opt_moments_ksloc,opt_occup_ksloc,opt_oper_ksloc
     262              :  character(len=4), optional, intent(in) :: wtype
     263              : !Local variables ------------------------------------
     264              :  integer :: i,ifreq,mkmem,natom,nsppol,nw,optmoments
     265              :  integer :: optmoments_ksloc,optoccup_ksloc,optoper_ksloc,shift
     266              : !************************************************************************
     267              : 
     268          551 :  optoper_ksloc = 2
     269          551 :  if (present(opt_oper_ksloc)) optoper_ksloc = opt_oper_ksloc
     270              : 
     271          551 :  green%w_type = "imag"
     272          551 :  if (present(wtype)) green%w_type = wtype
     273              : 
     274          551 :  optmoments = 0
     275          551 :  if (present(opt_moments)) optmoments = opt_moments
     276              : 
     277          551 :  optoccup_ksloc = 3
     278          551 :  if (present(opt_occup_ksloc)) optoccup_ksloc = opt_occup_ksloc
     279              : 
     280          551 :  optmoments_ksloc = 3
     281          551 :  if (present(opt_moments_ksloc)) optmoments_ksloc = opt_moments_ksloc
     282              : 
     283          551 :  if (green%w_type == "imag") then
     284          547 :    nw = paw_dmft%dmft_nwlo
     285          547 :    green%omega => paw_dmft%omega_lo(:)
     286          547 :    green%distrib => paw_dmft%distrib
     287            4 :  else if (green%w_type == "real") then
     288            4 :    nw = size(paw_dmft%omega_r(:))
     289            4 :    green%omega => paw_dmft%omega_r(:)
     290            4 :    green%distrib => paw_dmft%distrib_r
     291              :  end if ! w_type
     292              : 
     293          551 :  natom  = paw_dmft%natom
     294          551 :  nsppol = paw_dmft%nsppol
     295              : 
     296          551 :  green%dmft_nwlo = paw_dmft%dmft_nwlo
     297          551 :  green%dmft_nwli = paw_dmft%dmft_nwli
     298          551 :  green%charge_ks = zero
     299         2204 :  ABI_MALLOC(green%charge_matlu,(nsppol+1,natom))
     300         7109 :  green%charge_matlu(:,:) = zero
     301          551 :  green%has_charge_matlu = 1
     302          551 :  green%has_greenmatlu_xsum = 0
     303              : 
     304         1653 :  ABI_MALLOC(green%charge_matlu_solver,(nsppol+1,natom))
     305         7109 :  green%charge_matlu_solver(:,:) = zero
     306          551 :  green%has_charge_matlu_solver = 1
     307              : 
     308         1653 :  ABI_MALLOC(green%charge_matlu_prev,(nsppol+1,natom))
     309         7109 :  green%charge_matlu_prev(:,:) = zero
     310          551 :  green%has_charge_matlu_prev = 1
     311              : 
     312          551 :  call init_oper(paw_dmft,green%occup,opt_ksloc=optoccup_ksloc)
     313              : 
     314              : !  build simple arrays to distribute the tasks in compute_green.
     315              :  !ABI_MALLOC(green%procb,(nw,paw_dmft%nkpt))
     316              :  !ABI_MALLOC(green%proct,(nw,0:paw_dmft%nproc-1))
     317              : 
     318              :  !call distrib_paral(paw_dmft%nkpt,paw_dmft%nproc,nw,nw_perproc,green%procb,green%proct)
     319          551 :  green%nw = nw
     320              : 
     321              : !  need to distribute memory over frequencies
     322              : 
     323              : !!  begin of temporary modificatios
     324              : ! ABI_MALLOC(green%oper,(green%nw_perproc))
     325              : ! do ifreq=1,green%nw_perproc
     326              : !  call init_oper(paw_dmft,green%oper(ifreq),opt_ksloc=optoper_ksloc)
     327              : ! enddo
     328              : !
     329              : ! do ifreq=1,green%nw
     330              : !   if(green%proct(ifreq,myproc)==1) then
     331              : !     do ikpt = 1 , paw_dmft%nkpt
     332              : !       if (green%procb(ifreq,ikpt)==myproc) then
     333              : !       endif
     334              : !     enddo ! ikpt
     335              : !   endif ! parallelisation
     336              : ! enddo ! ifreq
     337              : !
     338              : !
     339              : !!  end of temporary modificatios
     340       132226 :  ABI_MALLOC(green%oper,(nw))
     341       131124 :  do ifreq=1,nw
     342       131124 :    call init_oper(paw_dmft,green%oper(ifreq),opt_ksloc=optoper_ksloc)
     343              :  end do ! ifreq
     344          551 :  green%ichargeloc_cv = 0
     345          551 :  green%ifermie_cv    = 0
     346              : 
     347          551 :  if (paw_dmft%dmft_solv >= 5) then
     348          522 :    ABI_MALLOC(green%ecorr_qmc,(natom))
     349          488 :    green%ecorr_qmc(:) = zero
     350              :  end if
     351              : 
     352          551 :  green%fileprt_tau = 0
     353          551 :  green%fileprt_w = 0
     354              : 
     355          551 :  green%has_moments = optmoments
     356              : 
     357          551 :  green%nmoments = 0
     358              : 
     359          551 :  if (green%has_moments == 1) then
     360            0 :    green%nmoments = 5
     361            0 :    shift = green%distrib%shiftk
     362            0 :    mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
     363            0 :    ABI_MALLOC(green%moments,(green%nmoments))
     364            0 :    call init_oper(paw_dmft,green%moments(1),nkpt=mkmem,shiftk=shift,opt_ksloc=2)
     365            0 :    do i=2,green%nmoments
     366            0 :      call init_oper(paw_dmft,green%moments(i),nkpt=mkmem,shiftk=shift,opt_ksloc=optmoments_ksloc)
     367              :    end do ! i
     368            0 :    if (paw_dmft%dmft_triqs_entropy == 1) then
     369            0 :      ABI_MALLOC(green%trace_moments_log_ks,(green%nmoments-1))
     370            0 :      ABI_MALLOC(green%trace_moments_log_loc,(green%nmoments-1))
     371              :    end if ! entropy
     372              :  end if ! moments
     373              : 
     374          551 : end subroutine init_green
     375              : !!***
     376              : 
     377              : !!****f* m_green/init_green_tau
     378              : !! NAME
     379              : !! init_green_tau
     380              : !!
     381              : !! FUNCTION
     382              : !!  Allocate variables used in type green_type.
     383              : !!
     384              : !! INPUTS
     385              : !!  green  <type(green_type)>= green function data
     386              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     387              : !!
     388              : !! OUTPUTS
     389              : !!  green  <type(green_type)>= green function data
     390              : !!
     391              : !! SOURCE
     392              : 
     393           37 : subroutine init_green_tau(green,paw_dmft)
     394              : 
     395              : !Arguments ------------------------------------
     396              :  type(green_type), intent(inout) :: green
     397              :  type(paw_dmft_type), intent(in) :: paw_dmft
     398              : !Local variables ------------------------------------
     399              :  integer :: itau,optksloc
     400              : !************************************************************************
     401              : 
     402           37 :  green%use_oper_tau_ks = 0
     403           37 :  optksloc = 2
     404              : 
     405           37 :  green%dmftqmc_l = paw_dmft%dmftqmc_l
     406          111 :  ABI_MALLOC(green%tau,(green%dmftqmc_l))
     407         7779 :  do itau=1,green%dmftqmc_l
     408         7779 :    green%tau(itau) = dble(itau-1) / dble(green%dmftqmc_l) / paw_dmft%temp
     409              :  end do
     410              : 
     411           37 :  call init_oper(paw_dmft,green%occup_tau,opt_ksloc=optksloc)
     412              : 
     413         7853 :  ABI_MALLOC(green%oper_tau,(paw_dmft%dmftqmc_l))
     414         7779 :  do itau=1,green%dmftqmc_l
     415         7779 :    call init_oper(paw_dmft,green%oper_tau(itau),opt_ksloc=optksloc)
     416              :  end do
     417              : 
     418           37 : end subroutine init_green_tau
     419              : !!***
     420              : 
     421              : !!****f* m_green/destroy_green
     422              : !! NAME
     423              : !! destroy_green
     424              : !!
     425              : !! FUNCTION
     426              : !!  Deallocate green
     427              : !!
     428              : !! INPUTS
     429              : !!  green  <type(green_type)>= green function data
     430              : !!
     431              : !! OUTPUT
     432              : !!
     433              : !! SOURCE
     434              : 
     435          551 : subroutine destroy_green(green)
     436              : 
     437              : !Arguments ------------------------------------
     438              :  type(green_type), intent(inout) :: green
     439              : !Local variables-------------------------------
     440              :  integer :: i,ifreq
     441              : ! *********************************************************************
     442              : 
     443          551 :  call destroy_oper(green%occup)
     444          551 :  if (allocated(green%oper)) then
     445       131124 :    do ifreq=1,green%nw
     446       131124 :      call destroy_oper(green%oper(ifreq))
     447              :    end do ! ifreq
     448       131124 :    ABI_FREE(green%oper)
     449              :  end if ! green%oper
     450              : 
     451          551 :  ABI_SFREE(green%charge_matlu)
     452          551 :  green%has_charge_matlu = 0
     453              : 
     454          551 :  ABI_SFREE(green%charge_matlu_prev)
     455          551 :  green%has_charge_matlu_prev = 0
     456              : 
     457          551 :  ABI_SFREE(green%charge_matlu_solver)
     458          551 :  green%has_charge_matlu_solver = 0
     459              : 
     460          551 :  ABI_SFREE(green%trace_moments_log_ks)
     461          551 :  ABI_SFREE(green%trace_moments_log_loc)
     462          551 :  ABI_SFREE(green%ecorr_qmc)
     463              : 
     464          551 :  if (allocated(green%moments)) then
     465            0 :    do i=1,green%nmoments
     466            0 :      call destroy_oper(green%moments(i))
     467              :    end do ! i
     468            0 :    ABI_FREE(green%moments)
     469              :  end if  ! green%moments
     470              : 
     471              :  !ABI_SFREE(green%procb)
     472              :  !ABI_SFREE(green%proct)
     473          551 :  green%distrib => null()
     474          551 :  green%omega => null()
     475              : 
     476          551 : end subroutine destroy_green
     477              : !!***
     478              : 
     479              : !!****f* m_green/destroy_green_tau
     480              : !! NAME
     481              : !! destroy_green_tau
     482              : !!
     483              : !! FUNCTION
     484              : !!  Deallocate green
     485              : !!
     486              : !! INPUTS
     487              : !!  green  <type(green_type)>= green function data
     488              : !!
     489              : !! OUTPUT
     490              : !!
     491              : !! SOURCE
     492              : 
     493           37 : subroutine destroy_green_tau(green)
     494              : 
     495              : !Arguments ------------------------------------
     496              :  type(green_type), intent(inout) :: green
     497              : ! integer, optional, intent(in) :: opt_ksloc
     498              : !Local variables-------------------------------
     499              :  integer :: itau
     500              : ! integer :: optksloc
     501              : ! *********************************************************************
     502              : ! if(present(opt_ksloc)) then
     503              : !   optksloc=opt_ksloc
     504              : ! else
     505              : !   optksloc=3
     506              : ! endif
     507              : 
     508           37 :  call destroy_oper(green%occup_tau)
     509           37 :  if (allocated(green%oper_tau)) then
     510         7779 :    do itau=1,green%dmftqmc_l
     511         7779 :      call destroy_oper(green%oper_tau(itau))
     512              :    end do ! itau
     513         7779 :    ABI_FREE(green%oper_tau)
     514              :  end if ! green%oper_tau
     515           37 :  ABI_SFREE(green%tau)
     516              : 
     517           37 : end subroutine destroy_green_tau
     518              : !!***
     519              : 
     520              : !!****f* m_green/copy_green
     521              : !! NAME
     522              : !! copy_green
     523              : !!
     524              : !! FUNCTION
     525              : !!  Copy one data structure green1 into green2
     526              : !!
     527              : !! INPUTS
     528              : !!  green1  <type(green_type)>= green function data
     529              : !!  green2  <type(green_type)>= green function data
     530              : !!  opt_tw = option to specify which data to copy
     531              : !!          1: copy only green%occup_tau and green%oper_tau data
     532              : !!          2: copy only green%occup and green%oper data (frequency)
     533              : !!
     534              : !! OUTPUT
     535              : !!
     536              : !! SOURCE
     537              : 
     538           36 : subroutine copy_green(green1,green2,opt_tw)
     539              : 
     540              : !Arguments ------------------------------------
     541              :  type(green_type), intent(in) :: green1
     542              :  type(green_type), intent(inout) :: green2
     543              :  integer, intent(in) :: opt_tw
     544              : !Local variables-------------------------------
     545              :  integer :: i,ifreq,itau
     546              : ! *********************************************************************
     547              : 
     548           36 :  if (opt_tw == 2) then
     549           36 :    call copy_oper(green1%occup,green2%occup)
     550        18029 :    do ifreq=1,green1%nw
     551        18029 :      call copy_oper(green1%oper(ifreq),green2%oper(ifreq))
     552              :    end do
     553           36 :    if (green1%has_moments == 1) then
     554            0 :      do i=1,green1%nmoments
     555            0 :        call copy_oper(green1%moments(i),green2%moments(i))
     556              :      end do
     557              :    end if
     558              :    ! Indicate to integrate_green that xsum has been done
     559              :    ! for matlu in compute_green.
     560           36 :    if (green1%has_greenmatlu_xsum == 1) green2%has_greenmatlu_xsum = 1
     561            0 :  else if (opt_tw == 1) then
     562            0 :    call copy_oper(green1%occup_tau,green2%occup_tau)
     563            0 :    do itau=1,green1%dmftqmc_l
     564            0 :      call copy_oper(green1%oper_tau(itau),green2%oper_tau(itau))
     565              :    end do ! itau
     566              :  end if ! opt_tw
     567              : 
     568           36 : end subroutine copy_green
     569              : !!***
     570              : 
     571              : !!****f* m_green/printocc_green
     572              : !! NAME
     573              : !! printocc_green
     574              : !!
     575              : !! FUNCTION
     576              : !!  Print occupations
     577              : !!
     578              : !! INPUTS
     579              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     580              : !!  green  <type(green_type)>= green function data
     581              : !!  option= 1 :for G(w)
     582              : !!          2 :for G(tau)
     583              : !!          3 :for G(tau) and check % G(w)
     584              : !!          4
     585              : !!         <5: write diagonal part of KS occupation matrix
     586              : !!          5: for G(w)
     587              : !!          6: for G(tau)
     588              : !!          7 :for G(tau) and check % G(w)
     589              : !!         >8: write all elements of KS occup. matrix.
     590              : !!          9: for G(w)
     591              : !!  pawprtvol: flag for print
     592              : !!  opt_weissgreen = 1 for Weiss field
     593              : !!                 = 2 (default) for regular Green's function
     594              : !!  chtype: to specify the type of occupations being printed
     595              : !!
     596              : !! OUTPUT
     597              : !!
     598              : !! SOURCE
     599              : 
     600          583 : subroutine printocc_green(green,option,paw_dmft,pawprtvol,opt_weissgreen,chtype)
     601              : 
     602              : !Arguments ------------------------------------
     603              :  type(paw_dmft_type), intent(in) :: paw_dmft
     604              :  type(green_type), intent(in) :: green
     605              :  integer, intent(in) :: option,pawprtvol
     606              :  integer, optional, intent(in) :: opt_weissgreen
     607              :  character(len=*), optional, intent(in) :: chtype
     608              : !Local variables-------------------------------
     609              :  character(len=500) :: message
     610              :  integer :: i_tau,optweissgreen
     611              : ! *********************************************************************
     612              : 
     613          583 :  optweissgreen = 2
     614          583 :  if (present(opt_weissgreen)) optweissgreen = opt_weissgreen
     615              : 
     616          583 :  if (mod(option,4) == 1) then
     617          582 :    if (optweissgreen == 2) then
     618          582 :      if (present(chtype)) then
     619          478 :        write(message,'(4a)') ch10,"  == The ",trim(chtype)," occupations are  == "
     620              :      else
     621          104 :        write(message,'(2a)') ch10,"  == The occupations (integral of the Green's function) are  == "
     622              :      end if ! present(chtype)
     623            0 :    else if (optweissgreen == 1) then
     624            0 :      write(message,'(2a)') ch10,"  == The integrals of the Weiss function are  == "
     625              :    end if ! optweissgreen
     626          582 :    call wrtout(std_out,message,'COLL')
     627          582 :    call print_oper(green%occup,option,paw_dmft,pawprtvol)
     628              :  end if ! mod(option,4)=1
     629              : 
     630          583 :  if (mod(option,4) >= 2) then
     631            1 :    if (optweissgreen == 2) then
     632            1 :      write(message,'(2a)') ch10,"  == The occupations (value of G(tau) for tau=0-) are  == "
     633            0 :    else if (optweissgreen == 1) then
     634            0 :      write(message,'(2a)') ch10,"  == Values of G_0(tau) for tau=0- are  == "
     635              :    end if ! optweissgreen
     636            1 :    call wrtout(std_out,message,'COLL')
     637            1 :    call print_oper(green%occup_tau,option,paw_dmft,pawprtvol)
     638              : !   write(message,'(2a)') ch10," == check: occupations from Green functions are  == "
     639              : !   call wrtout(std_out,message,'COLL')
     640              : !   call print_oper(green%occup,1,paw_dmft,pawprtvol)
     641            1 :    if (mod(option,4) >= 3) then
     642              :      call diff_matlu("Local occup from integral of G(iw) ","Local occup from G(tau=0-) ",&
     643            0 :        & green%occup%matlu(:),green%occup_tau%matlu(:),paw_dmft%natom,1,tol4)
     644            0 :      write(message,'(2a)') ch10,&
     645            0 :        & '  *****  => Calculations of occupations in omega and tau spaces are coherent ****'
     646            0 :      call wrtout(std_out,message,'COLL')
     647              :    end if ! mod(option,4)>=3
     648              :  end if ! mod(option,4)>=2
     649              : 
     650          583 :  if (present(chtype)) then
     651              :    if (paw_dmft%prtvol >= 4 .and. &
     652              :       & (chtype == "DFT+DMFT (end of DMFT loop)" .or. chtype == "converged DMFT") &
     653          478 :       & .and. green%occup%has_opermatlu == 1) then
     654           87 :      write(message,'(4a)') ch10,"  == The DFT+DMFT occupation matrix for correlated electrons is == "
     655           87 :      call wrtout(ab_out,message,'COLL')
     656           87 :      call print_matlu(green%occup%matlu(:),paw_dmft%natom,pawprtvol,opt_ab_out=1)
     657           87 :      write(message,'(a)') "  "
     658           87 :      call wrtout(ab_out,message,'COLL')
     659              :    end if
     660              :  end if ! present(chtype)
     661              : 
     662          583 :  if (mod(option,4) >= 2) then
     663            1 :    i_tau = 1
     664            1 :    if (optweissgreen == 1) i_tau = -1
     665            1 :    call trace_matlu(green%occup_tau%matlu(:),paw_dmft%natom,itau=i_tau)
     666              :  end if ! mod(option,4)>=2
     667              : 
     668          583 : end subroutine printocc_green
     669              : !!***
     670              : 
     671              : !!****f* m_green/print_green
     672              : !! NAME
     673              : !! print_green
     674              : !!
     675              : !! FUNCTION
     676              : !!  print green function
     677              : !!
     678              : !! INPUTS
     679              : !!  char1 = character which describes the type of green function
     680              : !!  green  <type(green_type)>= green function data
     681              : !!  option=1 print local green function
     682              : !!         2 print KS green function
     683              : !!         3 print both local and KS green function
     684              : !!         4 print spectral function is green%w_type="real"
     685              : !!         5 print k-resolved spectral function is green%w_type="real"
     686              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     687              : !!  pawprtvol = printing option
     688              : !!  opt_wt=1 print green function as a function of frequency
     689              : !!         2 print green function as a function of imaginary time
     690              : !!  opt_decim= if present, write more decimals
     691              : !!
     692              : !! OUTPUT
     693              : !!
     694              : !! SOURCE
     695              : 
     696            1 : subroutine print_green(char1,green,option,paw_dmft,opt_wt,opt_decim)
     697              : 
     698              : !Arguments ------------------------------------
     699              :  type(paw_dmft_type), intent(in) :: paw_dmft
     700              :  type(green_type), intent(inout) :: green
     701              :  integer, intent(in) :: option
     702              :  integer, optional, intent(in) :: opt_wt,opt_decim
     703              :  character(len=*), intent(in) :: char1
     704              : !Local variables-------------------------------
     705              :  integer :: iall,iatom,ib,ifreq,ikpt,im,ispinor
     706              :  integer :: isppol,itau,lpawu,lsub,mbandc,natom
     707              :  integer :: ndim,nkpt,nspinor,nsppol,optwt,spf_unt
     708              :  integer :: spfkresolved_unt,spcorb_unt
     709              :  !real(dp) :: ima,re
     710              :  character(len=2000) :: message
     711              :  character(len=fnlen) :: tmpfil
     712              :  character(len=1) :: tag_is,tag_is2
     713              :  character(len=10) :: tag_at
     714              :  character(len=3) :: tag_ik
     715            1 :  integer, allocatable :: unitgreenfunc_arr(:),unitgreenloc_arr(:)
     716            1 :  complex(dp), allocatable :: sf(:,:),sf_corr(:),sf2(:)
     717              : ! *********************************************************************
     718              : 
     719            1 :  optwt = 1
     720            1 :  if (present(opt_wt)) optwt = opt_wt
     721              : 
     722            1 :  mbandc  = paw_dmft%mbandc
     723            1 :  natom   = paw_dmft%natom
     724            1 :  nkpt    = paw_dmft%nkpt
     725            1 :  nspinor = paw_dmft%nspinor
     726            1 :  nsppol  = paw_dmft%nsppol
     727              : 
     728              : !  == Print local Green Function
     729            1 :  if (option == 1 .or. option == 3) then
     730            0 :    ABI_MALLOC(unitgreenfunc_arr,(natom*nsppol*nspinor))
     731            0 :    iall = 0
     732            0 :    do iatom=1,natom
     733            0 :      lpawu = paw_dmft%lpawu(iatom)
     734            0 :      if (lpawu == -1) cycle
     735            0 :      ndim = 2*lpawu + 1
     736            0 :      call int2char4(iatom,tag_at)
     737            0 :      ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
     738            0 :      do isppol=1,nsppol
     739            0 :        write(tag_is,'(i1)') isppol
     740            0 :        do ispinor=1,nspinor
     741            0 :          iall = iall + 1
     742            0 :          write(tag_is2,'(i1)') ispinor
     743              : !       == Create names
     744            0 :          if (optwt == 1) then
     745              :            tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-omega_iatom'// &
     746            0 :              & trim(tag_at)//'_isppol'//tag_is//'_ispinor'//tag_is2
     747              :          else
     748              :            tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-tau_iatom'// &
     749            0 :              & trim(tag_at)//'_isppol'//tag_is//'_ispinor'//tag_is2
     750              :          end if ! optwt
     751            0 :          if (iall <= 4) then
     752            0 :            write(message,'(3a)') ch10,"  == Print green function on file ",trim(tmpfil)
     753            0 :            call wrtout(std_out,message,'COLL')
     754            0 :          else if (iall == 5) then
     755            0 :            write(message,'(3a)') ch10,"  == following values are printed in files"
     756            0 :            call wrtout(std_out,message,'COLL')
     757              :          end if ! iall
     758            0 :          unitgreenfunc_arr(iall) = 300 + iall - 1
     759            0 :          if ((optwt == 1 .or. green%fileprt_tau == 0) .or. (optwt == 2 .and. green%fileprt_tau == 1)) &
     760            0 :           & open(unit=unitgreenfunc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted',position='append')
     761              : 
     762              : !         == Write in files
     763              : !           rewind(unitgreenfunc_arr(iall))
     764              : !           write(message,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitgreenfunc_arr(iall)
     765              : !           call wrtout(std_out,message,'COLL')
     766            0 :          write(message,'(2a)') ch10,"# New record :"
     767            0 :          call wrtout(unitgreenfunc_arr(iall),message,'COLL')
     768            0 :          if (optwt == 1) then
     769            0 :            do ifreq=1,green%nw
     770            0 :              if (present(opt_decim)) then
     771            0 :                write(message,'(2x,30(e23.16,2x))') green%omega(ifreq), &
     772            0 :                  & (green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol),im=1,ndim)
     773              :              else
     774            0 :                write(message,'(2x,30(e10.3,2x))') green%omega(ifreq), &
     775            0 :                  & (green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol),im=1,ndim)
     776              :              end if ! opt_decim
     777            0 :              call wrtout(unitgreenfunc_arr(iall),message,'COLL')
     778              :                !re=real(green%oper(ifreq)%matlu(iatom)%mat(1,1,isppol,ispinor,ispinor))
     779              :                !ima=aimag(green%oper(ifreq)%matlu(iatom)%mat(1,1,isppol,ispinor,ispinor))
     780              : !               write(228,*) green%omega(ifreq),re/(re**2+ima**2),ima/(re**2+ima**2)+green%omega(ifreq)
     781              :            end do ! ifreq
     782              :          else
     783            0 :            do itau=1,green%dmftqmc_l
     784            0 :              write(message,'(2x,30(e10.3,2x))') green%tau(itau), &
     785            0 :                 & (green%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol),im=1,ndim)
     786            0 :                call wrtout(unitgreenfunc_arr(iall),message,'COLL')
     787              :            end do ! itau
     788            0 :            write(message,'(2x,30(e10.3,2x))') one/paw_dmft%temp,&
     789            0 :               & (-green%oper_tau(1)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)-one,im=1,ndim)
     790            0 :            call wrtout(unitgreenfunc_arr(iall),message,'COLL')
     791              :          end if ! optwt
     792            0 :          close(unitgreenfunc_arr(iall))
     793              :        end do ! ispinor
     794              :      end do ! isppol
     795              :    end do ! iatom
     796            0 :    ABI_FREE(unitgreenfunc_arr)
     797              :  end if ! option=1 or 3
     798              : 
     799              : !  == Print ks green function
     800            1 :  if ((option == 2 .or. option == 3) .and. green%oper(1)%has_operks == 1) then
     801            0 :    ABI_MALLOC(unitgreenloc_arr,(nsppol*nkpt))
     802            0 :    iall = 0
     803            0 :    do isppol=1,nsppol
     804            0 :      write(tag_is,'(i1)') isppol
     805            0 :      do ikpt=1,nkpt
     806            0 :        write(tag_ik,'(i3)') ikpt
     807              : !      do ib1 = 1, mbandc
     808            0 :        iall = iall + 1
     809              : !         == Create names
     810            0 :        if (optwt == 1) then
     811            0 :          tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-omega_isppol'//tag_is//'_ikpt'//trim(adjustl(tag_ik))
     812              :        else
     813            0 :          tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-tau_isppol'//tag_is//'_ikpt'//trim(adjustl(tag_ik))
     814              :        end if ! optwt
     815            0 :        if (iall <= 4) then
     816            0 :          write(message,'(3a)') ch10,"  == Print green function on file ",trim(tmpfil)
     817            0 :          call wrtout(std_out,message,'COLL')
     818            0 :        else if (iall == 5)  then
     819            0 :          write(message,'(3a)') ch10,"  == following values are printed in files"
     820            0 :          call wrtout(std_out,message,'COLL')
     821              :        end if ! iall
     822            0 :        unitgreenloc_arr(iall) = 400 + iall - 1
     823            0 :        open(unit=unitgreenloc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted')
     824              : !      rewind(unitgreenloc_arr(iall))
     825              : !       write(message,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitgreenloc_arr(iall)
     826              : !       call wrtout(std_out,message,'COLL')
     827              : 
     828              : !      == Write in files
     829            0 :        write(message,'(2a)') ch10,"# New record : First 20 bands"
     830            0 :        call wrtout(unitgreenloc_arr(iall),message,'COLL')
     831              : !       call flush(std_out)
     832            0 :        do lsub=1,mbandc/20+1
     833            0 :          if (optwt == 1) then
     834            0 :            do ifreq=1,green%nw
     835              : !             call flush(std_out)
     836            0 :              write(message,'(2x,50(e10.3,2x))') green%omega(ifreq), &
     837            0 :                & (green%oper(ifreq)%ks(ib,ib,ikpt,isppol),ib=20*(lsub-1)+1,min(20*lsub,mbandc))
     838            0 :              call wrtout(unitgreenloc_arr(iall),message,'COLL')
     839              :              !re  = dble(green%oper(ifreq)%ks(1,1,ikpt,isppol))
     840              :              !ima = aimag(green%oper(ifreq)%ks(1,1,ikpt,isppol))
     841              :              !if (ikpt == 1) write(229,*) green%omega(ifreq),re/(re**2+ima**2),ima/(re**2+ima**2)+green%omega(ifreq)
     842              :            end do ! ifreq
     843            0 :          else if (green%use_oper_tau_ks == 1) then
     844            0 :            do itau=1,green%dmftqmc_l
     845              : !               call flush(std_out)
     846            0 :              write(message,'(2x,50(e10.3,2x))') green%tau(itau), &
     847            0 :                  & (green%oper_tau(itau)%ks(ib,ib,ikpt,isppol),ib=20*(lsub-1)+1,min(20*lsub,mbandc))
     848            0 :              call wrtout(unitgreenloc_arr(iall),message,'COLL')
     849              :            end do ! itau
     850              :          end if ! optwt
     851            0 :          if (20*lsub < mbandc) write(message,'(2a,i5,a,i5)') ch10,"# Same record, Following bands : From ", &
     852            0 :            & 20*(lsub),"  to ",min(20*(lsub+1),mbandc)
     853            0 :          call wrtout(unitgreenloc_arr(iall),message,'COLL')
     854              :        end do ! lsub
     855            0 :        close(unitgreenloc_arr(iall))
     856              :      end do ! ikpt
     857              :    end do ! isppol
     858            0 :    ABI_FREE(unitgreenloc_arr)
     859              :  end if ! option=2 or 3
     860              : 
     861            1 :  if ((green%w_type == "real" .and. option >= 4) .and. green%oper(1)%has_operks == 1) then
     862            1 :    write(message,'(2a)') ch10,"  == About to print spectral function"
     863            1 :    call wrtout(std_out,message,'COLL')
     864            1 :    if (option == 4) then
     865            0 :      tmpfil = trim(paw_dmft%filapp)//'_SpFunc-'//trim(char1)
     866            0 :      if (open_file(tmpfil,message,newunit=spf_unt,status='unknown',form='formatted') /= 0) &
     867            0 :        & ABI_ERROR(message)
     868            0 :      write(spf_unt,'(3a)') "# This is the total spectral function (DOS).",ch10, &
     869            0 :                          & "#    Real frequency (Ha)        Spectral function"
     870              : 
     871              :    end if ! option=4
     872            1 :    if (option == 5) then
     873            1 :      tmpfil = trim(paw_dmft%filapp)//'_DFTDMFT_SpectralFunction_kres' !//trim(char1)
     874            1 :      if (open_file(tmpfil,message,newunit=spfkresolved_unt,status='unknown',form='formatted') /= 0) &
     875            0 :        & ABI_ERROR(message)
     876            1 :      write(spfkresolved_unt,'(3a)') "# This is the k-resolved spectral function.",ch10, &
     877            2 :                                 & "#  Real frequency (eV)       Spectral function (eV^-1)   ikpt"
     878            4 :      ABI_MALLOC(sf,(nkpt,green%nw))
     879        36001 :      sf(:,:) = czero
     880         3001 :      do ifreq=1,green%nw
     881         6001 :        do isppol=1,nsppol
     882        39000 :          do ikpt=1,nkpt
     883       333000 :            do ib=1,mbandc
     884       330000 :              sf(ikpt,ifreq) = sf(ikpt,ifreq) + green%oper(ifreq)%ks(ib,ib,ikpt,isppol)
     885              :            end do ! ib
     886              :          end do ! ikpt
     887              :        end do ! isppol
     888              :      end do ! ifreq
     889           12 :      do ikpt=1,nkpt
     890        33011 :        do ifreq=1,green%nw
     891        33000 :          write(message,'(2x,2(es24.16e3,2x),i5)') green%omega(ifreq)*Ha_eV,(-aimag(sf(ikpt,ifreq)))/pi/Ha_eV,ikpt
     892        33011 :          call wrtout(spfkresolved_unt,message,'COLL')
     893              :        end do ! ifreq
     894           11 :        write(message,*)
     895           12 :        call wrtout(spfkresolved_unt,message,'COLL')
     896              :      end do ! ikpt
     897            1 :      write(message,*) ch10
     898            1 :      call wrtout(spfkresolved_unt,message,'COLL')
     899            1 :      ABI_FREE(sf)
     900            1 :      close(spfkresolved_unt)
     901              : !
     902              : !     do isppol = 1 , nsppol
     903              : !       do ikpt = 1, nkpt
     904              : !         do ib=1,mbandc
     905              : !           sf=czero
     906              : !           write(71,*)
     907              : !           write(71,*)  "#", ikpt, ib
     908              : !           do ifreq=1,green%nw
     909              : !             sf(ifreq)=sf(ifreq)+green%oper(ifreq)%ks(isppol,ikpt,ib,ib)
     910              : !             write(71,*) green%omega(ifreq)*Ha_eV,(-aimag(sf(ifreq)))/pi/Ha_eV,ikpt
     911              : !           enddo
     912              : !         enddo
     913              : !       enddo
     914              : !     enddo
     915              :    end if ! option=5
     916              : 
     917            1 :    if (option == 4) then
     918            0 :      ABI_MALLOC(sf2,(green%nw))
     919            0 :      sf2(:) = czero
     920            0 :      do ifreq=1,green%nw
     921            0 :        do isppol=1,nsppol
     922            0 :          do ikpt=1,nkpt
     923            0 :            do ib=1,mbandc
     924            0 :              sf2(ifreq) = sf2(ifreq) + green%oper(ifreq)%ks(ib,ib,ikpt,isppol)*green%oper(1)%wtk(ikpt)
     925              :            end do ! ib
     926              :          end do ! ikpt
     927              :        end do ! isppol
     928              :      end do ! ifreq
     929            0 :      do ifreq=1,green%nw
     930            0 :        write(message,'(2x,2(es24.16e3,2x))') green%omega(ifreq),(-aimag(sf2(ifreq)))/pi
     931            0 :        call wrtout(spf_unt,message,'COLL')
     932              :      end do ! ifreq
     933            0 :      ABI_FREE(sf2)
     934            0 :      close(spf_unt)
     935              :    end if ! option=4
     936              : 
     937            1 :    if (paw_dmft%dmft_kspectralfunc == 1) then
     938            3 :      ABI_MALLOC(sf_corr,(green%nw))
     939            2 :      do iatom=1,natom
     940            1 :        lpawu = paw_dmft%lpawu(iatom)
     941            1 :        if (lpawu == -1) cycle
     942         3001 :        sf_corr(:) = czero
     943            1 :        call int2char4(iatom,tag_at)
     944            1 :        ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
     945            1 :        tmpfil = trim(paw_dmft%filapp)//'_DFTDMFT_SpFunloc_iatom'//trim(tag_at)
     946            1 :        if (open_file(tmpfil,message,newunit=spcorb_unt,status='unknown',form='formatted') /= 0) &
     947            0 :          & ABI_ERROR(message)
     948            1 :        ndim = 2*lpawu + 1
     949            1 :        write(message,'(3a,3(i3),i6,2a,i2,2a)') "# nspinor,nsppol,ndim,nw",ch10,"#",nspinor,nsppol,ndim,green%nw,ch10, &
     950            2 :                                           & "# lpawu",lpawu,ch10,"#       Frequency (Ha.)        Spectral function"
     951            1 :        call wrtout(spcorb_unt,message,'COLL')
     952            1 :        ndim = nspinor * ndim
     953         3001 :        do ifreq=1,green%nw
     954         6001 :          do isppol=1,nsppol
     955        21000 :            do im=1,ndim
     956        18000 :              sf_corr(ifreq) = sf_corr(ifreq) + green%oper(ifreq)%matlu(iatom)%mat(im,im,isppol)
     957              :            end do ! im
     958              :          end do ! isppol
     959              :        end do ! ifreq
     960         3001 :        do ifreq=1,green%nw
     961         3000 :          write(message,'(2x,2(es24.16e3,2x))') green%omega(ifreq),(-aimag(sf_corr(ifreq)))/pi
     962         3001 :          call wrtout(spcorb_unt,message,'COLL')
     963              :        end do ! ifreq
     964            2 :        close(spcorb_unt)
     965              :      end do ! iatom
     966            1 :      ABI_FREE(sf_corr)
     967              :    end if ! dmft_kspectralfunc=1
     968              :  end if ! (green%w_type == "real" .and. option >= 4) .and. green%oper(1)%has_operks == 1
     969              : 
     970            1 :  if (optwt == 2 .and. (option == 1 .or. option == 3)) green%fileprt_tau = 1  ! file for G(tau) has been created here
     971              : 
     972            1 : end subroutine print_green
     973              : !!***
     974              : 
     975              : !!****f* m_green/compute_green_batched_core
     976              : !! NAME
     977              : !! compute_green_batched_core
     978              : !!
     979              : !! FUNCTION
     980              : !! Variant for core loop of compute green function, useful for computation on GPU
     981              : !!
     982              : !! INPUTS
     983              : !!  green  <type(green_type)>= green function data
     984              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     985              : !!  prtopt : option for printing
     986              : !!  self <type(self_type)>= variables related to self-energy
     987              : !!  opt_self = optional argument, if =1, upfold self-energy
     988              : !!  opt_log = if 1, compute Tr(log(G))
     989              : !!
     990              : !! OUTPUT
     991              : !!
     992              : !! SOURCE
     993            0 : subroutine compute_green_batched_core(green,paw_dmft,self,optself,optlog)
     994              : 
     995              :  use m_abi_linalg, only : abi_xgemm
     996              :  use m_matlu, only : add_matlu,sym_matlu
     997              :  use m_oper, only : downfold_oper,inverse_oper,upfold_oper
     998              :  use m_time, only : timab
     999              : 
    1000              : !Arguments ------------------------------------
    1001              :  type(green_type), target, intent(inout) :: green
    1002              :  type(paw_dmft_type), target, intent(in) :: paw_dmft
    1003              :  type(self_type), intent(inout) :: self
    1004              :  integer, intent(in) :: optlog,optself
    1005              : !Local variables-------------------------------
    1006              :  logical :: oper_ndat_allocated
    1007              :  integer :: diag,ib,ib1,ifreq,ikpt,info,isppol,lwork,mbandc,ifreq_beg,ifreq_end,idat
    1008              :  integer :: me_kpt,mkmem,myproc,natom,nkpt,nmoments,nspinor,nsppol,gpu_option,ndat
    1009              :  integer :: option,shift,shift_green,spacecomm,optoper_ksloc
    1010              :  real(dp) :: fermilevel,wtk,temp
    1011              :  complex(dp) :: green_tmp,trace_tmp
    1012            0 :  real(dp), allocatable :: eig(:),rwork(:),fac(:)
    1013            0 :  complex(dp), allocatable :: mat_tmp(:,:),work(:),omega_current(:)
    1014            0 :  type(oper_type), target :: green_oper_ndat
    1015            0 :  real(dp), ABI_CONTIGUOUS pointer :: eigen_dft(:,:,:)
    1016            0 :  complex(dp), ABI_CONTIGUOUS pointer :: ks(:,:,:,:),occup_ks(:,:,:,:)
    1017              : ! *********************************************************************
    1018              : 
    1019              :  ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_GREEN_BATCHED)
    1020              : 
    1021            0 :  diag = 1 - optself
    1022              : 
    1023              : ! Initialise spaceComm, myproc, and nproc
    1024            0 :  me_kpt = green%distrib%me_kpt
    1025            0 :  myproc = paw_dmft%myproc
    1026            0 :  spacecomm = paw_dmft%spacecomm
    1027            0 :  oper_ndat_allocated = .false.
    1028              : 
    1029              : ! Initialise integers
    1030            0 :  mbandc  = paw_dmft%mbandc
    1031            0 :  natom   = paw_dmft%natom
    1032            0 :  nkpt    = paw_dmft%nkpt
    1033            0 :  nspinor = paw_dmft%nspinor
    1034            0 :  nsppol  = paw_dmft%nsppol
    1035            0 :  temp    = paw_dmft%temp
    1036            0 :  gpu_option = paw_dmft%gpu_option
    1037              : 
    1038            0 :  if (optlog == 1) then
    1039            0 :    ABI_MALLOC(eig,(mbandc))
    1040            0 :    ABI_MALLOC(work,(2*mbandc-1))
    1041            0 :    ABI_MALLOC(rwork,(3*mbandc-2))
    1042            0 :    ABI_MALLOC(mat_tmp,(mbandc,mbandc))
    1043            0 :    call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),-1,rwork(:),info)
    1044            0 :    lwork = int(work(1))
    1045            0 :    ABI_FREE(work)
    1046            0 :    ABI_MALLOC(work,(lwork))
    1047            0 :    green%trace_log = zero
    1048              :  end if ! optlog=1
    1049              : 
    1050            0 :  fermilevel = paw_dmft%fermie
    1051              : 
    1052              :  ! option for downfold_oper
    1053            0 :  option = 1
    1054            0 :  if (diag == 1) option = 3
    1055              : 
    1056              : ! ================================
    1057              : ! == Compute Green function G(k)
    1058              : ! ================================
    1059            0 :  green%occup%ks(:,:,:,:) = czero
    1060              : 
    1061            0 :  nmoments = 1
    1062              :  if (green%has_moments == 1) then
    1063              :    nmoments = green%nmoments
    1064              :  end if ! moments
    1065              : 
    1066            0 :  shift = green%distrib%shiftk
    1067            0 :  mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
    1068            0 :  shift_green = shift
    1069            0 :  ndat = green%distrib%nw_mem_kptparal(green%distrib%me_freq+1)
    1070            0 :  if (green%oper(1)%has_operks == 0) shift_green = 0
    1071              : 
    1072            0 :  if(green%oper(1)%has_opermatlu==0) optoper_ksloc=1
    1073            0 :  if(green%oper(1)%has_opermatlu==1) optoper_ksloc=3
    1074              : 
    1075            0 :  do ifreq=1,green%nw
    1076            0 :    if (green%distrib%proct(ifreq) == green%distrib%me_freq) then
    1077            0 :      ifreq_beg = ifreq; ifreq_end = ifreq_beg + ndat - 1
    1078            0 :      exit
    1079              :    end if
    1080              :  end do
    1081              : 
    1082            0 :  ABI_MALLOC(omega_current,(green%nw))
    1083            0 :  ABI_MALLOC(fac,(green%nw))
    1084              : ! Initialise for compiler
    1085            0 :  omega_current = czero
    1086            0 :  do ifreq=1,green%nw
    1087              :    !if(present(iii)) write(6,*) ch10,'ifreq  self', ifreq,self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
    1088              : !   ====================================================
    1089              : !   First Upfold self-energy and double counting  Self_imp -> self(k)
    1090              : !   ====================================================
    1091              : !   if(mod(ifreq-1,nproc)==myproc) then
    1092              : !    write(6,*) "compute_green ifreq",ifreq, mod(ifreq-1,nproc)==myproc,proct(ifreq,myproc)==1
    1093            0 :    if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
    1094            0 :    if (green%w_type == "imag") then
    1095            0 :      omega_current(ifreq) = cmplx(zero,green%omega(ifreq),kind=dp)
    1096            0 :      fac(ifreq) = two * paw_dmft%wgt_wlo(ifreq) * paw_dmft%temp
    1097            0 :    else if (green%w_type == "real") then
    1098            0 :      omega_current(ifreq) = cmplx(green%omega(ifreq),paw_dmft%temp,kind=dp)
    1099              :    end if ! green%w_type
    1100              : 
    1101            0 :    if (green%oper(ifreq)%has_operks == 0) then
    1102            0 :      ABI_MALLOC(green%oper(ifreq)%ks,(mbandc,mbandc,mkmem,nsppol))
    1103            0 :      green%oper(ifreq)%nkpt   = mkmem
    1104            0 :      green%oper(ifreq)%paral  = 1
    1105            0 :      green%oper(ifreq)%shiftk = shift
    1106              :    end if
    1107            0 :    if(.not. oper_ndat_allocated) then
    1108            0 :      call init_oper_ndat(paw_dmft,green_oper_ndat,ndat,nkpt=green%oper(ifreq)%nkpt,opt_ksloc=optoper_ksloc,gpu_option=gpu_option)
    1109            0 :      if (green%oper(ifreq)%has_operks == 0) then
    1110            0 :        green_oper_ndat%paral  = 1
    1111            0 :        green_oper_ndat%shiftk = shift
    1112              :      end if
    1113              :      oper_ndat_allocated=.true.
    1114              :    end if
    1115              :  end do ! ifreq
    1116              : 
    1117            0 :  if (optself == 0) then
    1118            0 :    if(green_oper_ndat%gpu_option==ABI_GPU_DISABLED) then
    1119            0 :      green_oper_ndat%ks(:,:,:,:) = czero
    1120            0 :    else if(green_oper_ndat%gpu_option==ABI_GPU_OPENMP) then
    1121            0 :      call gpu_set_to_zero_complex(green_oper_ndat%ks, int(nsppol,c_size_t)*ndat*mbandc*mbandc*mkmem)
    1122              :    end if
    1123            0 :    call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.false.)
    1124              :  else
    1125            0 :    do ifreq=ifreq_beg,ifreq_end
    1126            0 :      call add_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),green%oper(ifreq)%matlu(:),natom,-1)
    1127              :    end do
    1128            0 :    call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.false.)
    1129            0 :    call upfold_oper(green_oper_ndat,paw_dmft,procb=green%distrib%procb(:),iproc=me_kpt,gpu_option=gpu_option)
    1130              :  end if ! optself
    1131              : 
    1132            0 :  ks => green_oper_ndat%ks
    1133            0 :  eigen_dft => paw_dmft%eigen_dft
    1134            0 :  if(gpu_option==ABI_GPU_DISABLED) then
    1135            0 :    do ifreq=ifreq_beg,ifreq_end
    1136            0 :      do isppol=1,nsppol
    1137            0 :        do ikpt=1,mkmem
    1138            0 :          do ib=1,mbandc
    1139            0 :            idat=ifreq-(ifreq_end-ndat)
    1140            0 :            green_tmp = omega_current(ifreq) + fermilevel - eigen_dft(ib,ikpt+shift,isppol)
    1141            0 :            if (optself == 0) then
    1142            0 :              ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = cone / green_tmp
    1143              :            else
    1144              :              ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = &
    1145            0 :                  & ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) + green_tmp
    1146              :            end if
    1147              :          end do ! ib
    1148              :        end do ! ikpt
    1149              :      end do ! isppol
    1150              :    end do ! ifreq
    1151              :  else if(gpu_option==ABI_GPU_OPENMP) then
    1152              : #ifdef HAVE_OPENMP_OFFLOAD
    1153              :    if (optself == 0) then
    1154              :      !$OMP TARGET TEAMS DISTRIBUTE MAP(to:ks,eigen_dft) PRIVATE(ifreq,idat)
    1155              :      do ifreq=ifreq_beg,ifreq_end
    1156              :        idat=ifreq-(ifreq_end-ndat)
    1157              :        !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(isppol,ikpt,ib,green_tmp)
    1158              :        do isppol=1,nsppol
    1159              :          do ikpt=1,mkmem
    1160              :            do ib=1,mbandc
    1161              :              green_tmp = omega_current(ifreq) + fermilevel - eigen_dft(ib,ikpt+shift,isppol)
    1162              :              ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = cone / green_tmp
    1163              :            end do ! ib
    1164              :          end do ! ikpt
    1165              :        end do ! isppol
    1166              :      end do ! ifreq
    1167              :    else
    1168              :      !$OMP TARGET TEAMS DISTRIBUTE MAP(to:ks,eigen_dft) PRIVATE(ifreq,idat)
    1169              :      do ifreq=ifreq_beg,ifreq_end
    1170              :        idat=ifreq-(ifreq_end-ndat)
    1171              :        !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(isppol,ikpt,ib,green_tmp)
    1172              :        do isppol=1,nsppol
    1173              :          do ikpt=1,mkmem
    1174              :            do ib=1,mbandc
    1175              :              green_tmp = omega_current(ifreq) + fermilevel - eigen_dft(ib,ikpt+shift,isppol)
    1176              :              ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = &
    1177              :                  & ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) + green_tmp
    1178              :            end do ! ib
    1179              :          end do ! ikpt
    1180              :        end do ! isppol
    1181              :      end do ! ifreq
    1182              :    end if
    1183              : #endif
    1184              :  end if
    1185              : 
    1186            0 :  if (optself /= 0) then
    1187            0 :    call inverse_oper(green_oper_ndat,1,procb=green%distrib%procb(:),iproc=me_kpt,gpu_option=gpu_option)
    1188              :  end if
    1189              : 
    1190            0 :  if (optlog == 1) then
    1191            0 :    call copy_oper_from_ndat(green_oper_ndat,green%oper,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.true.)
    1192            0 :    do ifreq=1,green%nw
    1193            0 :      if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
    1194              :      trace_tmp = czero
    1195            0 :      do isppol=1,nsppol
    1196            0 :        do ikpt=1,mkmem
    1197            0 :          wtk = green%oper(ifreq)%wtk(ikpt+shift)
    1198            0 :          if (optself == 0) then
    1199            0 :            do ib=1,mbandc
    1200            0 :              trace_tmp = trace_tmp + two*temp*wtk*log(green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol)*omega_current(ifreq))
    1201              :            end do ! ib
    1202              :          else
    1203              :            ! Use Tr(log(G(iw))) + Tr(log(G(-iw))) = Tr(log(G(iw)G(iw)^H)) so that we can use the much faster zheev instead of
    1204              :            ! zgeev. Even if G(iw) and G(iw)^H have no reason to commute, this equality still holds since we only care about the trace.
    1205              :            call abi_xgemm("n","c",mbandc,mbandc,mbandc,cone,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol), &
    1206            0 :                         & mbandc,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol),mbandc,czero,mat_tmp(:,:),mbandc)
    1207            0 :            call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),lwork,rwork(:),info)
    1208              :            ! Do not use DOT_PRODUCT
    1209            0 :            trace_tmp = trace_tmp + sum(log(eig(:)*omega_current(ifreq)))*wtk*temp
    1210              :          end if ! optself
    1211              :        end do ! ikpt
    1212              :      end do ! isppol
    1213            0 :      if (nsppol == 1 .and. nspinor == 1) trace_tmp = trace_tmp * two
    1214            0 :      green%trace_log = green%trace_log + dble(trace_tmp)
    1215              :    end do ! ifreq
    1216            0 :    call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.true.)
    1217              :  end if ! optlog=1
    1218              : 
    1219            0 :  if (green%w_type /= "real") then
    1220              :    ABI_NVTX_START_RANGE(NVTX_DMFT_ADD_INT_FCT)
    1221            0 :    occup_ks    => green%occup%ks
    1222            0 :    ks          => green_oper_ndat%ks
    1223            0 :    if(gpu_option==ABI_GPU_DISABLED) then
    1224            0 :      do ifreq=ifreq_beg,ifreq_end
    1225              : 
    1226            0 :        do isppol=1,nsppol
    1227            0 :          do ikpt=1,mkmem
    1228            0 :            do ib1=1,mbandc
    1229            0 :              idat=ifreq-(ifreq_end-ndat)
    1230            0 :              if (diag == 1) then
    1231              :                green%occup%ks(ib1,ib1,ikpt+shift,isppol) = green%occup%ks(ib1,ib1,ikpt+shift,isppol) + &
    1232            0 :                   & fac(ifreq)*green_oper_ndat%ks(ib1,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
    1233              :              else
    1234            0 :                do ib=1,mbandc
    1235              :                  green%occup%ks(ib,ib1,ikpt+shift,isppol) = green%occup%ks(ib,ib1,ikpt+shift,isppol) + &
    1236            0 :                    & fac(ifreq)*green_oper_ndat%ks(ib,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
    1237              :                end do ! ib
    1238              :              end if ! diag
    1239              :            end do ! ib1
    1240              :          end do ! ikpt
    1241              :        end do ! isppol
    1242              : 
    1243              :      end do ! ifreq
    1244              :    else if(gpu_option==ABI_GPU_OPENMP) then
    1245              : #ifdef HAVE_OPENMP_OFFLOAD
    1246              :      if (diag == 1) then
    1247              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1248              :        !$OMP& MAP(tofrom:occup_ks) MAP(to:ks,fac) PRIVATE(isppol,ikpt)
    1249              :        do isppol=1,nsppol
    1250              :          do ikpt=1,mkmem
    1251              :            !$OMP PARALLEL DO PRIVATE(ib1,ifreq,idat)
    1252              :            do ib1=1,mbandc
    1253              :              do ifreq=ifreq_beg,ifreq_end
    1254              :                idat=ifreq-(ifreq_end-ndat)
    1255              :                occup_ks(ib1,ib1,ikpt+shift,isppol) = occup_ks(ib1,ib1,ikpt+shift,isppol) + &
    1256              :                  & fac(ifreq)*ks(ib1,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
    1257              :              end do ! ifreq
    1258              :            end do ! ib1
    1259              :          end do ! ikpt
    1260              :        end do ! isppol
    1261              : 
    1262              :      else
    1263              : 
    1264              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(3) &
    1265              :        !$OMP& MAP(tofrom:occup_ks) MAP(to:ks,fac) PRIVATE(isppol,ikpt,ib1)
    1266              :        do isppol=1,nsppol
    1267              :          do ikpt=1,mkmem
    1268              :            do ib1=1,mbandc
    1269              :              !$OMP PARALLEL DO PRIVATE(ib,ifreq,idat)
    1270              :              do ib=1,mbandc
    1271              :                do ifreq=ifreq_beg,ifreq_end
    1272              :                  idat=ifreq-(ifreq_end-ndat)
    1273              :                  occup_ks(ib,ib1,ikpt+shift,isppol) = occup_ks(ib,ib1,ikpt+shift,isppol) + &
    1274              :                    & fac(ifreq)*ks(ib,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
    1275              :                end do ! ib
    1276              :              end do ! ib1
    1277              :            end do ! ikpt
    1278              :          end do ! isppol
    1279              :        end do ! ifreq
    1280              : 
    1281              :      end if ! diag
    1282              : #endif
    1283              :    end if
    1284              :    ABI_NVTX_END_RANGE()
    1285              :  end if ! w_type/="real"
    1286              : 
    1287            0 :  if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
    1288              :    call downfold_oper(green_oper_ndat,paw_dmft,&
    1289            0 :    &    procb=green%distrib%procb(:),iproc=me_kpt,option=option,gpu_option=gpu_option)
    1290              :  end if ! lchipsiortho=1
    1291              : 
    1292              :  call copy_oper_from_ndat(green_oper_ndat,green%oper,ndat,green%nw,green%distrib%proct,&
    1293            0 :  &    green%distrib%me_freq,green%oper(ifreq_beg)%has_operks /= 0)
    1294              : 
    1295            0 :  do ifreq=1,green%nw
    1296            0 :    if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
    1297            0 :    if (green%oper(ifreq)%has_operks == 0) then
    1298            0 :      ABI_FREE(green%oper(ifreq)%ks)
    1299              :    end if
    1300              :  end do ! ifreq
    1301              : 
    1302            0 :  call destroy_oper(green_oper_ndat)
    1303            0 :  ABI_FREE(omega_current)
    1304            0 :  ABI_FREE(fac)
    1305              : 
    1306              :  ABI_NVTX_END_RANGE()
    1307              : 
    1308            0 : end subroutine compute_green_batched_core
    1309              : !!***
    1310              : 
    1311              : !!****f* m_green/compute_green
    1312              : !! NAME
    1313              : !! compute_green
    1314              : !!
    1315              : !! FUNCTION
    1316              : !! compute green function from DFT and self-energy
    1317              : !!
    1318              : !! INPUTS
    1319              : !!  green  <type(green_type)>= green function data
    1320              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    1321              : !!  prtopt : option for printing
    1322              : !!  self <type(self_type)>= variables related to self-energy
    1323              : !!  opt_self = optional argument, if =1, upfold self-energy
    1324              : !!  opt_nonxsum = 0 : do usual xsum after calculation of green(freq)%ks
    1325              : !!              = 1 : do not do xsum after calculation of green(freq)%ks: each proc as only a part
    1326              : !!                    of the data: this is useful where only the total number of electron will be computed.
    1327              : !!  opt_nonxsum2 0 : green(ifreq)%matlu will be broadcasted
    1328              : !!               1 : green(ifreq)%matlu will not be broadcasted in compute_green: calc
    1329              : !!                   if occupations will not possible.
    1330              : !!                   (a keyword: compute_local_green would be in fact equivalent and more clear)
    1331              : !!  opt_log = if 1, compute Tr(log(G))
    1332              : !!  opt_restart_moments = if 1, activate quick restart for calculation of the high frequency moments
    1333              : !!                        (useful when compute_green is called after fermi_green)
    1334              : !!
    1335              : !! OUTPUT
    1336              : !!
    1337              : !! SOURCE
    1338              : 
    1339         4884 : subroutine compute_green(green,paw_dmft,prtopt,self,opt_self,opt_nonxsum,opt_nonxsum2,opt_log,opt_restart_moments)
    1340              : 
    1341              : !Arguments ------------------------------------
    1342              :  type(green_type), intent(inout) :: green
    1343              :  type(paw_dmft_type), intent(in) :: paw_dmft
    1344              :  !type(MPI_type), intent(in) :: mpi_enreg
    1345              :  type(self_type), intent(inout) :: self
    1346              :  integer, intent(in) :: prtopt
    1347              :  integer, optional, intent(in) :: opt_log,opt_nonxsum,opt_nonxsum2,opt_restart_moments,opt_self
    1348              : !Local variables-------------------------------
    1349              :  !logical :: lintegrate
    1350              :  integer :: band_index,diag,i,ib,ierr,ifreq,ikpt,info,isppol,lwork,mbandc
    1351              :  integer :: me_kpt,mkmem,myproc,natom,nband_k,nkpt,nmoments,nspinor,nsppol
    1352              :  integer :: opt_quick_restart,option,optlog,optnonxsum,optnonxsum2,optself
    1353              :  integer :: shift,shift_green,spacecomm,gpu_option
    1354              :  real(dp) :: beta,correction,eigen,fac,fermilevel,freq2,temp,wtk
    1355              :  complex(dp) :: green_tmp,omega_current,trace_tmp
    1356              :  character(len=500) :: message
    1357              :  real(dp) :: tsec(2)
    1358         4884 :  real(dp), allocatable :: eig(:),rwork(:)
    1359         4884 :  complex(dp), allocatable :: mat_tmp(:,:),omega_fac(:),work(:)
    1360              : #ifdef HAVE_OPENMP_OFFLOAD
    1361              :  integer :: ndat
    1362              :  type(oper_type), target :: green_oper_ndat
    1363              : #endif
    1364              : ! integer, allocatable :: procb(:,:),proct(:,:)
    1365              : ! *********************************************************************
    1366              : 
    1367              :  ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_GREEN)
    1368              :  !lintegrate=.true.
    1369              :  !if(lintegrate.and.green%w_type=="real") then
    1370              :  !if(green%w_type=="real") then
    1371              :  !  message = 'integrate_green not implemented for real frequency'
    1372              :  !  ABI_BUG(message)
    1373              :  !endif
    1374         4884 :  call timab(624,1,tsec(:))
    1375         4884 :  optself = 0
    1376         4884 :  if (present(opt_self)) optself = opt_self
    1377         4884 :  optnonxsum = 0
    1378         4884 :  if (present(opt_nonxsum)) optnonxsum = opt_nonxsum
    1379         4884 :  optnonxsum2 = 0
    1380         4884 :  if (present(opt_nonxsum2)) optnonxsum2 = opt_nonxsum2
    1381         4884 :  optlog = 0
    1382         4884 :  if (present(opt_log)) optlog = opt_log
    1383         4884 :  opt_quick_restart = 0
    1384         4884 :  if (present(opt_restart_moments)) opt_quick_restart = opt_restart_moments
    1385              : 
    1386         4884 :  diag = 1 - optself
    1387              : 
    1388         4884 :  if (prtopt > 0) then
    1389          434 :    write(message,'(2a)') ch10," ===  Compute Green's function "
    1390          434 :    call wrtout(std_out,message,'COLL')
    1391              :  end if ! prtopt>0
    1392              : 
    1393         4884 :  if (self%nw /= green%nw) then
    1394            0 :    message = ' BUG: frequencies for green and self not coherent'
    1395            0 :    ABI_BUG(message)
    1396              :  end if
    1397              : 
    1398              : ! Initialise spaceComm, myproc, and nproc
    1399         4884 :  me_kpt = green%distrib%me_kpt
    1400         4884 :  myproc = paw_dmft%myproc
    1401              :  !nproc     = paw_dmft%nproc
    1402         4884 :  spacecomm = paw_dmft%spacecomm
    1403              : 
    1404              : ! Initialise integers
    1405              :  !mband   = paw_dmft%mband
    1406         4884 :  mbandc  = paw_dmft%mbandc
    1407         4884 :  natom   = paw_dmft%natom
    1408         4884 :  nkpt    = paw_dmft%nkpt
    1409         4884 :  nspinor = paw_dmft%nspinor
    1410         4884 :  nsppol  = paw_dmft%nsppol
    1411         4884 :  temp    = paw_dmft%temp
    1412         4884 :  gpu_option = paw_dmft%gpu_option
    1413              : 
    1414         4884 :  if (optlog == 1) then
    1415            0 :    ABI_MALLOC(eig,(mbandc))
    1416            0 :    ABI_MALLOC(work,(2*mbandc-1))
    1417            0 :    ABI_MALLOC(rwork,(3*mbandc-2))
    1418            0 :    ABI_MALLOC(mat_tmp,(mbandc,mbandc))
    1419            0 :    call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),-1,rwork(:),info)
    1420            0 :    lwork = int(work(1))
    1421            0 :    ABI_FREE(work)
    1422            0 :    ABI_MALLOC(work,(lwork))
    1423            0 :    green%trace_log = zero
    1424              :  end if ! optlog=1
    1425              : 
    1426              :  !icomp_chloc = 0
    1427              : 
    1428              :  option = 1
    1429         4884 :  fermilevel = paw_dmft%fermie
    1430              :  if (option == 123) then
    1431              :    fermilevel = two
    1432              :    write(message,'(2a,e14.3,a)') ch10,'  Warning (special case for check: fermi level=',fermilevel,')'
    1433              :    call wrtout(std_out,message,'COLL')
    1434              :  end if ! option=123
    1435              : 
    1436         4884 :  option = merge(3,1,diag==1) ! option for downfold_oper
    1437              : 
    1438              : ! ====================================================
    1439              : ! Upfold self-energy and double counting  Self_imp -> self(k)
    1440              : ! ====================================================
    1441              : ! if(optself==1) then
    1442              : !   do ifreq=1,green%nw
    1443              : !     call upfold_oper(self%oper(ifreq),paw_dmft,1)
    1444              : !   enddo ! ifreq
    1445              : !   call upfold_oper(self%hdc,paw_dmft,1)
    1446              : ! endif
    1447              : 
    1448              : ! ================================
    1449              : ! == Compute Green function G(k)
    1450              : ! ================================
    1451      7124010 :  green%occup%ks(:,:,:,:) = czero
    1452              : 
    1453         4884 :  nmoments = 1
    1454         4884 :  if (green%has_moments == 1) then
    1455            0 :    nmoments = green%nmoments
    1456              :    call compute_moments_ks(green,self,paw_dmft,opt_self=optself,opt_log=optlog, &
    1457            0 :                          & opt_quick_restart=opt_quick_restart)
    1458            0 :    if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
    1459            0 :      call downfold_oper(green%moments(1),paw_dmft,option=2)
    1460            0 :      do i=2,green%nmoments
    1461            0 :        call downfold_oper(green%moments(i),paw_dmft,option=option)
    1462              :      end do ! i
    1463            0 :      do i=1,green%nmoments
    1464            0 :        call xmpi_matlu(green%moments(i)%matlu(:),natom,green%distrib%comm_kpt)
    1465            0 :        call sym_matlu(green%moments(i)%matlu(:),paw_dmft)
    1466              :      end do ! i
    1467              :    end if ! lchipsiortho=1
    1468              :  end if ! moments
    1469              : 
    1470         4884 :  if (green%w_type /= "real") then
    1471        14640 :    ABI_MALLOC(omega_fac,(nmoments))
    1472         9760 :    do i=1,nmoments
    1473         4880 :      omega_fac(i) = czero
    1474       991739 :      do ifreq=green%nw,1,-1 ! NEVER change the summation order and DON'T use the intrinsic SUM
    1475       991739 :        omega_fac(i) = omega_fac(i) + paw_dmft%wgt_wlo(ifreq) / (paw_dmft%omega_lo(ifreq))**i
    1476              :      end do
    1477         4880 :      omega_fac(i) = - two * temp * omega_fac(i) / (j_dpc)**i
    1478         4880 :      if (i == 1) omega_fac(i) = omega_fac(i) + half
    1479         4880 :      if (i == 2) omega_fac(i) = omega_fac(i) - cone/(four*temp)
    1480         9760 :      if (i == 4) omega_fac(i) = omega_fac(i) + cone/(dble(48)*(temp**3))
    1481              :    end do ! i
    1482              :  end if ! w_type
    1483              : 
    1484         4884 :  shift = green%distrib%shiftk
    1485         4884 :  mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
    1486         4884 :  shift_green = merge(0,shift,green%oper(1)%has_operks==0)
    1487              : 
    1488              : 
    1489         4884 :  if(mkmem>0 .and. gpu_option==ABI_GPU_OPENMP) then
    1490            0 :    call compute_green_batched_core(green,paw_dmft,self,optself,optlog)
    1491         4884 :  else if(mkmem>0) then
    1492              :    ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_GREEN_LOOP)
    1493              : ! Initialise for compiler
    1494         4763 :  omega_current = czero
    1495       999750 :  do ifreq=1,green%nw
    1496              :    !if(present(iii)) write(6,*) ch10,'ifreq  self', ifreq,self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
    1497              : !   ====================================================
    1498              : !   First Upfold self-energy and double counting  Self_imp -> self(k)
    1499              : !   ====================================================
    1500              : !   if(mod(ifreq-1,nproc)==myproc) then
    1501              : !    write(6,*) "compute_green ifreq",ifreq, mod(ifreq-1,nproc)==myproc,proct(ifreq,myproc)==1
    1502       994987 :    if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
    1503       994987 :    if (green%w_type == "imag") then
    1504       982987 :      omega_current = cmplx(zero,green%omega(ifreq),kind=dp)
    1505       982987 :      fac = two * paw_dmft%wgt_wlo(ifreq) * temp
    1506        12000 :    else if (green%w_type == "real") then
    1507        12000 :      omega_current = cmplx(green%omega(ifreq),paw_dmft%temp,kind=dp)
    1508              :    end if ! green%w_type
    1509              : 
    1510       994987 :    if (green%oper(ifreq)%has_operks == 0) then
    1511      5897922 :      ABI_MALLOC(green%oper(ifreq)%ks,(mbandc,mbandc,mkmem,nsppol))
    1512       982987 :      green%oper(ifreq)%nkpt   = mkmem
    1513       982987 :      green%oper(ifreq)%paral  = 1
    1514       982987 :      green%oper(ifreq)%shiftk = shift
    1515              :    end if
    1516              : 
    1517       994987 :    if (optself == 0) then
    1518     24492174 :      green%oper(ifreq)%ks(:,:,:,:) = czero
    1519              :    else
    1520       949905 :      call add_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),green%oper(ifreq)%matlu(:),natom,-1)
    1521              : ! do iatom = 1 , natom
    1522              :    !write(6,*) 'self matlu', ifreq, self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
    1523              :    !write(6,*) 'self hdc  ', ifreq, self%hdc%matlu(1)%mat(1,1,1,1,1)
    1524              :    !write(6,*) 'self_minus_hdc_oper  ', ifreq, self_minus_hdc_oper%matlu(1)%mat(1,1,1,1,1)
    1525              : ! enddo ! natom
    1526              :      !if(paw_dmft%dmft_solv==4)  then
    1527              :      !  call shift_matlu(self_minus_hdc_oper%matlu,paw_dmft%natom,cmplx(self%qmc_shift,0.d0,kind=dp),-1)
    1528              :      !  call shift_matlu(self_minus_hdc_oper%matlu,paw_dmft%natom,cmplx(self%qmc_xmu,0.d0,kind=dp),-1)
    1529              :      !endif
    1530       949905 :      call upfold_oper(green%oper(ifreq),paw_dmft,procb=green%distrib%procb(:),iproc=me_kpt)
    1531              :    end if ! optself
    1532              : 
    1533      2670781 :    do isppol=1,nsppol
    1534     11483801 :      do ikpt=1,mkmem
    1535     68181838 :        do ib=1,mbandc
    1536     57693024 :          green_tmp = omega_current + fermilevel - paw_dmft%eigen_dft(ib,ikpt+shift,isppol)
    1537     66506044 :          if (optself == 0) then
    1538      2856368 :            green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol) = cone / green_tmp
    1539              :          else
    1540              :            green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol) = &
    1541     54836656 :              & green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol) + green_tmp
    1542              :          end if
    1543              :        end do ! ib
    1544              :      end do ! ikpt
    1545              :    end do ! isppol
    1546              : 
    1547              :     ! do ib1 = 1 , paw_dmft%mbandc
    1548              :     !   do ib = 1 , paw_dmft%mbandc
    1549              :     !     do ikpt = 1 , paw_dmft%nkpt
    1550              :     !       do is = 1 , paw_dmft%nsppol
    1551              :     !         if (green%procb(ifreq,ikpt)==myproc) then
    1552              : !               green%oper(ifreq)%ks(is,ikpt,ib,ib1)=       &
    1553              :     !           green_temp%ks(is,ikpt,ib,ib1)=       &
    1554              : !&               ( omega_current     &
    1555              : !&               + fermilevel                               &
    1556              : !&               - paw_dmft%eigen_dft(is,ikpt,ib)) * Id(ib,ib1) &
    1557              : !&               - self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
    1558              :           !if(ikpt==2.and.ib==ib1) then
    1559              :           !  write(6,*)
    1560              :           !  "self",ib1,ib,ikpt,is,ifreq,self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
    1561              :           !endif
    1562              : !&               -
    1563              : !(self%oper(ifreq)%ks(is,ikpt,ib,ib1)-self%hdc%ks(is,ikpt,ib,ib1))
    1564              : !               if(prtopt>5) then
    1565              : !               if(ikpt==1.and.(ifreq==1.or.ifreq==3).and.ib==16.and.ib1==16)
    1566              : !               then
    1567              : !                write(std_out,*) 'omega_current
    1568              : !                ',omega_current
    1569              : !                write(std_out,*) 'fermilevel
    1570              : !                ',fermilevel
    1571              : !                write(std_out,*) ' paw_dmft%eigen_dft(is,ikpt,ib)       ',
    1572              : !                paw_dmft%eigen_dft(is,ikpt,ib),Id(ib,ib1)
    1573              : !                write(std_out,*)
    1574              : !                'self_minus_hdc_oper%ks(is,ikpt,ib,ib1)',self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
    1575              : !                write(std_out,*) 'green
    1576              : !                ',green%oper(ifreq)%ks(is,ikpt,ib,ib1)
    1577              : !               endif
    1578              : !               if(ib==1.and.ib1==3) then
    1579              : !                 write(std_out,*) "ff compute",ikpt,ifreq,is,ikpt,ib,ib1
    1580              : !                 write(std_out,*) "ff compute",ikpt,ifreq,
    1581              : !                 green_temp%ks(is,ikpt,ib,ib1)
    1582              : !                 write(std_out,*) "ff details",paw_dmft%eigen_dft(is,ikpt,ib)
    1583              : !                 write(std_out,*) "ff details2",fermilevel
    1584              : !                 write(std_out,*) "ff details3",Id(ib,ib1)
    1585              : !        !        write(std_out,*) "ff
    1586              : !        details4",self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
    1587              : !               endif
    1588              :         !     endif
    1589              :         !   enddo ! is
    1590              :         ! enddo ! ikpt
    1591              :        !enddo ! ib
    1592              :      !enddo ! ib1
    1593              : 
    1594              : !     call print_oper(green%oper(ifreq),9,paw_dmft,3)
    1595              : !       write(std_out,*) 'after print_oper'
    1596              : !     if(ifreq==1.or.ifreq==3) then
    1597              : !         write(std_out,*) 'after print_oper', ifreq
    1598              : !       write(std_out,*) 'green1  ifreq         %ks(1,1,16,16)',ifreq,green%oper(ifreq)%ks(1,1,16,16)
    1599              : !     endif
    1600              : !       write(std_out,*) 'before inverse_oper'
    1601       994987 :    if (optself /= 0) then
    1602       949905 :      call inverse_oper(green%oper(ifreq),1,procb=green%distrib%procb(:),iproc=me_kpt)
    1603              :    end if
    1604              :     !if(ifreq==1) then
    1605              :     !  write(std_out,*) "1188",green_temp%ks(1,1,8,8)
    1606              :     !  write(std_out,*) "1189",green_temp%ks(1,1,8,9)
    1607              :     !  write(std_out,*) "1198",green_temp%ks(1,1,9,8)
    1608              :     !  write(std_out,*) "1199",green_temp%ks(1,1,9,9)
    1609              :     !endif
    1610       994987 :    if (optlog == 1) then
    1611            0 :      freq2 = paw_dmft%omega_lo(ifreq)**2
    1612            0 :      trace_tmp = czero
    1613            0 :      do isppol=1,nsppol
    1614            0 :        do ikpt=1,mkmem
    1615            0 :          wtk = green%oper(ifreq)%wtk(ikpt+shift)
    1616            0 :          if (optself == 0) then
    1617            0 :            do ib=1,mbandc
    1618            0 :              trace_tmp = trace_tmp + two*temp*wtk*log(green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol)*omega_current)
    1619              :            end do ! ib
    1620              :          else
    1621              :            ! Use Tr(log(G(iw))) + Tr(log(G(-iw))) = Tr(log(G(iw)G(iw)^H)) so that we can use the much faster zheev instead of
    1622              :            ! zgeev. Even if G(iw) and G(iw)^H have no reason to commute, this equality still holds since we only care about the trace.
    1623              :            call abi_xgemm("n","c",mbandc,mbandc,mbandc,cone,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol), &
    1624            0 :                         & mbandc,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol),mbandc,czero,mat_tmp(:,:),mbandc)
    1625            0 :            call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),lwork,rwork(:),info)
    1626              :            ! Do not use DOT_PRODUCT
    1627            0 :            trace_tmp = trace_tmp + sum(log(eig(:)*freq2))*wtk*temp
    1628              :          end if ! optself
    1629              :        end do ! ikpt
    1630              :      end do ! isppol
    1631            0 :      if (nsppol == 1 .and. nspinor == 1) trace_tmp = trace_tmp * two
    1632            0 :      green%trace_log = green%trace_log + dble(trace_tmp)
    1633              :    end if ! optlog=1
    1634              : 
    1635              :      !if(lintegrate) then
    1636              : !    accumulate integration
    1637       994987 :    if (green%w_type /= "real") then
    1638              : 
    1639              :      !do isppol=1,nsppol
    1640              :      !  do ikpt=1,nkpt
    1641              :      !    if (green%distrib%procb(ikpt+(isppol-1)*nkpt) /= me_spkpt) cycle
    1642              : 
    1643              :          !do ib1=1,mbandc
    1644              :          !  do ib=1,mbandc
    1645              :               ! if (green%procb(ifreq,ikpt)==myproc) then
    1646              :           !   call
    1647              :           !   add_int_fct(ifreq,green%oper(ifreq)%ks(ib,ib1,ikpt,isppol),ib==ib1,
    1648              :           !   &
    1649              :           !         & omega_current,2,green%occup%ks(ib,ib1,ikpt,isppol), &
    1650              :           !         & paw_dmft%temp,paw_dmft%wgt_wlo(ifreq),paw_dmft%dmft_nwlo)
    1651              : 
    1652              :                !endif
    1653              :          !  end do ! ib
    1654              :          !end do ! ib1
    1655              :      !  end do ! ikpt
    1656              :      !end do ! isppol
    1657              : 
    1658       982987 :      if (diag == 1) then
    1659       402510 :        do ib=1,mbandc
    1660              :          green%occup%ks(ib,ib,1+shift:mkmem+shift,:) = green%occup%ks(ib,ib,1+shift:mkmem+shift,:) + &
    1661      3835334 :                  & fac*green%oper(ifreq)%ks(ib,ib,1+shift_green:mkmem+shift_green,:)
    1662              :        end do ! ib
    1663              :      else
    1664              :        green%occup%ks(:,:,1+shift:mkmem+shift,:) = green%occup%ks(:,:,1+shift:mkmem+shift,:) + &
    1665    492153235 :           & fac*green%oper(ifreq)%ks(:,:,1+shift_green:mkmem+shift_green,:)
    1666              :      end if ! diag
    1667              : 
    1668              :    end if ! green%wtype
    1669              : 
    1670              : !        write(std_out,*) 'after inverse_oper'
    1671              : !      if(ikpt==1.and.is==1.and.ib==1.and.ib1==1) then
    1672              : !        write(6,*) 'occup(is,ikpt,ib,ib1)',ifreq,green%occup%ks(1,1,1,1),green_temp%ks(1,1,1,1)
    1673              : !      endif
    1674              : !        write(std_out,*) 'green1afterinversion  %ks(1,1,16,16)',ifreq,green%oper(ifreq)%ks(1,1,16,16)
    1675              : !      endif
    1676              : !        write(std_out,*) 'before flush'
    1677              : !      call flush(std_out)
    1678              :      !endif
    1679              : ! ================================
    1680              : ! == Compute Local Green function
    1681              : ! ================================
    1682              :    !write(message,'(2a)') ch10,' loc'
    1683              :    !call wrtout(std_out,message,'COLL')
    1684              :    !call flush(std_out)
    1685       994987 :    if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
    1686       972414 :      call downfold_oper(green%oper(ifreq),paw_dmft,procb=green%distrib%procb(:),iproc=me_kpt,option=option)
    1687              :     !if(ifreq==1) then
    1688              :     !  write(std_out,*) "4411",green_temp%matlu(1)%mat(4,4,1,1,1)
    1689              :     !  write(std_out,*) "4512",green_temp%matlu(1)%mat(4,5,1,1,2)
    1690              :     !  write(std_out,*) "5421",green_temp%matlu(1)%mat(5,4,1,2,1)
    1691              :     !  write(std_out,*) "5522",green_temp%matlu(1)%mat(5,5,1,2,2)
    1692              :     !  write(std_out,*) "(5512)",green_temp%matlu(1)%mat(5,5,1,1,2)
    1693              :     !endif
    1694              : !     write(std_out,*) ifreq,nproc,'before if after loc_oper'
    1695              : !     if(ifreq==1.or.ifreq==11) then
    1696              : !       write(std_out,*) ifreq,nproc,'before sym'
    1697              : !       call print_matlu(green%oper(ifreq)%matlu,green%oper(ifreq)%natom,2,-1,0)
    1698              : !       ! ok
    1699              : !     endif
    1700              : ! call flush(std_out)
    1701              :    end if ! lchipsiortho=1
    1702              :      !call copy_matlu(green_temp%matlu,green%oper(ifreq)%matlu,natom)
    1703              : !     if(ifreq==1.and.ifreq==11) then
    1704              : !       write(std_out,*) ifreq,nproc,'after sym'
    1705              : !       call print_matlu(green%oper(ifreq)%matlu,green%oper(ifreq)%natom,2,-1,0)
    1706              : !       ! ok
    1707              : !     endif
    1708       999750 :    if (green%oper(ifreq)%has_operks == 0) then
    1709       982987 :      ABI_FREE(green%oper(ifreq)%ks)
    1710              :    end if
    1711              : ! call flush(std_out)
    1712              :  end do ! ifreq
    1713              :    ABI_NVTX_END_RANGE()
    1714              :  end if
    1715              : 
    1716              : 
    1717         4884 :  if (optlog == 1) then
    1718              : 
    1719            0 :    ABI_FREE(eig)
    1720            0 :    ABI_FREE(work)
    1721            0 :    ABI_FREE(rwork)
    1722            0 :    ABI_FREE(mat_tmp)
    1723              : 
    1724            0 :    call xmpi_sum(green%trace_log,spacecomm,ierr)
    1725              : 
    1726            0 :    correction = - log(two) * mbandc * nsppol * temp
    1727              : 
    1728            0 :    band_index = 0
    1729            0 :    beta = one / paw_dmft%temp
    1730            0 :    do isppol=1,nsppol
    1731            0 :      do ikpt=1,nkpt
    1732            0 :        nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
    1733            0 :        do ib=1,nband_k
    1734            0 :          if (paw_dmft%band_in(ib)) cycle
    1735            0 :          eigen = paw_dmft%eigen(ib+band_index)
    1736            0 :          if (eigen-fermilevel >= zero) then
    1737            0 :            correction = correction - temp*paw_dmft%wtk(ikpt)*log(one+exp(-beta*(eigen-fermilevel)))
    1738              :          else
    1739            0 :            correction = correction - temp*paw_dmft%wtk(ikpt)*(log(one+exp(beta*(eigen-fermilevel)))-beta*(eigen-fermilevel))
    1740              :          end if ! eigen-fermilevel>=0
    1741              :        end do ! ib
    1742            0 :        band_index = band_index + nband_k
    1743              :      end do ! ikpt
    1744              :    end do ! isppol
    1745            0 :    if (nsppol == 1 .and. nspinor == 1) correction = correction * two
    1746              : 
    1747              :    ! Do not use DOT_PRODUCT
    1748              :    green%trace_log = green%trace_log + correction + fermilevel*paw_dmft%nelectval + &
    1749            0 :       & dble(sum(green%trace_moments_log_ks(1:nmoments-1)*omega_fac(1:nmoments-1)))
    1750              : 
    1751              :  end if ! optlog=1
    1752              : 
    1753              : ! =============================================
    1754              : ! Build total green function (sum over procs).
    1755              : ! =============================================
    1756              :  !call xmpi_barrier(spacecomm)
    1757              : !  call xmpi_sum(green%oper(ifreq)%ks,spacecomm,ierr)
    1758              : !       print *, "myproc, proct, ifreq ------------------- ", myproc, ifreq
    1759              : !   do ikpt=1,paw_dmft%nkpt
    1760              : !     call xmpi_bcast(green%oper(ifreq)%ks(:,ikpt,:,:),procb(ifreq,ikpt),spacecomm,ierr)
    1761              : !   enddo
    1762              : !! or
    1763         4884 :  if (optnonxsum == 0 .and. green%oper(1)%has_operks == 1) then
    1764            4 :    call gather_oper(green%oper(:),green%distrib,paw_dmft,opt_ksloc=1,opt_diag=diag)
    1765            0 :  else if (optnonxsum == 0 .and. green%oper(1)%has_operks == 0) then
    1766            0 :    message = 'optnonxsum=0 and green%oper(1)%has_operks=0: not compatible'
    1767            0 :    ABI_BUG(message)
    1768              :  end if ! optnonxsum
    1769              : !   endif
    1770              : ! enddo ! ifreq
    1771              : !  print *,"myproc", myproc
    1772         4884 :  if (optnonxsum2 == 0) then
    1773          681 :    if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
    1774          587 :      call gather_oper(green%oper(:),green%distrib,paw_dmft,opt_ksloc=2,opt_commkpt=1)
    1775              : 
    1776          587 :      if(gpu_option==ABI_GPU_DISABLED) then
    1777       149153 :        do ifreq=1,green%nw
    1778       148566 :          if (green%distrib%procf(ifreq) /= myproc) cycle
    1779       149153 :          call sym_matlu(green%oper(ifreq)%matlu(:),paw_dmft)
    1780              :        end do
    1781              :      else if(gpu_option==ABI_GPU_OPENMP) then
    1782              : #ifdef HAVE_OPENMP_OFFLOAD
    1783              :        !FIXME: Remove those CPU-GPU transfers once gather_oper has been ported to GPU
    1784              :        ! 1) Init green_oper_ndat
    1785              :        ndat = green%distrib%nw_mem_kptparal(green%distrib%me_freq+1)
    1786              :        do ifreq=1,green%nw
    1787              :          if (green%distrib%procf(ifreq) /= myproc) cycle
    1788              :          call init_oper_ndat(paw_dmft,green_oper_ndat,ndat,nkpt=green%oper(ifreq)%nkpt,opt_ksloc=2,gpu_option=gpu_option)
    1789              :          if (green%oper(ifreq)%has_operks == 0) then
    1790              :            green_oper_ndat%paral  = 1
    1791              :            green_oper_ndat%shiftk = shift
    1792              :          end if
    1793              :          exit
    1794              :        end do
    1795              :        ! 2) Copy green%oper(:)%matlu into green_oper_ndat (CPU->GPU transfer)
    1796              :        call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.false.)
    1797              : 
    1798              :        ! 3) Perform sym_matlu on green_oper_ndat (GPU enabled)
    1799              :        call sym_matlu(green_oper_ndat%matlu(:),paw_dmft)
    1800              : 
    1801              :        ! 4) Copy back green%oper(:)%matlu from green_oper_ndat (GPU->CPU transfer)
    1802              :        call copy_oper_from_ndat(green_oper_ndat,green%oper,ndat,green%nw,green%distrib%proct,&
    1803              :        &    green%distrib%me_freq,.false.)
    1804              :        ! 5) Destroy green_oper_ndat
    1805              :        call destroy_oper(green_oper_ndat)
    1806              : #endif
    1807              :      end if
    1808              : 
    1809          587 :      call gather_oper(green%oper(:),green%distrib,paw_dmft,opt_ksloc=2)
    1810              :    end if
    1811          681 :    green%has_greenmatlu_xsum = 1
    1812         4203 :  else if (optnonxsum2 == 1) then
    1813         4203 :    green%has_greenmatlu_xsum = 0
    1814              :  end if ! optnonxsum2
    1815              : !     if(ifreq==1.or.ifreq==11) then
    1816              : !       write(std_out,*) ifreq,nproc,'after xsum'
    1817              : !       call print_matlu(green%oper(ifreq)%matlu,green%oper(ifreq)%natom,2,-1,0)
    1818              : !       ! ok
    1819              : !     endif
    1820              :  !end do ! ifreq
    1821              :  !call xmpi_barrier(spacecomm)
    1822              : ! write(std_out,*) 'afterxsum sym     %matlu(1)%mat(2,5,1,1,1) 1',green%oper(1)%matlu(1)%mat(2,5,1,1,1)
    1823              : 
    1824         4884 :  if (green%w_type /= "real") then
    1825              : 
    1826         4880 :    if (green%distrib%me_freq == 0) then
    1827              : 
    1828        68179 :      do ib=1,mbandc
    1829       355207 :        green%occup%ks(ib,ib,1+shift:mkmem+shift,:) = green%occup%ks(ib,ib,1+shift:mkmem+shift,:) + omega_fac(1)
    1830              :      end do ! ib
    1831              : 
    1832         4759 :      do i=2,nmoments
    1833         4759 :        if (diag == 1) then
    1834            0 :          do ib=1,mbandc
    1835              :            green%occup%ks(ib,ib,1+shift:mkmem+shift,:) = green%occup%ks(ib,ib,1+shift:mkmem+shift,:) + &
    1836            0 :                 & omega_fac(i)*green%moments(i)%ks(ib,ib,:,:)
    1837              :          end do ! ib
    1838              :        else
    1839              :          green%occup%ks(:,:,1+shift:mkmem+shift,:) = green%occup%ks(:,:,1+shift:mkmem+shift,:) + &
    1840            0 :            & omega_fac(i)*green%moments(i)%ks(:,:,:,:)
    1841              :        end if ! diag
    1842              :      end do ! i
    1843              : 
    1844              :    end if ! me_freq = 0
    1845              : 
    1846         4880 :    call gather_oper_ks(green%occup,green%distrib,paw_dmft,opt_diag=diag)
    1847              : 
    1848              :  end if ! w_type/="real"
    1849              : 
    1850         4884 :  ABI_SFREE(omega_fac)
    1851              : 
    1852         4884 :  if (prtopt /= 0 .and. prtopt > -100) then
    1853          470 :    write(message,'(2a)') ch10," ===  Green's function is computed"
    1854          470 :    call wrtout(std_out,message,'COLL')
    1855              :  end if
    1856              : 
    1857         4884 :  if (prtopt /= 0 .and. prtopt > -100 .and. (paw_dmft%lchipsiortho == 1 .or. optself == 1)) then
    1858          376 :    write(message,'(2a)') ch10,&
    1859          752 :      & " ===  Local Green's function has been computed and projected on local orbitals"
    1860          376 :    call wrtout(std_out,message,'COLL')
    1861              :  end if
    1862              : ! useless test
    1863         4884 :  if (abs(prtopt) >= 4 .and. prtopt > -100) then
    1864            0 :    write(message,'(2a)') ch10," == Green's function is now printed for first frequency"
    1865            0 :    call wrtout(std_out,message,'COLL')
    1866            0 :    call print_oper(green%oper(1),9,paw_dmft,3)
    1867            0 :    write(message,'(2a)') ch10," == Green's function is now printed for second frequency"
    1868            0 :    call wrtout(std_out,message,'COLL')
    1869            0 :    call print_oper(green%oper(2),9,paw_dmft,3)
    1870            0 :    if (paw_dmft%dmft_nwlo >= 11) then
    1871            0 :      write(message,'(2a)') ch10," == Green's function is now printed for 11th frequency"
    1872            0 :      call wrtout(std_out,message,'COLL')
    1873            0 :      call print_oper(green%oper(11),9,paw_dmft,3)
    1874              :    end if
    1875              :  end if
    1876              : ! call flush(std_out)
    1877              : 
    1878              :  ABI_NVTX_END_RANGE()
    1879         4884 :  call timab(624,2,tsec(:))
    1880              : 
    1881         4884 : end subroutine compute_green
    1882              : !!***
    1883              : 
    1884              : !!****f* m_green/integrate_green
    1885              : !! NAME
    1886              : !! integrate_green
    1887              : !!
    1888              : !! FUNCTION
    1889              : !!  Integrate green function
    1890              : !!
    1891              : !! INPUTS
    1892              : !!  green <type(green_type)>=green function  (green%oper(:))
    1893              : !!  paw_dmft <type(m_paw_dmft)>= paw+dmft data
    1894              : !!  prtopt : flag for printing
    1895              : !!  opt_ksloc=   1: only integrate on the KS basis
    1896              : !!               2: do the integration on the local basis
    1897              : !!                 (This can work only if chipsi are renormalized!!!)
    1898              : !!               3: do both calculations and test the consistency of it
    1899              : !!              -1: do the integration on the KS basis, but only
    1900              : !!                      compute diagonal part of the band-band density matrix
    1901              : !!                      in order to compute the total charge for fermi_green
    1902              : !!  opt_after_solver= to be activated after a call to impurity_solve
    1903              : !!  opt_diff= check the change in the local charge compared to the previous iteration
    1904              : !!  opt_fill_occnd= 0 (default) : do not fill paw_dmft%occnd with the Green's function occupations
    1905              : !!                = 1 : fill paw_dmft%occnd with the Green's function occupations
    1906              : !!  opt_self= 0 : assume the green%ks is diagonal
    1907              : !!          = 1 (default) : assume there is a self-energy and green%ks is non-diagonal
    1908              : !!
    1909              : !! OUTPUT
    1910              : !!   green%occup = occupations
    1911              : !!
    1912              : !! SOURCE
    1913              : 
    1914         4984 : subroutine integrate_green(green,paw_dmft,prtopt,opt_ksloc,opt_after_solver,opt_diff,opt_fill_occnd,opt_self)
    1915              : 
    1916              : !Arguments ------------------------------------
    1917              :  type(green_type), intent(inout) :: green
    1918              :  !type(MPI_type), intent(in) :: mpi_enreg
    1919              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    1920              :  integer, intent(in) :: prtopt
    1921              :  integer, optional, intent(in) :: opt_after_solver,opt_diff,opt_fill_occnd,opt_ksloc,opt_self
    1922              : !Local variables-------------------------------
    1923              :  integer :: band_index,i,iatom,ib,ib1,icomp_chloc,ifreq,ikpt,isppol
    1924              :  integer :: lpawu,mbandc,myproc,natom,nband_k,nkpt,nmoments,nspinor
    1925              :  integer :: nsppol,optaftsolv,optdiff,optfilloccnd,option,optksloc,optself,optiondiff
    1926              :  real(dp) :: correction,diff_chloc,fac,temp
    1927              :  character(len=12) :: tag
    1928              :  character(len=500) :: message
    1929              :  real(dp) :: tsec(2)
    1930         4984 :  complex(dp), allocatable :: omega_fac(:),shift(:)
    1931         4984 :  type(matlu_type), allocatable :: matlu_temp(:)
    1932              : ! real(dp), allocatable :: charge_loc_old(:,:)
    1933              : ! type(oper_type)  :: oper_c
    1934              : ! *********************************************************************
    1935              : 
    1936              :  DBG_ENTER("COLL")
    1937         4984 :  call timab(625,1,tsec(:))
    1938              :  ABI_NVTX_START_RANGE(NVTX_DMFT_INTEGRATE_GREEN)
    1939              : 
    1940         4984 :  if (prtopt > 0) then
    1941          582 :    write(message,'(2a,i3,13x,a)') ch10," ===  Integrate Green's function"
    1942          582 :    call wrtout(std_out,message,'COLL')
    1943              :  end if
    1944         4984 :  if (green%w_type == "real") then
    1945            0 :    message = 'integrate_green not implemented for real frequency'
    1946            0 :    ABI_BUG(message)
    1947              :  end if
    1948              : 
    1949         4984 :  optfilloccnd = 0
    1950         4984 :  if (present(opt_fill_occnd)) optfilloccnd = opt_fill_occnd
    1951              : 
    1952         4984 :  optself = 1
    1953         4984 :  if (present(opt_self)) optself = opt_self
    1954          279 :  option = merge(3,1,optself==0) ! option for downfold_oper
    1955              : 
    1956              : ! Initialize spaceComm, myproc, and master
    1957              :  !spacecomm=paw_dmft%spacecomm
    1958         4984 :  myproc = paw_dmft%myproc
    1959              :  !nproc=paw_dmft%nproc
    1960              : 
    1961              : ! Initialise integers
    1962              :  !mband   = paw_dmft%mband
    1963         4984 :  mbandc  = paw_dmft%mbandc
    1964         4984 :  natom   = paw_dmft%natom
    1965         4984 :  nkpt    = paw_dmft%nkpt
    1966         4984 :  nspinor = paw_dmft%nspinor
    1967         4984 :  nsppol  = paw_dmft%nsppol
    1968         4984 :  temp    = paw_dmft%temp
    1969              : 
    1970         4984 :  nmoments = merge(green%nmoments,1,green%has_moments==1)
    1971              : 
    1972              : ! Initialize green%oper before calculation (important for xmpi_sum)
    1973              : ! allocate(charge_loc_old(paw_dmft%natom,paw_dmft%nsppol+1))
    1974              : ! if(.not.present(opt_diff)) then  ! if integrate_green is called in m_dmft after calculation of self
    1975              : !   charge_loc_old=green%charge_matlu
    1976              : ! endif
    1977         4984 :  icomp_chloc = 0
    1978         4984 :  optdiff = 0
    1979         4984 :  if (present(opt_diff)) optdiff = opt_diff
    1980              : 
    1981              : ! Choose what to compute
    1982         4984 :  optksloc = 3
    1983         4984 :  if (present(opt_ksloc)) optksloc = opt_ksloc
    1984         4984 :  optaftsolv = 0
    1985         4984 :  if (present(opt_after_solver)) optaftsolv = opt_after_solver
    1986              : 
    1987          103 :  if (optaftsolv == 1 .and. abs(optksloc) /= 2) then
    1988            0 :     message = "integration of ks green function should not be done after call to solver : it has not been computed"
    1989            0 :     ABI_BUG(message)
    1990              :  end if
    1991              : 
    1992         4984 :  if (abs(optksloc) >= 2 .and. green%has_greenmatlu_xsum == 0) then
    1993            0 :    write(message,'(4a)') ch10,&
    1994            0 :       & "BUG: integrate_green is asked to integrate local green function",ch10,&
    1995            0 :       & " and local green function was non broadcasted in compute_green"
    1996            0 :     ABI_BUG(message)
    1997              :  end if
    1998              : 
    1999              : ! Allocations
    2000        33684 :  ABI_MALLOC(matlu_temp,(natom))
    2001         4984 :  call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),matlu_temp(:))
    2002              : 
    2003              : ! =================================================
    2004              : ! == Integrate Local Green function ===============
    2005         4984 :  if (abs(optksloc)/2 == 1) then ! optksloc=2 or 3
    2006              : ! =================================================
    2007              : 
    2008              : ! ==  Calculation of \int{G_{LL'}{\sigma\sigma',s}(R)(i\omega_n)}
    2009          781 :    if (paw_dmft%lchipsiortho == 1) then
    2010              : !  - Calculation of frequency sum over positive frequency
    2011              :      !if (nspinor==1) option=1
    2012              :      !if (nspinor==2) option=2
    2013              : 
    2014              :     !do atom=1, natom
    2015              :     !   ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
    2016              :     !   if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
    2017              :     !         do ispinor1 = 1, nspinor
    2018              :     !       do ispinor = 1, nspinor
    2019              :     !     do is = 1 , nsppol
    2020              :     !           do im=1,ndim
    2021              :     !             do im1=1,ndim
    2022              :     !               do ifreq=1,green%nw
    2023              :     !                 ff(ifreq)= &
    2024              : !& green%oper(ifreq)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
    2025              : !                     write(std_out,*) green%omega(ifreq),ff(ifreq)," integrate
    2026              : !                     green fw_lo"
    2027              :    !if(present(iii).and.im==1.and.im1==1) write(std_out_default,*)
    2028              :    !ch10,ifreq,ff(ifreq),"#ff"
    2029              :  !                  enddo
    2030              : !                   call int_fct(ff,(im==im1).and.(ispinor==ispinor1),&
    2031              : !&                   option,paw_dmft,integral)
    2032              :   !                 call int_fct(ff,(im==im1).and.(ispinor==ispinor1),&
    2033              : !&                   2,paw_dmft,integral)  ! test_1
    2034              :  !                  green%occup%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)=integral
    2035              :    !if(present(iii).and.im==1.and.im1==1) write(std_out_default,*)
    2036              :    !ch10,'integral',im,im1,ifreq,integral
    2037              : !                   if(im==2.and.im1==5.and.is==1.and.iatom==1) then
    2038              : !                     write(std_out,*) " occup
    2039              : !                     %matlu(1)%mat(2,5,1,1,1)",green%occup%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
    2040              : !                   endif
    2041              :            !      enddo
    2042              :            !    enddo
    2043              :            !  enddo ! ispinor1
    2044              :         !   enddo ! ispinor
    2045              :         ! enddo ! is
    2046              :         ! matlu_temp(iatom)%mat=green%occup%matlu(iatom)%mat
    2047              :     !   endif ! lpawu=/-1
    2048              :     ! enddo ! iatom
    2049              : 
    2050          682 :      call zero_matlu(green%occup%matlu(:),natom)
    2051              : 
    2052         2046 :      ABI_MALLOC(omega_fac,(nmoments))
    2053              : 
    2054         1364 :      do i=1,nmoments
    2055          682 :        omega_fac(i) = czero
    2056       160113 :        do ifreq=green%nw,1,-1 ! NEVER change the summation order and DON'T use the intrinsic SUM
    2057       160113 :          omega_fac(i) = omega_fac(i) + paw_dmft%wgt_wlo(ifreq) / (paw_dmft%omega_lo(ifreq))**i
    2058              :        end do
    2059          682 :        omega_fac(i) = - two * temp * omega_fac(i) / (j_dpc)**i
    2060          682 :        if (i == 1) omega_fac(i) = omega_fac(i) + half
    2061          682 :        if (i == 2) omega_fac(i) = omega_fac(i) - cone/(four*temp)
    2062         1364 :        if (i == 4) omega_fac(i) = omega_fac(i) + cone/(dble(48)*(temp**3))
    2063              :      end do ! i
    2064              : 
    2065       160113 :      do ifreq=1,green%nw
    2066              : 
    2067       159431 :        if (green%distrib%procf(ifreq) /= myproc) cycle
    2068        54800 :        fac = two * temp * paw_dmft%wgt_wlo(ifreq)
    2069       161146 :        do iatom=1,natom
    2070       105664 :          lpawu = paw_dmft%lpawu(iatom)
    2071       105664 :          if (lpawu == -1) cycle
    2072              :          green%occup%matlu(iatom)%mat(:,:,:) = green%occup%matlu(iatom)%mat(:,:,:) + &
    2073      3437655 :             & fac*green%oper(ifreq)%matlu(iatom)%mat(:,:,:)
    2074              :        end do ! iatom
    2075              : 
    2076              :      end do ! ifreq
    2077              : 
    2078          682 :      call xmpi_matlu(green%occup%matlu(:),natom,paw_dmft%spacecomm)
    2079              : 
    2080          682 :      if (green%has_moments == 1) then
    2081            0 :        do i=1,nmoments
    2082            0 :          do iatom=1,natom
    2083            0 :            lpawu = paw_dmft%lpawu(iatom)
    2084            0 :            if (lpawu == -1) cycle
    2085              :            green%occup%matlu(iatom)%mat(:,:,:) = green%occup%matlu(iatom)%mat(:,:,:) + &
    2086            0 :              omega_fac(i)*green%moments(i)%matlu(iatom)%mat(:,:,:)
    2087              :          end do ! iatom
    2088              :        end do ! i
    2089              :      else
    2090         2046 :        ABI_MALLOC(shift,(natom))
    2091         3060 :        shift(:) = omega_fac(1)
    2092          682 :        call shift_matlu(green%occup%matlu(:),natom,shift(:),signe=-1)
    2093          682 :        ABI_FREE(shift)
    2094              :      end if
    2095              : 
    2096          682 :      ABI_FREE(omega_fac)
    2097              : 
    2098              : !    Print density matrix if prtopt high
    2099          682 :      if (abs(prtopt) > 2) then
    2100          105 :        write(message,'(2a,i10,a)') ch10,"  = green%occup%matlu from int(gloc(w))"
    2101          105 :        call wrtout(std_out,message,'COLL')
    2102          105 :        call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
    2103              :      end if ! abs(prtopt)>2
    2104              : 
    2105              : !  - Symmetrize: continue sum over k-point: Full BZ
    2106          682 :      call sym_matlu(green%occup%matlu(:),paw_dmft)
    2107          682 :      if (abs(prtopt) > 2) then
    2108          105 :        write(message,'(2a,i10,a)') ch10, &
    2109          210 :          & "  = green%occup%matlu from int(gloc(w)) with symmetrization"
    2110          105 :        call wrtout(std_out,message,'COLL')
    2111          105 :        call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
    2112              :      end if ! abs(prtopt)>2
    2113              : 
    2114              : !  - Post-treatment for summation over negative and positive frequencies:
    2115              : !    necessary in the case of nspinor==2 AND nspinor==1, but valid anywhere
    2116              : !    N(ll'sigmasigma')= (N(ll'sigmasigma')+ N*(l'lsigma'sigma))/2
    2117              : !    because [G_{LL'}^{sigma,sigma'}(iomega_n)]*= G_{L'L}^{sigma',sigma}(-iomega_n)
    2118         3060 :      do iatom=1,natom
    2119         2378 :        lpawu = paw_dmft%lpawu(iatom)
    2120         2378 :        if (lpawu == -1) cycle
    2121         2018 :        do isppol=1,nsppol
    2122              :          green%occup%matlu(iatom)%mat(:,:,isppol) = (green%occup%matlu(iatom)%mat(:,:,isppol) + &
    2123        71522 :             & conjg(transpose(green%occup%matlu(iatom)%mat(:,:,isppol)))) * half
    2124              :        end do ! isppol
    2125        39028 :        matlu_temp(iatom)%mat(:,:,:) = green%occup%matlu(iatom)%mat(:,:,:)
    2126              :      end do ! iatom
    2127          682 :      if (abs(prtopt) > 2) then
    2128          105 :        write(message,'(2a,i10,a)') ch10, &
    2129          210 :          & "  = green%occup%matlu from int(gloc(w)) symmetrized with post-treatment"
    2130          105 :        call wrtout(std_out,message,'COLL')
    2131          105 :        call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
    2132              :      end if ! abs(prtopt)>2
    2133              : 
    2134          682 :      if (optaftsolv == 0) then
    2135          579 :        call trace_oper(green%occup,green%charge_ks,green%charge_matlu(:,:),2)
    2136          579 :        green%has_charge_matlu = 2
    2137          579 :        green%has_charge_matlu_solver = 0
    2138          579 :        icomp_chloc = 1
    2139          103 :      else if (optaftsolv == 1) then ! .and. paw_dmft%dmft_solv /= 4) then
    2140              : !     else if(optaftsolv==1) then
    2141              :        !if(paw_dmft%dmft_solv==4) then
    2142              :        !  write(message,'(a,a,a)') ch10,&
    2143              : !&        "  = WARNING: Double Counting will be computed with solver charge.." ,&
    2144              : !&        "might be problematic with Hirsch Fye QMC"
    2145              :     !     call wrtout(std_out,message,'COLL')
    2146              :     !   endif
    2147              : !      This is done only when called from impurity_solver with solver
    2148              : !      green function. (And if QMC is NOT used).
    2149          103 :        if (paw_dmft%dmft_solv >= 5 .and. green%has_charge_matlu_solver /= 2) then
    2150            0 :          write(message,'(2a,i3)') ch10,&
    2151            0 :            & "  = BUG : has_charge_matlu_solver should be 2 and is",green%has_charge_matlu_solver
    2152            0 :          ABI_BUG(message)
    2153              :        end if
    2154          103 :        if (paw_dmft%dmft_solv <= 4) then
    2155           69 :          call trace_oper(green%occup,green%charge_ks,green%charge_matlu_solver(:,:),2)
    2156           69 :          green%has_charge_matlu_solver = 2
    2157              :        end if
    2158              :      end if ! optaftsolv
    2159              :    else
    2160           99 :      write(message,'(a,4x,3a,4x,a)') ch10,&
    2161           99 :        & "  Local basis is not (yet) orthonormal:",&
    2162           99 :        & " local Green's function is thus not integrated",ch10,&
    2163          198 :        & "  Local occupations are computed by downfolding the Kohn-Sham occupations instead"
    2164           99 :      call wrtout(std_out,message,'COLL')
    2165              :    end if ! lchipsiortho=1
    2166              : 
    2167              :  end if ! optksloc
    2168              : ! =================================================
    2169              : 
    2170              : ! =================================================
    2171              : ! == Integrate Kohn Sham Green function ===========
    2172         4984 :  if (mod(abs(optksloc),2) == 1) then ! optksloc=1 or 3 or -1
    2173              : !   green%occup%ks=czero ! important for xmpi_sum
    2174              : !! =================================================
    2175              : !! ==  Calculation of \int{G_{\nu\nu'}{k,s}(i\omega_n)}
    2176              : !   ff=czero
    2177              : !   do is = 1 , nsppol
    2178              : !     do ikpt = 1, nkpt
    2179              : !!020212       if(mod(ikpt-1,nproc)==myproc) then
    2180              : !!!         print'(A,3I4)', "P ",myproc,is,ikpt
    2181              : !         do ib = 1, mbandc
    2182              : !           do ib1 = 1, mbandc
    2183              : !             if(optksloc==-1.and.(ib/=ib1)) cycle
    2184              : !             ff(:)=czero
    2185              : !             do ifreq=1,green%nw
    2186              : !             !!  the following line is a quick and dirty tricks and should be removed when the data will
    2187              : !             !!  be correctly distributed.
    2188              : !!!               if((optnonxsum==1).and.(green%procb(ifreq,ikpt)==myproc)).or.(optnonxsum==0)) then
    2189              : !               if(green%procb(ifreq,ikpt)==myproc) then
    2190              : !                 ff(ifreq)=green%oper(ifreq)%ks(is,ikpt,ib,ib1)
    2191              : !!!                 print'(A,5I4,3(2E15.5,3x))', "P1",myproc,is,ikpt,ib,ib1,ff(:)
    2192              : !               endif
    2193              : !               !endif
    2194              : !             enddo
    2195              : !!             call int_fct(ff,ib==ib1,nspinor,paw_dmft,integral) ! here, option==1 even if nspinor==2
    2196              : !!             green%occup%ks(is,ikpt,ib,ib1)=integral
    2197              : !!!                 print'(A,5I4,3(2E15.5,3x))', "PP",myproc,is,ikpt,ib,ib1,ff(:)
    2198              : !             call int_fct(ff,ib==ib1,2,paw_dmft,integral,green%procb(:,ikpt),myproc) ! here, option==1 even if nspinor==2
    2199              : !!020212             call int_fct(ff,ib==ib1,2,paw_dmft,integral) ! here, option==1 even if nspinor==2
    2200              : !             green%occup%ks(is,ikpt,ib,ib1)=integral
    2201              : !!!                 print'(A,5I4,2E15.8)', "P2",myproc,is,ikpt,ib,ib1,integral
    2202              : !            !   write(std_out,*) "integral",ikpt,green%occup%ks(is,ikpt,ib,ib1)
    2203              : !            ! endif
    2204              : !!        write(std_out,'(a,4i6,e14.5,e14.5)') "ks",is,ikpt,ib,ib1,integral
    2205              : !           enddo ! ib1
    2206              : !         enddo ! ib
    2207              : !!020212       endif
    2208              : !     enddo ! ikpt
    2209              : !   enddo ! isppol
    2210              : 
    2211              : 
    2212              : !   call xmpi_barrier(spacecomm)
    2213              : !   call xmpi_sum(green%occup%ks,spacecomm,ierr)
    2214              : 
    2215              : 
    2216              : !!   do is = 1 , nsppol
    2217              : !!     do ikpt = 1, nkpt
    2218              : !!         do ib = 1, mbandc
    2219              : !!           do ib1 = 1, mbandc
    2220              : !!             write(6,'(A,5I4,2E15.8)') "AAAFTERXSUM",myproc,is,ikpt,ib,ib1,green%occup%ks(is,ikpt,ib,ib1)
    2221              : !!             print '(A,5I4,2E15.8)', "AFTERXSUM P",myproc,is,ikpt,ib,ib1,green%occup%ks(is,ikpt,ib,ib1)
    2222              : !!           enddo ! ib1
    2223              : !!         enddo ! ib
    2224              : !!     enddo ! ikpt
    2225              : !!   enddo ! isppol
    2226              :                !write(std_out,*) "occup%ks ik1",green%occup%ks(1,1,1,3)
    2227              :                !write(std_out,*) "occup%ks ik2",green%occup%ks(1,2,1,3)
    2228              : !  - Post-treatment for summation over negative and positive frequencies:
    2229              : !    necessary in the case of nspinor==2, but valid everywhere
    2230              : !    N(k,n_1,n_2)= (N(k,n_1,n_2)+ N*(k,n_2,n_1))/2
    2231              : !    because [G_{k}^{n_1,n_2}(iomega_n)]*= G_{k}^{n_2,n_1}(-iomega_n)
    2232        11564 :    do isppol=1,nsppol
    2233        60270 :      do ikpt=1,nkpt
    2234              :        green%occup%ks(:,:,ikpt,isppol) = (green%occup%ks(:,:,ikpt,isppol)+ &
    2235     14174846 :           & conjg(transpose(green%occup%ks(:,:,ikpt,isppol)))) * half
    2236              :      end do ! ikpt
    2237              :    end do ! isppol
    2238              :                !write(std_out,*) "occup%ks ik1 BB",green%occup%ks(1,1,1,3)
    2239              :                !write(std_out,*) "occup%ks ik2 AA",green%occup%ks(1,2,1,3)
    2240         4880 :    if (optfilloccnd == 1) then
    2241          199 :      band_index = 0
    2242          199 :      fac = merge(two,one,nsppol==1.and.nspinor==1)
    2243          486 :      do isppol=1,nsppol
    2244         2708 :        do ikpt=1,nkpt
    2245        23638 :          do ib1=1,mbandc
    2246       319390 :            do ib=1,mbandc
    2247              :              paw_dmft%occnd(1,paw_dmft%include_bands(ib),paw_dmft%include_bands(ib1),&
    2248       295752 :                 & ikpt,isppol) = fac * dble(green%occup%ks(ib,ib1,ikpt,isppol))
    2249              :              paw_dmft%occnd(2,paw_dmft%include_bands(ib),paw_dmft%include_bands(ib1),&
    2250       317168 :                 & ikpt,isppol) = fac * aimag(green%occup%ks(ib,ib1,ikpt,isppol))
    2251              :            end do  ! ib
    2252              :          end do ! ib1
    2253         2509 :          if (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7) then
    2254            0 :            nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
    2255            0 :            do ib=1,nband_k
    2256            0 :              if (paw_dmft%band_in(ib)) cycle
    2257            0 :              paw_dmft%occnd(:,:,ib,ikpt,isppol)  = zero
    2258              :              paw_dmft%occnd(1,ib,ib,ikpt,isppol) = fac * &
    2259            0 :                & occup_fd(paw_dmft%eigen(ib+band_index),paw_dmft%fermie,paw_dmft%temp)
    2260              :            end do ! ib
    2261            0 :            band_index = band_index + nband_k
    2262              :          end if ! use_all_bands
    2263              :        end do ! ikpt
    2264              :      end do ! isppol
    2265              :    end if ! optfilloccnd
    2266              : 
    2267         4880 :    if (optksloc > 0) then
    2268              : !  - Compute local occupations
    2269              :      call downfold_oper(green%occup,paw_dmft,procb=green%distrib%procb(:), &
    2270          677 :                       & iproc=green%distrib%me_kpt,option=option)
    2271          677 :      call xmpi_matlu(green%occup%matlu(:),natom,green%distrib%comm_kpt)
    2272          677 :      if (abs(prtopt) > 2) then
    2273          106 :        write(message,'(2a,i10,a)') ch10,&
    2274          212 :           & "  = green%occup%matlu from projection of int(gks(w)) without symmetrization"
    2275          106 :        call wrtout(std_out,message,'COLL')
    2276          106 :        call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
    2277              :      end if ! abs(prtopt)>2
    2278              : 
    2279              : !  - Symmetrize: continue sum over k-point: Full BZ
    2280          677 :      call sym_matlu(green%occup%matlu(:),paw_dmft)
    2281          677 :      if (abs(prtopt) >= 2) then
    2282              : !       write(message,'(a,a,i10,a)') ch10,&
    2283              : !&        "  = green%occup%matlu from projection of int(gks(w)) with symetrization"
    2284          478 :        write(message,'(2a,i10,a)') ch10,"  ==  Occupation matrix from downfolded Kohn-Sham occupations"
    2285          478 :        call wrtout(std_out,message,'COLL')
    2286          478 :        call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=0)
    2287              :      end if ! abs(prtopt)>=2
    2288              : 
    2289              : !    - If the trace of occup matrix in the LOCAL basis was not done
    2290              : !    before because lchipsiortho/=1 , do it now
    2291          677 :      if (paw_dmft%lchipsiortho /= 1 .and. abs(prtopt) > 0) then
    2292           97 :        call trace_oper(green%occup,green%charge_ks,green%charge_matlu(:,:),2)
    2293           97 :        green%has_charge_matlu = 2
    2294           97 :        icomp_chloc = 1
    2295              :      end if ! lchipsiortho/=1 and abs(prtopt)>0
    2296              :    end if ! optksloc>0: only diagonal elements of G\nunu' are computed
    2297              : 
    2298              : !  - Compute trace over ks density matrix
    2299         4880 :    call trace_oper(green%occup,green%charge_ks,green%charge_matlu(:,:),1)
    2300         4880 :    if (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7) then
    2301              : 
    2302              :      band_index = 0
    2303              :      correction = zero
    2304            0 :      do isppol=1,nsppol
    2305            0 :        do ikpt=1,nkpt
    2306            0 :          nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
    2307            0 :          do ib=1,nband_k
    2308            0 :            if (paw_dmft%band_in(ib)) cycle
    2309              :            correction = correction + &
    2310            0 :              & occup_fd(paw_dmft%eigen(ib+band_index),paw_dmft%fermie,paw_dmft%temp)*green%occup%wtk(ikpt)
    2311              :          end do ! ib
    2312            0 :          band_index = band_index + nband_k
    2313              :        end do ! ikpt
    2314              :      end do ! isppol
    2315            0 :      if (nsppol == 1 .and. nspinor == 1) correction = correction * two
    2316            0 :      green%charge_ks = green%charge_ks + correction
    2317              :    end if ! use_all_bands
    2318         4880 :    if (abs(prtopt) > 0) then
    2319          478 :      write(tag,'(f12.6)') green%charge_ks
    2320          478 :      write(message,'(3a)') ch10,&
    2321          956 :        & "  ==  Total number of electrons from integration of Kohn-Sham Green's function is : ",adjustl(tag)
    2322          478 :      call wrtout(std_out,message,'COLL')
    2323          478 :      write(tag,'(f12.6)') paw_dmft%nelectval
    2324          478 :      write(message,'(8x,3a)') " (should be ",trim(adjustl(tag)),")"
    2325          478 :      call wrtout(std_out,message,'COLL')
    2326              :    end if ! abs(prtopt)>0
    2327              :  end if ! optksloc
    2328              : ! =================================================
    2329              : 
    2330              : ! =================================================
    2331              : ! Tests and compute precision on local charge
    2332              : ! =================================================
    2333              : !  - Check that if, renormalized psichi are used, occupations matrices
    2334              : !    obtained directly from local green function or, through kohn sham
    2335              : !    occupations are the same.
    2336         4984 :  if ((abs(optksloc) == 3) .and. (paw_dmft%lchipsiortho == 1)) then ! optksloc= 3
    2337              : 
    2338          578 :    if(nspinor == 2) then
    2339            8 :      optiondiff = 2
    2340              :    else
    2341          570 :       optiondiff = 1
    2342              :    endif
    2343              :    call diff_matlu("Local projection of Kohn-Sham occupations ",&
    2344              :         & "Integration of local Green's function ",&
    2345          578 :         & green%occup%matlu(:),matlu_temp(:),natom,optiondiff,tol4)
    2346          578 :    write(message,'(2a)') ch10,&
    2347         1156 :        & "  ***** => Calculations of Green's function in Kohn-Sham and local spaces are coherent ****"
    2348          578 :    call wrtout(std_out,message,'COLL')
    2349              :  end if ! abs(optksloc)=3
    2350              : 
    2351              : ! == Precision on charge_matlu (done only if local charge was computed ie not for optksloc=-1)
    2352         4984 :  if (icomp_chloc == 1 .and. paw_dmft%idmftloop >= 1 .and. optdiff == 1) then ! if the computation was done here.
    2353          106 :    if (green%has_charge_matlu_prev == 2) then
    2354              :      diff_chloc = zero
    2355           62 :      do iatom=1,natom
    2356           49 :        lpawu = paw_dmft%lpawu(iatom)
    2357           49 :        if (lpawu == -1) cycle
    2358           87 :        do isppol=1,nsppol
    2359              :          diff_chloc = diff_chloc + &
    2360           98 :            & (green%charge_matlu_prev(isppol,iatom)-green%charge_matlu(isppol,iatom))**2
    2361              :        end do ! isppol
    2362              :      end do ! iatom
    2363           13 :      if (sqrt(diff_chloc) < paw_dmft%dmft_lcpr) then
    2364            0 :        green%ichargeloc_cv = 1
    2365            0 :        write(message,'(a,8x,a,e9.2,a,8x,a)') ch10,"Change of correlated number of electron =<",&
    2366            0 :           & paw_dmft%dmft_lcpr,ch10,"DMFT Loop: Local charge is converged"
    2367            0 :        call wrtout(std_out,message,'COLL')
    2368              :      else
    2369           13 :        green%ichargeloc_cv = 0
    2370           13 :        write(message,'(a,8x,a,e9.2,a,8x,a)') ch10,"Change of correlated number of electron  >",&
    2371           26 :          & paw_dmft%dmft_lcpr,ch10,"DMFT Loop: Local charge is not converged"
    2372           13 :        call wrtout(std_out,message,'COLL')
    2373              :      end if ! sqrt(diff_chloc)<dmft_lcpr
    2374              :    end if ! green%has_charge_matlu_prev=2
    2375         1370 :    green%charge_matlu_prev(:,:) = green%charge_matlu(:,:)
    2376          106 :    green%has_charge_matlu_prev = 2
    2377              :  end if ! icomp_chloc=1 and present(opt_diff) and idmftloop>=1
    2378              : 
    2379         4984 :  call destroy_matlu(matlu_temp(:),natom)
    2380        23716 :  ABI_FREE(matlu_temp)
    2381              : ! deallocate(charge_loc_old)
    2382              :  ABI_NVTX_END_RANGE()
    2383         4984 :  call timab(625,2,tsec(:))
    2384              :  DBG_EXIT("COLL")
    2385              : 
    2386         4984 : end subroutine integrate_green
    2387              : !!***
    2388              : 
    2389              : !!****f* m_green/icip_green
    2390              : !! NAME
    2391              : !!  icip_green
    2392              : !!
    2393              : !! FUNCTION
    2394              : !!  init, compute, integrate and print lda green function
    2395              : !!
    2396              : !! INPUTS
    2397              : !!  char1 = character which precises the type of green function computed.
    2398              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    2399              : !!  green  <type(green_type)>= green function data
    2400              : !!  pawprtvol  = option for printing
    2401              : !!  self <type(self_type)>= variables related to self-energy
    2402              : !!  opt_self = optional argument, if =1, upfold self-energy
    2403              : !!  opt_moments = 1 to activate the computation of high-frequency moments
    2404              : !!  opt_log = 1 to compute Tr(log(G))
    2405              : !!
    2406              : !! OUTPUT
    2407              : !!
    2408              : !! SOURCE
    2409              : 
    2410          279 : subroutine icip_green(char1,green,paw_dmft,pawprtvol,self,opt_self,opt_moments,opt_log)
    2411              : 
    2412              : !Arguments ------------------------------------
    2413              :  !type(MPI_type), intent(in) :: mpi_enreg
    2414              :  type(green_type), intent(inout) :: green
    2415              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    2416              :  type(self_type), intent(inout) :: self
    2417              :  integer, intent(in) :: pawprtvol
    2418              :  character(len=*), intent(in) :: char1
    2419              :  integer, optional, intent(in) :: opt_log,opt_moments,opt_self
    2420              : !Local variables ------------------------------------
    2421              :  integer :: option,optlog,optmoments,optself,optlocks,prtopt_for_integrate_green,opt_nonxsum_icip
    2422              :  character(len=500) :: message
    2423              : ! *********************************************************************
    2424              : 
    2425              :  !green%whichgreen="DFT"
    2426          279 :  prtopt_for_integrate_green = 2
    2427              : 
    2428          279 :  optself = 0
    2429          279 :  if (present(opt_self)) optself = opt_self
    2430          279 :  opt_nonxsum_icip = 1
    2431              :  !if(paw_dmft%dmftcheck==1) then ! for fourier_green
    2432              :  !  opt_nonxsum_icip=0
    2433              :  !endif
    2434              : 
    2435          279 :  optlog = 0
    2436          279 :  if (present(opt_log)) optlog = opt_log
    2437              : 
    2438          279 :  optmoments = 0
    2439          279 :  if (present(opt_moments)) optmoments = opt_moments
    2440              : 
    2441          279 :  call init_green(green,paw_dmft,opt_moments=optmoments)
    2442              : 
    2443              : ! useless test ok
    2444              : ! call printocc_green(green,1,paw_dmft,2)
    2445              : ! write(std_out,*)" printocc_green zero finished "
    2446              : 
    2447              : !== Compute green%oper(:)%ks
    2448              : !== Deduce  green%oper(:)%matlu(:)%mat
    2449          279 :  call compute_green(green,paw_dmft,pawprtvol,self,opt_self=optself,opt_nonxsum=opt_nonxsum_icip,opt_log=optlog)
    2450          279 :  if (paw_dmft%dmft_prgn >= 1 .and. paw_dmft%dmft_prgn <= 2) then
    2451            0 :    optlocks = paw_dmft%dmft_prgn*2 + 1 ! if dmft_prgn==2 => do not print
    2452            0 :    if (paw_dmft%lchipsiortho == 1 .and. pawprtvol > -100) then
    2453            0 :       call print_green(char1,green,optlocks,paw_dmft)
    2454              : !     call print_green('inicip',green,1,paw_dmft,pawprtvol=1,opt_wt=1)
    2455              :    end if
    2456              :  end if
    2457              : 
    2458              : !== Integrate green%oper(:)%ks
    2459              : !== Integrate green%oper(:)%matlu(:)%mat
    2460          279 :  call integrate_green(green,paw_dmft,prtopt_for_integrate_green,opt_ksloc=3,opt_self=optself)!,opt_nonxsum=opt_nonxsum_icip)
    2461              : !== Print green%oper(:)%ks
    2462              : !== Print green%oper(:)%matlu(:)%mat
    2463          279 :  if (char1 == "DFT") then
    2464           93 :    option = 1
    2465           93 :    if (self%oper(1)%matlu(1)%lpawu /= -1) then
    2466           93 :      if (abs(dble(self%oper(1)%matlu(1)%mat(1,1,1))) > tol7) then
    2467              : ! todo_ab: generalise this
    2468            0 :        write(message,'(2a)') ch10,&
    2469            0 :           & "Warning: a DFT calculation is carried out and self is not zero"
    2470            0 :        ABI_WARNING(message)
    2471              : !       call abi_abort('COLL')
    2472              :      end if
    2473              :    end if
    2474              :  else
    2475          186 :    option = 5
    2476              :  end if ! char1
    2477              : 
    2478          279 :  if (pawprtvol > -100) then
    2479          279 :    call printocc_green(green,option,paw_dmft,3,chtype=char1)
    2480              :  end if
    2481              : 
    2482          279 : end subroutine icip_green
    2483              : !!***
    2484              : 
    2485              : !!****f* m_green/fourier_green
    2486              : !! NAME
    2487              : !! fourier_green
    2488              : !!
    2489              : !! FUNCTION
    2490              : !!  integrate green function in the band index basis
    2491              : !!
    2492              : !! INPUTS
    2493              : !!  cryst_struc <type(crystal_t)>= crystal structure data.
    2494              : !!  green  <type(green_type)>= green function data
    2495              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    2496              : !!
    2497              : !! OUTPUT
    2498              : !!
    2499              : !! SOURCE
    2500              : 
    2501            2 : subroutine fourier_green(cryst_struc,green,paw_dmft,opt_ksloc,opt_tw)
    2502              : 
    2503              : !Arguments ------------------------------------
    2504              : !type
    2505              :  type(crystal_t),intent(in) :: cryst_struc
    2506              :  type(green_type),intent(inout) :: green
    2507              :  !type(MPI_type), intent(in) :: mpi_enreg
    2508              :  type(paw_dmft_type), intent(in) :: paw_dmft
    2509              :  integer,intent(in) :: opt_ksloc,opt_tw ! fourier on ks or local
    2510              : 
    2511              : !local variables-------------------------------
    2512              :  integer :: iatom,ib,ib1,ierr,ifreq,ikpt,im,im1,iparal,is,ispinor,ispinor1,itau
    2513              :  integer :: mband,mbandc,myproc,natom,ndim,nkpt,nproc,nspinor,nsppol,spacecomm!,opt_four
    2514              :  character(len=500) :: message
    2515              : ! complex(dp):: ybcbeg,ybcend
    2516              : ! arrays
    2517            2 :  complex(dp), allocatable :: fw(:)
    2518            2 :  complex(dp), allocatable :: ft(:)
    2519            2 :  type(green_type) :: green_temp
    2520              : ! *********************************************************************
    2521              : ! ybcbeg=czero
    2522              : ! ybcend=czero
    2523              : 
    2524              : ! define spaceComm, myproc, and nproc from world communicator
    2525              : ! and mpi_enreg
    2526            2 :  spacecomm=paw_dmft%spacecomm
    2527            2 :  myproc=paw_dmft%myproc
    2528            2 :  nproc=paw_dmft%nproc
    2529              : 
    2530              : ! Initialise integers
    2531            2 :  mband   = paw_dmft%mband
    2532            2 :  mbandc  = paw_dmft%mbandc
    2533            2 :  nkpt    = paw_dmft%nkpt
    2534            2 :  nspinor = paw_dmft%nspinor
    2535            2 :  nsppol  = paw_dmft%nsppol
    2536            2 :  natom   = cryst_struc%natom
    2537              : 
    2538              : ! Only imaginary frequencies here
    2539            2 :  if(green%w_type=="real") then
    2540            0 :    message = 'fourier_green not implemented for real frequency'
    2541            0 :    ABI_BUG(message)
    2542              :  endif
    2543              : 
    2544              : ! Initialise temporary green function
    2545            2 :  call init_green(green_temp,paw_dmft)
    2546            2 :  call init_green_tau(green_temp,paw_dmft)
    2547              : 
    2548              :  !green%oper(:)%matlu(1)%mat(1,1,1,1,1)
    2549            6 :  ABI_MALLOC(fw,(green%nw))
    2550            6 :  ABI_MALLOC(ft,(green%dmftqmc_l))
    2551              : 
    2552              : !==============================================
    2553              : ! == Inverse fourier transformation ===========
    2554              : !==============================================
    2555              : 
    2556            2 :  if(opt_tw==-1) then
    2557              : 
    2558              : !  = For Kohn Sham green function
    2559              : !==============================================
    2560            1 :    if(opt_ksloc==1.and.green%use_oper_tau_ks==1) then
    2561              : 
    2562            0 :      do is = 1 , nsppol
    2563            0 :        do ikpt = 1, nkpt
    2564            0 :          do ib = 1, mbandc
    2565            0 :            do ib1 = 1, mbandc
    2566            0 :              do ifreq=1,green%nw
    2567            0 :                fw(ifreq)=green%oper(ifreq)%ks(ib,ib1,ikpt,is)
    2568              :              enddo
    2569            0 :              call fourier_fct(fw,ft,ib==ib1,green%dmftqmc_l,-1,paw_dmft) ! inverse fourier
    2570            0 :              do itau=1,green%dmftqmc_l
    2571            0 :                green_temp%oper_tau(itau)%ks(ib,ib1,ikpt,is)=ft(itau)
    2572              :              enddo
    2573            0 :              if(ib==ib1) then
    2574            0 :                green%occup_tau%ks(ib,ib1,ikpt,is)=ft(1)+one
    2575              :              else
    2576            0 :                green%occup_tau%ks(ib,ib1,ikpt,is)=ft(1)
    2577              :              endif
    2578              :            enddo ! ib1
    2579              :          enddo ! ib
    2580              :        enddo ! ikpt
    2581              :      enddo ! isppol
    2582              : 
    2583              : !  = Post-treatment: necessary in the case of nspinor==2, but valid anywhere
    2584              : !    because G(tau)=G_{nu,nu'}(tau)+[G_{nu,nu'}(tau)]*
    2585              : 
    2586            0 :      do is = 1 , nsppol
    2587            0 :        do ikpt = 1, nkpt
    2588            0 :          do ib = 1, mbandc
    2589            0 :            do ib1 = 1, mbandc
    2590            0 :              do itau=1,green%dmftqmc_l
    2591              :                green%oper_tau(itau)%ks(ib,ib1,ikpt,is)=&
    2592              : &                (green_temp%oper_tau(itau)%ks(ib,ib1,ikpt,is)+ &
    2593            0 : &                 conjg(green_temp%oper_tau(itau)%ks(ib1,ib,ikpt,is)))/two
    2594            0 :                if(ib==ib1) then
    2595            0 :                  green%occup_tau%ks(ib,ib1,ikpt,is)=green%oper_tau(1)%ks(ib,ib1,ikpt,is)+one
    2596              :                else
    2597            0 :                  green%occup_tau%ks(ib,ib1,ikpt,is)=green%oper_tau(1)%ks(ib,ib1,ikpt,is)
    2598              :                endif
    2599              :              enddo
    2600              :            enddo ! ib1
    2601              :          enddo ! ib
    2602              :        enddo ! ikpt
    2603              :      enddo ! isppol
    2604            0 :      call downfold_oper(green%occup_tau,paw_dmft)
    2605            0 :      call sym_matlu(green%occup_tau%matlu,paw_dmft)
    2606            0 :      write(message,'(a,a,i10,a)') ch10,"  green%occup_tau%matlu from green_occup_tau%ks"
    2607            0 :      call wrtout(std_out,message,'COLL')
    2608            0 :      call print_matlu(green%occup_tau%matlu,natom,prtopt=3)
    2609              :    endif
    2610              : 
    2611              : !  = For local green function
    2612              : !==============================================
    2613            1 :    if(opt_ksloc ==2) then
    2614              : 
    2615              :      iparal=0
    2616            3 :      do iatom=1, natom
    2617            3 :        if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
    2618            1 :          ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
    2619            3 :          do is = 1 , nsppol
    2620            5 :            do ispinor = 1, nspinor
    2621            6 :              do ispinor1 = 1, nspinor
    2622           14 :                do im=1,ndim
    2623           62 :                  do im1=1,ndim
    2624           50 :                    iparal=iparal+1
    2625           60 :                    if(mod(iparal-1,nproc)==myproc) then
    2626         1650 :                      do ifreq=1,green%nw
    2627         1650 :                        fw(ifreq)=green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)
    2628              :                      enddo
    2629              :                      ! inverse fourier
    2630              : !                     write(std_out,'(a)') "fourierbeforeposttreatement,ispinor,ispinor1,is,im,im1"
    2631              : !                     write(std_out,'(a,5i4,f12.5,f12.5)') "fourier",ispinor,ispinor1,is,im,im1
    2632              : !                     write(std_out,'(a,e12.5,e12.5)')&
    2633              : !                     &"green%oper(4)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)"&
    2634              : !&                     ,green%oper(4)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
    2635           50 :                      call fourier_fct(fw,ft,(im==im1).and.(ispinor==ispinor1),green%dmftqmc_l,-1,paw_dmft)
    2636         3250 :                      do itau=1,green%dmftqmc_l
    2637         3250 :                        green_temp%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=ft(itau)
    2638              : !                     write(std_out,*) itau,green_temp%oper_tau(itau)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
    2639              :                      enddo
    2640              : !                    if((im==im1).and.(ispinor==ispinor1)) then
    2641              : !                      green%occup_tau%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)=ft(1)+one
    2642              : !                    else
    2643              : !                      green%occup_tau%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)=ft(1)
    2644              : !                    endif
    2645              :                    endif ! iparal
    2646              :                  enddo
    2647              :                enddo
    2648              :              enddo ! ispinor1
    2649              :            enddo ! ispinor
    2650              :          enddo ! isppol
    2651              :        endif ! lpawu.ne.-1
    2652              :      enddo ! iatom
    2653              : 
    2654              : !    Parallelisation must be finished here, because in the post
    2655              : !    treatment, value from different proc will be mixed.
    2656            1 :      call xmpi_barrier(spacecomm)
    2657            3 :      do iatom=1,natom
    2658            2 :        if (green%oper(1)%matlu(iatom)%lpawu==-1) cycle
    2659           66 :        do itau=1,green%dmftqmc_l
    2660           66 :         call xmpi_sum(green_temp%oper_tau(itau)%matlu(iatom)%mat,spacecomm,ierr)
    2661              :        enddo
    2662              :      enddo
    2663            1 :      call xmpi_barrier(spacecomm)
    2664              : 
    2665              : !  = Post-treatment: necessary in the case of nspinor==2, but valid anywhere
    2666              : !    because G(tau)=G_{LL'}^{sigma,sigma'}(tau)+[G_{L'L}^{sigma',sigma}(tau)]*
    2667              : 
    2668            1 :      if(nspinor>0) Then
    2669            3 :        do iatom=1, natom
    2670            3 :          if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
    2671            1 :            ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
    2672            3 :            do is = 1 , nsppol
    2673            5 :              do ispinor = 1, nspinor
    2674            6 :                do ispinor1 = 1, nspinor
    2675           14 :                  do im=1,ndim
    2676           62 :                    do im1=1,ndim
    2677              : !                   write(std_out,'(a,5i4,f12.5,f12.5)') "fourier -1",ispinor,ispinor1,is,im,im1
    2678         3260 :                      do itau=1,green%dmftqmc_l
    2679              :                        green%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=&
    2680              : &                      ((green_temp%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)+ &
    2681         3200 : &                      conjg(green_temp%oper_tau(itau)%matlu(iatom)%mat(im1+(ispinor1-1)*ndim,im+(ispinor-1)*ndim,is))))/two
    2682              : !                       write(std_out,*) itau,green%oper_tau(itau)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
    2683         3250 :                        if((im==im1).and.(ispinor==ispinor1)) then
    2684              :                          green%occup_tau%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=&
    2685          640 : &                         green%oper_tau(1)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)+one
    2686              :                        else
    2687              :                          green%occup_tau%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=&
    2688         2560 : &                         green%oper_tau(1)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)
    2689              :                        endif ! test diag
    2690              :                      enddo  ! itau
    2691              :                    enddo  ! im1
    2692              :                  enddo ! im
    2693              :                enddo ! ispinor1
    2694              :              enddo ! ispinor
    2695              :            enddo ! isppol
    2696              :          endif
    2697              :        enddo ! iatom
    2698              :      endif ! nspinor>0
    2699              :    endif ! opt_ksloc=2
    2700              :  endif ! opt_tw==-1
    2701              : 
    2702              : 
    2703              : !==============================================
    2704              : ! == Direct fourier transformation
    2705              : !==============================================
    2706              : ! todo_ba ft useful only for diagonal elements ...
    2707              : 
    2708            2 :  if(opt_tw==1) then
    2709              : 
    2710              : !  = For local green function
    2711              : !==============================================
    2712            1 :    if(opt_ksloc ==2) then
    2713              : 
    2714              :      iparal=0
    2715            3 :      do iatom=1, natom
    2716              : !  put to zero (usefull at least for parallelism)
    2717            3 :        if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
    2718           33 :          do ifreq=1,green%nw
    2719         2017 :            green%oper(ifreq)%matlu(iatom)%mat=czero
    2720              :          enddo
    2721            1 :          ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
    2722            3 :          do is = 1 , nsppol
    2723            5 :            do ispinor = 1, nspinor
    2724            6 :              do ispinor1 = 1, nspinor
    2725           14 :                do im=1,ndim
    2726           62 :                  do im1=1,ndim
    2727           50 :                    iparal=iparal+1
    2728           60 :                    if(mod(iparal-1,nproc)==myproc) then
    2729         3250 :                      do itau=1,green%dmftqmc_l
    2730         3250 :                        ft(itau)=green%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)
    2731              :                      enddo
    2732              : !                     if(im==1.and.im1==1) write(std_out,*) "ft(itau=1)",is,ft(1) ! debug
    2733           50 :                      call fourier_fct(fw,ft,(im==im1).and.(ispinor==ispinor1),green%dmftqmc_l,1,paw_dmft)
    2734         1650 :                      do ifreq=1,green%nw
    2735         1650 :                        green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=fw(ifreq)
    2736              :                      enddo
    2737              : !                     if(im==1.and.im1==1) write(std_out,*) "fw(ifreq=1)",is,fw(1) ! debug
    2738              :                    endif
    2739              :                  enddo
    2740              :                enddo
    2741              :              enddo ! ispinor1
    2742              :            enddo ! ispinor
    2743              :          enddo ! isppol
    2744              :        endif ! lpawu=/-1
    2745              :      enddo ! iatom
    2746            1 :      call xmpi_barrier(spacecomm)
    2747            3 :      do iatom=1,natom
    2748            2 :        if (green%oper(1)%matlu(iatom)%lpawu==-1) cycle
    2749           34 :        do ifreq=1,green%nw
    2750           34 :        call xmpi_sum(green%oper(ifreq)%matlu(iatom)%mat,spacecomm,ierr)
    2751              :        enddo
    2752              :      enddo
    2753              :    endif ! opt_ksloc=2
    2754              :  endif ! opt_tw==-1
    2755            2 :  ABI_FREE(fw)
    2756            2 :  ABI_FREE(ft)
    2757            2 :  call destroy_green_tau(green_temp)
    2758            2 :  call destroy_green(green_temp)
    2759              : 
    2760            2 : end subroutine fourier_green
    2761              : !!***
    2762              : 
    2763              : 
    2764              : !!****f* m_green/check_fourier_green
    2765              : !! NAME
    2766              : !! check_fourier_green
    2767              : !!
    2768              : !! FUNCTION
    2769              : !!  Check fourier transformations
    2770              : !!
    2771              : !! INPUTS
    2772              : !!  cryst_struc <type(crystal_t)>= crystal structure data.
    2773              : !!  green  <type(green_type)>= green function data
    2774              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    2775              : !!  pawang <type(pawang)>=paw angular mesh and related data
    2776              : !!
    2777              : !! OUTPUT
    2778              : !!
    2779              : !! SOURCE
    2780              : 
    2781            1 : subroutine check_fourier_green(cryst_struc,green,paw_dmft)
    2782              : 
    2783              : !Arguments ------------------------------------
    2784              : !type
    2785              :  type(crystal_t),intent(in) :: cryst_struc
    2786              :  type(green_type),intent(inout) :: green
    2787              :  !type(MPI_type), intent(in) :: mpi_enreg
    2788              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    2789              : 
    2790              : !local variables-------------------------------
    2791            1 :  type(green_type) :: green_check
    2792              :  character(len=500) :: message
    2793              : ! *********************************************************************
    2794              : ! Only imaginary frequencies here
    2795            1 :  if(green%w_type=="real") then
    2796            0 :    message = 'check_fourier_green not implemented for real frequency'
    2797            0 :    ABI_BUG(message)
    2798              :  endif
    2799              : 
    2800            1 :  call init_green(green_check,paw_dmft)
    2801            1 :  call init_green_tau(green_check,paw_dmft)
    2802            1 :  call copy_green(green,green_check,opt_tw=2)
    2803              : 
    2804            1 :  write(message,'(2a,i3,13x,a)') ch10,'   ===  Inverse Fourier Transform w->t of Weiss Field'
    2805            1 :  call wrtout(std_out,message,'COLL')
    2806              :  call fourier_green(cryst_struc,green_check,paw_dmft,&
    2807            1 : & opt_ksloc=2,opt_tw=-1)
    2808              : 
    2809            1 :  write(message,'(3a)') ch10,' === Print (for check by user) of occupation matrix'&
    2810            2 : &   ,' after  fourier transform with respect to initial one'
    2811            1 :  call wrtout(std_out,message,'COLL')
    2812            1 :  call printocc_green(green_check,6,paw_dmft,3)
    2813              : 
    2814            1 :  write(message,'(2a,i3,13x,a)') ch10,'   ===  Direct Fourier Transform t->w of Weiss Field'
    2815            1 :  call wrtout(std_out,message,'COLL')
    2816              :  call fourier_green(cryst_struc,green_check,paw_dmft,&
    2817            1 : & opt_ksloc=2,opt_tw=1)
    2818              : ! call print_matlu(green%oper(1)%matlu,paw_dmft%natom,1) ! debug
    2819              : 
    2820              :  call integrate_green(green_check,paw_dmft,&
    2821            1 : & prtopt=2,opt_ksloc=2)
    2822              : 
    2823            1 :  write(message,'(3a)') ch10,' === Print (for check by user) of occupation matrix'&
    2824            2 : &   ,' after double fourier transform with respect to initial one'
    2825            1 :  call wrtout(std_out,message,'COLL')
    2826            1 :  call printocc_green(green_check,5,paw_dmft,3)
    2827              : 
    2828            1 :  call destroy_green_tau(green_check)
    2829            1 :  call destroy_green(green_check)
    2830              : 
    2831            1 : end subroutine check_fourier_green
    2832              : !!***
    2833              : 
    2834              : !!****f* m_green/compa_occup_ks
    2835              : !! NAME
    2836              : !! compa_occup_ks
    2837              : !!
    2838              : !! FUNCTION
    2839              : !!  Compare occupations to Fermi Dirac Occupations
    2840              : !!
    2841              : !! INPUTS
    2842              : !!  green  <type(green_type)>= green function data
    2843              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    2844              : !!
    2845              : !! OUTPUT
    2846              : !!
    2847              : !! SOURCE
    2848              : 
    2849            0 : subroutine compa_occup_ks(green,paw_dmft)
    2850              : 
    2851              : !Arguments ------------------------------------
    2852              : !type
    2853              :  type(green_type),intent(inout) :: green
    2854              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    2855              : 
    2856              : !local variables-------------------------------
    2857              :  character(len=500) :: message
    2858              :  integer :: ib,ikpt,isppol
    2859              :  integer :: ib_,ikpt_,isppol_
    2860              :  integer :: ib__,ikpt__,isppol__
    2861              :  real(dp) :: diffmax,occ1,occ2,occ_a,occ_b,diffrel,occ_aa,occ_bb
    2862              : ! *********************************************************************
    2863            0 :  diffmax=zero
    2864            0 :  diffrel=zero
    2865            0 :  do isppol=1,paw_dmft%nsppol
    2866            0 :    do ikpt=1,paw_dmft%nkpt
    2867            0 :      do ib=1,paw_dmft%mbandc
    2868            0 :        occ1=occup_fd(paw_dmft%eigen_dft(ib,ikpt,isppol),paw_dmft%fermie,paw_dmft%temp)
    2869            0 :        occ2=real(green%occup%ks(ib,ib,ikpt,isppol))
    2870            0 :        if(abs(occ1-occ2)>diffmax) then
    2871            0 :          diffmax=abs(occ1-occ2)
    2872            0 :          occ_a=occ1
    2873            0 :          occ_b=occ2
    2874            0 :          ib_=ib;isppol_=isppol;ikpt_=ikpt
    2875              :        endif
    2876            0 :        if(abs(two*(occ1-occ2)/(occ1+occ2))>diffrel) then
    2877            0 :          diffrel=abs(two*(occ1-occ2)/(occ1+occ2))
    2878            0 :          occ_aa=occ1
    2879            0 :          occ_bb=occ2
    2880            0 :          ib__=ib;isppol__=isppol;ikpt__=ikpt
    2881              :        endif
    2882              :      enddo
    2883              :    enddo
    2884              :  enddo
    2885              : 
    2886              : 
    2887            0 :  write(message,'(2a)') ch10,'   ===  Compare green function occupations and Fermi Dirac occupations'
    2888            0 :  call wrtout(std_out,message,'COLL')
    2889            0 :  write(message,'(2a,f12.5,2a,f12.5,2a,f12.5,2a,3i5)') ch10,'     =  Max difference is',diffmax,&
    2890            0 : &                           ch10,'        Corresponding Occupation from green function is',occ_b,&
    2891            0 : &                           ch10,'        Corresponding Occupation Fermi Dirac weight  is',occ_a,&
    2892            0 : &                           ch10,'        (For polarization, k-point and band index)     ',isppol_,ikpt_,ib_
    2893            0 :  call wrtout(std_out,message,'COLL')
    2894            0 :  write(message,'(2a,f12.5,2a,f12.5,2a,f12.5,2a,3i5)') ch10,'     =  Max relative difference is',diffrel,&
    2895            0 : &                           ch10,'        Corresponding Occupation from green function is',occ_bb,&
    2896            0 : &                           ch10,'        Corresponding Occupation Fermi Dirac weight  is',occ_aa,&
    2897            0 : &                           ch10,'        (For polarization, k-point and band index)     ',isppol__,ikpt__,ib__
    2898            0 :  call wrtout(std_out,message,'COLL')
    2899              : 
    2900            0 : end subroutine compa_occup_ks
    2901              : !!***
    2902              : 
    2903              : !!****f* m_green/add_int_fct
    2904              : !! NAME
    2905              : !! add_int_fct
    2906              : !!
    2907              : !! FUNCTION
    2908              : !! Do integration in matsubara space
    2909              : !!
    2910              : !! COPYRIGHT
    2911              : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
    2912              : !! This file is distributed under the terms of the
    2913              : !! GNU General Public License, see ~abinit/COPYING
    2914              : !! or http://www.gnu.org/copyleft/gpl.txt .
    2915              : !!
    2916              : !! INPUTS
    2917              : !!  ff= function is frequency space
    2918              : !!  ldiag    = option according to diagonal or non-diagonal elements
    2919              : !!  option = nspinor
    2920              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    2921              : !!  proct= for parallelism
    2922              : !!
    2923              : !! SIDE EFFECTS
    2924              : !!  * integral = integral of ff over matsubara frequencies (there is an accumulation in the present routine, so intent(inout))
    2925              : !!  * ft= function is time space
    2926              : !!
    2927              : !! SOURCE
    2928            0 : subroutine add_int_fct(ifreq,ff,ldiag,omega_current,option,integral,temp,wgt_wlo,dmft_nwlo)
    2929              : 
    2930              : !Arguments ------------------------------------
    2931              : !type
    2932              :  integer,intent(in) :: ifreq
    2933              :  logical,intent(in) :: ldiag
    2934              :  integer,intent(in) :: option,dmft_nwlo
    2935              :  complex(dp),intent(inout) :: integral
    2936              :  complex(dp), intent(in) :: ff
    2937              :  complex(dp), intent(in) :: omega_current
    2938              :  real(dp), intent(in) :: temp, wgt_wlo
    2939              : 
    2940              : !local variables-------------------------------
    2941              :  real(dp)  :: omega
    2942              : ! *********************************************************************
    2943            0 :  omega=aimag(omega_current)
    2944            0 :  if(ldiag) then
    2945              : 
    2946            0 :   if(option==1) then ! nspinor==1
    2947              : !   write(500,*) paw_dmft%omega_lo(ifreq),real(ff(ifreq)),imag(ff(ifreq))
    2948              :     integral=integral+2.d0*temp *                         &
    2949              : &      real( ff-one / ( j_dpc*omega ) ) *  &
    2950            0 : &      wgt_wlo
    2951            0 :     if(ifreq==dmft_nwlo) integral=integral+half
    2952              : !    integral=integral+half
    2953              :     ! the if is here, to count only one time this correction
    2954              :   endif
    2955              : 
    2956            0 :   if(option==2) then ! nspinor==2
    2957              :     integral=integral+2.d0*temp *                         &
    2958              : &       ( ff-one / ( j_dpc*omega ) ) *  &
    2959            0 : &   wgt_wlo
    2960            0 :     if(ifreq==dmft_nwlo) integral=integral+half
    2961              : !    integral=integral+half
    2962              :     ! the if is here, to count only one time this correction
    2963              :   endif
    2964              : 
    2965              : 
    2966              :  else   ! ldiag
    2967              : 
    2968              : ! write(std_out,*) "nondiag"
    2969            0 :   if(option==1) then
    2970              :     integral=integral+2.d0*temp *   &
    2971              : &    real( ff ) *                     &
    2972            0 : &   wgt_wlo
    2973              :   endif
    2974            0 :   if(option==2) then
    2975              :     integral=integral+2.d0*temp *   &
    2976              : &        ff   *                     &
    2977            0 : &    wgt_wlo
    2978              :   endif
    2979              :  endif  ! ldiag
    2980              : 
    2981            0 : end subroutine add_int_fct
    2982              : !!***
    2983              : 
    2984              : !!****m* m_green/int_fct
    2985              : !! NAME
    2986              : !! int_fct
    2987              : !!
    2988              : !! FUNCTION
    2989              : !! Do integration in matsubara space
    2990              : !!
    2991              : !! COPYRIGHT
    2992              : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
    2993              : !! This file is distributed under the terms of the
    2994              : !! GNU General Public License, see ~abinit/COPYING
    2995              : !! or http://www.gnu.org/copyleft/gpl.txt .
    2996              : !!
    2997              : !! INPUTS
    2998              : !!  ff= function is frequency space
    2999              : !!  ldiag    = option according to diagonal or non-diagonal elements
    3000              : !!  option = nspinor
    3001              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    3002              : !!  proct= for parallelism
    3003              : !!
    3004              : !! OUTPUT
    3005              : !!  integral = integral of ff over matsubara frequencies
    3006              : !!
    3007              : !! SIDE EFFECTS
    3008              : !!  ft= function is time space
    3009              : !!
    3010              : !! SOURCE
    3011            0 : subroutine int_fct(ff,ldiag,option,paw_dmft,integral,procb,myproc)
    3012              : 
    3013              : !Arguments ------------------------------------
    3014              : !type
    3015              :  logical,intent(in) :: ldiag
    3016              :  integer,intent(in) :: option
    3017              :  complex(dp),intent(out) :: integral
    3018              :  type(paw_dmft_type), intent(in) :: paw_dmft
    3019              :  complex(dp), intent(in) :: ff(paw_dmft%dmft_nwlo)
    3020              :  integer, optional, intent(in) :: procb(paw_dmft%dmft_nwlo)
    3021              :  integer, optional, intent(in) :: myproc
    3022              : 
    3023              : !local variables-------------------------------
    3024            0 :  logical, allocatable :: procb2(:)
    3025              :  character(len=500) :: message
    3026              :  integer :: ifreq
    3027              : ! *********************************************************************
    3028            0 :  ABI_MALLOC(procb2,(paw_dmft%dmft_nwlo))
    3029            0 :  if(present(procb).and.present(myproc)) then
    3030            0 :    do ifreq=1,paw_dmft%dmft_nwlo
    3031            0 :     procb2(ifreq)=(procb(ifreq)==myproc)
    3032              :    enddo
    3033            0 :  else if(present(procb).and..not.present(myproc)) then
    3034            0 :    write(message,'(a,a,2(e15.4))') ch10,&
    3035            0 : &    "BUG: procb is present and not myproc in int_fct"
    3036            0 :    ABI_BUG(message)
    3037            0 :  else if(.not.present(procb).and.present(myproc)) then
    3038            0 :    write(message,'(a,a,2(e15.4))') ch10,&
    3039            0 : &    "BUG: procb is not present and myproc is in int_fct"
    3040            0 :    ABI_BUG(message)
    3041              :  else
    3042            0 :    do ifreq=1,paw_dmft%dmft_nwlo
    3043            0 :      procb2(ifreq)=(1==1)
    3044              :    enddo
    3045              :  endif
    3046              : 
    3047            0 :  integral=czero
    3048            0 :  if(ldiag) then
    3049              : 
    3050            0 :   if(option==1) then ! nspinor==1
    3051            0 :     do ifreq=1,paw_dmft%dmft_nwlo
    3052            0 :       if(procb2(ifreq)) then
    3053              : !     write(500,*) paw_dmft%omega_lo(ifreq),real(ff(ifreq)),imag(ff(ifreq))
    3054              :        integral=integral+2.d0*paw_dmft%temp *                         &
    3055              : &        real( ff(ifreq)-one / ( j_dpc*paw_dmft%omega_lo(ifreq) ) ) *  &
    3056            0 : &        paw_dmft%wgt_wlo(ifreq)
    3057              :       endif
    3058              :     enddo
    3059            0 :     if(procb2(paw_dmft%dmft_nwlo)) integral=integral+half
    3060              : !    integral=integral+half
    3061              :     ! the if is here, to count only one time this correction
    3062              :   endif
    3063              : 
    3064            0 :   if(option==2) then ! nspinor==2
    3065            0 :     do ifreq=1,paw_dmft%dmft_nwlo
    3066            0 :       if(procb2(ifreq)) then
    3067              :         integral=integral+2.d0*paw_dmft%temp *                         &
    3068              : &           ( ff(ifreq)-one / ( j_dpc*paw_dmft%omega_lo(ifreq) ) ) *  &
    3069            0 : &       paw_dmft%wgt_wlo(ifreq)
    3070              :       endif
    3071              :     enddo
    3072            0 :     if(procb2(paw_dmft%dmft_nwlo)) integral=integral+half
    3073              : !    integral=integral+half
    3074              :     ! the if is here, to count only one time this correction
    3075              :   endif
    3076              : 
    3077              : 
    3078              :  else   ! ldiag
    3079              : 
    3080              : ! write(std_out,*) "nondiag"
    3081            0 :   if(option==1) then
    3082            0 :     do ifreq=1,paw_dmft%dmft_nwlo
    3083            0 :       if(procb2(ifreq)) then
    3084              :         integral=integral+2.d0*paw_dmft%temp *   &
    3085              : &        real( ff(ifreq) ) *                     &
    3086            0 : &       paw_dmft%wgt_wlo(ifreq)
    3087              :       endif
    3088              :     enddo
    3089              :   endif
    3090            0 :   if(option==2) then
    3091            0 :     do ifreq=1,paw_dmft%dmft_nwlo
    3092            0 :       if(procb2(ifreq)) then
    3093              :         integral=integral+2.d0*paw_dmft%temp *   &
    3094              : &            ff(ifreq)   *                     &
    3095            0 : &        paw_dmft%wgt_wlo(ifreq)
    3096              :       endif
    3097              :     enddo
    3098              :   endif
    3099              :  endif  ! ldiag
    3100            0 :  ABI_FREE(procb2)
    3101              : 
    3102            0 : end subroutine int_fct
    3103              : !!***
    3104              : 
    3105              : !!****f* m_green/fourier_fct
    3106              : !! NAME
    3107              : !! fourier_fct
    3108              : !!
    3109              : !! FUNCTION
    3110              : !! Do fourier transformation from matsubara space to imaginary time
    3111              : !! (A spline is performed )
    3112              : !!
    3113              : !! COPYRIGHT
    3114              : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
    3115              : !! This file is distributed under the terms of the
    3116              : !! GNU General Public License, see ~abinit/COPYING
    3117              : !! or http://www.gnu.org/copyleft/gpl.txt .
    3118              : !!
    3119              : !! INPUTS
    3120              : !!  ldiag    = option according to diagonal or non-diagonal elements
    3121              : !!  opt_four = option for direct (1) or inverse (-1) fourier transform
    3122              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    3123              : !!
    3124              : !! OUTPUT
    3125              : !!
    3126              : !! SIDE EFFECTS
    3127              : !!  fw= function is frequency space
    3128              : !!  ft= function is time space
    3129              : !!
    3130              : !! SOURCE
    3131          100 : subroutine fourier_fct(fw,ft,ldiag,ltau,opt_four,paw_dmft)
    3132              : 
    3133              : !Arguments ------------------------------------
    3134              : !type
    3135              :  logical,intent(in) :: ldiag
    3136              :  integer,intent(in) :: ltau,opt_four
    3137              :  type(paw_dmft_type), intent(in) :: paw_dmft
    3138              :  complex(dp), intent(inout) :: fw(paw_dmft%dmft_nwlo)
    3139              :  complex(dp), intent(inout) :: ft(ltau)
    3140              : 
    3141              : !local variables-------------------------------
    3142          100 :  complex(dp), allocatable ::  splined_li(:)
    3143          100 :  complex(dp), allocatable ::  tospline_li(:)
    3144              : ! complex(dp), allocatable :: fw1(:)
    3145          100 :  real(dp), allocatable :: ftr(:)
    3146              :  real(dp) :: beta
    3147              :  complex(dp) :: xsto
    3148              :  integer :: iflag,ifreq,itau,iwarn,log_direct
    3149              :  character(len=500) :: message
    3150          100 :  real(dp), allocatable :: omega_li(:)
    3151              : ! *********************************************************************
    3152          100 :  beta=one/paw_dmft%temp
    3153          100 :  iflag=0
    3154          100 :  log_direct=1
    3155              : 
    3156          100 :  if(ldiag) iflag=1
    3157              : 
    3158              : ! == inverse fourier transform
    3159          100 :  if(opt_four==-1) then
    3160              : 
    3161          150 :    ABI_MALLOC(splined_li,(paw_dmft%dmft_nwli))
    3162              : !   allocate(fw1(0:paw_dmft%dmft_nwlo-1))
    3163           50 :    if(paw_dmft%dmft_log_freq==1) then
    3164          150 :      ABI_MALLOC(omega_li,(1:paw_dmft%dmft_nwli))
    3165           50 :      call construct_nwli_dmft(paw_dmft,paw_dmft%dmft_nwli,omega_li)
    3166              :      call spline_c(paw_dmft%dmft_nwlo,paw_dmft%dmft_nwli,paw_dmft%omega_lo,&
    3167           50 : &                   omega_li,splined_li,fw)
    3168           50 :      ABI_FREE(omega_li)
    3169              :    else
    3170            0 :      splined_li=fw
    3171              :    endif
    3172           50 :    call invfourier(splined_li,ft,paw_dmft%dmft_nwli,ltau,iflag,beta)
    3173              : !   deallocate(fw1)
    3174           50 :    ABI_FREE(splined_li)
    3175              : 
    3176              : ! == direct fourier transform
    3177           50 :  else if(opt_four==1) then
    3178              : 
    3179          150 :    ABI_MALLOC(ftr,(ltau))
    3180              : 
    3181         3250 :    iwarn=0
    3182         3250 :    do itau=1,ltau
    3183         3250 :      if(abs(aimag(ft(itau)))>tol12) then
    3184            0 :        if(ldiag) then
    3185            0 :          write(message,'(a,a,2(e15.4))') ch10,&
    3186            0 : &          "green function is not real in imaginary time space",ft(itau)
    3187            0 :          ABI_ERROR(message)
    3188              :        else
    3189            0 :          iwarn=iwarn+1
    3190            0 :          ftr(itau)=real(ft(itau))
    3191            0 :          xsto=ft(itau)
    3192              :        endif
    3193              :      else
    3194         3200 :        ftr(itau)=real(ft(itau))
    3195              :      endif
    3196              : !       write(std_out,*) itau,ftr(itau)
    3197              :    enddo
    3198              : 
    3199          150 :    ABI_MALLOC(tospline_li,(paw_dmft%dmft_nwli))
    3200              :    if (log_direct==1) then
    3201              : !   do not have a physical meaning..because the log frequency is not
    3202              : !   one of the linear frequency.
    3203              : !   if log frequencies are also one of linear frequency, it should be good
    3204         1650 :      do ifreq=1, paw_dmft%dmft_nwlo
    3205         1650 :        call nfourier2(ftr,fw(ifreq),iflag,paw_dmft%omega_lo(ifreq),ltau,beta)
    3206              :      enddo
    3207              :    else
    3208              :      call nfourier(ftr,tospline_li,iflag,paw_dmft%dmft_nwli-1,ltau,beta)
    3209              :      do ifreq=1,paw_dmft%dmft_nwli
    3210              :         write(1112,*) paw_dmft%temp*pi*real(2*ifreq-1,kind=dp),real(tospline_li(ifreq),kind=dp),aimag(tospline_li(ifreq))
    3211              :         !write(1112,*) paw_dmft%omega_li(ifreq),real(tospline_li(ifreq)),aimag(tospline_li(ifreq))
    3212              :      enddo
    3213              :      if(paw_dmft%dmft_log_freq==1) then
    3214              :        ABI_MALLOC(omega_li,(1:paw_dmft%dmft_nwli))
    3215              :        call construct_nwli_dmft(paw_dmft,paw_dmft%dmft_nwli,omega_li)
    3216              :        call spline_c(paw_dmft%dmft_nwli,paw_dmft%dmft_nwlo,omega_li,&
    3217              : &                 paw_dmft%omega_lo,fw,tospline_li)
    3218              :        ABI_FREE(omega_li)
    3219              :      else
    3220              :        fw=tospline_li
    3221              :      endif
    3222              :    endif
    3223              : 
    3224           50 :    ABI_FREE(tospline_li)
    3225              : 
    3226           50 :    ABI_FREE(ftr)
    3227           50 :    if(iwarn>0) then
    3228            0 :      write(message,'(a,a,2(e15.4))') ch10,&
    3229            0 : &     "WARNING: off-diag green function is not real in imaginary time space",xsto
    3230            0 :      call wrtout(std_out,message,'COLL')
    3231              :    endif
    3232              : 
    3233              :  endif
    3234              : 
    3235          100 : end subroutine fourier_fct
    3236              : !!***
    3237              : 
    3238              : !!****f* m_green/spline_fct
    3239              : !! NAME
    3240              : !! spline_fct
    3241              : !!
    3242              : !! FUNCTION
    3243              : !! Do fourier transformation from matsubara space to imaginary time
    3244              : !! (A spline is performed )
    3245              : !!
    3246              : !! COPYRIGHT
    3247              : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
    3248              : !! This file is distributed under the terms of the
    3249              : !! GNU General Public License, see ~abinit/COPYING
    3250              : !! or http://www.gnu.org/copyleft/gpl.txt .
    3251              : !!
    3252              : !! INPUTS
    3253              : !!  opt_spline = option for the spline
    3254              : !!              -1 log to linear.
    3255              : !!               1 linear to log.
    3256              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    3257              : !!
    3258              : !! OUTPUT
    3259              : !!
    3260              : !! SIDE EFFECTS
    3261              : !!  fw= function is frequency space
    3262              : !!  ft= function is time space
    3263              : !!
    3264              : !! SOURCE
    3265              : 
    3266            0 : subroutine spline_fct(fw1,fw2,opt_spline,paw_dmft)
    3267              : 
    3268              : !Arguments ------------------------------------
    3269              : !type
    3270              :  integer,intent(in) :: opt_spline
    3271              :  type(paw_dmft_type), intent(in) :: paw_dmft
    3272              :  complex(dp), intent(inout) :: fw1(:)
    3273              :  complex(dp), intent(inout) :: fw2(:)
    3274              :  integer :: size_fw1
    3275              :  integer :: size_fw2
    3276            0 :  real(dp), allocatable :: omega_li(:)
    3277              : ! *********************************************************************
    3278              : 
    3279            0 :  size_fw1 = size(fw1)
    3280            0 :  size_fw2 = size(fw2)
    3281              : 
    3282              : ! == inverse fourier transform
    3283            0 :  if(opt_spline==-1) then
    3284              : 
    3285              : !   allocate(fw1(0:paw_dmft%dmft_nwlo-1))
    3286            0 :    if(paw_dmft%dmft_log_freq==1) then
    3287            0 :      ABI_MALLOC(omega_li,(1:size_fw2))
    3288            0 :      call construct_nwli_dmft(paw_dmft,size_fw2,omega_li)
    3289              :      call spline_c(size_fw1,size_fw2,paw_dmft%omega_lo(1:size_fw1),&
    3290            0 : &                   omega_li(1:size_fw2),fw2,fw1)
    3291            0 :      ABI_FREE(omega_li)
    3292              :    else
    3293            0 :      fw2=fw1
    3294              :    endif
    3295              : 
    3296              : ! == direct fourier transform
    3297            0 :  else if(opt_spline==1) then
    3298              : 
    3299              : 
    3300            0 :    if(paw_dmft%dmft_log_freq==1) then
    3301            0 :      ABI_MALLOC(omega_li,(1:size_fw2))
    3302            0 :      call construct_nwli_dmft(paw_dmft,size_fw2,omega_li)
    3303              :      call spline_c(size_fw2,size_fw1,omega_li(1:size_fw2),&
    3304            0 : &                 paw_dmft%omega_lo(1:size_fw1),fw1,fw2)
    3305            0 :      ABI_FREE(omega_li)
    3306              :    else
    3307            0 :      fw1=fw2
    3308              :    endif
    3309              : 
    3310              :  endif
    3311              : 
    3312            0 : end subroutine spline_fct
    3313              : !!***
    3314              : 
    3315              : !!****f* m_green/occup_green_tau
    3316              : !! NAME
    3317              : !! occup_green_tau
    3318              : !!
    3319              : !! FUNCTION
    3320              : !!  Compute occup_tau from green%oper_tau
    3321              : !!
    3322              : !! INPUTS
    3323              : !!  green  <type(green_type)>= green function data
    3324              : !!
    3325              : !! OUTPUT
    3326              : !!
    3327              : !! SOURCE
    3328              : 
    3329           68 : subroutine occup_green_tau(green)
    3330              : 
    3331              : !Arguments ------------------------------------
    3332              :  type(green_type), intent(inout) :: green
    3333              : !Local variables-------------------------------
    3334              :  integer :: natom
    3335           68 :  complex(dp), allocatable :: shift(:)
    3336              : ! *********************************************************************
    3337              : 
    3338           68 :  natom = green%oper_tau(1)%natom
    3339              : 
    3340          204 :  ABI_MALLOC(shift,(natom))
    3341              : 
    3342          192 :  shift(:) = - cone
    3343              : 
    3344           68 :  call copy_matlu(green%oper_tau(1)%matlu(:),green%occup_tau%matlu(:),natom)
    3345           68 :  call shift_matlu(green%occup_tau%matlu(:),natom,shift(:))
    3346              : 
    3347           68 :  ABI_FREE(shift)
    3348              : 
    3349           68 : end subroutine occup_green_tau
    3350              : !!***
    3351              : 
    3352              : !!****f* m_green/occupfd
    3353              : !! NAME
    3354              : !! occupfd
    3355              : !!
    3356              : !! FUNCTION
    3357              : !!
    3358              : !! INPUTS
    3359              : !!
    3360              : !! OUTPUT
    3361              : !!
    3362              : !!
    3363              : !! SOURCE
    3364              : 
    3365              :  !function occupfd(eig,fermie,temp)
    3366              : 
    3367              : 
    3368              : !Arguments ------------------------------------
    3369              : !type
    3370              : ! Integrate analytic tail 1/(iw-mu)
    3371              :  !real(dp),intent(in) :: eig,fermie,temp
    3372              :  !real(dp) :: occupfd
    3373              : !Local variables-------------------------------
    3374              : ! *********************************************************************
    3375              : 
    3376              :  !if ((eig-fermie) > zero) then
    3377              :  !  occupfd = exp(-(eig-fermie)/temp)/(one+exp(-(eig-fermie)/temp))
    3378              :  !else
    3379              :  !  occupfd = one / (one+exp((eig-fermie)/temp))
    3380              :  !end if
    3381              : 
    3382              :  !end function occupfd
    3383              : !!***
    3384              : 
    3385              : !!****f* m_green/distrib_paral
    3386              : !! NAME
    3387              : !! distrib_paral
    3388              : !!
    3389              : !! FUNCTION
    3390              : !!
    3391              : !! INPUTS
    3392              : !!  nw : number of frequencies
    3393              : !!  nkpt : number of k-points
    3394              : !!  nproc : number of procs
    3395              : !!
    3396              : !! OUTPUT
    3397              : !!  procb(iw,ikpt) :  number of the proc  that is in charge of the combination {iw,ikpt}.
    3398              : !!  proct(iw,iproc) : 1 if the frequency "iw" should be computed by the proc "iproc"
    3399              : !!                    0 if iw should not   "      "
    3400              : !!                    careful: if proct=1, it does not mean that each combination {iw,ikpt} is treated by this proc.
    3401              : !! SOURCE
    3402              : 
    3403            0 :  subroutine distrib_paral(nkpt,nproc,nw,nw_perproc,procb,proct)
    3404              : 
    3405              : !Arguments ------------------------------------
    3406              : !type
    3407              : ! Integrate analytic tail 1/(iw-mu)
    3408              :  integer, intent(in) :: nw,nkpt,nproc
    3409              :  integer, intent(out) :: nw_perproc
    3410              :  integer, intent(out):: procb(nw,nkpt),proct(nw,0:nproc-1)
    3411              : !Local variables-------------------------------
    3412              :  integer :: ikpt,iw,ir,ratio,m,iproc
    3413            0 :  integer, allocatable :: proca(:,:)
    3414              : ! *********************************************************************
    3415              : 
    3416              : 
    3417            0 :  proct(:,:)=0
    3418            0 :  procb(:,:)=-1
    3419              : 
    3420            0 :  if(nproc.ge.2*nw) then
    3421              :  !write(6,*) "AA"
    3422            0 :    ratio=nproc/nw
    3423            0 :    ABI_MALLOC(proca,(nw,nproc/nw))
    3424            0 :    do ir=1,ratio
    3425            0 :      do iw=1,nw
    3426            0 :        proca(iw,ir)=iw+(ir-1)*nw-1
    3427            0 :        proct(iw,iw+(ir-1)*nw-1)=1
    3428              :      enddo
    3429              :    enddo
    3430              : !     do iw=1,nw
    3431              : !        write(6,*) " freq, procs"
    3432              : !        write(6,*) iw,proca(iw,:)
    3433              : !     enddo
    3434            0 :    do iw=1,nw
    3435            0 :      do ikpt=1,nkpt
    3436            0 :        if(ikpt.le.ratio) procb(iw,ikpt)=proca(iw,ikpt)
    3437            0 :        if(ikpt.ge.ratio) then
    3438            0 :          m=mod(ikpt,ratio)
    3439            0 :          if(m==0) then
    3440            0 :             procb(iw,ikpt)=proca(iw,ratio)
    3441              :          else
    3442            0 :             procb(iw,ikpt)=proca(iw,m)
    3443              :          endif
    3444              :        endif
    3445              : !       write(6,*) " freq, k-point, proc"
    3446              : !       write(6,*) iw,ikpt,procb(iw,ikpt)
    3447              :      enddo
    3448              :    enddo
    3449            0 :    nw_perproc=1
    3450            0 :    ABI_FREE(proca)
    3451              : 
    3452            0 :  else if (nproc.ge.nw) then
    3453              :  !write(6,*) "BB"
    3454            0 :    do iw=1,nw
    3455            0 :      procb(iw,:)= iw
    3456            0 :      proct(iw,iw)=1
    3457              :    enddo
    3458              : !  do iw=1,nw
    3459              : !        write(6,*) " freq, proc"
    3460              : !        write(6,*) iw, procb(iw,1)
    3461              : !  enddo
    3462            0 :    nw_perproc=1
    3463              : 
    3464              :  else if (nproc.le.nw) then
    3465              :  !write(6,*) "CC"
    3466            0 :    ratio=nw/nproc
    3467              :  !write(6,*) "ratio", ratio
    3468            0 :    do iproc=0,nproc-1
    3469            0 :      do iw=1,nw
    3470            0 :        if (mod(iw-1,nproc)==iproc) then
    3471            0 :          procb(iw,:)=iproc
    3472            0 :          proct(iw,iproc)=1
    3473              :        endif
    3474              :      enddo
    3475              :    enddo
    3476              :     ! do iw=1,nw
    3477              :     !   write(6,*) "iw, iproc", iw, procb(iw,1)
    3478              :     ! enddo
    3479            0 :    nw_perproc=ratio+1
    3480              : !  some procs will compute a number of frequency which is ratio and some
    3481              : !  other will compute a number of frequency which is ratio+1.
    3482              : 
    3483              : !  do iw=1,nw
    3484              : !        write(6,*) " freq, proc"
    3485              : !        write(6,*) iw, procb(iw,1)
    3486              : !  enddo
    3487              :   endif
    3488              : 
    3489              : !     do iw=1,nw
    3490              : !      do iproc=0,nproc-1
    3491              : !        write(6,*) " freq, procs,?"
    3492              : !        write(6,*) iw,iproc,proct(iw,iproc)
    3493              : !      enddo
    3494              : !     enddo
    3495              : 
    3496              : 
    3497              : 
    3498            0 :  end subroutine distrib_paral
    3499              : !!***
    3500              : 
    3501              : !!****f* ABINIT/greendftcompute_green
    3502              : !! NAME
    3503              : !! greendftcompute_green
    3504              : !!
    3505              : !! FUNCTION
    3506              : !! Compute levels for ctqmc
    3507              : !!
    3508              : !! COPYRIGHT
    3509              : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
    3510              : !! This file is distributed under the terms of the
    3511              : !! GNU General Public License, see ~abinit/COPYING
    3512              : !! or http://www.gnu.org/copyleft/gpl.txt .
    3513              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
    3514              : !!
    3515              : !! INPUTS
    3516              : !!
    3517              : !! OUTPUT
    3518              : !!
    3519              : !! SOURCE
    3520              : 
    3521            0 :  subroutine greendftcompute_green(green,paw_dmft)
    3522              : 
    3523              : !Arguments ------------------------------------
    3524              : !scalars
    3525              :  type(paw_dmft_type), intent(in)  :: paw_dmft
    3526              :  type(green_type),intent(inout) :: green
    3527              : 
    3528              : !Local variables ------------------------------
    3529              : ! scalars
    3530              :  integer :: ifreq,iband,ikpt,isppol
    3531              :  integer :: mbandc,natom,nspinor,nsppol,nkpt
    3532              :  character(len=500) :: message
    3533              : ! arrays
    3534              : !************************************************************************
    3535              : 
    3536            0 :  mbandc=paw_dmft%mbandc
    3537            0 :  nkpt=paw_dmft%nkpt
    3538            0 :  nsppol=paw_dmft%nsppol
    3539            0 :  nspinor=paw_dmft%nspinor
    3540            0 :  natom=paw_dmft%natom
    3541              : 
    3542              :      !  write(6,*) green%oper(1)%ks(1,1,1,1)
    3543            0 :  if(green%oper(1)%has_operks==0) then
    3544            0 :   ABI_ERROR("greendft%oper(1)%ks not allocated")
    3545              :  endif
    3546              : 
    3547              : !======================================
    3548              : !Get Green's function G=1/(iw_n+mu-e_nk)
    3549              : !======================================
    3550            0 :  do ifreq=1,green%nw
    3551            0 :    do iband=1,mbandc
    3552            0 :      do ikpt=1,nkpt
    3553            0 :        do isppol=1,nsppol
    3554              :      !  write(6,*) green%oper(ifreq)%ks(isppol,ikpt,iband,iband)
    3555              :      !  write(6,*) ifreq,iband,ikpt,isppol
    3556              :      !  write(6,*) cmplx(0.d0,paw_dmft%omega_lo(ifreq),kind=dp)
    3557              :      !  write(6,*) paw_dmft%fermie
    3558              :      !  write(6,*) paw_dmft%eigen_dft(isppol,ikpt,iband)
    3559              :          green%oper(ifreq)%ks(iband,iband,ikpt,isppol)=&
    3560            0 :          cone/(cmplx(0.d0,paw_dmft%omega_lo(ifreq),kind=dp)+paw_dmft%fermie-paw_dmft%eigen_dft(iband,ikpt,isppol))
    3561              :        end do
    3562              :      end do
    3563              :    end do
    3564              : 
    3565              : 
    3566              : !======================================================================
    3567              : ! Compute local Green's function
    3568              : !======================================================================
    3569            0 :    call downfold_oper(green%oper(ifreq),paw_dmft)
    3570              : 
    3571              : !======================================================================
    3572              : ! Symetrize
    3573              : !======================================================================
    3574            0 :    call sym_matlu(green%oper(ifreq)%matlu,paw_dmft)
    3575              :  enddo
    3576            0 :  write(message,'(a,2x,a,f13.5)') ch10," == Print DFT Green's function for last frequency"
    3577            0 :  call wrtout(std_out,message,'COLL')
    3578            0 :  call print_matlu(green%oper(paw_dmft%dmft_nwlo)%matlu,natom,1)
    3579              : 
    3580            0 :  end subroutine greendftcompute_green
    3581              : !!***
    3582              : 
    3583              : !!****f* m_green/fermi_green
    3584              : !! NAME
    3585              : !! fermi_green
    3586              : !!
    3587              : !! FUNCTION
    3588              : !!  Compute Fermi level for DMFT or DFT.
    3589              : !!
    3590              : !! COPYRIGHT
    3591              : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
    3592              : !! This file is distributed under the terms of the
    3593              : !! GNU General Public License, see ~abinit/COPYING
    3594              : !! or http://www.gnu.org/copyleft/gpl.txt .
    3595              : !!
    3596              : !! INPUTS
    3597              : !!  green  <type(green_type)>= green function data
    3598              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    3599              : !!  self <type(self_type)>= variables related to self-energy
    3600              : !!
    3601              : !! OUTPUT
    3602              : !!
    3603              : !! SOURCE
    3604              : 
    3605          199 : subroutine fermi_green(green,paw_dmft,self)
    3606              : 
    3607              : !Arguments ------------------------------------
    3608              :  type(green_type), intent(inout) :: green
    3609              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    3610              :  !type(MPI_type), intent(in) :: mpi_enreg
    3611              :  type(self_type), intent(inout) :: self
    3612              : !Local variables-------------------------------
    3613              :  integer :: ierr_hh,max_iter
    3614              :  real(dp) :: f_precision,fermi_old,x_precision
    3615              : ! real(dp) :: hx
    3616              :  character(len=13) :: tag
    3617              :  character(len=500) :: message
    3618              : !************************************************************************
    3619              : !
    3620              :  ABI_NVTX_START_RANGE(NVTX_DMFT_FERMI_GREEN)
    3621          199 :  write(message,'(a,8x,a)') ch10,"  == Compute Fermi level"
    3622          199 :  call wrtout(std_out,message,'COLL')
    3623              : 
    3624              : !=============
    3625              : !headers
    3626              : !=============
    3627          199 :  write(message,'(2a)') ch10,"  |--- Newton method to search for Fermi level ------------|"
    3628          199 :  call wrtout(std_out,message,'COLL')
    3629          199 :  write(tag,'(f13.6)') paw_dmft%fermie
    3630          199 :  write(message,'(3a)') ch10,"  |--- Initial value for Fermi level ",adjustl(tag)
    3631          199 :  call wrtout(std_out,message,'COLL')
    3632              : 
    3633              : !========================================
    3634              : !Define precision and nb of iterations
    3635              : !=========================================
    3636          199 :  fermi_old = paw_dmft%fermie
    3637          199 :  ierr_hh = 0
    3638          199 :  f_precision = paw_dmft%dmft_charge_prec
    3639              :  !f_precision=0.01
    3640          199 :  x_precision = tol5
    3641              : !if(option==1) then
    3642              : !f_precision=(erreursurlacharge)/100d0
    3643              : !else
    3644              : !f_precision=tol11
    3645              : !endif
    3646              :  !max_iter=1 ! for tests only
    3647              :  !write(6,*) "for tests max_iter=1"
    3648          199 :  max_iter = 50
    3649              :  !opt_noninter = 4
    3650              : 
    3651              :  ! Precompute some useful quantities so that the update of the moments can be done in constant time at each iteration
    3652          199 :  green%trace_fermie(1) = cmplx(paw_dmft%nsppol*paw_dmft%mbandc,zero,kind=dp)
    3653          199 :  if (paw_dmft%nsppol == 1 .and. paw_dmft%nspinor == 1) green%trace_fermie(1) = &
    3654          108 :                & green%trace_fermie(1) * two
    3655          199 :  if (green%has_moments == 1) then
    3656            0 :    call compute_trace_moments_ks(green,self,paw_dmft)
    3657              :  end if
    3658              : 
    3659              : !=====================
    3660              : !Call newton method
    3661              : !=====================
    3662          199 :  write(message,'(a,4x,a,e13.6)') ch10," Precision required :",f_precision
    3663          199 :  call wrtout(std_out,message,'COLL')
    3664          199 :  if (f_precision < ten) then
    3665          199 :    call newton(green,self,paw_dmft,paw_dmft%fermie,x_precision,max_iter,f_precision,ierr_hh)
    3666              :  end if
    3667              : 
    3668              : !===========================
    3669              : !Deals with errors signals
    3670              : !===========================
    3671          199 :  if (ierr_hh == -314) then
    3672            0 :    write(message,'(a)') "Warning, check Fermi level"
    3673            0 :    call wrtout(std_out,message,'COLL')
    3674              : !  call abi_abort('COLL')
    3675            0 :    write(message,'(2a,f13.6)') ch10,"  |--- Final value for Fermi level (check)",paw_dmft%fermie
    3676            0 :    call wrtout(std_out,message,'COLL')
    3677          199 :  else if (ierr_hh == -123) then
    3678            0 :    write(message,'(a,f13.6)') " Fermi level is set to",fermi_old
    3679            0 :    paw_dmft%fermie = fermi_old
    3680            0 :    call wrtout(std_out,message,'COLL')
    3681              : 
    3682              : !  =====================================
    3683              : !  If fermi level search was successful
    3684              : !  =====================================
    3685              :  else
    3686          199 :    write(tag,'(e13.6)') x_precision
    3687          199 :    write(message,'(a,4x,2a)') ch10," Precision achieved on Fermi Level : ",adjustl(tag)
    3688          199 :    call wrtout(std_out,message,'COLL')
    3689          199 :    write(tag,'(e13.6)') f_precision
    3690          199 :    write(message,'(4x,2a)') " Precision achieved on number of electrons : ",adjustl(tag)
    3691          199 :    call wrtout(std_out,message,'COLL')
    3692          199 :    write(tag,'(f13.6)') paw_dmft%fermie
    3693          199 :    write(message,'(3a)') ch10,"  |--- Final value for Fermi level ",adjustl(tag)
    3694          199 :    call wrtout(std_out,message,'COLL')
    3695              :  end if ! ierr_hh
    3696              : 
    3697              : !========================================================
    3698              : ! Check convergence of fermi level during DMFT iterations
    3699              : !========================================================
    3700          199 :  if (paw_dmft%idmftloop >= 2) then
    3701          110 :    if (abs(paw_dmft%fermie-fermi_old) <= paw_dmft%dmft_fermi_prec) then
    3702              : !    write(message,'(a,8x,a,e9.2,a,8x,a,e12.5)') ch10,"|fermie(n)-fermie(n-1)|=<",paw_dmft%dmft_fermi_prec,ch10,&
    3703            1 :      write(message,'(a,8x,a,e9.2,a,e9.2,a,8x,a,e12.5)') ch10,"|fermie(n)-fermie(n-1)|=",&
    3704            1 :        & abs(paw_dmft%fermie-fermi_old),"<",paw_dmft%dmft_fermi_prec,ch10,&
    3705            2 :        & "=> DMFT Loop: Fermi level is converged to:",paw_dmft%fermie
    3706            1 :      call wrtout(std_out,message,'COLL')
    3707            1 :      green%ifermie_cv = 1
    3708              :    else
    3709          109 :      write(tag,'(f12.5)') paw_dmft%fermie
    3710          109 :      write(message,'(a,8x,2a)') ch10,"DMFT Loop: Fermi level is not converged: ",adjustl(tag)
    3711          109 :      call wrtout(std_out,message,'COLL')
    3712          109 :      green%ifermie_cv = 0
    3713              :    end if ! convergence of Fermi level
    3714              :  end if ! idmftloop>=2
    3715          199 :  write(message,'(2a)') ch10, "  |---------------------------------------------------|"
    3716          199 :  call wrtout(std_out,message,'COLL')
    3717              : !
    3718              : !==========================================================
    3719              : !Recompute full green function including non diag elements
    3720              : !==========================================================
    3721              :  !call compute_green(green,paw_dmft,0,self,opt_self=1,opt_nonxsum=1)
    3722              :  !call integrate_green(green,paw_dmft,prtopt=0,opt_ksloc=3) !,opt_nonxsum=1)
    3723              : 
    3724              :  ABI_NVTX_END_RANGE()
    3725              :  !return
    3726          199 : end subroutine fermi_green
    3727              : !!***
    3728              : 
    3729              : !!****f* m_green/newton
    3730              : !! NAME
    3731              : !! newton
    3732              : !!
    3733              : !! FUNCTION
    3734              : !!  Compute root of a function with newton methods (newton/halley)
    3735              : !!
    3736              : !! COPYRIGHT
    3737              : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
    3738              : !! This file is distributed under the terms of the
    3739              : !! GNU General Public License, see ~abinit/COPYING
    3740              : !! or http://www.gnu.org/copyleft/gpl.txt .
    3741              : !!
    3742              : !! INPUTS
    3743              : !!  green  <type(green_type)>= green function data
    3744              : !!  self <type(self_type)>= variables related to self-energy
    3745              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    3746              : !!  x_input      : input value for x
    3747              : !!  max_iter     : maximum number of iterations
    3748              : !!  f_precision  : required precision on function F
    3749              : !!  opt_algo     : 1 for Newton, 2 for Halley
    3750              : !!
    3751              : !! OUTPUT
    3752              : !!  x_precision  : output precision on x
    3753              : !!  ierr_hh      : different from zero if an error occurs
    3754              : !!
    3755              : !! SOURCE
    3756              : 
    3757          199 : subroutine newton(green,self,paw_dmft,x_input,x_precision,max_iter,&
    3758              :                 & f_precision,ierr_hh,opt_algo)
    3759              : 
    3760              : !Arguments ------------------------------------
    3761              :  type(green_type), intent(inout) :: green
    3762              :  type(self_type), intent(inout) :: self
    3763              :  !type(MPI_type), intent(in) :: mpi_enreg
    3764              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    3765              :  integer, intent(in) :: max_iter
    3766              :  integer, intent(out) :: ierr_hh
    3767              :  real(dp), intent(in) :: f_precision
    3768              :  real(dp), intent(inout) :: x_input,x_precision
    3769              :  integer, optional, intent(in) :: opt_algo
    3770              : !Local variables-------------------------------
    3771              :  integer :: iter,option
    3772              :  logical :: dmft_optim,l_minus,l_plus
    3773              :  real(dp) :: Fx,Fxdouble,Fxoptimum,Fxprime,nb_elec_x,step
    3774              :  real(dp) :: x_minus,x_optimum,x_plus,xold
    3775              :  character(len=500) :: message
    3776              : ! *********************************************************************
    3777              : 
    3778          199 :  x_minus = - dble(10)
    3779          199 :  x_plus  = - dble(11)
    3780          199 :  xold    = - dble(12)
    3781              : 
    3782          199 :  ierr_hh = 0
    3783          199 :  option = 1
    3784          199 :  if (present(opt_algo)) option = opt_algo
    3785          199 :  step = paw_dmft%dmft_fermi_step
    3786              : 
    3787              : !write(std_out,*) "ldaprint",opt_noninter
    3788              : 
    3789              : !--- Start of iterations
    3790          199 :  write(message,'(a,3a)') "     Fermi level   Charge    Difference"
    3791          199 :  call wrtout(std_out,message,'COLL')
    3792              : !do iter=1, 40
    3793              : !x_input=float(iter)/100_dp
    3794              : !call function_and_deriv(cryst_struc,f_precision,green,iter,mpi_enreg,paw_dmft,pawang,self,&
    3795              : !&  x_input,x_before,x_precision,Fx,Fxprime,Fxdouble,opt_noninter,option)
    3796              : !write(std_out,*) x_input,Fx
    3797              : !enddo
    3798              : !call abi_abort('COLL')
    3799              : 
    3800          199 :  l_minus = .false.
    3801          199 :  l_plus  = .false.
    3802          199 :  Fxoptimum = one
    3803          199 :  x_optimum = zero
    3804              : 
    3805          199 :  dmft_optim = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
    3806              : 
    3807          199 :  if (dmft_optim) xold = x_input
    3808              : 
    3809              : !========================================
    3810              : ! Start iteration to find fermi level
    3811              : !========================================
    3812         2394 :  do iter=1,max_iter
    3813              : 
    3814              : !  ========================================
    3815              : !  If zero is located between two values: apply newton method or dichotomy
    3816              : !  ========================================
    3817         2394 :    if ((l_minus .and. l_plus) .or. dmft_optim) then
    3818              : 
    3819              : !    ==============================================
    3820              : !    Compute the function and derivatives for newton
    3821              : !    ==============================================
    3822              :      call function_and_deriv(green,self,paw_dmft,x_input,x_precision, &
    3823         1975 :                            & f_precision,Fx,Fxprime,Fxdouble,option)
    3824              : 
    3825              : !    Apply stop criterion on Fx
    3826         1975 :      if (abs(Fx) < f_precision) then
    3827              : !      write(message,'(a,2f12.6)') "Fx,f_precision",Fx,f_precision
    3828              : !      call wrtout(std_out,message,'COLL')
    3829          199 :        x_precision = x_input - xold
    3830          199 :        return
    3831              :      end if ! abs(Fx)<f_precision
    3832         1776 :      if (iter == max_iter) then
    3833            0 :        write(message,'(a,2f12.6)') "   Fermi level could not be found"
    3834            0 :        call wrtout(std_out,message,'COLL')
    3835            0 :        x_input = x_optimum
    3836            0 :        ierr_hh = -123
    3837            0 :        return
    3838              :      end if ! iter=max_iter
    3839              : 
    3840              : !    Cannot divide by Fxprime if too small
    3841         1776 :      if (abs(Fxprime) <= tol15) then
    3842            0 :        ierr_hh = -314
    3843            0 :        write(message,'(a,f12.7)') "Fxprime=",Fxprime
    3844            0 :        call wrtout(std_out,message,'COLL')
    3845            0 :        return
    3846              :      end if ! abs(Fxprime)<=tol15
    3847              : 
    3848         1776 :      x_precision = x_input - xold
    3849              : 
    3850              : !    ==============================================
    3851              : !    Newton/Halley's formula for next iteration
    3852              : !    ==============================================
    3853         1776 :      xold = x_input
    3854         1776 :      if (option == 1) then
    3855         1776 :        if (dmft_optim) then
    3856            0 :          x_input = x_input - sign(one,Fx)*merge(step,min(step,abs(Fx/Fxprime)),Fxprime<0)
    3857              :        else
    3858         1776 :          x_input = x_input - Fx/Fxprime
    3859              :        end if ! dmft_optim
    3860              :      end if ! option=1
    3861         1776 :      if (option == 2) x_input = x_input - two*Fx*Fxprime/(two*(Fxprime**2)-Fx*Fxdouble)
    3862              : 
    3863              : !    ==============================================
    3864              : !    If newton does not work well, use dichotomy.
    3865              : !    ==============================================
    3866              : 
    3867         1776 :      if (dmft_optim) then
    3868            0 :        if (Fx < 0) then
    3869            0 :          l_minus = .true.
    3870            0 :          x_minus = xold
    3871              :        end if
    3872            0 :        if (Fx > 0) then
    3873            0 :          l_plus = .true.
    3874            0 :          x_plus = xold
    3875              :        end if
    3876              :      end if ! dmft_optim
    3877              : 
    3878         1776 :      if ((x_input < x_minus .or. x_input > x_plus) .and. (l_minus .and. l_plus)) then
    3879              : 
    3880           33 :        if (.not. dmft_optim) then
    3881           33 :          call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,xold)
    3882              :        end if
    3883              : 
    3884           33 :        write(message,'(a,3f12.6)') " ---",x_input,Fx+paw_dmft%nelectval,Fx
    3885           33 :        call wrtout(std_out,message,'COLL')
    3886           33 :        if (.not. dmft_optim) then
    3887           33 :          if (Fx > 0) then
    3888              :            x_plus = xold
    3889           17 :          else if (Fx < 0) then
    3890           33 :            x_minus = xold
    3891              :          end if ! Fx>0
    3892              :        end if
    3893           33 :        x_input = (x_plus+x_minus) * half
    3894              : 
    3895              :      end if ! x_input<x_minus or x_input>x_plus
    3896              : !    write(std_out,'(a,2f12.6)') " Q(xold) and dQ/dx=",Fx,Fxprime
    3897              : !    write(std_out,'(a,f12.6)') " =>  new Fermi level",x_input
    3898              : !    ========================================
    3899              : !    Locate zero between two values
    3900              : !    ========================================
    3901              :    else
    3902          419 :      call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,x_input)
    3903          419 :      write(message,'(a,3f12.6)') "  --",x_input,nb_elec_x,Fx
    3904              : !    Possible improvement for large systems, removed temporarely for
    3905              : !    automatic tests: more study is necessary: might worsen the convergency
    3906              : !    if(iter==1) then
    3907              : !    f_precision=max(abs(Fx/50),f_precision)
    3908              : !    write(message,'(a,4x,a,e12.6)') ch10," Precision required changed to:",f_precision
    3909              : !    call wrtout(std_out,message,'COLL')
    3910              : !    endif
    3911          419 :      call wrtout(std_out,message,'COLL')
    3912          419 :      if (Fx > 0) then
    3913          217 :        l_plus  = .true.
    3914          217 :        x_plus  = x_input
    3915          217 :        x_input = x_input - step
    3916          202 :      else if (Fx < 0) then
    3917          202 :        l_minus = .true.
    3918          202 :        x_minus = x_input
    3919          202 :        x_input = x_input + step
    3920              :      end if ! Fx>0
    3921              : 
    3922              :    end if ! l_minus and l_plus
    3923              : 
    3924         2195 :    if (abs(Fx) < abs(Fxoptimum) .or. (iter == 1 .and. dmft_optim)) then
    3925         1169 :      Fxoptimum = Fx
    3926         1169 :      x_optimum = merge(xold,x_input,dmft_optim)
    3927              :    end if ! abs(Fx)<abs(Fxoptimum)
    3928              : 
    3929              : 
    3930              : 
    3931              : !  if(myid==master) then
    3932              : !  write(std_out,'(a,i4,3f12.6)') "i,xnew,F,Fprime",i,x_input,Fx,Fxprime
    3933              : !  endif
    3934              : 
    3935              : 
    3936              : !  ! Apply stop criterion on x
    3937              : !  if(abs(x_input-xold) .le. x_input*x_precision) then
    3938              : !  !    write(std_out,'(a,4f12.6)') "x_input-xold, x_precision*x_input   "&
    3939              : !  !&    ,x_input-xold,x_precision*x_input,x_precision
    3940              : !  f_precision=Fx
    3941              : !  return
    3942              : !  endif
    3943              : 
    3944              :  end do ! iter
    3945              : !--- End of iterations
    3946              : 
    3947              : 
    3948            0 :  ierr_hh = 1
    3949              :  !return
    3950              : 
    3951              :  CONTAINS  !========================================================================================
    3952              : !-----------------------------------------------------------------------
    3953              : !!***
    3954              : 
    3955              : !!****f* newton/function_and_deriv
    3956              : !! NAME
    3957              : !!  function_and_deriv
    3958              : !!
    3959              : !! FUNCTION
    3960              : !!  Compute value of a function and its numerical derivatives
    3961              : !!
    3962              : !! INPUTS
    3963              : !!  green  <type(green_type)>= green function data
    3964              : !!  self <type(self_type)>= variables related to self-energy
    3965              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    3966              : !!  x_input = input value for x
    3967              : !!  option = 1 to only compute the first derivative
    3968              : !!         = 2 to compute the two first derivatives.
    3969              : !!
    3970              : !! OUTPUTS
    3971              : !!  Fx           : Value of F(x)
    3972              : !!  Fxprime      : Value of F'(x)
    3973              : !!  Fxdouble     : Value of F''(x)
    3974              : !!
    3975              : !! SOURCE
    3976              : 
    3977         1975 : subroutine function_and_deriv(green,self,paw_dmft,x_input,x_precision, &
    3978              :                             & f_precision,Fx,Fxprime,Fxdouble,option)
    3979              : 
    3980              : !Arguments ------------------------------------
    3981              :  type(green_type), intent(inout) :: green
    3982              :  type(self_type), intent(inout) :: self
    3983              :  !type(MPI_type), intent(in) :: mpi_enreg
    3984              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    3985              :  integer, intent(in) :: option
    3986              :  real(dp), intent(in) :: f_precision,x_input,x_precision
    3987              :  real(dp), intent(out) :: Fx,Fxprime,Fxdouble
    3988              : !Local variables-------------------------------
    3989              :  logical :: dmft_optim
    3990              :  real(dp) :: deltax,Fxminus,Fxplus,nb_elec_x,xminus,x0,xplus
    3991              :  character(len=500) :: message
    3992              : ! *********************************************************************
    3993              : 
    3994         1975 :    dmft_optim = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
    3995              : 
    3996         1975 :    if (.not. dmft_optim) then
    3997              : 
    3998              : !  Choose deltax: for numeric evaluation of derivative
    3999              :    !if(iter==1) then
    4000              : !    deltax=0.02
    4001              :    !end if
    4002              : !  deltax=max((x_input-x_old)/10.d0,min(0.00001_dp,x_precision/100_dp))
    4003         1975 :      deltax = min(tol5,x_precision/dble(100))  ! small but efficient
    4004              : !  endif
    4005              : !  write(std_out,*) "iter,x_input,deltax",iter,x_input,deltax
    4006         1975 :      x0 = x_input
    4007         1975 :      xminus = x0 - deltax
    4008         1975 :      xplus  = x0 + deltax
    4009              : 
    4010         1975 :      call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,x0)
    4011              : 
    4012         1975 :      write(message,'(a,3f12.6)') "  - ",x0,nb_elec_x,Fx
    4013         1975 :      call wrtout(std_out,message,'COLL')
    4014              : 
    4015              : !  write(std_out,*) "Fx", Fx
    4016         1975 :      if (abs(Fx) < f_precision) return
    4017              : 
    4018         1776 :      call compute_nb_elec(green,self,paw_dmft,Fxplus,nb_elec_x,xplus)
    4019              : 
    4020         1776 :      write(message,'(a,3f12.6)') "  - ",xplus,nb_elec_x,Fxplus
    4021         1776 :      call wrtout(std_out,message,'COLL')
    4022              : 
    4023         1776 :      if (option == 2) then
    4024            0 :        call compute_nb_elec(green,self,paw_dmft,Fxminus,nb_elec_x,xminus)
    4025              : 
    4026            0 :        write(message,'(a,3f12.6)') "  - ",xminus,nb_elec_x,Fxminus
    4027            0 :        call wrtout(std_out,message,'COLL')
    4028              :      end if ! option=2
    4029              : 
    4030         1776 :      if (option == 1) then
    4031         1776 :        Fxprime = (Fxplus-Fx) / deltax
    4032            0 :      else if (option == 2) then
    4033            0 :        Fxprime  = (Fxplus-Fxminus) / (two*deltax)
    4034            0 :        Fxdouble = (Fxplus+Fxminus-two*Fx) / (deltax**2)
    4035              :      end if ! option
    4036              : !  write(std_out,*) "after computation of Fxprime",myid
    4037              : 
    4038              :    else
    4039              : 
    4040            0 :      call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,x_input,Fxprime=Fxprime)
    4041              : 
    4042            0 :      write(message,'(a,3f12.6)') "  - ",x_input,nb_elec_x,Fx
    4043            0 :      call wrtout(std_out,message,'COLL')
    4044              : 
    4045              :    end if ! dmft_optim
    4046              : 
    4047         1776 :    if (Fxprime < zero) then
    4048            0 :      write(message,'(a,f12.6)') "  Warning: slope of charge versus fermi level is negative !",Fxprime
    4049            0 :      call wrtout(std_out,message,'COLL')
    4050              :    end if
    4051              : 
    4052              :  end subroutine function_and_deriv
    4053              : !!***
    4054              : 
    4055              : !!****f* newton/compute_nb_elec
    4056              : !! NAME
    4057              : !! compute_nb_elec
    4058              : !!
    4059              : !! FUNCTION
    4060              : !!  Compute nb of electrons as a function of Fermi level
    4061              : !!
    4062              : !! INPUTS
    4063              : !! fermie       : input of energy
    4064              : !! opt_noninter
    4065              : !!
    4066              : !! OUTPUTS
    4067              : !! Fx           : Value of F(x).
    4068              : !! nb_elec_x    : Number of electrons for the value of x
    4069              : !!
    4070              : !! SOURCE
    4071              : 
    4072         4203 : subroutine compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,fermie,Fxprime)
    4073              : 
    4074              : !Arguments ------------------------------------
    4075              :  type(green_type), intent(inout) :: green
    4076              :  type(self_type), intent(inout) :: self
    4077              :  !type(MPI_type), intent(in) :: mpi_enreg
    4078              :  type(paw_dmft_type), intent(inout) :: paw_dmft
    4079              :  !integer,intent(in) :: opt_noninter
    4080              :  real(dp), intent(in) :: fermie
    4081              :  real(dp), intent(out) :: Fx,nb_elec_x
    4082              :  real(dp), optional, intent(out) :: Fxprime
    4083              : !Local variables-------------------------------
    4084              :  integer :: band_index,i,ib,ierr,ifreq,ikpt,isppol,mbandc
    4085              :  integer :: mkmem,nband_k,nkpt,nmoments,nspinor,nsppol,shift
    4086              :  logical :: dmft_optim
    4087              :  real(dp) :: correction,correction_prime,eig
    4088              :  real(dp) :: fac,occ_prime,temp,wtk
    4089              :  complex(dp) :: omega
    4090         4203 :  type(oper_type) :: oper_tmp
    4091         4203 :  complex(dp), allocatable :: omega_fac(:),trace_moments(:),trace_moments_prime(:)
    4092              : ! *********************************************************************
    4093              : 
    4094              :    ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_NB_ELEC)
    4095         4203 :    dmft_optim = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
    4096              : 
    4097         4203 :    if (.not. dmft_optim) then
    4098              : 
    4099         4203 :      paw_dmft%fermie = fermie
    4100         4203 :      call compute_green(green,paw_dmft,0,self,opt_self=1,opt_nonxsum=1,opt_nonxsum2=1)
    4101         4203 :      call integrate_green(green,paw_dmft,0,opt_ksloc=-1) !,opt_nonxsum=1)
    4102              :         !  opt_ksloc=-1, compute total charge
    4103              : 
    4104              :    else
    4105              : 
    4106            0 :      green%charge_ks = zero
    4107              : 
    4108            0 :      mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
    4109            0 :      shift = green%distrib%shiftk
    4110            0 :      nmoments = merge(green%nmoments,1,green%has_moments==1)
    4111              : 
    4112            0 :      mbandc  = paw_dmft%mbandc
    4113            0 :      nkpt    = paw_dmft%nkpt
    4114            0 :      nspinor = paw_dmft%nspinor
    4115            0 :      nsppol  = paw_dmft%nsppol
    4116            0 :      temp    = paw_dmft%temp
    4117              : 
    4118            0 :      ABI_MALLOC(trace_moments,(nmoments))
    4119            0 :      ABI_MALLOC(trace_moments_prime,(nmoments))
    4120              : 
    4121            0 :      trace_moments(1) = green%trace_fermie(1)
    4122            0 :      trace_moments_prime(:) = czero
    4123            0 :      Fxprime = zero
    4124              : 
    4125            0 :      if (green%has_moments == 1) then
    4126            0 :        call compute_trace_moments(fermie,green%trace_fermie(:),trace_moments(:),trace_moments_prime(:))
    4127              :      end if
    4128              : 
    4129            0 :      call init_oper(paw_dmft,oper_tmp,nkpt=mkmem,shiftk=shift)
    4130              : 
    4131            0 :      do ifreq=1,green%nw
    4132            0 :        if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
    4133            0 :        omega = cmplx(zero,green%omega(ifreq),kind=dp)
    4134            0 :        fac = two * paw_dmft%wgt_wlo(ifreq) * merge(two*temp,temp,nsppol==1.and.nspinor==1)
    4135              : 
    4136            0 :        call add_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),oper_tmp%matlu(:),paw_dmft%natom,-1)
    4137            0 :        call upfold_oper(oper_tmp,paw_dmft)
    4138              : 
    4139            0 :        do isppol=1,nsppol
    4140            0 :          do ikpt=1,mkmem
    4141            0 :            wtk = paw_dmft%wtk(ikpt+shift)
    4142            0 :            do ib=1,mbandc
    4143              :              oper_tmp%ks(ib,ib,ikpt,isppol) = oper_tmp%ks(ib,ib,ikpt,isppol) + omega + &
    4144            0 :                 & fermie - paw_dmft%eigen_dft(ib,ikpt+shift,isppol)
    4145              :            end do ! ib
    4146            0 :            call xginv(oper_tmp%ks(:,:,ikpt,isppol),mbandc)
    4147              : 
    4148            0 :            Fxprime = Fxprime - dble(sum(oper_tmp%ks(:,:,ikpt,isppol)*transpose(oper_tmp%ks(:,:,ikpt,isppol))))*wtk*fac
    4149            0 :            do ib=1,mbandc
    4150            0 :              green%charge_ks = green%charge_ks + dble(oper_tmp%ks(ib,ib,ikpt,isppol))*wtk*fac
    4151              :            end do ! ib
    4152              :          end do ! ikpt
    4153              :        end do ! isppol
    4154              : 
    4155              :      end do ! ifreq
    4156              : 
    4157            0 :      call xmpi_sum(green%charge_ks,paw_dmft%spacecomm,ierr)
    4158            0 :      call xmpi_sum(Fxprime,paw_dmft%spacecomm,ierr)
    4159              : 
    4160            0 :      call destroy_oper(oper_tmp)
    4161              : 
    4162            0 :      ABI_MALLOC(omega_fac,(nmoments))
    4163              : 
    4164            0 :      do i=1,nmoments
    4165            0 :        omega_fac(i) = czero
    4166            0 :        do ifreq=green%nw,1,-1 ! NEVER change the summation order and DON'T use the intrinsic SUM
    4167            0 :          omega_fac(i) = omega_fac(i) + paw_dmft%wgt_wlo(ifreq) / (paw_dmft%omega_lo(ifreq))**i
    4168              :        end do
    4169            0 :        omega_fac(i) = - two * temp * omega_fac(i) / (j_dpc)**i
    4170            0 :        if (i == 1) omega_fac(i) = omega_fac(i) + half
    4171            0 :        if (i == 2) omega_fac(i) = omega_fac(i) - cone/(four*temp)
    4172            0 :        if (i == 4) omega_fac(i) = omega_fac(i) + cone/(dble(48)*(temp**3))
    4173              :      end do ! i
    4174              : 
    4175              :      ! Do not use DOT_PRODUCT
    4176            0 :      green%charge_ks = green%charge_ks + dble(sum(trace_moments(1:nmoments)*omega_fac(1:nmoments)))
    4177              :      ! Do not use DOT_PRODUCT
    4178            0 :      Fxprime = Fxprime + dble(sum(trace_moments_prime(1:nmoments)*omega_fac(1:nmoments)))
    4179              : 
    4180            0 :      ABI_FREE(trace_moments)
    4181            0 :      ABI_FREE(trace_moments_prime)
    4182            0 :      ABI_FREE(omega_fac)
    4183              : 
    4184            0 :      if (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7) then
    4185              :        band_index = 0
    4186              :        correction = zero
    4187              :        correction_prime = zero
    4188            0 :        do isppol=1,nsppol
    4189            0 :          do ikpt=1,nkpt
    4190            0 :            nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
    4191            0 :            wtk = paw_dmft%wtk(ikpt)
    4192            0 :            do ib=1,nband_k
    4193            0 :              if (paw_dmft%band_in(ib)) cycle
    4194            0 :              eig = paw_dmft%eigen(ib+band_index)
    4195            0 :              correction = correction + occup_fd(eig,fermie,temp)*wtk
    4196            0 :              if ((eig-fermie) > zero) then
    4197            0 :                occ_prime = exp(-(eig-fermie)/temp) / (one+exp(-(eig-fermie)/temp))**2 / temp
    4198              :              else
    4199            0 :                occ_prime = exp((eig-fermie)/temp) / (one+exp((eig-fermie)/temp))**2 / temp
    4200              :              end if
    4201            0 :              correction_prime = correction_prime + occ_prime*wtk
    4202              :            end do ! ib
    4203            0 :            band_index = band_index + nband_k
    4204              :          end do ! ikpt
    4205              :        end do ! isppol
    4206            0 :        if (nsppol == 1 .and. nspinor == 1) correction = correction * two
    4207            0 :        green%charge_ks = green%charge_ks + correction
    4208            0 :        if (nsppol == 1 .and. nspinor == 1) correction_prime = correction_prime * two
    4209            0 :        Fxprime = Fxprime + correction_prime
    4210              :      end if ! use_all_bands
    4211              : 
    4212              :    end if ! dmft_optim
    4213              : 
    4214         4203 :    nb_elec_x = green%charge_ks
    4215         4203 :    Fx = green%charge_ks - paw_dmft%nelectval
    4216              : 
    4217              :    ABI_NVTX_END_RANGE()
    4218         4203 :  end subroutine compute_nb_elec
    4219              : !!***
    4220              : 
    4221            0 : subroutine compute_trace_moments(fermie,trace_fermie,trace_moments,trace_moments_prime)
    4222              : 
    4223              : !Arguments ------------------------------------
    4224              :  real(dp), intent(in) :: fermie
    4225              :  complex(dp), intent(in) :: trace_fermie(:)
    4226              :  complex(dp), intent(inout) :: trace_moments(:),trace_moments_prime(:)
    4227              : !Local variables-------------------------------
    4228              :  real(dp) :: fermie2,fermie3,fermie4
    4229              : ! *********************************************
    4230              : 
    4231            0 :   fermie2 = fermie * fermie
    4232            0 :   fermie3 = fermie2 * fermie
    4233            0 :   fermie4 = fermie3 * fermie
    4234              : 
    4235            0 :   trace_moments(2) = trace_fermie(2) - fermie*trace_fermie(1)
    4236              :   trace_moments(3) = trace_fermie(3) + trace_fermie(4) - two*fermie*trace_fermie(2) + &
    4237            0 :          & fermie2*trace_fermie(1)
    4238              :   trace_moments(4) = trace_fermie(5) + two*(trace_fermie(6)-fermie*trace_fermie(3)) + &
    4239              :          & trace_fermie(7) - three*fermie*trace_fermie(4) + &
    4240            0 :          & three*fermie2*trace_fermie(2) - fermie3*trace_fermie(1)
    4241              :   trace_moments(5) = trace_fermie(8) + two*(trace_fermie(9)-fermie*trace_fermie(5)) + &
    4242              :          & trace_fermie(10) + three*(trace_fermie(11)-two*fermie*trace_fermie(6)+ &
    4243              :          & fermie2*trace_fermie(3)) + trace_fermie(12) - four*fermie*trace_fermie(7) + &
    4244              :          & six*fermie2*trace_fermie(4) - four*fermie3*trace_fermie(2) + &
    4245            0 :          & fermie4*trace_fermie(1)
    4246              : 
    4247            0 :   trace_moments_prime(2) = - trace_fermie(1)
    4248            0 :   trace_moments_prime(3) = two * (fermie*trace_fermie(1)-trace_fermie(2))
    4249              :   trace_moments_prime(4) = - two*trace_fermie(3) - three*trace_fermie(4) + &
    4250            0 :          & six*fermie*trace_fermie(2) - three*fermie2*trace_fermie(1)
    4251              :   trace_moments_prime(5) = - two*trace_fermie(5) + three*(-two*trace_fermie(6)+ &
    4252              :          & two*fermie*trace_fermie(3)) - four*trace_fermie(7) + &
    4253              :          & dble(12)*fermie*trace_fermie(4) - dble(12)*fermie2*trace_fermie(2) + &
    4254            0 :          & four*fermie3*trace_fermie(1)
    4255              : 
    4256            0 :  end subroutine compute_trace_moments
    4257              : !!***
    4258              : 
    4259              : end subroutine newton
    4260              : !!***
    4261              : 
    4262              : !!****f* m_green/local_ks_green
    4263              : !! NAME
    4264              : !! local_ks_green
    4265              : !!
    4266              : !! FUNCTION
    4267              : !! Compute the sum over k-point of ks green function.
    4268              : !! do the fourier transformation and print it
    4269              : !!
    4270              : !! COPYRIGHT
    4271              : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
    4272              : !! This file is distributed under the terms of the
    4273              : !! GNU General Public License, see ~abinit/COPYING
    4274              : !! or http://www.gnu.org/copyleft/gpl.txt .
    4275              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
    4276              : !!
    4277              : !! INPUTS
    4278              : !!  cryst_struc
    4279              : !!  istep    =  step of iteration for DFT.
    4280              : !!  dft_occup
    4281              : !!  mpi_enreg=information about MPI parallelization
    4282              : !!  paw_dmft =  data for self-consistent DFT+DMFT calculations.
    4283              : !!
    4284              : !! OUTPUT
    4285              : !!  paw_dmft =  data for self-consistent DFT+DMFT calculations.
    4286              : !!
    4287              : !! SOURCE
    4288              : 
    4289            0 : subroutine local_ks_green(green,paw_dmft,prtopt)
    4290              : 
    4291              : !Arguments ------------------------------------
    4292              : !scalars
    4293              :  type(green_type), intent(in) :: green
    4294              :  type(paw_dmft_type), intent(in)  :: paw_dmft
    4295              :  integer, intent(in) :: prtopt
    4296              : 
    4297              : !Local variables ------------------------------
    4298              :  character(len=500) :: message
    4299              :  integer :: iband,ifreq,ikpt,isppol,itau,lsub,ltau,mbandc,nkpt,nsppol
    4300              :  character(len=1) :: tag_is
    4301              :  character(len=fnlen) :: tmpfil
    4302            0 :  integer,allocatable :: unitgreenlocks_arr(:)
    4303              :  real(dp) :: beta
    4304            0 :  real(dp), allocatable :: tau(:)
    4305            0 :  complex(dp), allocatable :: loc_ks(:,:,:)
    4306            0 :  complex(dp), allocatable :: loc_ks_tau(:,:,:),fw(:),ft(:)
    4307              : !************************************************************************
    4308            0 :  mbandc=paw_dmft%mbandc
    4309            0 :  nkpt=paw_dmft%nkpt
    4310            0 :  nsppol=paw_dmft%nsppol
    4311            0 :  ltau=128
    4312            0 :  ABI_MALLOC(tau,(ltau))
    4313            0 :  do itau=1,ltau
    4314            0 :    tau(itau)=float(itau-1)/float(ltau)/paw_dmft%temp
    4315              :  end do
    4316            0 :  beta=one/paw_dmft%temp
    4317              : 
    4318              : !Only imaginary frequencies here
    4319            0 :  if(green%w_type=="real") then
    4320            0 :    message = ' compute_energy not implemented for real frequency'
    4321            0 :    ABI_BUG(message)
    4322              :  end if
    4323              : 
    4324              : !=========================================
    4325              : !Compute local band ks green function
    4326              : ! should be computed in compute_green: it would be less costly in memory.
    4327              : !=========================================
    4328            0 :  ABI_MALLOC(loc_ks,(nsppol,mbandc,paw_dmft%dmft_nwlo))
    4329            0 :  if(green%oper(1)%has_operks==1) then
    4330            0 :    loc_ks(:,:,:)=czero
    4331            0 :    do isppol=1,nsppol
    4332            0 :      do iband=1,mbandc
    4333            0 :        do ifreq=1,paw_dmft%dmft_nwlo
    4334            0 :          do ikpt=1,nkpt
    4335              :            loc_ks(isppol,iband,ifreq)=loc_ks(isppol,iband,ifreq)+  &
    4336            0 : &           green%oper(ifreq)%ks(iband,iband,ikpt,isppol)*paw_dmft%wtk(ikpt)
    4337              :          end do
    4338              :        end do
    4339              :      end do
    4340              :    end do
    4341              :  else
    4342            0 :    message = ' green fct is not computed in ks space'
    4343            0 :    ABI_BUG(message)
    4344              :  end if
    4345              : 
    4346              : !=========================================
    4347              : !Compute fourier transformation
    4348              : !=========================================
    4349              : 
    4350            0 :  ABI_MALLOC(loc_ks_tau,(nsppol,mbandc,ltau))
    4351            0 :  ABI_MALLOC(fw,(paw_dmft%dmft_nwlo))
    4352            0 :  ABI_MALLOC(ft,(ltau))
    4353            0 :  loc_ks_tau(:,:,:)=czero
    4354            0 :  do isppol=1,nsppol
    4355            0 :    do iband=1,mbandc
    4356            0 :      do ifreq=1,paw_dmft%dmft_nwlo
    4357            0 :        fw(ifreq)=loc_ks(isppol,iband,ifreq)
    4358              :      end do
    4359            0 :      call fourier_fct(fw,ft,.true.,ltau,-1,paw_dmft) ! inverse fourier
    4360            0 :      do itau=1,ltau
    4361            0 :        loc_ks_tau(isppol,iband,itau)=ft(itau)
    4362              :      end do
    4363              :    end do
    4364              :  end do
    4365            0 :  ABI_FREE(fw)
    4366            0 :  ABI_FREE(ft)
    4367            0 :  do isppol=1,nsppol
    4368            0 :    do iband=1,mbandc
    4369            0 :      do itau=1,ltau
    4370            0 :        loc_ks_tau(isppol,iband,itau)=(loc_ks_tau(isppol,iband,itau)+conjg(loc_ks_tau(isppol,iband,itau)))/two
    4371              :      end do
    4372              :    end do
    4373              :  end do
    4374              : 
    4375              : !=========================================
    4376              : !Print out ksloc green function
    4377              : !=========================================
    4378            0 :  if(abs(prtopt)==1) then
    4379            0 :    ABI_MALLOC(unitgreenlocks_arr,(nsppol))
    4380            0 :    do isppol=1,nsppol
    4381            0 :      write(tag_is,'(i1)')isppol
    4382            0 :      tmpfil = trim(paw_dmft%filapp)//'Gtau_locks_isppol'//tag_is
    4383            0 :      write(message,'(3a)') ch10," == Print green function on file ",trim(tmpfil)
    4384            0 :      call wrtout(std_out,message,'COLL')
    4385            0 :      unitgreenlocks_arr(isppol)=500+isppol-1
    4386            0 :      open (unit=unitgreenlocks_arr(isppol),file=trim(tmpfil),status='unknown',form='formatted')
    4387            0 :      rewind(unitgreenlocks_arr(isppol))
    4388            0 :      write(message,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitgreenlocks_arr(isppol)
    4389            0 :      write(message,'(a,a)') ch10,"# New record : First 40 bands"
    4390            0 :      call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
    4391            0 :      do lsub=1,mbandc/40+1
    4392            0 :        do itau=1, ltau
    4393            0 :          write(message,'(2x,50(e10.3,2x))') tau(itau), &
    4394            0 : &         (real(loc_ks_tau(isppol,iband,itau)),iband=40*(lsub-1)+1,min(40*lsub,mbandc))
    4395            0 :          call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
    4396              :        end do
    4397            0 :        write(message,'(2x,50(e10.3,2x))') beta, &
    4398            0 : &       ((-one-real(loc_ks_tau(isppol,iband,1))),iband=40*(lsub-1)+1,min(40*lsub,mbandc))
    4399            0 :        call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
    4400            0 :        if(40*lsub<mbandc) then
    4401              :          write(message,'(a,a,i5,a,i5)')    &
    4402            0 : &         ch10,"# Same record, Following bands : From ",    &
    4403            0 : &         40*(lsub),"  to ",min(40*(lsub+1),mbandc)
    4404            0 :          call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
    4405              :        end if
    4406              :      end do
    4407              : !    call flush(unitgreenlocks_arr(isppol))
    4408              :    end do
    4409            0 :    ABI_FREE(unitgreenlocks_arr)
    4410              :  end if
    4411              : 
    4412              : !Deallocations
    4413            0 :  ABI_FREE(loc_ks)
    4414            0 :  ABI_FREE(loc_ks_tau)
    4415            0 :  ABI_FREE(tau)
    4416              : 
    4417            0 : end subroutine local_ks_green
    4418              : !!***
    4419              : 
    4420              : !!****f* m_green/compute_moments_ks
    4421              : !! NAME
    4422              : !! compute_moments_ks
    4423              : !!
    4424              : !! FUNCTION
    4425              : !! Compute the high-frequency moments of the Green's function in KS space
    4426              : !!
    4427              : !! COPYRIGHT
    4428              : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
    4429              : !! This file is distributed under the terms of the
    4430              : !! GNU General Public License, see ~abinit/COPYING
    4431              : !! or http://www.gnu.org/copyleft/gpl.txt .
    4432              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
    4433              : !!
    4434              : !! INPUTS
    4435              : !!  green  <type(green_type)>= green function data
    4436              : !!  self <type(self_type)>= variables related to self-energy
    4437              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    4438              : !!  opt_self = 0 : do not use the self-energy
    4439              : !!           = 1 (default) : use the self-energy, by upfolding its moments
    4440              : !!  opt_log = 0 (default): the moments of G are computed in green%moments using self%moments
    4441              : !!          = 1 : the trace of the moments of log(G)+log(iw*Id)=-log(Id+(mu-sigma)/iw) is computed in green%trace_moments_log_ks
    4442              : !!  opt_quick_restart = 0 (default) : default behavior, recompute everything from scratch
    4443              : !!                    = 1 : use precomputed quantities from fermi_green : assume that self%moments(i>=2) have
    4444              : !!                    already been upfolded, that self%moments(1)-self%hdc has already been upfolded in
    4445              : !!                    green%moments(2), and that (self%moments(1)-self%hdc+eigen_dft)**2 has been computed
    4446              : !!                    in green%moments(3)
    4447              : !!  The conventions are: green%moments(i) -> ith order moment of the Green's function in the usual case
    4448              : !!                                            (the 1st one is not computed, since this is simply the identity)
    4449              : !!                       self%moments(i)  -> (i-1)th order moment of the self-energy (the 1st one is not upfolded, since we directly
    4450              : !!                                  upfold self%moments(1) - self%hdc
    4451              : !!  where the ith order moment corresponds to the factor in front of 1/(jw_n)^i in the asymptotic expansion
    4452              : !!
    4453              : !! OUTPUT
    4454              : !!
    4455              : !! SOURCE
    4456              : 
    4457            0 : subroutine compute_moments_ks(green,self,paw_dmft,opt_self,opt_log,opt_quick_restart)
    4458              : 
    4459              : !Arguments ------------------------------------
    4460              : !scalars
    4461              :  type(green_type), intent(inout) :: green
    4462              :  type(self_type), intent(inout) :: self
    4463              :  type(paw_dmft_type), intent(in)  :: paw_dmft
    4464              :  integer, optional, intent(in) :: opt_log,opt_quick_restart,opt_self
    4465              : !Local variables ------------------------------
    4466              :  integer :: diag,i,ib,ierr,mkmem,natom,nsppol
    4467              :  integer :: optlog,optquickrestart,optself,shift
    4468              :  real(dp) :: dum,mu,mu2,mu3,mu4
    4469              :  complex(dp) :: trace_tmp
    4470            0 :  type(oper_type) :: oper(2)
    4471            0 :  real(dp), allocatable :: trace_loc(:,:)
    4472              :  character(len=500) :: message
    4473              : !************************************************************************
    4474              : 
    4475            0 :  optlog = 0
    4476            0 :  if (present(opt_log)) optlog = opt_log
    4477              : 
    4478            0 :  optself = 1
    4479            0 :  if (present(opt_self)) optself = opt_self
    4480              : 
    4481            0 :  optquickrestart = 0
    4482            0 :  if (present(opt_quick_restart)) optquickrestart = opt_quick_restart
    4483              : 
    4484            0 :  if (optself == 0 .and. optquickrestart == 1) then
    4485            0 :    message = "Case optself=0 and optquickrestart=1 is not supposed to happen"
    4486            0 :    ABI_ERROR(message)
    4487              :  end if
    4488              : 
    4489            0 :  diag   = 1 - optself
    4490            0 :  mkmem  = green%moments(1)%nkpt
    4491            0 :  mu     = paw_dmft%fermie
    4492            0 :  mu2    = mu * mu
    4493            0 :  mu3    = mu2 * mu
    4494            0 :  mu4    = mu3 * mu
    4495            0 :  natom  = paw_dmft%natom
    4496            0 :  nsppol = paw_dmft%nsppol
    4497            0 :  shift  = green%moments(1)%shiftk
    4498              : 
    4499            0 :  if (optlog == 1 .and. optquickrestart == 0) then
    4500            0 :    ABI_MALLOC(trace_loc,(nsppol+1,natom))
    4501              :  end if
    4502              : 
    4503            0 :  if (optself == 1 .and. optquickrestart == 0) then
    4504            0 :    call add_matlu(self%moments(1)%matlu(:),self%hdc%matlu(:),green%moments(2)%matlu(:),natom,-1)
    4505            0 :    call upfold_oper(green%moments(2),paw_dmft)
    4506            0 :    do i=2,self%nmoments
    4507            0 :      call upfold_oper(self%moments(i),paw_dmft)
    4508              :    end do ! i
    4509              :  end if ! optself=1
    4510              : 
    4511            0 :  do ib=1,paw_dmft%mbandc
    4512            0 :    if (optself == 1) then
    4513              :      green%moments(2)%ks(ib,ib,:,:) = green%moments(2)%ks(ib,ib,:,:) + &
    4514            0 :             & paw_dmft%eigen_dft(ib,1+shift:mkmem+shift,:) - mu
    4515              :    else
    4516            0 :      green%moments(2)%ks(ib,ib,:,:) = paw_dmft%eigen_dft(ib,1+shift:mkmem+shift,:) - mu
    4517              :    end if
    4518              :    ! Careful, we need to substract mu**2 below, not add it (think about it)
    4519            0 :    if (optquickrestart == 1) green%moments(3)%ks(ib,ib,:,:) = green%moments(3)%ks(ib,ib,:,:) - mu2
    4520              :  end do ! ib
    4521              : 
    4522            0 :  if (optquickrestart == 1) then
    4523            0 :    green%moments(3)%ks(:,:,:,:) = green%moments(3)%ks(:,:,:,:) - two*mu*green%moments(2)%ks(:,:,:,:)
    4524              :  else
    4525            0 :    call prod_oper(green%moments(2),green%moments(2),green%moments(3),1,opt_diag=diag)
    4526              :  end if ! optquickrestart
    4527            0 :  do i=3,green%nmoments-1
    4528            0 :    call prod_oper(green%moments(2),green%moments(i),green%moments(i+1),1,opt_diag=diag)
    4529              :  end do ! i
    4530              : 
    4531            0 :  if (optlog == 1 .and. optquickrestart == 0) then
    4532            0 :    do i=1,green%nmoments-1
    4533            0 :      call trace_oper(green%moments(i+1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
    4534            0 :      green%trace_moments_log_ks(i) = trace_tmp / dble(i)
    4535              :    end do ! i
    4536            0 :    if (optself == 1) then
    4537            0 :      do i=2,self%nmoments
    4538            0 :        call trace_oper(self%moments(i),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
    4539            0 :        green%trace_moments_log_ks(i) = green%trace_moments_log_ks(i) + trace_tmp
    4540              :      end do ! i
    4541              :    end if ! optself=1
    4542              :  end if ! optlog=1 and optquickrestart=0
    4543              : 
    4544            0 :  if (optlog == 1 .and. optquickrestart == 1) then
    4545            0 :    green%trace_moments_log_ks(1) = green%trace_fermie(2) - mu*green%trace_fermie(1)
    4546              :    green%trace_moments_log_ks(2) = green%trace_fermie(3) + &
    4547            0 :        & half*(green%trace_fermie(4)-two*mu*green%trace_fermie(2)+mu2*green%trace_fermie(1))
    4548              :    green%trace_moments_log_ks(3) = green%trace_fermie(5) + green%trace_fermie(6) - &
    4549              :       & mu*green%trace_fermie(3) + third*(green%trace_fermie(7)+ &
    4550              :       & three*mu2*green%trace_fermie(2)-three*mu*green%trace_fermie(4)- &
    4551            0 :       & mu3*green%trace_fermie(1))
    4552              :    green%trace_moments_log_ks(4) = green%trace_fermie(8) + green%trace_fermie(9) - &
    4553              :       & mu*green%trace_fermie(5) + half*green%trace_fermie(10) + &
    4554              :       & green%trace_fermie(11) - two*mu*green%trace_fermie(6) + mu2*green%trace_fermie(3) + &
    4555              :       & quarter*(green%trace_fermie(12)-four*mu3*green%trace_fermie(2)+ &
    4556              :       & six*mu2*green%trace_fermie(4)-four*mu*green%trace_fermie(7)+ &
    4557            0 :       & mu4*green%trace_fermie(1))
    4558              :  end if ! optlog=1 and optquickrestart=1
    4559              : 
    4560            0 :  if (optself == 1) then
    4561            0 :    do i=1,2
    4562            0 :      call init_oper(paw_dmft,oper(i),nkpt=mkmem,shiftk=shift,opt_ksloc=1)
    4563              :    end do
    4564            0 :    call prod_oper(green%moments(2),self%moments(2),oper(1),1)
    4565            0 :    if (optlog == 1 .and. optquickrestart == 0) then
    4566            0 :      call trace_oper(oper(1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
    4567            0 :      green%trace_moments_log_ks(3) = green%trace_moments_log_ks(3) + trace_tmp
    4568              :    end if
    4569            0 :    call prod_oper(self%moments(2),green%moments(2),oper(2),1)
    4570            0 :    oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
    4571            0 :    green%moments(4)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + green%moments(4)%ks(:,:,:,:)
    4572            0 :    call prod_oper(oper(2),green%moments(2),oper(1),1)
    4573            0 :    call prod_oper(green%moments(3),self%moments(2),oper(2),1)
    4574            0 :    if (optlog == 1 .and. optquickrestart == 0) then
    4575            0 :      call trace_oper(oper(2),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
    4576            0 :      green%trace_moments_log_ks(4) = green%trace_moments_log_ks(4) + trace_tmp
    4577              :    end if
    4578            0 :    oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
    4579            0 :    call prod_oper(green%moments(2),self%moments(3),oper(1),1)
    4580            0 :    if (optlog == 1 .and. optquickrestart == 0) then
    4581            0 :      call trace_oper(oper(1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
    4582            0 :      green%trace_moments_log_ks(4) = green%trace_moments_log_ks(4) + trace_tmp
    4583              :    end if
    4584            0 :    oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
    4585            0 :    call prod_oper(self%moments(3),green%moments(2),oper(1),1)
    4586            0 :    oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
    4587            0 :    call prod_oper(self%moments(2),self%moments(2),oper(1),1)
    4588            0 :    if (optlog == 1 .and. optquickrestart == 0) then
    4589            0 :      call trace_oper(oper(1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
    4590            0 :      green%trace_moments_log_ks(4) = green%trace_moments_log_ks(4) + trace_tmp*half
    4591              :    end if
    4592            0 :    oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
    4593            0 :    green%moments(5)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + green%moments(5)%ks(:,:,:,:)
    4594            0 :    do i=2,self%nmoments
    4595            0 :      green%moments(i+1)%ks(:,:,:,:) = green%moments(i+1)%ks(:,:,:,:) + self%moments(i)%ks(:,:,:,:)
    4596              :    end do ! i
    4597            0 :    do i=1,2
    4598            0 :      call destroy_oper(oper(i))
    4599              :    end do
    4600              :  end if ! optself>=1
    4601              : 
    4602            0 :  if (optlog == 1 .and. optquickrestart == 0) then
    4603            0 :    call xmpi_sum(green%trace_moments_log_ks(1:green%nmoments-1),green%distrib%comm_kpt,ierr)
    4604              :  end if
    4605              : 
    4606            0 :  ABI_SFREE(trace_loc)
    4607              : 
    4608            0 : end subroutine compute_moments_ks
    4609              : !!***
    4610              : 
    4611              : !!****f* m_green/compute_trace_moments_ks
    4612              : !! NAME
    4613              : !! compute_trace_moments_ks
    4614              : !!
    4615              : !! FUNCTION
    4616              : !! Precompute some useful quantities for the calculation of the trace of the moments (for
    4617              : !! Fermi level search)
    4618              : !!
    4619              : !! COPYRIGHT
    4620              : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
    4621              : !! This file is distributed under the terms of the
    4622              : !! GNU General Public License, see ~abinit/COPYING
    4623              : !! or http://www.gnu.org/copyleft/gpl.txt .
    4624              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
    4625              : !!
    4626              : !! INPUTS
    4627              : !!  green  <type(green_type)>= green function data
    4628              : !!  self <type(self_type)>= variables related to self-energy
    4629              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    4630              : !!  The conventions are:
    4631              : !!    trace_fermie(1)  = nsppol*mbandc (=tr(Id))
    4632              : !!    trace_fermie(2)  = tr(m0) (with m0=self%moments(1)-self%hdc+eigen_dft*Id
    4633              : !!    trace_fermie(3)  = tr(self%moments(2))
    4634              : !!    trace_fermie(4)  = tr(m0**2)
    4635              : !!    trace_fermie(5)  = tr(self%moments(3))
    4636              : !!    trace_fermie(6)  = tr(m0*self%moments(2))
    4637              : !!    trace_fermie(7)  = tr(m0**3)
    4638              : !!    trace_fermie(8)  = tr(self%moments(4))
    4639              : !!    trace_fermie(9)  = tr(m0*self%moments(3))
    4640              : !!    trace_fermie(10) = tr(self%moments(2)**2)
    4641              : !!    trace_fermie(11) = tr(m0**2*self%moments(2))
    4642              : !!    trace_fermie(12) = tr(m0**4)
    4643              : !!
    4644              : !! OUTPUT
    4645              : !!
    4646              : !! SOURCE
    4647              : 
    4648            0 : subroutine compute_trace_moments_ks(green,self,paw_dmft)
    4649              : 
    4650              : !Arguments ------------------------------------
    4651              : !scalars
    4652              :  type(green_type), intent(inout) :: green
    4653              :  type(self_type), intent(inout) :: self
    4654              :  type(paw_dmft_type), intent(in) :: paw_dmft
    4655              : !Local variables ------------------------------
    4656              :  integer :: i,ib,ierr,mkmem,natom,nsppol,shift
    4657              :  real(dp) :: dum
    4658            0 :  type(oper_type) :: oper_tmp
    4659            0 :  real(dp), allocatable :: trace_loc(:,:)
    4660              : !************************************************************************
    4661              : 
    4662            0 :  mkmem  = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
    4663            0 :  natom  = paw_dmft%natom
    4664            0 :  nsppol = paw_dmft%nsppol
    4665            0 :  shift  = green%distrib%shiftk
    4666              : 
    4667            0 :  ABI_MALLOC(trace_loc,(nsppol+1,natom))
    4668              : 
    4669            0 :  call init_oper(paw_dmft,oper_tmp,nkpt=mkmem,shiftk=shift,opt_ksloc=1)
    4670              : 
    4671            0 :  call add_matlu(self%moments(1)%matlu(:),self%hdc%matlu(:),green%moments(2)%matlu(:),natom,-1)
    4672            0 :  call upfold_oper(green%moments(2),paw_dmft)
    4673            0 :  do i=2,self%nmoments
    4674            0 :    call upfold_oper(self%moments(i),paw_dmft)
    4675              :  end do ! i
    4676              : 
    4677            0 :  oper_tmp%ks(:,:,:,:) = green%moments(2)%ks(:,:,:,:)
    4678              : 
    4679            0 :  do ib=1,paw_dmft%mbandc
    4680            0 :    oper_tmp%ks(ib,ib,:,:) = oper_tmp%ks(ib,ib,:,:) + paw_dmft%eigen_dft(ib,1+shift:mkmem+shift,:)
    4681              :  end do ! ib
    4682              : 
    4683            0 :  call prod_oper(oper_tmp,oper_tmp,green%moments(3),1)
    4684            0 :  call trace_oper(oper_tmp,dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(2))
    4685            0 :  call trace_oper(self%moments(2),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(3))
    4686            0 :  call trace_oper(green%moments(3),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(4))
    4687            0 :  call trace_oper(self%moments(3),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(5))
    4688            0 :  call trace_prod_oper(oper_tmp,self%moments(2),green%trace_fermie(6))
    4689            0 :  call trace_prod_oper(oper_tmp,green%moments(3),green%trace_fermie(7))
    4690            0 :  call trace_oper(self%moments(4),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(8))
    4691            0 :  call trace_prod_oper(oper_tmp,self%moments(3),green%trace_fermie(9))
    4692            0 :  call trace_prod_oper(self%moments(2),self%moments(2),green%trace_fermie(10))
    4693            0 :  call trace_prod_oper(green%moments(3),self%moments(2),green%trace_fermie(11))
    4694            0 :  call trace_prod_oper(green%moments(3),green%moments(3),green%trace_fermie(12))
    4695              : 
    4696            0 :  call destroy_oper(oper_tmp)
    4697            0 :  ABI_FREE(trace_loc)
    4698              : 
    4699            0 :  call xmpi_sum(green%trace_fermie(2:12),green%distrib%comm_kpt,ierr)
    4700              : 
    4701            0 : end subroutine compute_trace_moments_ks
    4702              : !!***
    4703              : 
    4704              : !!****f* m_green/compute_moments_loc
    4705              : !! NAME
    4706              : !! compute_moments_loc
    4707              : !!
    4708              : !! FUNCTION
    4709              : !!  Computes the high-frequency moments in local space.
    4710              : !!
    4711              : !! INPUTS
    4712              : !!  green  <type(green_type)>= green function data
    4713              : !!  self <type(self_type)>= variables related to self-energy
    4714              : !!  energy_level = local energy levels
    4715              : !!  weiss <type(green_type)>= weiss field
    4716              : !!  option = 0 : computes the hybridization moments in weiss%moments up to 4th order (including
    4717              : !!               the spurious 0th order moment, which is removed from the weiss field later),
    4718              : !!               using the moments of the self-energy and Green's function as inputs
    4719              : !!         = 1 : compute the self-energy moments in self%moments using the moments of the hybridization
    4720              : !!               and the Green's function (assuming the spurious 0th order moment of the hybridization
    4721              : !!               has been removed)
    4722              : !!  opt_log = if set to 1, also computes the trace of the moments of log(G)+log(iw*Id) and
    4723              : !!            log(G0)+log(iw*Id) in green%trace_moments_log_loc and weiss%trace_moments_log_loc
    4724              : !!  shift_mu = shift to apply to the chemical potential for the moments of G0
    4725              : !!
    4726              : !! OUTPUTS
    4727              : !!
    4728              : !! SOURCE
    4729              : 
    4730            0 : subroutine compute_moments_loc(green,self,energy_level,weiss,option,opt_log,shift_mu)
    4731              : 
    4732              : !Arguments ------------------------------------
    4733              :  type(green_type), intent(inout) :: green,weiss
    4734              :  type(self_type), intent(inout) :: self
    4735              :  type(oper_type), target, intent(in) :: energy_level
    4736              :  integer, intent(in) :: option
    4737              :  integer, optional, intent(in) :: opt_log
    4738              :  real(dp), optional, intent(in) :: shift_mu
    4739              : !Local variables ------------------------------
    4740              :  integer :: i,natom,nspinor,nsppol,optlog
    4741              :  complex(dp) :: trace
    4742            0 :  type(matlu_type), target, allocatable :: level_shift(:)
    4743            0 :  integer, allocatable :: lpawu(:)
    4744            0 :  complex(dp), allocatable :: shift(:),trace_loc(:)
    4745            0 :  type(matlu_type), allocatable :: matlu(:,:)
    4746              : !************************************************************************
    4747              : 
    4748            0 :  optlog = 0
    4749            0 :  if (present(opt_log)) optlog = opt_log
    4750              : 
    4751            0 :  natom   = energy_level%natom
    4752            0 :  nspinor = energy_level%nspinor
    4753            0 :  nsppol  = energy_level%nsppol
    4754              : 
    4755            0 :  ABI_MALLOC(trace_loc,(natom))
    4756              : 
    4757            0 :  ABI_MALLOC(lpawu,(natom))
    4758            0 :  ABI_MALLOC(matlu,(natom,6))
    4759              : 
    4760            0 :  lpawu(:) = energy_level%matlu(:)%lpawu ! to prevent the creation of a temporary array when calling init_matlu
    4761              : 
    4762            0 :  do i=1,6
    4763            0 :    call init_matlu(natom,nspinor,nsppol,lpawu(:),matlu(:,i))
    4764              :  end do
    4765              : 
    4766            0 :  if (option == 0) then
    4767            0 :    call add_matlu(green%moments(2)%matlu(:),energy_level%matlu(:),matlu(:,1),natom,-1)
    4768            0 :    call add_matlu(matlu(:,1),self%moments(1)%matlu(:),weiss%moments(1)%matlu(:),natom,-1)
    4769              :  else
    4770            0 :    call add_matlu(green%moments(2)%matlu(:),energy_level%matlu(:),self%moments(1)%matlu(:),natom,-1)
    4771              :  end if ! option
    4772              : 
    4773            0 :  if (optlog > 0) then
    4774              : 
    4775            0 :    ABI_MALLOC(level_shift,(natom))
    4776            0 :    ABI_MALLOC(shift,(natom))
    4777            0 :    call init_matlu(natom,nspinor,nsppol,lpawu(:),level_shift(:))
    4778            0 :    call copy_matlu(energy_level%matlu(:),level_shift(:),natom)
    4779              : 
    4780            0 :    shift(:) = cmplx(shift_mu,zero,kind=dp)
    4781            0 :    call shift_matlu(level_shift(:),natom,shift(:),signe=1)
    4782              : 
    4783            0 :    call trace_matlu(level_shift(:),natom,itau=0,trace=weiss%trace_moments_log_loc(1))
    4784            0 :    do i=2,green%nmoments-1
    4785            0 :      call trace_matlu(weiss%moments(i)%matlu(:),natom,itau=0,trace=weiss%trace_moments_log_loc(i))
    4786              :    end do ! i
    4787            0 :    call prod_matlu(level_shift(:),level_shift(:),matlu(:,1),natom)
    4788            0 :    call trace_matlu(matlu(:,1),natom,itau=0,trace=trace)
    4789            0 :    weiss%trace_moments_log_loc(2) = weiss%trace_moments_log_loc(2) + trace*half
    4790            0 :    call trace_prod_matlu(level_shift(:),weiss%moments(2)%matlu(:),natom,trace_loc(:),trace_tot=trace)
    4791            0 :    weiss%trace_moments_log_loc(3) = weiss%trace_moments_log_loc(3) + trace
    4792            0 :    call trace_prod_matlu(level_shift(:),matlu(:,1),natom,trace_loc(:),trace_tot=trace)
    4793            0 :    weiss%trace_moments_log_loc(3) = weiss%trace_moments_log_loc(3) + trace*third
    4794            0 :    call trace_prod_matlu(level_shift(:),weiss%moments(3)%matlu(:),natom,trace_loc(:),trace_tot=trace)
    4795            0 :    weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace
    4796            0 :    call trace_prod_matlu(weiss%moments(2)%matlu(:),weiss%moments(2)%matlu(:),natom,trace_loc(:),trace_tot=trace)
    4797            0 :    weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace*half
    4798            0 :    call trace_prod_matlu(weiss%moments(2)%matlu(:),matlu(:,1),natom,trace_loc(:),trace_tot=trace)
    4799            0 :    weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace
    4800            0 :    call trace_prod_matlu(matlu(:,1),matlu(:,1),natom,trace_loc(:),trace_tot=trace)
    4801            0 :    weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace*quarter
    4802              : 
    4803            0 :    call trace_matlu(green%moments(2)%matlu(:),natom,itau=0,trace=green%trace_moments_log_loc(1))
    4804              : 
    4805            0 :    call destroy_matlu(level_shift(:),natom)
    4806            0 :    ABI_FREE(level_shift)
    4807            0 :    ABI_FREE(shift)
    4808              : 
    4809              :  end if ! optlog
    4810              : 
    4811            0 :  call prod_matlu(green%moments(2)%matlu(:),green%moments(2)%matlu(:),matlu(:,1),natom) ! matlu=m0m0
    4812              : 
    4813            0 :  call add_matlu(green%moments(3)%matlu(:),matlu(:,1),matlu(:,2),natom,-1) ! matlu2=m1
    4814              : 
    4815            0 :  if (optlog > 0) then
    4816            0 :    call trace_matlu(matlu(:,2),natom,itau=0,trace=green%trace_moments_log_loc(2))
    4817            0 :    call trace_matlu(matlu(:,1),natom,itau=0,trace=trace)
    4818            0 :    green%trace_moments_log_loc(2) = green%trace_moments_log_loc(2) + half*trace
    4819              :  end if ! optlog
    4820              : 
    4821            0 :  if (option == 0) then
    4822            0 :    call add_matlu(matlu(:,2),self%moments(2)%matlu(:),weiss%moments(2)%matlu(:),natom,-1)
    4823            0 :  else if (option == 1) then
    4824            0 :    call add_matlu(matlu(:,2),weiss%moments(2)%matlu(:),self%moments(2)%matlu(:),natom,-1)
    4825              :  end if ! option
    4826              : 
    4827            0 :  call prod_matlu(green%moments(2)%matlu(:),matlu(:,1),matlu(:,3),natom) ! matlu3=m0m0m0
    4828            0 :  call add_matlu(green%moments(4)%matlu(:),matlu(:,3),matlu(:,1),natom,-1) ! matlu=green%moments(4)-m0m0m0
    4829              : 
    4830            0 :  if (optlog > 0) then
    4831            0 :    call trace_matlu(matlu(:,3),natom,itau=0,trace=trace)
    4832            0 :    green%trace_moments_log_loc(3) = trace * third
    4833              :  end if ! optlog
    4834              : 
    4835            0 :  call prod_matlu(green%moments(2)%matlu(:),matlu(:,2),matlu(:,4),natom) ! matlu4=m0m1
    4836            0 :  call prod_matlu(matlu(:,2),green%moments(2)%matlu(:),matlu(:,5),natom) ! matlu5=m1m0
    4837              : 
    4838            0 :  call add_matlu(matlu(:,4),matlu(:,5),matlu(:,6),natom,1) ! matlu6=m0m1+m1m0
    4839              : 
    4840            0 :  if (optlog > 0) then
    4841            0 :    call trace_matlu(matlu(:,4),natom,itau=0,trace=trace)
    4842            0 :    green%trace_moments_log_loc(3) = trace + green%trace_moments_log_loc(3)
    4843              :  end if ! optlog
    4844              : 
    4845            0 :  call add_matlu(matlu(:,1),matlu(:,6),matlu(:,5),natom,-1) ! matlu5=m2
    4846              : 
    4847            0 :  if (optlog > 0) then
    4848            0 :    call trace_matlu(matlu(:,5),natom,itau=0,trace=trace)
    4849            0 :    green%trace_moments_log_loc(3) = trace + green%trace_moments_log_loc(3)
    4850              :  end if ! optlog
    4851              : 
    4852            0 :  if (option == 0) then
    4853            0 :    call add_matlu(matlu(:,5),self%moments(3)%matlu(:),weiss%moments(3)%matlu(:),natom,-1)
    4854            0 :  else if (option == 1) then
    4855            0 :    call add_matlu(matlu(:,5),weiss%moments(3)%matlu(:),self%moments(3)%matlu(:),natom,-1)
    4856              :  end if ! option
    4857              : 
    4858            0 :  call prod_matlu(green%moments(2)%matlu(:),matlu(:,3),matlu(:,1),natom) ! matlu=m0m0m0m0
    4859            0 :  call prod_matlu(matlu(:,6),green%moments(2)%matlu(:),matlu(:,3),natom) ! matlu3 = m0m1m0+m1m0m0
    4860            0 :  call prod_matlu(green%moments(2)%matlu(:),matlu(:,4),matlu(:,6),natom) ! matlu6 = m0m0m1
    4861            0 :  call add_matlu(matlu(:,3),matlu(:,6),matlu(:,4),natom,1) ! matlu4 = m0m1m0+m1m0m0+m0m0m1
    4862              : 
    4863            0 :  if (optlog > 0) then
    4864            0 :    call trace_matlu(matlu(:,4),natom,itau=0,trace=trace)
    4865            0 :    green%trace_moments_log_loc(4) = trace * third
    4866            0 :    call trace_matlu(matlu(:,1),natom,itau=0,trace=trace)
    4867            0 :    green%trace_moments_log_loc(4) = green%trace_moments_log_loc(4) + trace*quarter
    4868              :  end if ! optlog
    4869              : 
    4870            0 :  call add_matlu(matlu(:,1),matlu(:,4),matlu(:,3),natom,1) ! matlu3 = m0m1m0+m1m0m0+m0m0m1+m0m0m0m0
    4871              : 
    4872            0 :  call prod_matlu(green%moments(2)%matlu(:),matlu(:,5),matlu(:,1),natom) ! matlu=m0m2
    4873            0 :  call prod_matlu(matlu(:,5),green%moments(2)%matlu(:),matlu(:,4),natom) ! matlu4=m2m0
    4874            0 :  call add_matlu(matlu(:,1),matlu(:,4),matlu(:,5),natom,1) ! matlu5=m0m2+m2m0
    4875            0 :  call prod_matlu(matlu(:,2),matlu(:,2),matlu(:,1),natom) ! matlu=m1m1
    4876            0 :  call add_matlu(matlu(:,1),matlu(:,5),matlu(:,2),natom,1) ! matlu2=m1m1+m0m2+m2m0
    4877              : 
    4878            0 :  if (optlog > 0) then
    4879            0 :    call trace_matlu(matlu(:,2),natom,itau=0,trace=trace)
    4880            0 :    green%trace_moments_log_loc(4) = green%trace_moments_log_loc(4) + trace*half
    4881              :  end if ! optlog
    4882              : 
    4883            0 :  call add_matlu(green%moments(5)%matlu(:),matlu(:,2),matlu(:,1),natom,-1)
    4884            0 :  call add_matlu(matlu(:,1),matlu(:,3),matlu(:,2),natom,-1) ! matlu2=m3
    4885              : 
    4886            0 :  if (optlog > 0) then
    4887            0 :    call trace_matlu(matlu(:,2),natom,itau=0,trace=trace)
    4888            0 :    green%trace_moments_log_loc(4) = green%trace_moments_log_loc(4) + trace
    4889              :  end if ! optlog
    4890              : 
    4891            0 :  if (option == 0) then
    4892            0 :    call add_matlu(matlu(:,2),self%moments(4)%matlu(:),weiss%moments(4)%matlu(:),natom,-1)
    4893            0 :  else if (option == 1) then
    4894            0 :    call add_matlu(matlu(:,2),weiss%moments(4)%matlu(:),self%moments(4)%matlu(:),natom,-1)
    4895              :  end if ! option
    4896              : 
    4897            0 :  do i=1,6
    4898            0 :    call destroy_matlu(matlu(:,i),natom)
    4899              :  end do
    4900              : 
    4901            0 :  ABI_FREE(lpawu)
    4902            0 :  ABI_FREE(matlu)
    4903            0 :  ABI_FREE(trace_loc)
    4904              : 
    4905            0 : end subroutine compute_moments_loc
    4906              : !!***
    4907              : 
    4908              : !!****f* m_green/occup_fd
    4909              : !! NAME
    4910              : !! occup_fd
    4911              : !!
    4912              : !! FUNCTION
    4913              : !!  Computes the Fermi-Dirac occupation
    4914              : !!
    4915              : !! INPUTS
    4916              : !!  eig = eigenvalues
    4917              : !!  fermie = Fermi level
    4918              : !!  temp = temperature
    4919              : !!
    4920              : !! OUTPUT
    4921              : !!
    4922              : !!
    4923              : !! SOURCE
    4924              : 
    4925         9852 :  function occup_fd(eig,fermie,temp)
    4926              : 
    4927              : !Arguments ------------------------------------
    4928              : !type
    4929              : ! Integrate analytic tail 1/(iw-mu)
    4930              :  real(dp), intent(in) :: eig,fermie,temp
    4931              :  real(dp) :: occup_fd
    4932              : !Local variables-------------------------------
    4933              : ! *********************************************************************
    4934              : 
    4935         9852 :  if ((eig-fermie) > zero) then
    4936         5067 :    occup_fd = exp(-(eig-fermie)/temp) / (one+exp(-(eig-fermie)/temp))
    4937              :  else
    4938         4785 :    occup_fd = one / (one+exp((eig-fermie)/temp))
    4939              :  end if ! eig-fermie>0
    4940              : 
    4941         9852 :  end function occup_fd
    4942              : 
    4943            0 : END MODULE m_green
    4944              : !!***
        

Generated by: LCOV version 2.3-1