LCOV - code coverage report
Current view: top level - src/68_dmft - m_self.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.3 % 764 598
Test Date: 2026-09-19 17:42:43 Functions: 81.8 % 11 9

            Line data    Source code
       1              : !!****m* ABINIT/m_self
       2              : !! NAME
       3              : !!  m_self
       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_self
      26              : 
      27              :  use defs_basis
      28              :  use m_errors
      29              :  use m_abicore
      30              : 
      31              :  use m_datafordmft, only : compute_levels
      32              :  use m_fstrings, only : int2char4
      33              :  use m_hu, only : hu_type
      34              :  use m_io_tools, only : get_unit
      35              :  use m_matlu, only : add_matlu,copy_matlu,destroy_matlu,diag_matlu,fac_matlu, &
      36              :                    & init_matlu,matlu_type,print_matlu,rotate_matlu,xmpi_matlu,zero_matlu
      37              :  use m_oper, only : destroy_oper,gather_oper,init_oper,oper_type,print_oper
      38              :  use m_paw_dmft, only : mpi_distrib_dmft_type,paw_dmft_type
      39              :  use m_paw_exactDC, only : compute_exactDC
      40              :  use m_pawtab, only : pawtab_type
      41              :  use m_xmpi, only : xmpi_bcast,xmpi_sum
      42              : 
      43              : #ifdef HAVE_GPU_MARKERS
      44              :  use m_nvtx_data
      45              : #endif
      46              : 
      47              :  implicit none
      48              : 
      49              :  private
      50              : 
      51              :  public :: alloc_self
      52              :  public :: initialize_self
      53              :  public :: destroy_self
      54              :  public :: print_self
      55              :  public :: rw_self
      56              :  public :: dc_self
      57              :  public :: new_self
      58              :  !public :: make_qmcshift_self
      59              :  public :: selfreal2imag_self
      60              : 
      61              : !!***
      62              : 
      63              : !!****t* m_self/self_type
      64              : !! NAME
      65              : !!  self_type
      66              : !!
      67              : !! FUNCTION
      68              : !!  This structured datatype contains the necessary data
      69              : !!
      70              : !! SOURCE
      71              : 
      72              :  type, public :: self_type ! for each atom
      73              : 
      74              :   integer :: dmft_nwli
      75              :   ! Linear index of the last imaginary frequency
      76              : 
      77              :   integer :: dmft_nwlo
      78              :   ! Number of imaginary frequencies
      79              : 
      80              :   integer :: has_moments
      81              :   ! =1 if the high-frequency moments are computed
      82              : 
      83              :   integer :: iself_cv
      84              :   ! Integer for convergence of self-energy
      85              : 
      86              :   integer :: nmoments
      87              :   ! Number of high-frequency moments which will be computed
      88              : 
      89              :   integer :: nw
      90              :   ! Number of frequencies (equal to dmft_nwlo only if w_type="imag")
      91              : 
      92              :   character(len=4) :: w_type
      93              :   ! Type of frequencies used ("real" or "imag")
      94              : 
      95              :   !real(dp), allocatable :: qmc_shift(:)
      96              :   ! value of frequencies
      97              : 
      98              :   !real(dp), allocatable :: qmc_xmu(:)
      99              :   ! value of frequencies
     100              : 
     101              :   type(oper_type) :: hdc
     102              :   ! Operator for double counting
     103              : 
     104              :   type(oper_type), allocatable :: moments(:)
     105              :   ! High-frequency moments
     106              : 
     107              :   type(oper_type), allocatable :: oper(:)
     108              :   ! Operator for self-energy, for each frequency
     109              : 
     110              :   real(dp), ABI_CONTIGUOUS pointer :: omega(:) => null()
     111              :   ! Value of frequencies
     112              : 
     113              :   type(mpi_distrib_dmft_type), pointer :: distrib => null()
     114              :   ! Datastructure for MPI parallelization
     115              : 
     116              :  end type self_type
     117              : !!***
     118              : 
     119              : !----------------------------------------------------------------------
     120              : 
     121              : 
     122              : CONTAINS  !========================================================================================
     123              : !!***
     124              : 
     125              : !!****f* m_self/alloc_self
     126              : !! NAME
     127              : !! alloc_self
     128              : !!
     129              : !! FUNCTION
     130              : !!  Allocate variables used in type self_type.
     131              : !!
     132              : !! INPUTS
     133              : !!  self <type(self_type)>= variables related to self-energy
     134              : !!  paw_dmft <type(paw_dmft_type)> =  variables related to self-consistent DFT+DMFT calculations.
     135              : !!  opt_oper = 1  Allocate only quantities in the KS basis.
     136              : !!             2  Allocate only quantities in the local basis.
     137              : !!             3  Allocate quantities in both the KS and local basis.
     138              : !!  wtype = "real" Self energy will be computed for real frequencies
     139              : !!        = "imag" (default) Self energy will be computed for imaginary frequencies
     140              : !!  opt_moments = 1 to allocate the high-frequency moments
     141              : !!
     142              : !! OUTPUTS
     143              : !!  self <type(self_type)>= variables related to self-energy
     144              : !!
     145              : !! SOURCE
     146              : 
     147          211 : subroutine alloc_self(self,paw_dmft,opt_oper,wtype,opt_moments)
     148              : 
     149              : !Arguments ------------------------------------
     150              :  type(self_type), intent(inout) :: self
     151              :  type(paw_dmft_type), target, intent(in) :: paw_dmft
     152              :  integer, optional, intent(in) :: opt_moments,opt_oper
     153              :  character(len=4), optional :: wtype
     154              : !Local variables ------------------------------------
     155              :  integer :: i,ifreq,mkmem,optmoments,optoper,shift
     156              : !************************************************************************
     157              : 
     158          211 :  optoper = 2
     159          211 :  self%w_type = "imag"
     160          211 :  self%nmoments = 0
     161          211 :  optmoments = 0
     162              : 
     163          211 :  if (present(opt_oper)) optoper  = opt_oper
     164          211 :  if (present(wtype)) self%w_type = wtype
     165          211 :  if (present(opt_moments)) optmoments = opt_moments
     166              : 
     167          211 :  self%has_moments = optmoments
     168              : 
     169          211 :  if (self%w_type == "imag") then
     170          207 :    self%nw = paw_dmft%dmft_nwlo
     171          207 :    self%omega => paw_dmft%omega_lo(:)
     172          207 :    self%distrib => paw_dmft%distrib
     173            4 :  else if (self%w_type == "real") then
     174            4 :    self%nw = size(paw_dmft%omega_r(:))
     175            4 :    self%omega => paw_dmft%omega_r(:)
     176            4 :    self%distrib => paw_dmft%distrib_r
     177              :  end if ! w_type
     178              : 
     179          211 :  self%dmft_nwlo = paw_dmft%dmft_nwlo
     180          211 :  self%dmft_nwli = paw_dmft%dmft_nwli
     181          211 :  self%iself_cv  = 0
     182              : 
     183          211 :  call init_oper(paw_dmft,self%hdc,opt_ksloc=optoper)
     184              : 
     185        68311 :  ABI_MALLOC(self%oper,(self%nw))
     186        67889 :  do ifreq=1,self%nw
     187        67889 :    call init_oper(paw_dmft,self%oper(ifreq),opt_ksloc=optoper)
     188              :  end do ! ifreq
     189              : 
     190          211 :  if (optmoments == 1) then
     191            0 :    self%nmoments = 4
     192            0 :    shift = self%distrib%shiftk
     193            0 :    mkmem = self%distrib%nkpt_mem(self%distrib%me_kpt+1)
     194            0 :    ABI_MALLOC(self%moments,(self%nmoments))
     195            0 :    call init_oper(paw_dmft,self%moments(1),nkpt=mkmem,shiftk=shift,opt_ksloc=2)
     196            0 :    do i=2,self%nmoments
     197            0 :      call init_oper(paw_dmft,self%moments(i),nkpt=mkmem,shiftk=shift,opt_ksloc=3)
     198              :    end do ! i
     199              :  end if ! optmoments
     200              : 
     201              :  !if (paw_dmft%dmft_solv == 4) then
     202              :  !  ABI_MALLOC(self%qmc_shift,(paw_dmft%natom))
     203              :  !  ABI_MALLOC(self%qmc_xmu,(paw_dmft%natom))
     204              :  !  self%qmc_shift(:) = zero
     205              :  !  self%qmc_xmu(:) = zero
     206              :  !end if ! dmft_solv=4
     207              : 
     208          211 : end subroutine alloc_self
     209              : !!***
     210              : 
     211              : !!****f* m_self/initialize_self
     212              : !! NAME
     213              : !! initialize_self
     214              : !!
     215              : !! FUNCTION
     216              : !!  Initialize self-energy.
     217              : !!
     218              : !! INPUTS
     219              : !!  self <type(self_type)>= variables related to self-energy
     220              : !!  paw_dmft <type(paw_dmft_type)> =  variables related to self-consistent DFT+DMFT calculations.
     221              : !!  wtype = "real" Self energy will be computed for real frequencies
     222              : !!        = "imag" (default) Self energy will be computed for imaginary frequencies
     223              : !!  opt_moments = 1 to compute the high frequency moments
     224              : !!
     225              : !! OUTPUTS
     226              : !!  self <type(self_type)>= variables related to self-energy
     227              : !!
     228              : !!
     229              : !! SOURCE
     230              : 
     231          211 : subroutine initialize_self(self,paw_dmft,wtype,opt_moments)
     232              : 
     233              : !Arguments ------------------------------------
     234              :  type(self_type), intent(inout) :: self
     235              :  type(paw_dmft_type), intent(in) :: paw_dmft
     236              :  character(len=4), optional, intent(in) :: wtype
     237              :  integer, optional, intent(in) :: opt_moments
     238              : !Local variables ------------------------------------
     239              : ! character(len=500) :: message
     240              :  integer :: optmoments
     241              :  character(len=4) :: wtype2
     242              : !************************************************************************
     243              : 
     244          211 :  optmoments = 0
     245          211 :  wtype2 = "imag"
     246          211 :  if (present(wtype)) wtype2 = wtype
     247          211 :  if (present(opt_moments)) optmoments = opt_moments
     248              : 
     249          211 :  call alloc_self(self,paw_dmft,opt_oper=2,wtype=wtype2,opt_moments=optmoments) !  opt_oper=1 is not useful and not implemented
     250              : ! if(paw_dmft%dmft_rslf==1.and.opt_read==1) then
     251              : !   call rw_self(cryst_struc,self,mpi_enreg,paw_dmft,pawtab,pawprtvol=2,opt_rw=1)
     252              : ! endif
     253              : ! write(message,'(a,a)') ch10,"   Self-energy for large frequency is"
     254              : ! call wrtout(std_out,message,'COLL')
     255              : ! call print_matlu(self%oper(paw_dmft%dmft_nwlo)%matlu,  &
     256              : !&                 paw_dmft%natom,3)
     257              : 
     258          211 : end subroutine initialize_self
     259              : !!***
     260              : 
     261              : !!****f* m_self/destroy_self
     262              : !! NAME
     263              : !! destroy_self
     264              : !!
     265              : !! FUNCTION
     266              : !!  Deallocate self
     267              : !!
     268              : !! INPUTS
     269              : !!  self <type(self_type)>= variables related to self-energy
     270              : !!
     271              : !! OUTPUT
     272              : !!
     273              : !! SOURCE
     274              : 
     275          211 : subroutine destroy_self(self)
     276              : 
     277              : !Arguments ------------------------------------
     278              :  type(self_type), intent(inout) :: self
     279              : !Local variables-------------------------------
     280              :  integer :: i,ifreq
     281              : ! *********************************************************************
     282              : 
     283          211 :  if (allocated(self%oper)) then
     284        67889 :    do ifreq=1,self%nw
     285        67889 :      call destroy_oper(self%oper(ifreq))
     286              :    end do
     287        67889 :    ABI_FREE(self%oper)
     288              :  end if
     289              : 
     290          211 :  call destroy_oper(self%hdc)
     291              : 
     292          211 :  if (allocated(self%moments)) then
     293            0 :    do i=1,self%nmoments
     294            0 :      call destroy_oper(self%moments(i))
     295              :    end do ! i
     296            0 :    ABI_FREE(self%moments)
     297              :  end if
     298              :  !if (allocated(self%qmc_shift)) ABI_FREE(self%qmc_shift)
     299              :  !if (allocated(self%qmc_xmu)) ABI_FREE(self%qmc_xmu)
     300          211 :  self%distrib => null()
     301          211 :  self%omega => null()
     302              : 
     303          211 : end subroutine destroy_self
     304              : !!***
     305              : 
     306              : !!****f* m_self/print_self
     307              : !! NAME
     308              : !! print_self
     309              : !!
     310              : !! FUNCTION
     311              : !!  Print self-energy
     312              : !!
     313              : !! INPUTS
     314              : !!  self <type(self_type)>= variables related to self-energy
     315              : !!  prtdc = print double counting if equal to "print_dc"
     316              : !!  paw_dmft <type(paw_dmft_type)> =  variables related to self-consistent DFT+DMFT calculations.
     317              : !!  prtopt = integer which specifies the amount of printing in the subroutine called
     318              : !!
     319              : !! OUTPUT
     320              : !!  self <type(self_type)>= variables related to self-energy
     321              : !!
     322              : !! SOURCE
     323              : 
     324          339 : subroutine print_self(self,prtdc,paw_dmft,prtopt)
     325              : 
     326              : !Arguments ------------------------------------
     327              :  type(paw_dmft_type), intent(in) :: paw_dmft
     328              :  type(self_type), intent(in)  :: self
     329              :  character(len=*), intent(in) :: prtdc
     330              :  integer, intent(in) :: prtopt
     331              : !Local variables-------------------------------
     332              :  character(len=500) :: message
     333              : ! *********************************************************************
     334              : 
     335          339 :  write(message,'(2a)') ch10,"  == The self-energy for smallest frequency is   == "
     336          339 :  call wrtout(std_out,message,'COLL')
     337          339 :  call print_oper(self%oper(1),1,paw_dmft,prtopt)
     338              : ! write(message,'(2a)') ch10,"  == The self-energy for small (3) frequency is   == "
     339              : ! call wrtout(std_out,message,'COLL')
     340              : ! call print_oper(self%oper(3),1,paw_dmft,prtopt)
     341          339 :  write(message,'(2a)') ch10,"  == The self-energy for largest frequency is   == "
     342          339 :  call wrtout(std_out,message,'COLL')
     343          339 :  call print_oper(self%oper(self%nw),1,paw_dmft,prtopt)
     344          339 :  if (prtdc == "print_dc") then
     345          339 :    write(message,'(2a)') ch10,"  == The double counting potential is  == "
     346          339 :    call wrtout(std_out,message,'COLL')
     347          339 :    call print_matlu(self%hdc%matlu(:),paw_dmft%natom,prtopt)
     348              :  end if ! prtdc
     349              : 
     350          339 : end subroutine print_self
     351              : !!***
     352              : 
     353              : !!****f* m_self/dc_self
     354              : !! NAME
     355              : !! dc_self
     356              : !!
     357              : !! FUNCTION
     358              : !!  Computes the double counting
     359              : !!
     360              : !! INPUTS
     361              : !!  charge_loc : local charge for each polarization and each atom
     362              : !!  hu <type(hu_type)>= U interaction
     363              : !!  paw_dmft <type(paw_dmft_type)> =  variables related to self-consistent DFT+DMFT calculations.
     364              : !!  pawtab <type(pawtab_type)>=paw tabulated starting data
     365              : !!  occ_matlu : local occupation matrix
     366              : !!
     367              : !! OUTPUT
     368              : !!  hdc : double counting
     369              : !!
     370              : !! SOURCE
     371              : 
     372          199 : subroutine dc_self(charge_loc,hdc,hu,paw_dmft,pawtab,occ_matlu)
     373              : 
     374              : !Arguments ------------------------------------
     375              : !type
     376              :  !type(crystal_t),intent(in) :: cryst_struc
     377              :  type(paw_dmft_type), intent(inout) :: paw_dmft
     378              :  type(matlu_type), intent(inout) :: hdc(paw_dmft%natom)
     379              :  real(dp), intent(in) :: charge_loc(paw_dmft%nsppol+1,paw_dmft%natom)
     380              :  type(hu_type), intent(in) :: hu(paw_dmft%ntypat)
     381              :  type(pawtab_type), intent(inout) :: pawtab(paw_dmft%ntypat)
     382              :  type(matlu_type), intent(in) :: occ_matlu(paw_dmft%natom)
     383              :  !type(hu_type),intent(inout) :: hu(cryst_struc%ntypat)
     384              :  !integer, intent(in) :: dmft_dc
     385              : !Local variables-------------------------------
     386              :  integer :: dmft_dc,iatom,iatomc,ierr,im,ispinor,isppol
     387              :  integer :: itypat,lpawu,natom,ndim,nspinor,nsppol
     388              :  real(dp) :: dc,jpawu,ntot,upawu
     389              :  logical :: amf,fll,nmdc
     390              :  character(len=500) :: message
     391          199 :  complex(dp), allocatable :: occ(:,:),vdc(:,:)
     392              : ! *********************************************************************
     393              : 
     394          199 :  dmft_dc = paw_dmft%dmft_dc
     395          199 :  natom   = paw_dmft%natom
     396          199 :  nspinor = paw_dmft%nspinor
     397          199 :  nsppol  = paw_dmft%nsppol
     398              : 
     399          199 :  amf  = (dmft_dc == 2 .or. dmft_dc == 6) ! AMF double counting
     400          199 :  fll  = (dmft_dc == 1 .or. dmft_dc == 4 .or. dmft_dc == 5) ! FLL double counting
     401          199 :  nmdc = (nspinor == 2 .or. (dmft_dc >= 5 .and. dmft_dc <= 8)) ! non-magnetic double counting
     402              : 
     403          199 :  if ((.not. fll) .and. (.not. amf) .and. dmft_dc /= 7 .and. dmft_dc /= 8) &
     404            0 :    & ABI_ERROR("not implemented")
     405          199 :  if (amf .and. (nspinor == 2)) then
     406            0 :    write(message,'(a,i4,i4,2x,e20.10)') " AMF Double counting is under test for SOC"
     407            0 :    ABI_WARNING(message)
     408              :  end if
     409              : 
     410          199 :  if (dmft_dc == 8) then
     411            0 :    paw_dmft%edc(:)   = zero
     412            0 :    paw_dmft%edcdc(:) = zero
     413            0 :    call zero_matlu(hdc(:),natom)
     414              :  end if
     415              : 
     416              :  iatomc = -1
     417              : 
     418          890 :  do iatom=1,natom
     419          691 :    lpawu = paw_dmft%lpawu(iatom)
     420          691 :    if (lpawu == -1) cycle
     421          235 :    iatomc = iatomc + 1
     422        10896 :    hdc(iatom)%mat(:,:,:) = czero
     423          235 :    ntot   = charge_loc(nsppol+1,iatom)
     424          235 :    ndim   = 2*lpawu + 1
     425          235 :    itypat = paw_dmft%typat(iatom)
     426          235 :    upawu  = hu(itypat)%upawu
     427          235 :    jpawu = merge(zero,hu(itypat)%jpawu,dmft_dc==4)
     428              : 
     429          434 :    if (dmft_dc == 8) then
     430            0 :      if (mod(iatomc,paw_dmft%nproc) /= paw_dmft%myproc) cycle
     431            0 :      ABI_MALLOC(occ,(ndim,ndim))
     432            0 :      ABI_MALLOC(vdc,(ndim,ndim))
     433            0 :      occ(:,:) = czero
     434            0 :      do isppol=1,nsppol
     435            0 :        do ispinor=1,nspinor
     436            0 :          occ(:,:) = occ(:,:) + occ_matlu(iatom)%mat(1+(ispinor-1)*ndim:ispinor*ndim,1+(ispinor-1)*ndim:ispinor*ndim,isppol)
     437              :        end do ! ispinor
     438              :      end do ! isppol
     439            0 :      if (nsppol == 1 .and. nspinor == 1) occ(:,:) = occ(:,:) * two
     440              :      call compute_exactDC(lpawu,pawtab(itypat),paw_dmft%radgrid(itypat),occ(:,:), &
     441            0 :                         & vdc(:,:),paw_dmft%edc(iatom),paw_dmft%edcdc(iatom),paw_dmft%ixc)
     442            0 :      do isppol=1,nsppol
     443            0 :        do ispinor=1,nspinor
     444            0 :          hdc(iatom)%mat(1+(ispinor-1)*ndim:ispinor*ndim,1+(ispinor-1)*ndim:ispinor*ndim,isppol) = vdc(:,:)
     445              :        end do ! ispinor
     446              :      end do ! isppol
     447            0 :      ABI_FREE(occ)
     448            0 :      ABI_FREE(vdc)
     449              :    else
     450          235 :      if (nmdc) then ! Non-magnetic DC
     451           29 :        if (fll) dc = upawu*(ntot-half) - half*jpawu*(ntot-one)
     452           29 :        if (amf) dc = upawu*ntot*half + (upawu-jpawu)*ntot*half*dble(2*lpawu)/dble(2*lpawu+1)
     453           29 :        if (dmft_dc == 7) dc = upawu*(dble(paw_dmft%dmft_nominal(iatom))-half) - &
     454            0 :          & half*jpawu*(dble(paw_dmft%dmft_nominal(iatom))-one)
     455              :      end if ! nmdc
     456          235 :      ndim = nspinor * ndim
     457          594 :      do isppol=1,nsppol
     458          359 :        if (.not. nmdc) then ! Magnetic DC
     459          304 :          if (fll) dc = upawu*(ntot-half) - jpawu*(charge_loc(isppol,iatom)-half)
     460          304 :          if (amf) dc = upawu*charge_loc(min(3-isppol,nsppol),iatom) + &
     461            0 :               & (upawu-jpawu)*charge_loc(isppol,iatom)*dble(2*lpawu)/dble(2*lpawu+1)
     462              :        end if ! not nmdc
     463         2728 :        do im=1,ndim
     464         2037 :          hdc(iatom)%mat(im,im,isppol) = dc
     465              :        end do ! im
     466              :      end do ! isppol
     467              :    end if ! dc=8
     468              :  end do ! iatom
     469              : 
     470          199 :  if (dmft_dc == 8) then
     471            0 :    call xmpi_sum(paw_dmft%edc(:),paw_dmft%spacecomm,ierr)
     472            0 :    call xmpi_sum(paw_dmft%edcdc(:),paw_dmft%spacecomm,ierr)
     473            0 :    call xmpi_matlu(hdc(:),natom,paw_dmft%spacecomm)
     474              :  end if ! dmft_dc=8
     475              : 
     476          199 : end subroutine dc_self
     477              : !!***
     478              : 
     479              : !!****f* m_self/rw_self
     480              : !! NAME
     481              : !! rw_self
     482              : !!
     483              : !! FUNCTION
     484              : !!  Read/write self-energy on file.
     485              : !!
     486              : !! INPUTS
     487              : !!  self <type(self_type)>= variables related to self-energy
     488              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     489              : !!  prtopt = flag for printing
     490              : !!  opt_rw = 0 (default) Set self-energy either to double counting or 0 depending on dmft_rslf
     491              : !!           1  Read Self-Energy.
     492              : !!           2  Write Self-Energy.
     493              : !!           3  Impose Self-Energy.
     494              : !!  istep_iter = iteration step
     495              : !!  opt_char = char to add at the end of the filename
     496              : !!  opt_imagonly = only reads the imaginary part (useful when reading from Maxent)
     497              : !!  opt_selflimit = 0th order moment of the self-energy (useful when reading from Maxent)
     498              : !!  opt_hdc = double counting (useful when reading from Maxent)
     499              : !!  opt_stop = stop when encountering errors
     500              : !!  opt_maxent = if > 0, read/write Maxent files
     501              : !!
     502              : !! OUTPUT
     503              : !!
     504              : !! SOURCE
     505              : 
     506          406 : subroutine rw_self(self,paw_dmft,prtopt,opt_rw,istep_iter,opt_char,opt_imagonly,&
     507          406 :                  & opt_selflimit,opt_hdc,opt_stop,opt_maxent)
     508              : 
     509              : !Arguments ------------------------------------
     510              : !type
     511              :  type(self_type), intent(inout) :: self
     512              :  type(paw_dmft_type), intent(inout) :: paw_dmft
     513              :  integer, intent(in) :: prtopt
     514              :  integer, optional, intent(in) :: istep_iter,opt_imagonly,opt_maxent,opt_rw,opt_stop
     515              :  character(len=4), optional, intent(in) :: opt_char
     516              :  type(matlu_type), optional, intent(inout) :: opt_selflimit(paw_dmft%natom)
     517              :  type(matlu_type), optional, intent(in) :: opt_hdc(paw_dmft%natom)
     518              : !local variables-------------------------------
     519              :  integer :: i,iall,iatom,iatu,icount,ier,iexist2,iexit,iflavor,ifreq,im,im1,ioerr
     520              :  integer :: ispinor,ispinor1,isppol,istep,istep_imp,istepiter,iter,iter_imp,lpawu,master
     521              :  integer :: myproc,natom,natom_read,ncount,ndim,ndim_read,nrecl,nspinor,nspinor_read
     522              :  integer :: nsppol,nsppol_read,nw_read,optmaxent,optrw,readimagonly,spacecomm,unitrot
     523              :  real(dp) :: fermie_read,x_r,x_i,xtemp
     524              :  logical :: lexist,lexist_rot,nondiaglevels,prtself
     525              :  character(len=30000) :: message ! Big buffer to avoid buffer overflow.
     526              :  character(len=fnlen) :: stringfile,tmpfil,tmpfil2,tmpfilrot,tmpmatrot
     527              :  character(len=1) :: tag_is
     528              :  character(len=3) :: self_iter
     529              :  character(len=4) :: chtemp
     530              :  character(len=5) :: tag_freq
     531              :  character(len=10) :: tag_at,tag_iflavor
     532              :  character(len=13) :: tag
     533              :  character(len=50) :: string_format
     534          406 :  type(oper_type) :: energy_level
     535          406 :  integer, allocatable :: unitselffunc_arr(:),unitselffunc_arr2(:),unitselfrot(:,:,:,:)
     536          406 :  real(dp), allocatable :: s_i(:,:),s_r(:,:) !,fermie_read2(:)
     537          406 :  complex(dp), allocatable :: buffer(:)
     538          406 :  type(matlu_type), allocatable :: eigvectmatlu(:),level_diag(:),selfmomrot(:,:)
     539          406 :  type(oper_type), allocatable :: selfrotmatlu(:)
     540              : ! *********************************************************************
     541              : 
     542              :  ABI_NVTX_START_RANGE(NVTX_DMFT_RW_SELF)
     543          406 :  natom   = paw_dmft%natom
     544          406 :  nspinor = paw_dmft%nspinor
     545          406 :  nsppol  = paw_dmft%nsppol
     546              :  !mbandc = paw_dmft%mbandc
     547              :  !nkpt = paw_dmft%nkpt
     548              : 
     549              : ! Initialise spaceComm, myproc, and nproc
     550          406 :  istep = 0
     551          406 :  iter  = 0
     552          406 :  istep_imp = 0
     553          406 :  istepiter = 0
     554          406 :  iter_imp  = 0
     555          406 :  optmaxent = 0
     556          406 :  optrw = 0
     557          406 :  prtself = (paw_dmft%dmft_prtself == 1)
     558          406 :  readimagonly = 0
     559              : 
     560          406 :  if (present(opt_rw)) optrw = opt_rw
     561          406 :  if (present(opt_maxent)) optmaxent = opt_maxent
     562              : 
     563          406 :  if (present(opt_imagonly)) then
     564            4 :    if (opt_imagonly == 1 .and. paw_dmft%dmft_solv >= 5) then
     565            4 :      readimagonly = opt_imagonly
     566            4 :      write(message,*)
     567            4 :      write(message,'(a,4x,2a)') ch10,"About to read imaginary part of Self energy"
     568            4 :      call wrtout(std_out,message,'COLL')
     569              :    else
     570            0 :      write(message,'(4x,2a)') "About to read both real and imaginary part of Self energy"
     571            0 :      call wrtout(std_out,message,'COLL')
     572              :    end if ! opt_imagonly
     573              :  end if ! present(opt_imagonly)
     574              : 
     575          406 :  if (present(istep_iter)) istepiter = istep_iter
     576              : 
     577          406 :  if (paw_dmft%use_fixed_self > 0) then
     578            0 :    istep = istepiter / 1000
     579            0 :    iter  = istepiter - (istepiter/1000)*1000
     580            0 :    istep_imp = paw_dmft%use_fixed_self / 1000
     581            0 :    iter_imp  = paw_dmft%use_fixed_self - (paw_dmft%use_fixed_self/1000)*1000
     582              :  end if !use_fixed_self
     583              : 
     584          406 :  if (paw_dmft%dmft_rslf <= 0 .and. optrw == 1) optrw = 0
     585              : 
     586          406 :  iexist2   = 1
     587          406 :  iexit     = 0
     588          406 :  ioerr     = 0
     589          406 :  lexist    = .true.
     590          406 :  master    = 0
     591          406 :  myproc    = paw_dmft%myproc
     592          406 :  spacecomm = paw_dmft%spacecomm
     593              :  !nproc = paw_dmft%nproc
     594              : 
     595              : ! write(std_out,*) "myproc,master",myproc,master
     596              :  !if(prtopt>200) then
     597              :  !endif
     598              : 
     599              : !   - For the Tentative rotation of the self-energy file (begin init)
     600          406 :  if (optmaxent > 0) then
     601          110 :    if (optrw == 2) then
     602          106 :      write(message,'(a,2x,a)') ch10," == About to print self-energy for MAXENT code in basis that diagonalizes the atomic levels"
     603            4 :    else if (optrw == 1)  then
     604            4 :      write(message,'(a,2x,a)') ch10," == About to read self-energy from MAXENT code"
     605              :    end if
     606          110 :    call wrtout(std_out,message,'COLL')
     607              : 
     608          704 :    ABI_MALLOC(eigvectmatlu,(natom))
     609          110 :    call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),eigvectmatlu(:))
     610              :  end if ! optmaxent > 0
     611              : !   - For the Tentative rotation of the self-energy file (end init)
     612              : 
     613              : !   - For the Tentative rotation of the self-energy file (begin diag)
     614          406 :  if (optrw == 2 .and. optmaxent > 0) then
     615          636 :    ABI_MALLOC(unitselfrot,(2*paw_dmft%maxlpawu+1,nspinor,nsppol,natom)) ! 7 is the max ndim possible
     616          688 :    ABI_MALLOC(level_diag,(natom))
     617        23407 :    ABI_MALLOC(selfrotmatlu,(self%nw))
     618          106 :    call init_oper(paw_dmft,energy_level,opt_ksloc=2)
     619          106 :    call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),level_diag(:))
     620          106 :    call compute_levels(energy_level,self%hdc,paw_dmft,nondiag=nondiaglevels)
     621          106 :    write(tag,'(f13.5)') paw_dmft%fermie
     622          106 :    if (self%nw >= 2) then
     623          106 :      write(message,'(a,2x,2a)') ch10," == Print non Diagonalized Self Energy for Fermi Level= ",adjustl(tag)
     624          106 :      call wrtout(std_out,message,'COLL')
     625          106 :      call print_matlu(self%oper(2)%matlu(:),natom,1,compl=1,opt_exp=1)
     626              :    end if
     627          106 :    call diag_matlu(energy_level%matlu(:),level_diag(:),natom,prtopt,eigvectmatlu(:),test=paw_dmft%dmft_solv)
     628          106 :    write(message,'(a,2x,2a)') ch10," == Print Diagonalized levels for Fermi Level= ",adjustl(tag)
     629          106 :    call wrtout(std_out,message,'COLL')
     630          106 :    call print_matlu(level_diag(:),natom,1,compl=1,opt_exp=1)
     631              :    ! Rotate self
     632        23195 :    do ifreq=1,self%nw
     633        23089 :      call init_oper(paw_dmft,selfrotmatlu(ifreq),opt_ksloc=2)
     634        23089 :      if (self%distrib%procf(ifreq) /= myproc) cycle
     635         8032 :      call copy_matlu(self%oper(ifreq)%matlu(:),selfrotmatlu(ifreq)%matlu(:),natom)
     636        23195 :      call rotate_matlu(selfrotmatlu(ifreq)%matlu(:),eigvectmatlu(:),natom,1)
     637              :    end do ! ifreq
     638          106 :    call gather_oper(selfrotmatlu(:),self%distrib,paw_dmft,2,master=master)
     639          106 :    if (self%has_moments == 1) then
     640            0 :      ABI_MALLOC(selfmomrot,(natom,self%nmoments))
     641            0 :      do i=1,self%nmoments
     642            0 :        call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),selfmomrot(:,i))
     643            0 :        call copy_matlu(self%moments(i)%matlu(:),selfmomrot(:,i),natom)
     644            0 :        call rotate_matlu(selfmomrot(:,i),eigvectmatlu(:),natom,1)
     645              :      end do ! i
     646              :    end if
     647          530 :    do ifreq=1,min(3,self%nw)
     648          318 :      write(tag_freq,'(i5)') ifreq
     649          424 :      if (ifreq < 3 .and. myproc == master) then ! very important to call print_matlu only on master node
     650           98 :        write(message,'(a,2x,2a)') ch10," == Print non Rotated Self Energy for frequency ",adjustl(tag_freq)
     651           98 :        call wrtout(std_out,message,'COLL')
     652           98 :        call print_matlu(self%oper(ifreq)%matlu(:),natom,1,compl=1)
     653           98 :        write(message,'(a,2x,2a)') ch10," == Print Rotated Self Energy for frequency ",adjustl(tag_freq)
     654           98 :        call wrtout(std_out,message,'COLL')
     655           98 :        call print_matlu(selfrotmatlu(ifreq)%matlu(:),natom,1,compl=1)
     656          220 :      else if (ifreq == 3) then
     657          106 :        write(message,'(a,2x,a,i4)') ch10,"  (Other frequencies not printed)"
     658          106 :        call wrtout(std_out,message,'COLL')
     659              :      end if ! ifreq<3
     660              :    end do ! ifreq
     661              :  end if ! optrw=2 and optmaxent>0
     662              :  !  Create file for rotation
     663          406 :  if (optmaxent > 0 .and. myproc == master .and. (optrw == 1 .or. optrw == 2)) then
     664          208 :    do iatom=1,natom
     665          158 :      lpawu = paw_dmft%lpawu(iatom)
     666          158 :      if (lpawu == -1) cycle
     667           62 :      call int2char4(iatom,tag_at)
     668           62 :      ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
     669           62 :      if (optrw == 2) then
     670           61 :        tmpmatrot = trim(paw_dmft%filapp)//'_UnitaryMatrix_iatom'//trim(tag_at)
     671              :      else if (optrw == 1) then
     672            1 :        tmpmatrot = trim(paw_dmft%filnamei)//'_UnitaryMatrix_iatom'//trim(tag_at)
     673            1 :        inquire(file=trim(tmpmatrot),exist=lexist_rot)
     674            1 :        if (.not. lexist_rot) ABI_ERROR("File "//trim(tmpmatrot)//" does not exist !")
     675              :      end if ! optrw
     676           62 :      unitrot = 3189 + iatom
     677              : #ifdef FC_NAG
     678              :      open(unit=unitrot,file=trim(tmpmatrot),status='unknown',form='formatted',recl=ABI_RECL)
     679              : #else
     680           62 :      open(unit=unitrot,file=trim(tmpmatrot),status='unknown',form='formatted')
     681              : #endif
     682           62 :      write(std_out,'(2a)') "      Open file ",trim(tmpmatrot)
     683           62 :      rewind(unitrot)
     684           62 :      ndim = (2*lpawu+1) * nspinor
     685          165 :      do isppol=1,nsppol
     686          674 :        do im=1,ndim
     687         3433 :          do im1=1,ndim
     688         3330 :            if (optrw == 2) then
     689         2796 :              write(message,*) dble(eigvectmatlu(iatom)%mat(im,im1,isppol)),aimag(eigvectmatlu(iatom)%mat(im,im1,isppol))
     690         2796 :              call wrtout(unitrot,message,'COLL')
     691              :            else if (optrw == 1) then
     692           25 :              read(unitrot,*) x_r,x_i
     693           25 :              eigvectmatlu(iatom)%mat(im,im1,isppol) = cmplx(x_r,x_i,kind=dp)
     694              :            end if ! optrw
     695              :          end do ! im1
     696              :        end do ! im
     697              :      end do ! isppol
     698          208 :      close(unitrot)
     699              :    end do ! iatom
     700              : 
     701           50 :    if (optrw == 1) then
     702            1 :      write(message,'(2a)') ch10," == Print non-rotated high-frequency limit of the self-energy"
     703            1 :      call wrtout(std_out,message,'COLL')
     704            1 :      call print_matlu(opt_selflimit(:),natom,1,compl=1)
     705            1 :      call rotate_matlu(opt_selflimit(:),eigvectmatlu(:),natom,1)
     706            1 :      write(message,'(2a)') ch10," == Print rotated high-frequency limit of the self-energy"
     707            1 :      call wrtout(std_out,message,'COLL')
     708            1 :      call print_matlu(opt_selflimit(:),natom,1,compl=1)
     709              :    end if ! optrw=1
     710              : 
     711              :  end if ! optmaxent > 0
     712              : !   - For the Tentative rotation of the self-energy file (end diag)
     713              : 
     714          406 :  if ((optrw == 2 .or. optrw == 1) .and. myproc == master) then
     715          390 :    ABI_MALLOC(unitselffunc_arr,(natom*nsppol))
     716          130 :    if (optrw == 2) then
     717          182 :      ABI_MALLOC(unitselffunc_arr2,(natom*nsppol))
     718           91 :      if (paw_dmft%idmftloop < 10) then
     719           89 :        write(self_iter,'("00",i1)') paw_dmft%idmftloop
     720            2 :      else if (paw_dmft%idmftloop >= 10 .and. paw_dmft%idmftloop < 100) then
     721            2 :        write(self_iter,'("0",i2)') paw_dmft%idmftloop
     722            0 :      else if (paw_dmft%idmftloop >= 100 .and. paw_dmft%idmftloop < 1000) then
     723            0 :        write(self_iter,'(i3)') paw_dmft%idmftloop
     724              :      else
     725            0 :        self_iter="xxx"
     726              :      end if ! idmftloop
     727              :    end if ! optrw=2
     728          130 :    iall = 0
     729          532 :    do iatom=1,natom
     730          402 :      lpawu = paw_dmft%lpawu(iatom)
     731          402 :      if (lpawu == -1) cycle
     732          150 :      ndim = 2*lpawu + 1
     733          600 :      ABI_MALLOC(s_r,(ndim*nspinor,ndim*nspinor))
     734          450 :      ABI_MALLOC(s_i,(ndim*nspinor,ndim*nspinor))
     735              : !       write(std_out,*) "print_self",ndim
     736          150 :      call int2char4(iatom,tag_at)
     737          150 :      ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
     738          390 :      do isppol=1,nsppol
     739          240 :        write(tag_is,'(i1)') isppol
     740              : !         do ispinor=1,nspinor
     741          240 :        iall = iall + 1
     742              : !           write(tag_is2,'(i1)')ispinor
     743              : 
     744              : !      ===========================
     745              : !      == Create name for file
     746              : !      ===========================
     747              : 
     748          240 :        if (self%w_type == "real") then
     749            1 :          tmpfil = trim(merge(paw_dmft%filnamei,paw_dmft%filapp,optrw==1))//'_Self_ra-omega_iatom'//trim(tag_at)//'_isppol'//tag_is
     750              :        else
     751          239 :          if (present(opt_char)) then
     752            0 :            tmpfil = trim(paw_dmft%filapp)//'Self_ra-omega_iatom'//trim(tag_at)//'_isppol'//tag_is//opt_char
     753              :          else
     754          239 :            stringfile = "_iatom" // trim(tag_at) // '_isppol' // tag_is
     755          239 :            if (optrw == 1 .and. paw_dmft%idmftloop == 0) then
     756           32 :              tmpfil = trim(paw_dmft%filselfin) // stringfile
     757           32 :              iexist2 = paw_dmft%ireadself
     758              :            else
     759          207 :              tmpfil = trim(paw_dmft%filapp) // '_Self-omega' // stringfile
     760              :            end if
     761              :          end if ! opt_char
     762              :        end if ! w_type
     763          240 :        if (optrw == 2) tmpfil2 = trim(tmpfil)//"_"//self_iter
     764              : 
     765          240 :        if (optrw == 1 .and. iexist2 == 1) then
     766           30 :          write(message,'(3a)') ch10,"  == Read self-energy and Fermi Level from file ",trim(tmpfil)
     767           30 :          call wrtout(std_out,message,'COLL')
     768          210 :        else if (optrw == 2) then
     769          179 :          write(message,'(3a)') ch10,"  == Write self-energy and Fermi Level on file ",trim(tmpfil)
     770          179 :          call wrtout(std_out,message,'COLL')
     771              :        end if
     772              :            !unitselffunc_arr(iall)=300+iall-1
     773          240 :        unitselffunc_arr(iall) = get_unit()
     774          240 :        ABI_CHECK(unitselffunc_arr(iall) > 0, "Cannot find free IO unit!")
     775              : 
     776              :        !- For the Tentative rotation of the self-energy file (create file)
     777          240 :        if (optrw == 2 .and. optmaxent > 0) then
     778          102 :          iflavor = 0
     779          206 :          do ispinor=1,nspinor
     780          710 :            do im=1,ndim
     781          504 :              iflavor = iflavor + 1
     782          504 :              call int2char4(iflavor,tag_iflavor)
     783          504 :              unitselfrot(im,ispinor,isppol,iatom) = 3000 + iflavor
     784              :              !ABI_CHECK(unitselfrot(im,ispinor,isppol,iatom) > 0, "Cannot find free IO unit for unitselfrot!")
     785              :              tmpfilrot = trim(paw_dmft%filapp)//'_Selfmxent'//&
     786          504 :                 & trim(tag_at)//'_is'//tag_is//'_iflav'//trim(tag_iflavor)
     787          504 :              write(std_out,*) "Create file  ",trim(tmpfilrot)," unit ",unitselfrot(im,ispinor,isppol,iatom)," for flavor",iflavor
     788              : #ifdef FC_NAG
     789              :              open(unit=unitselfrot(im,ispinor,isppol,iatom),file=trim(tmpfilrot),status='unknown',form='formatted',recl=ABI_RECL)
     790              : #else
     791          504 :              open(unit=unitselfrot(im,ispinor,isppol,iatom),file=trim(tmpfilrot),status='unknown',form='formatted')
     792              : #endif
     793          504 :              rewind(unitselfrot(im,ispinor,isppol,iatom))
     794          504 :              write(unitselfrot(im,ispinor,isppol,iatom),'(3a)') "#  Diagonal component of the self-energy, in the basis that diagonalizes the electronic levels.", &
     795         1112 :                                                          & ch10,"#       Frequency (Ha)              Real part              Imaginary part"
     796              : 
     797              :            end do ! im
     798              :          end do ! ispinor
     799              :        end if ! optrw=2 and optmaxent>0
     800              :        !- For the Tentative rotation of the self-energy file (create file)
     801              : 
     802              : !           write(std_out,*) "1"
     803              : 
     804              : !      ===========================
     805              : !      == Read: check that the file exists
     806              : !      ===========================
     807          240 :        if (optrw == 1) then
     808              : !           write(std_out,*) "3"
     809           61 :          inquire(file=trim(tmpfil),exist=lexist,recl=nrecl)
     810           61 :          if (.not. lexist .and. (paw_dmft%ireadself == 1 .or. paw_dmft%idmftloop > 0)) then
     811              : !           write(std_out,*) "4"
     812            0 :            iexist2 = 0
     813            0 :            write(message,'(4x,a,i5,3a)') "File number",unitselffunc_arr(iall),&
     814            0 :              & " called ",trim(tmpfil)," does not exist"
     815              : !               write(std_out,*) lexist,nrecl
     816            0 :            call wrtout(std_out,message,'COLL')
     817              :          end if ! not lexist
     818              :        end if ! optrw=1
     819              :            !write(std_out,*) "2"
     820              : 
     821              : !      ===========================
     822              : !      == Open file
     823              : !      ===========================
     824          240 :        if (optrw == 2 .or. (optrw == 1 .and. iexist2 == 1)) then
     825              :              !write(std_out,*) "5"
     826              : #ifdef FC_NAG
     827              :          open(unit=unitselffunc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted',recl=ABI_RECL)
     828              : #else
     829          209 :          open(unit=unitselffunc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted')
     830              : #endif
     831          209 :          rewind(unitselffunc_arr(iall))
     832              : 
     833          209 :          if (optrw == 2 .and. prtself) then
     834            0 :            unitselffunc_arr2(iall) = get_unit()
     835            0 :            ABI_CHECK(unitselffunc_arr2(iall) > 0,"Cannot find free IO unit!")
     836              : #ifdef FC_NAG
     837              :            open(unit=unitselffunc_arr2(iall),file=trim(tmpfil2),status="unknown",form="formatted",recl=ABI_RECL)
     838              : #else
     839            0 :            open(unit=unitselffunc_arr2(iall),file=trim(tmpfil2),status="unknown",form="formatted")
     840              : #endif
     841            0 :            rewind(unitselffunc_arr2(iall))
     842              :          end if ! optrw=2
     843              : 
     844              :              !write(std_out,*) "61",nrecl
     845          209 :          if (prtopt >= 3) then
     846            2 :            write(message,'(3a,i4)') '     Opened file : ',trim(tmpfil),' on unit ',unitselffunc_arr(iall)
     847            2 :            call wrtout(std_out,message,'COLL')
     848              :          end if ! prtopt>=3
     849              :        end if
     850              :            !write(std_out,*) "6",nrecl
     851              : 
     852              : !      ===========================
     853              : !      == Check Header
     854              : !      ===========================
     855              : 
     856          240 :        if (optrw == 2) then
     857              : 
     858          179 :          write(message,'(11a,4i5,i6,2x,e25.17e3)') "# DFT+DMFT self-energy for each frequency",ch10, &
     859          179 :                            & "# Columns are ordered this way:",ch10, &
     860          179 :                            & "# Frequency (Ha)  ((((Re(Sigma(im,im1,ispinor,ispinor1)) ", &
     861          179 :                            & "Im(Sigma(im,im1,ispinor,ispinor1)),im=1,2*l+1),im1=1,2*l+1),", &
     862          179 :                            & "ispinor=1,nspinor),ispinor1=1,nspinor) where the leftmost index varies first", &
     863          179 :                            & ch10,"# natom,nsppol,nspinor,ndim,nw,fermilevel",ch10,&
     864          358 :                            & "####",natom,nsppol,nspinor,ndim,self%nw,paw_dmft%fermie
     865          179 :          call wrtout(unitselffunc_arr(iall),message,'COLL')
     866          179 :          if (prtself) then
     867            0 :            call wrtout(unitselffunc_arr2(iall),message,'COLL')
     868              :          end if
     869           61 :        else if (optrw == 1 .and. iexist2 == 1 .and. readimagonly == 0) then
     870           29 :          read(unitselffunc_arr(iall),*)
     871           29 :          read(unitselffunc_arr(iall),*)
     872           29 :          read(unitselffunc_arr(iall),*)
     873           29 :          read(unitselffunc_arr(iall),*)
     874              :          read(unitselffunc_arr(iall),*,iostat=ioerr) &
     875           29 :            & chtemp,natom_read,nsppol_read,nspinor_read,ndim_read,nw_read,fermie_read
     876              :              !if(ioerr<0) then
     877              : !              write(std_out,*)" HEADER IOERR"
     878              : !              write(std_out,'(a4,2x,31(e15.8,2x))') chtemp,natom_read,nsppol_read,nspinor_read,ndim_read,nw_read,fermie_read
     879              :              !endif
     880           29 :          if (ioerr == 0) then
     881           29 :            write(message,'(a,3x,3a,i12,2a,i11,2a,i10,2a,i13,2a,i15,2a,e25.8)') ch10,"Data in Self Energy file corresponds to",&
     882           29 :               & ch10,"     natom",natom_read,&
     883           29 :               & ch10,"     nsppol",nsppol_read,&
     884           29 :               & ch10,"     nspinor",nspinor_read,&
     885           29 :               & ch10,"     ndim",ndim_read, &
     886           29 :               & ch10,"     nw",nw_read, &
     887           58 :               & ch10,"     Fermi level",fermie_read
     888           29 :            call wrtout(std_out,message,'COLL')
     889              :            if ((natom /= natom_read) .or. (nsppol_read /= nsppol) .or. &
     890           29 :              & (nspinor /= nspinor_read) .or. (nw_read /= self%nw)) then
     891            0 :              write(message,'(a,3x,3a,i12,2a,i11,2a,i10,2a,i13,2a,i15,2a,e25.8)') ch10,"Data required is ",&
     892            0 :                 & ch10,"     natom",natom,&
     893            0 :                 & ch10,"     nsppol",nsppol,&
     894            0 :                 & ch10,"     nspinor",nspinor,&
     895            0 :                 & ch10,"     ndim",ndim, &
     896            0 :                 & ch10,"     nw",self%nw, &
     897            0 :                 & ch10,"     Fermi level",paw_dmft%fermie
     898            0 :              call wrtout(std_out,message,'COLL')
     899            0 :              message = "Dimensions in self-energy file are not correct"
     900            0 :              if (present(opt_stop)) then
     901            0 :                ABI_ERROR(message)
     902              :              else
     903            0 :                ABI_WARNING(message)
     904              :              end if
     905            0 :              iexist2 = 2
     906              :            end if
     907              :          else
     908            0 :            ABI_WARNING("Self-energy file is empty")
     909              :          end if ! ioerr
     910              :        end if ! optrw
     911              :            !write(std_out,*) "7"
     912              : 
     913              : !      ===========================
     914              : !      == Write/Read self in the file
     915              : !      ===========================
     916              : 
     917              :        !rewind(111)
     918        46808 :        do ifreq=1,self%nw
     919        46808 :          if (optrw == 2) then
     920              : !               write(std_out,'(a,2x,31(e15.8,2x))') &
     921              : !&              "SETEST",self%omega(ifreq),&
     922              : !&              (self%oper(ifreq)%matlu(iatom)%mat(im,im,isppol,ispinor,ispinor)&
     923              : !&               ,im=1,ndim)
     924              : !               write(std_out,*) self%omega(ifreq),&
     925              : !&              ((self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor)&
     926              : !&               ,im=1,ndim),im1=1,ndim)
     927              : !               write(message,'(2x,393(e25.17,2x))')  self%omega(ifreq),&
     928              : !&              ((((self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
     929              : !&              ,im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
     930              : 
     931              :                !MGNAG Runtime Error: wrtout_cpp.f90, line 896: Buffer overflow on output
     932              :                !Is it possible to rewrite the code below to avoid such a long message
     933              :                !What about Netcdf binary files ?
     934        28956 :            string_format = merge('(2x,393(e25.17e3,2x))','(2x,393(e18.10e3,2x))',nspinor==1)
     935        28956 :            write(message,string_format) self%omega(ifreq),&
     936       746272 :                & ((((dble(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
     937       892640 :                & aimag(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
     938      1009664 :                & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
     939        28956 :            call wrtout(unitselffunc_arr(iall),message,'COLL')
     940        28956 :            if (prtself) then
     941            0 :              call wrtout(unitselffunc_arr2(iall),message,'COLL')
     942              :            end if
     943              : 
     944              :            !- For the Tentative rotation of the self-energy file (begin rot)
     945              :            !----------------------------------------------------------------
     946        28956 :            if (optmaxent > 0) then
     947              :              !iflavor = 0
     948        30024 :              do ispinor=1,nspinor
     949       103728 :                do im=1,ndim
     950              :                  !iflavor = iflavor + 1
     951              :                     ! if(ifreq<5) then
     952              :                     !   write(std_out,*) "Write in file unit",unitselfrot(iatom,isppol,ispinor,im),"for flavor",iflavor
     953              :                     ! endif
     954        73704 :                  write(message,'(2x,393(es24.16e3,2x))') self%omega(ifreq),&
     955        73704 :                   & dble(selfrotmatlu(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)),&
     956       147408 :                   & aimag(selfrotmatlu(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol))
     957              : !                     write(6,'(2x,393(e18.10,2x))')  self%omega(ifreq),&
     958              : !&                      real(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor)),&
     959              : !&                      aimag(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor))
     960              :                     ! if(iflavor==1) then
     961              :                     ! write(1024,*) iatom,isppol,ispinor,im,unitselfrot(iatom,isppol,ispinor,im)
     962              :                     ! write(1024,'(2x,393(e18.10,2x))')  self%omega(ifreq),&
     963              :                     ! &  real(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor)),&
     964              :                     ! &  aimag(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor))
     965              :                     ! endif
     966        88816 :                  call wrtout(unitselfrot(im,ispinor,isppol,iatom),message,'COLL')
     967              :                end do ! im
     968              :              end do ! ispinor
     969              :            end if ! optrw=2 and optmaxent>0
     970              :                !- For the Tentative rotation of the self-energy file (end rot)
     971              : 
     972              : !               write(std_out,*) unitselffunc_arr(iall)
     973        17612 :          else if (optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 0) then
     974              :            !write(std_out,*) "8"
     975              : !               read(unitselffunc_arr(iall),'(2x,31(e15.8,2x))',iostat=ioerr) &
     976              : !&              xtemp,(s_r(im),s_i(im),im=1,ndim)
     977              :            !if (readimagonly == 0) then
     978         3462 :            read(unitselffunc_arr(iall),*,iostat=ioerr) xtemp,&
     979        88928 :                & ((((s_r(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim),s_i(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim), &
     980       102776 :                & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
     981              : !               if(ioerr<0) then
     982              : !                write(std_out,*)" SELF IOERR<"
     983              : !               else if(ioerr>0) then
     984              : !                write(std_out,*)" SELF IOERR>"
     985              : !                write(std_out,'(a4,2x,31(e15.8,2x))') xtemp,(s_r(im),s_i(im),im=1,ndim)
     986              : !               endif
     987        92390 :            self%oper(ifreq)%matlu(iatom)%mat(:,:,isppol) = cmplx(s_r(:,:),s_i(:,:),kind=dp)
     988              :          end if ! optrw
     989              :        end do ! ifreq
     990              : 
     991              :        !- For the Tentative rotation of the self-energy file (begin close file)
     992          240 :        if (optrw == 2 .and. optmaxent > 0) then
     993          206 :          do ispinor=1,nspinor
     994          710 :            do im=1,ndim
     995          504 :              if (self%has_moments == 1) then
     996            0 :                do i=1,self%nmoments
     997            0 :                  write(tag_is,'(i1)') i
     998            0 :                  write(message,'(a,2x,2(es24.16e3,2x))') "#moments_"//tag_is, &
     999            0 :                    & dble(selfmomrot(iatom,i)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)), &
    1000            0 :                    & aimag(selfmomrot(iatom,i)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol))
    1001            0 :                  call wrtout(unitselfrot(im,ispinor,isppol,iatom),message,'COLL')
    1002              :                end do ! i
    1003              :              end if ! nmoments
    1004          504 :              close(unitselfrot(im,ispinor,isppol,iatom))
    1005          608 :              write(std_out,*) "Close file unit",unitselfrot(im,ispinor,isppol,iatom)
    1006              :            end do ! im
    1007              :          end do ! ispinor
    1008              :        end if ! optrw=2 and optmaxent>0
    1009              : 
    1010              :        !- For the Tentative rotation of the self-energy file (end close file)
    1011              : 
    1012          240 :        if (optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 1) then
    1013              : 
    1014              :          ! Read self energy from Maxent (imag part) on the real axis
    1015              :          !----------------------------------------------------------
    1016         3001 :          do ifreq=1,self%nw
    1017        96001 :            self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = czero
    1018              :          end do ! ifreq
    1019            2 :          do ispinor=1,nspinor
    1020            7 :            do im=1,ndim
    1021        15006 :              do ifreq=1,self%nw
    1022        15000 :                read(unitselffunc_arr(iall),*,iostat=ioerr) xtemp,s_i(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim)
    1023              :                ! minus sign because - Im Sigma is the output of OmegaMaxent
    1024              :                self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol) &
    1025        15005 :                  & = cmplx(zero,-half*s_i(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim),kind=dp)
    1026              :              end do ! ifreq
    1027              :            end do ! im
    1028              :          end do ! ispinor
    1029              : 
    1030            1 :          write(message,'(4x,2a)') " Read only diagonal self energy from Maxent"
    1031            1 :          call wrtout(std_out,message,'COLL')
    1032              :                !write(6,*) "opt_hdc",opt_hdc(1)%mat(1,1,1,1,1)
    1033              : 
    1034              :        end if ! optrw=1
    1035              : 
    1036              : !      ===========================
    1037              : !      == Write/Read hdc in the file
    1038              : !      ===========================
    1039          240 :        if (optrw == 2) then
    1040              : !             write(std_out,'(a,2x,31(e15.8,2x))') &
    1041              : !&            "SETEST #dc ",(self%hdc%matlu(iatom)%mat(im,im,isppol,ispinor,ispinor),im=1,ndim)
    1042              :          write(message,'(a,2x,500(e25.17e3,2x))') &
    1043         5891 :           & "#dc ",((((self%hdc%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol),&
    1044         6440 :             & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
    1045          179 :          call wrtout(unitselffunc_arr(iall),message,'COLL')
    1046          179 :          if (prtself) then
    1047            0 :            call wrtout(unitselffunc_arr2(iall),message,'COLL')
    1048              :          end if
    1049          179 :          if (self%has_moments == 1) then
    1050            0 :            do i=1,self%nmoments
    1051            0 :              write(tag_is,'(i1)') i
    1052            0 :              write(message,'(a,2x,500(e25.17e3,2x))') "#moments_"//trim(tag_is),&
    1053            0 :                 & ((self%moments(i)%matlu(iatom)%mat(im,im1,isppol),im=1,nspinor*ndim),im1=1,nspinor*ndim)
    1054            0 :              call wrtout(unitselffunc_arr(iall),message,'COLL')
    1055            0 :              if (prtself) then
    1056            0 :                call wrtout(unitselffunc_arr2(iall),message,'COLL')
    1057              :              end if
    1058              :            end do ! i
    1059              :          end if ! moments
    1060           61 :        else if (optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 0) then
    1061              :          !write(std_out,*) "8"
    1062              :          read(unitselffunc_arr(iall),*,iostat=ioerr) &
    1063          775 :            & chtemp,((((s_r(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim),s_i(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim),&
    1064          862 :               & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
    1065              :             !if(ioerr<0) then
    1066              : !              write(std_out,*)" HDC IOERR<",ioerr
    1067              :              !else if(ioerr>0) then
    1068              : !              write(std_out,*)" HDC IOERR>",ioerr
    1069              :              !endif
    1070          775 :          self%hdc%matlu(iatom)%mat(:,:,isppol) = cmplx(s_r(:,:),s_i(:,:),kind=dp)
    1071              : 
    1072           29 :          if (self%has_moments == 1) then
    1073            0 :            do i=1,self%nmoments
    1074              :              read(unitselffunc_arr(iall),*,iostat=ioerr) &
    1075            0 :                & chtemp,((s_r(im,im1),s_i(im,im1),im=1,nspinor*ndim),im1=1,nspinor*ndim)
    1076            0 :              self%moments(i)%matlu(iatom)%mat(:,:,isppol) = cmplx(s_r(:,:),s_i(:,:),kind=dp)
    1077              :            end do ! i
    1078              :          end if ! moments
    1079              :              !write(6,*) "read selfhdc",self%hdc%matlu(1)%mat(1,1,1,1,1)
    1080           32 :        else if (readimagonly == 1 .and. (.not. present(opt_hdc))) then
    1081            0 :          self%hdc%matlu(iatom)%mat(:,:,isppol) = czero
    1082              :        !else
    1083              :        !  write(std_out,*) "     self%hdc fixed in kramerskronig_self"
    1084              :        end if ! optrw
    1085          240 :        close(unitselffunc_arr(iall))
    1086          390 :        if (optrw == 2 .and. prtself) close(unitselffunc_arr2(iall))
    1087              : !         enddo ! ispinor
    1088              :      end do ! isppol
    1089          150 :      ABI_FREE(s_r)
    1090          532 :      ABI_FREE(s_i)
    1091              :    end do ! iatom
    1092              : 
    1093          130 :    ABI_FREE(unitselffunc_arr)
    1094          130 :    ABI_SFREE(unitselffunc_arr2)
    1095              :  end if ! optrw==1 or 2 and myproc==master
    1096              : 
    1097              : !  ===========================
    1098              : !  == Error messages
    1099              : !  ===========================
    1100          289 :  if (optrw == 1) then
    1101              : !   call xmpi_barrier(spacecomm)
    1102              :    !write(std_out,*) ncount,maxval(pawtab(:)%lpawu)*2+1
    1103           90 :    call xmpi_bcast(iexist2,master,spacecomm,ier)
    1104           90 :    call xmpi_bcast(ioerr,master,spacecomm,ier)
    1105           90 :    if (iexist2 == 0 .or. ioerr /= 0) then
    1106           32 :      message = "Self-energy file does not exist or is incomplete"
    1107           32 :      if (readimagonly == 1 .or. present(opt_stop)) then
    1108            0 :        if (readimagonly == 1) message = "Self-energy file does not exist or is incomplete: check the number of self-energy data in file"
    1109            0 :        ABI_ERROR(message)
    1110           32 :      else if (paw_dmft%ireadself == 1 .or. paw_dmft%idmftloop > 0) then
    1111            0 :        ABI_WARNING(message)
    1112              :      end if ! readimagonly=1 or present(opt_stop)
    1113           32 :      if (iexist2 == 0 .and. (paw_dmft%ireadself == 1 .or. paw_dmft%idmftloop > 0)) then
    1114            0 :        write(message,'(4x,2a)') "File does not exist"
    1115            0 :        call wrtout(std_out,message,'COLL')
    1116              :      end if ! iexist2=0
    1117           32 :      if (ioerr < 0) then
    1118            0 :        write(message,'(4x,2a)') "End of file reached"
    1119            0 :        call wrtout(std_out,message,'COLL')
    1120              :      end if ! ioerr<0
    1121           32 :      if (ioerr > 0) then
    1122            0 :        write(message,'(4x,2a)') "Error during read statement"
    1123            0 :        call wrtout(std_out,message,'COLL')
    1124              :      end if ! ioerr>0
    1125              :      !if (paw_dmft%dmft_solv /= 4) then
    1126           32 :      write(message,'(4x,2a,5i5,2x,e14.7)') "-> Set Self-Energy Equal to double counting term"
    1127              :      !else if (paw_dmft%dmft_solv == 4) then
    1128              :      !  write(message,'(4x,a,a,5i5,2x,e14.7)') "-> Put Self-Energy Equal to dc term - shift"
    1129              :      !  call wrtout(std_out,message,'COLL')
    1130              :      !  write(message,'(4x,a,a,5i5,2x,e14.7)') " No self energy is given, change dmft_rslf"
    1131              :      !  ABI_ERROR(message)
    1132              :      !end if
    1133           32 :      call wrtout(std_out,message,'COLL')
    1134        17513 :      do ifreq=1,self%nw
    1135              : !       write(std_out,*) "before",self%oper(1)%matlu(1)%mat(1,1,1,1,1)
    1136              : !       write(std_out,*) "before",self%hdc%matlu(1)%mat(1,1,1,1,1)
    1137        17481 :        call copy_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),natom)
    1138        17513 :        if (nspinor == 1 .and. nsppol == 2 .and. paw_dmft%dmft_dc >= 5) then
    1139        32162 :          do iatom=1,natom
    1140        16081 :            lpawu = paw_dmft%lpawu(iatom)
    1141        16081 :            if (lpawu == -1) cycle
    1142        16081 :            ndim = 2*lpawu + 1
    1143       112567 :            do im=1,ndim
    1144              :              self%oper(ifreq)%matlu(iatom)%mat(im,im,1) = self%oper(ifreq)%matlu(iatom)%mat(im,im,2) + &
    1145        96486 :                  & paw_dmft%dmft_shiftself(iatom)
    1146              :            end do ! im
    1147              :          end do ! iatom
    1148              :        end if ! nspinor=1 and nsppol=2
    1149              : !       write(std_out,*) "after",self%oper(1)%matlu(1)%mat(1,1,1,1,1)
    1150              : !       write(std_out,*) "before",self%hdc%matlu(1)%mat(1,1,1,1,1)
    1151              :        !if (paw_dmft%dmft_solv == 4) then
    1152              : !         if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
    1153              :        !  call shift_matlu(self%oper(ifreq)%matlu(:),natom,cmplx(self%qmc_shift(:),zero,kind=dp),1)
    1154              : !         if(ifreq==1) write(std_out,*) "self after dc and shift",self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
    1155              : !         if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
    1156              :        !end if ! dmft_solv=4
    1157              :      end do ! ifreq
    1158           32 :      if (self%has_moments == 1) then
    1159            0 :        call copy_matlu(self%oper(1)%matlu(:),self%moments(1)%matlu(:),natom)
    1160              :      end if
    1161              :    else ! test read successfull
    1162              : !   call xmpi_barrier(spacecomm)
    1163              : !! lignes 924-928 semblent inutiles puisque la valeur de paw_dmft%fermie creee
    1164              : !! en ligne 927 est ecrasee en ligne 992. BA+jmb
    1165              : !!     ABI_MALLOC(fermie_read2,(1))
    1166              : !!     fermie_read2(1)=fermie_read
    1167              : !!     call xmpi_sum(fermie_read2,spacecomm ,ier)
    1168              : !!     paw_dmft%fermie=fermie_read2(1)
    1169              : !!     ABI_FREE(fermie_read2)
    1170              :      !ncount = natom * nsppol * (nspinor**2) * (self%nw+1) *(maxval(paw_dmft%lpawu(:))*2+1)**2
    1171           58 :      ncount = 0
    1172          279 :      do iatom=1,natom
    1173          221 :        lpawu = paw_dmft%lpawu(iatom)
    1174          221 :        if (lpawu == -1) cycle
    1175           59 :        ndim = 2*lpawu + 1
    1176          279 :        ncount = ncount + ndim**2
    1177              :      end do ! iatom
    1178           58 :      ncount = ncount * (nspinor**2) * (self%nw+self%nmoments+1) * nsppol
    1179              : 
    1180              : !    ===========================
    1181              : !     bcast to other proc
    1182              : !    ===========================
    1183          174 :      ABI_MALLOC(buffer,(ncount))
    1184              : !! BA+jmb
    1185              :      !fermie_read2 = zero
    1186              :    !write(std_out,*) self%nw
    1187           58 :      if (myproc == master) then
    1188              : 
    1189              : !      == Send read data to all process
    1190           22 :        if (readimagonly == 0) paw_dmft%fermie = fermie_read
    1191           22 :        icount = 0
    1192              : !      Self energy-----------
    1193         6020 :        do ifreq=1,self%nw
    1194        17058 :          do iatom=1,natom
    1195        11038 :            lpawu = paw_dmft%lpawu(iatom)
    1196        11038 :            if (lpawu == -1) cycle
    1197         6030 :            ndim = (2*lpawu+1) * nspinor
    1198        18490 :            do isppol=1,nsppol
    1199        47694 :              do im1=1,ndim
    1200       178928 :                buffer(icount+1:icount+ndim) = self%oper(ifreq)%matlu(iatom)%mat(:,im1,isppol)
    1201        36656 :                icount = icount + ndim
    1202              :                  !if (icount > ncount) then
    1203              :                  !  write(message,'(2a,2i5)') ch10,"Error buffer",icount,ncount
    1204              :                  !  iexit = 1
    1205              :                  !  ABI_ERROR(message)
    1206              :                  !end if ! icount > ncount
    1207              :              end do ! im1
    1208              :            end do ! isppol
    1209              :          end do ! iatom
    1210              :        end do ! ifreq
    1211              : !      Double counting-------
    1212           99 :        do iatom=1,natom
    1213           77 :          lpawu = paw_dmft%lpawu(iatom)
    1214           77 :          if (lpawu == -1) cycle
    1215           23 :          ndim = (2*lpawu+1) * nspinor
    1216           75 :          do isppol=1,nsppol
    1217          237 :            do im1=1,ndim
    1218          776 :              buffer(icount+1:icount+ndim) = self%hdc%matlu(iatom)%mat(:,im1,isppol)
    1219          160 :              icount = icount + ndim
    1220              :              !if (icount > ncount) then
    1221              :              !  write(message,'(2a,2i5)') ch10,"Error buffer",icount,ncount
    1222              :              !  iexit = 1
    1223              :              !  ABI_ERROR(message)
    1224              :              !end if ! icount > ncount
    1225              :            end do ! im1
    1226              :          end do ! isppol
    1227              :        end do ! iatom
    1228           22 :        if (self%has_moments == 1) then
    1229            0 :          do i=1,self%nmoments
    1230            0 :            do iatom=1,natom
    1231            0 :              lpawu = paw_dmft%lpawu(iatom)
    1232            0 :              if (lpawu == -1) cycle
    1233            0 :              ndim = (2*lpawu+1) * nspinor
    1234            0 :              do isppol=1,nsppol
    1235            0 :                do im1=1,ndim
    1236            0 :                  buffer(icount+1:icount+ndim) = self%moments(i)%matlu(iatom)%mat(:,im1,isppol)
    1237            0 :                  icount = icount + ndim
    1238              :                end do ! im1
    1239              :              end do ! isppol
    1240              :            end do ! iatom
    1241              :          end do ! i
    1242              :        end if ! moments
    1243              :      end if ! proc=master
    1244           58 :      call xmpi_bcast(buffer(:),master,spacecomm,ier)
    1245              : !    call xmpi_sum(iexit,spacecomm ,ier)
    1246              : !!JB call xmpi_barrier(spacecomm)
    1247              :      !call xmpi_sum(buffer,spacecomm,ier)
    1248              : !!JB call xmpi_barrier(spacecomm)
    1249              : 
    1250              : ! bcast fermi level
    1251              :      !call xmpi_sum(fermie_read2,spacecomm,ier)
    1252           58 :      if (readimagonly == 0) then
    1253           54 :        call xmpi_bcast(paw_dmft%fermie,master,spacecomm,ier)
    1254              :      end if
    1255              : 
    1256           58 :      if (ier /= 0) then
    1257            0 :        message =  "error in xmpi_sum in rw_self"
    1258            0 :        ABI_ERROR(message)
    1259              :      end if
    1260              :      !paw_dmft%fermie = fermie_read2(1)
    1261              : !     write(std_out,*) "Fermi level",paw_dmft%fermie
    1262           58 :      icount = 0
    1263              : !    Self ---------------
    1264        21770 :      do ifreq=1,self%nw
    1265        59322 :        do iatom=1,natom
    1266        37552 :          lpawu = paw_dmft%lpawu(iatom)
    1267        37552 :          if (lpawu == -1) cycle
    1268        21744 :          ndim = (2*lpawu+1) * nspinor
    1269        65632 :          do isppol=1,nsppol
    1270       163632 :            do im1=1,ndim
    1271       608768 :              self%oper(ifreq)%matlu(iatom)%mat(:,im1,isppol) = buffer(icount+1:icount+ndim)
    1272       126080 :              icount = icount + ndim
    1273              :                      !write(6,*)'self procs', ifreq, self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)
    1274              :            end do ! im1
    1275              :          end do ! isppol
    1276              :        end do ! iatom
    1277              :      end do ! ifreq
    1278              : !    hdc  ---------------
    1279          279 :      do iatom=1,natom
    1280          221 :        lpawu = paw_dmft%lpawu(iatom)
    1281          221 :        if (lpawu == -1) cycle
    1282           59 :        ndim = (2*lpawu+1) * nspinor
    1283          183 :        do isppol=1,nsppol
    1284          549 :          do im1=1,ndim
    1285         1448 :            self%hdc%matlu(iatom)%mat(:,im1,isppol) = buffer(icount+1:icount+ndim)
    1286          328 :            icount = icount + ndim
    1287              :          end do ! im1
    1288              :        end do ! isppol
    1289              :      end do ! iatom
    1290           58 :      if (self%has_moments == 1) then
    1291            0 :        do i=1,self%nmoments
    1292            0 :          do iatom=1,natom
    1293            0 :            lpawu = paw_dmft%lpawu(iatom)
    1294            0 :            if (lpawu == -1) cycle
    1295            0 :            ndim = (2*lpawu+1) * nspinor
    1296            0 :            do isppol=1,nsppol
    1297            0 :              do im1=1,ndim
    1298            0 :                self%moments(i)%matlu(iatom)%mat(:,im1,isppol) = buffer(icount+1:icount+ndim)
    1299            0 :                icount = icount + ndim
    1300              :              end do ! im1
    1301              :            end do ! isppol
    1302              :          end do ! iatom
    1303              :        end do ! i
    1304              :      end if ! moments
    1305              :      !ABI_FREE(fermie_read2)
    1306           58 :      ABI_FREE(buffer)
    1307              :    end if  ! test read successful
    1308              :  end if  ! optrw==1
    1309              : 
    1310          406 :  if (optmaxent > 0 .and. optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 1) then
    1311              : 
    1312            4 :    write(message,'(4x,2a)') " Rotate Back self-energy in the cubic basis"
    1313            4 :    call wrtout(std_out,message,'COLL')
    1314              : 
    1315              :    ! Kramers Kronig
    1316              :    !-----------------------------
    1317              : 
    1318            4 :    call kramerskronig_self(self,opt_selflimit(:),opt_hdc(:),paw_dmft,paw_dmft%filapp)
    1319              : 
    1320            4 :    call xmpi_matlu(eigvectmatlu(:),natom,spacecomm,master=master,option=2)
    1321              : 
    1322            4 :    call copy_matlu(opt_hdc(:),self%hdc%matlu(:),natom)
    1323              : 
    1324              :    ! Rotate back self
    1325              :    !-----------------------------
    1326              : 
    1327        12004 :    do ifreq=1,self%nw
    1328        12000 :      if (ifreq < 20) then
    1329           76 :        write(tag_freq,'(i5)') ifreq
    1330           76 :        write(message,'(a,2x,2a)') ch10," == Print Rotated Self Energy on real axis for frequency ",adjustl(tag_freq)
    1331           76 :        call wrtout(std_out,message,'COLL')
    1332           76 :        call print_matlu(self%oper(ifreq)%matlu(:),natom,1,compl=1)
    1333              :      end if ! ifreq<20
    1334        12000 :      if (self%distrib%procf(ifreq) /= myproc) cycle
    1335        12004 :      call rotate_matlu(self%oper(ifreq)%matlu(:),eigvectmatlu(:),natom,-1)
    1336              :    end do ! ifreq
    1337            4 :    call gather_oper(self%oper(:),self%distrib,paw_dmft,opt_ksloc=2)
    1338           80 :    do ifreq=1,min(19,self%nw)
    1339           76 :      write(tag_freq,'(i5)') ifreq
    1340           76 :      write(message,'(a,2x,2a)') ch10," == Print Self Energy rotated back in cubic basis on real axis for frequency ",adjustl(tag_freq)
    1341           76 :      call wrtout(std_out,message,'COLL')
    1342           80 :      call print_matlu(self%oper(ifreq)%matlu(:),natom,1,compl=1)
    1343              :    end do ! ifreq
    1344              :  end if ! rotate back self-energy
    1345              : 
    1346              : ! call xmpi_barrier(spacecomm)
    1347              :            !write(std_out,*) "9"
    1348              : !   - For the Tentative rotation of the self-energy file (begin destroy)
    1349          406 :  if (optmaxent > 0) then
    1350              : 
    1351          110 :    if (optrw == 2) then
    1352          106 :      call destroy_oper(energy_level)
    1353          106 :      call destroy_matlu(level_diag(:),natom)
    1354          106 :      if (self%has_moments == 1) then
    1355            0 :        do i=1,self%nmoments
    1356            0 :          call destroy_matlu(selfmomrot(:,i),natom)
    1357              :        end do
    1358            0 :        ABI_FREE(selfmomrot)
    1359              :      end if
    1360        23195 :      do ifreq=1,self%nw
    1361        23195 :        call destroy_oper(selfrotmatlu(ifreq))
    1362              :      end do ! ifreq
    1363          476 :      ABI_FREE(level_diag)
    1364        23195 :      ABI_FREE(selfrotmatlu)
    1365          106 :      ABI_FREE(unitselfrot) ! 7 is the max ndim possible
    1366              :    end if ! optrw=2
    1367              : 
    1368          110 :    call destroy_matlu(eigvectmatlu(:),natom)
    1369          484 :    ABI_FREE(eigvectmatlu)
    1370              :  end if ! optmaxent > 0
    1371              : !   - For the Tentative rotation of the self-energy file (end destroy)
    1372              : 
    1373              : 
    1374              : !   call flush_unit(std_out)
    1375              : !   ABI_ERROR("Aboring now")
    1376          406 :  if (optrw == 0) then
    1377           11 :    if (paw_dmft%dmft_rslf == 0) then
    1378              :      !if (paw_dmft%dmft_solv /= 4) then
    1379           11 :      write(message,'(4x,a)') "-> Set Self-Energy Equal to double counting term"
    1380              :      !else if (paw_dmft%dmft_solv == 4) then
    1381              :      !  write(message,'(4x,a,a,5i5,2x,e14.7)') "-> Put Self-Energy Equal to dc term - shift"
    1382              :      !end if ! dmft_solv=4
    1383            0 :    else if (paw_dmft%dmft_rslf == -1) then
    1384            0 :      write(message,'(4x,a)') "-> Set Self-Energy Equal to zero"
    1385              :    end if ! dmft_rslf=0
    1386           11 :    call wrtout(std_out,message,'COLL')
    1387          415 :    do ifreq=1,self%nw
    1388          415 :      if (paw_dmft%dmft_rslf == 0) then
    1389          404 :        call copy_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),natom)
    1390              :       ! if(ifreq==1) write(std_out,*) "self after dc",self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
    1391              :        !if (paw_dmft%dmft_solv == 4) then
    1392              :       !   if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
    1393              :        !  call shift_matlu(self%oper(ifreq)%matlu(:),natom,cmplx(self%qmc_shift(:),zero,kind=dp),1)
    1394              :       !   if(ifreq==1) write(std_out,*) "self after dc and shift",self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
    1395              :       !   if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
    1396              :        !end if ! dmft_solv=4
    1397            0 :      else if (paw_dmft%dmft_rslf == -1) then
    1398            0 :        call zero_matlu(self%oper(ifreq)%matlu(:),natom)
    1399              :      end if ! dmft_rslf
    1400              :    end do ! ifreq
    1401           11 :    if (paw_dmft%dmft_rslf == 0 .and. self%has_moments == 1) then
    1402            0 :      call copy_matlu(self%hdc%matlu(:),self%moments(1)%matlu(:),natom)
    1403              :    end if
    1404              :  end if ! optrw=0
    1405              : 
    1406              : ! write(std_out,*) "optrw,use_fixed_self,istep,iter,istep_imp,iter_imp"
    1407              : ! write(std_out,*) optrw,paw_dmft%use_fixed_self,istep,iter,istep_imp,iter_imp
    1408          406 :  if ((optrw == 1 .or. optrw == 3) .and. paw_dmft%use_fixed_self > 0 .and. istep <= istep_imp .and. iter <= iter_imp) then
    1409            0 :    write(message,'(4x,a)') "-> Set Self-Energy Equal to imposed self-energy"
    1410            0 :    call wrtout(std_out,message,'COLL')
    1411            0 :    do ifreq=1,self%nw
    1412            0 :      iatu = 0
    1413            0 :      do iatom=1,natom
    1414            0 :        lpawu = paw_dmft%lpawu(iatom)
    1415            0 :        if (lpawu == -1) cycle
    1416            0 :        self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = czero
    1417            0 :        iatu = iatu + 1
    1418            0 :        ndim = 2*lpawu + 1
    1419            0 :        do isppol=1,nsppol
    1420            0 :          do ispinor=1,nspinor
    1421            0 :            do im=1,ndim
    1422            0 :              if (nspinor == 1) then
    1423            0 :                self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol) = paw_dmft%fixed_self(im,im,isppol,iatu)
    1424              : !            write(std_out,*) paw_dmft%fixed_self(im,im,isppol,iatu)
    1425              :              else
    1426            0 :                self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol) = paw_dmft%fixed_self(im,im,ispinor,iatu)
    1427              : !                 write(message,'(a,i4,i4,2x,e20.10)') " Fixed self not implemented for nspinor==2"
    1428              : !                 call wrtout(std_out,  message,'COLL')
    1429              : !                 ABI_ERROR("Aboring now")
    1430              :              end if ! nspinor
    1431              :            end do ! im
    1432              :          end do ! ispinor
    1433              :        end do ! isppol
    1434              :      end do ! iatom
    1435              :    end do ! ifreq
    1436            0 :    if (self%has_moments == 1) then
    1437            0 :      call copy_matlu(self%oper(1)%matlu(:),self%moments(1)%matlu(:),natom)
    1438            0 :      do i=2,self%nmoments
    1439            0 :        call zero_matlu(self%moments(i)%matlu(:),natom)
    1440              :      end do ! i
    1441              :    end if
    1442              : 
    1443              :  end if ! use_fixed_self
    1444              :  ABI_NVTX_END_RANGE()
    1445              : 
    1446          406 : end subroutine rw_self
    1447              : !!***
    1448              : 
    1449              : !!****f* m_self/new_self
    1450              : !! NAME
    1451              : !! new_self
    1452              : !!
    1453              : !! FUNCTION
    1454              : !!
    1455              : !!  Mix Old and New self_energy with the mixing coefficient dmft_mxsf
    1456              : !!
    1457              : !! INPUTS
    1458              : !!  self <type(self_type)>= variables related to self-energy
    1459              : !!  self_new <type(self_type)>= variables related to the new self-energy
    1460              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    1461              : !!
    1462              : !! OUTPUT
    1463              : !!  self <type(self_type)>= variables related to mixed self-energy
    1464              : !!
    1465              : !! SOURCE
    1466              : 
    1467          106 : subroutine new_self(self,self_new,paw_dmft)
    1468              : 
    1469              : !Arguments ------------------------------------
    1470              : !type
    1471              : ! type(crystal_t),intent(in) :: cryst_struc
    1472              :  type(self_type), intent(inout) :: self
    1473              :  type(self_type), intent(in) :: self_new
    1474              :  type(paw_dmft_type), intent(in) :: paw_dmft
    1475              : !Local variables-------------------------------
    1476              :  integer :: i,iatom,icount,ifreq,im,im1,isppol,lpawu,natom,ndim,nspinor,nsppol
    1477              :  real(dp) :: alpha,diff_self,sum_self
    1478              :  character(len=500) :: message
    1479              : ! *********************************************************************
    1480              : 
    1481          106 :  alpha   = paw_dmft%dmft_mxsf
    1482          106 :  natom   = paw_dmft%natom
    1483          106 :  nspinor = paw_dmft%nspinor
    1484          106 :  nsppol  = paw_dmft%nsppol
    1485              : 
    1486        23195 :  do ifreq=1,self%nw
    1487        67068 :    do iatom=1,natom
    1488        43873 :      lpawu = paw_dmft%lpawu(iatom)
    1489        43873 :      if (lpawu == -1) cycle
    1490              :      self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = (one-alpha)*self%oper(ifreq)%matlu(iatom)%mat(:,:,:) + &
    1491      1355756 :          & alpha*self_new%oper(ifreq)%matlu(iatom)%mat(:,:,:)
    1492              :        !  warning: self_new is the recent self-energy, which is mixed with self
    1493              :        !  to give self= mixed self energy. self_new is deallocated just after.
    1494              :    end do ! iatom
    1495              :  end do ! ifreq
    1496              : 
    1497          106 :  diff_self = zero
    1498          106 :  sum_self = zero
    1499          106 :  icount = 0
    1500              : 
    1501          476 :  do iatom=1,natom
    1502          370 :    lpawu = paw_dmft%lpawu(iatom)
    1503          370 :    if (lpawu == -1) cycle
    1504          130 :    ndim = nspinor * (2*lpawu+1)
    1505          130 :    icount = icount + nsppol*ndim
    1506          440 :    do isppol=1,nsppol
    1507         1540 :      do im1=1,ndim
    1508         6180 :        do im=1,ndim
    1509         5010 :          diff_self = diff_self + abs(self%hdc%matlu(iatom)%mat(im,im1,isppol)-self_new%hdc%matlu(iatom)%mat(im,im1,isppol))
    1510         5010 :          sum_self = sum_self + abs(self%hdc%matlu(iatom)%mat(im,im1,isppol))
    1511              :          self%hdc%matlu(iatom)%mat(im,im1,isppol) = (one-alpha)*self%hdc%matlu(iatom)%mat(im,im1,isppol) + &
    1512         5976 :            & alpha*self_new%hdc%matlu(iatom)%mat(im,im1,isppol)
    1513              :        end do ! im
    1514              :      end do ! im1
    1515              :    end do ! isppol
    1516              :  end do ! iatom
    1517              : 
    1518          106 :  if (self%has_moments == 1) then
    1519            0 :    do i=1,self%nmoments
    1520            0 :      do iatom=1,natom
    1521            0 :        lpawu = paw_dmft%lpawu(iatom)
    1522            0 :        if (lpawu == -1) cycle
    1523              :        self%moments(i)%matlu(iatom)%mat(:,:,:) = (one-alpha)*self%moments(i)%matlu(iatom)%mat(:,:,:) + &
    1524            0 :            & alpha*self_new%moments(i)%matlu(iatom)%mat(:,:,:)
    1525              :      end do ! iatom
    1526              :    end do ! i
    1527              :  end if ! moments
    1528              : 
    1529              :  !if(opt_mix==1) then
    1530              :  !endif
    1531              : 
    1532          106 :  diff_self = diff_self / dble(icount)
    1533              : 
    1534          106 :  write(message,'(8x,a,e12.5)') "DMFT Loop: Precision on self-energy is",diff_self
    1535          106 :  call wrtout(std_out,message,'COLL')
    1536          106 :  if (diff_self < paw_dmft%dmft_fermi_prec .and. sum_self > tol6 .and. paw_dmft%idmftloop >= 2) then
    1537            0 :     write(message,'(a,8x,a,e9.2,a,8x,a)') ch10, "Change of self =<", paw_dmft%dmft_fermi_prec,&
    1538            0 :       & ch10,"DMFT Loop: Self Energy is converged"
    1539            0 :     call wrtout(std_out,message,'COLL')
    1540            0 :     self%iself_cv = 1
    1541              :  else
    1542          106 :     write(message,'(a,8x,a)') ch10,"DMFT Loop: Self Energy is not converged"
    1543          106 :     call wrtout(std_out,message,'COLL')
    1544          106 :     self%iself_cv = 0
    1545              :  end if ! diff_self
    1546              : 
    1547          106 : end subroutine new_self
    1548              : !!***
    1549              : 
    1550              : !!****f* m_self/make_qmcshift_self
    1551              : !! NAME
    1552              : !! make_qmcshift_hu
    1553              : !!
    1554              : !! FUNCTION
    1555              : !!
    1556              : !! INPUTS
    1557              : !!  hu <type(hu_type)> = U interaction
    1558              : !!  paw_dmft  <type(paw_dmft_type)> = paw+dmft related data
    1559              : !!
    1560              : !! OUTPUT
    1561              : !!  self%qmc_shift in self <type(self_type)> = Self-energy
    1562              : !!
    1563              : !! SOURCE
    1564              : 
    1565              : !subroutine make_qmcshift_self(cryst_struc,hu,self,apply)
    1566              : 
    1567              : !Arguments ------------------------------------
    1568              : !type
    1569              : ! type(crystal_t),intent(in) :: cryst_struc
    1570              : ! type(hu_type),intent(in) :: hu(cryst_struc%ntypat)
    1571              : ! type(self_type),intent(inout) :: self
    1572              : ! logical, optional :: apply
    1573              : 
    1574              : !Local variables-------------------------------
    1575              : ! integer :: im,iatom,ifreq,itypat,lpawu,tndim
    1576              : ! real(dp) :: hu_shift2
    1577              : ! character(len=500) :: message
    1578              : ! *********************************************************************
    1579              : 
    1580              : ! do iatom = 1 , cryst_struc%natom
    1581              : !   lpawu=self%hdc%matlu(iatom)%lpawu
    1582              : !   tndim=2*lpawu+1
    1583              : !   itypat=cryst_struc%typat(iatom)
    1584              : !   if(lpawu/=-1) then
    1585              : !     self%qmc_shift(iatom) = zero
    1586              : !     do im =1, 2*tndim-1
    1587              : !!       write(std_out,*)"make before",self%qmc_shift(iatom)
    1588              : !       self%qmc_shift(iatom) = self%qmc_shift(iatom) + hu(itypat)%uqmc(im)
    1589              : !!       write(std_out,*)"make after",self%qmc_shift(iatom)
    1590              : !     enddo
    1591              : !     self%qmc_shift(iatom) = self%qmc_shift(iatom) / two
    1592              : !     hu_shift2 = hu(itypat)%uqmc(1)
    1593              : !
    1594              : !     do im = 2*tndim, 2*tndim + 2*tndim -3
    1595              : !       hu_shift2 = hu_shift2 + hu(itypat)%uqmc(im)
    1596              : !     enddo
    1597              : 
    1598              : !     hu_shift2 = hu_shift2 / two
    1599              : !     write(message,'(2a,i4)')  ch10,'  -------> For Correlated atom',iatom
    1600              : !     call wrtout(std_out,  message,'COLL')
    1601              : 
    1602              : !     if(abs(self%qmc_shift(iatom)-hu_shift2)>tol6) then
    1603              : !       write(message,'(2a,2f16.7)')  "  Shift for QMC is not correctly"&
    1604              : !&      ," computed",self%qmc_shift(iatom),hu_shift2
    1605              : !       ABI_ERROR(message)
    1606              : !     endif ! shifts not equals
    1607              : !
    1608              : !     write(message,'(4x,a,f16.7)')  &
    1609              : !&     "  Shift for QMC (used to compute G(w)) is (in Ha) :",&
    1610              : !&     self%qmc_shift(iatom)
    1611              : !     call wrtout(std_out,  message,'COLL')
    1612              : 
    1613              : !     self%qmc_xmu(iatom)=-self%qmc_shift(iatom)
    1614              : !     self%qmc_xmu(iatom)=zero
    1615              : !     write(message,'(4x,a,f16.7)')  &
    1616              : !&     "Artificial Shift used in QMC AND to compute G is (in Ha) :",self%qmc_xmu(iatom)
    1617              : !     ABI_WARNING(message)
    1618              : 
    1619              : !   endif ! lpawu/=1
    1620              : ! enddo ! natom
    1621              : 
    1622              : ! if(present(apply)) then
    1623              : !   if (apply) then
    1624              : !     write(message,'(5x,a,f16.7,a)')  " Shifts applied to self"
    1625              : !     call wrtout(std_out,  message,'COLL')
    1626              : !     do ifreq=1,self%nw
    1627              : !       call shift_matlu(self%oper(ifreq)%matlu,cryst_struc%natom,cmplx(self%qmc_shift,0.d0,kind=dp),1)
    1628              : !       call shift_matlu(self%oper(ifreq)%matlu,cryst_struc%natom,cmplx(self%qmc_xmu,0.d0,kind=dp),1)
    1629              : !     enddo
    1630              : !   endif
    1631              : ! endif
    1632              : 
    1633              : 
    1634              : !end subroutine make_qmcshift_self
    1635              : !!***
    1636              : 
    1637              : !!****f* m_self/kramerskronig_self
    1638              : !! NAME
    1639              : !! kramerskronig_self
    1640              : !!
    1641              : !! FUNCTION
    1642              : !!  Compute the real part of the self-energy using Kramers-Kronig formula.
    1643              : !!
    1644              : !! INPUTS
    1645              : !!  self <type(self_type)>= variables related to self-energy
    1646              : !!  selflimit = 0th order moment of the self-energy for each atom
    1647              : !!  selfhdc = double counting
    1648              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    1649              : !!  filapp = name of the file
    1650              : !!
    1651              : !! OUTPUT
    1652              : !!
    1653              : !! SOURCE
    1654              : 
    1655            4 : subroutine kramerskronig_self(self,selflimit,selfhdc,paw_dmft,filapp)
    1656              : 
    1657              : !Arguments ------------------------------------
    1658              :  type(self_type), intent(inout) :: self
    1659              :  type(matlu_type), intent(in) :: selfhdc(self%hdc%natom),selflimit(self%hdc%natom)
    1660              :  type(paw_dmft_type), intent(in) :: paw_dmft
    1661              :  character(len=fnlen), intent(in) :: filapp
    1662              : !Local variables-------------------------------
    1663              :  integer :: iatom,ifreq,im,im1,ispinor,ispinor1,isppol,jfreq
    1664              :  integer :: lpawu,myproc,natom,ndim,nspinor,nsppol,unt
    1665              :  character(len=2) :: tag_im,tag_im1
    1666              :  character(len=4) :: tag_at
    1667              :  character(len=50) :: tag_is
    1668              :  character(len=500) :: message
    1669              : ! *********************************************************************
    1670              : 
    1671              :  !delta = 0.0000000
    1672              : 
    1673            4 :  myproc  = paw_dmft%myproc
    1674            4 :  natom   = self%hdc%natom
    1675            4 :  nspinor = self%hdc%nspinor
    1676            4 :  nsppol  = self%hdc%nsppol
    1677              : 
    1678              :  !ABI_MALLOC(selftemp_imag,(self%nw))
    1679              : 
    1680            4 :  write(message,'(2a,i4)') ch10,'  ------ High-frequency limit of the Self-Energy'
    1681            4 :  call wrtout(std_out,message,'COLL')
    1682              : 
    1683            4 :  call print_matlu(selflimit(:),natom,3)
    1684              : 
    1685              : !print norms
    1686            4 :  write(message,'(2a,i4)')  ch10,'  ------ Double counting'
    1687            4 :  call wrtout(std_out,message,'COLL')
    1688              : 
    1689            4 :  call print_matlu(selfhdc(:),natom,3)
    1690              : 
    1691              : !  Compute limit of Real Part and put in double counting energy.
    1692              : ! call copy_matlu(selfhdc,self%hdc%matlu,natom)
    1693              :      !!write(6,*) "selfhdc   kramerskronig",selfhdc(1)%mat(1,1,1,1,1)
    1694              :      !write(6,*) "selfr%hdc kramerskronig",self%hdc%matlu(1)%mat(1,1,1,1,1)
    1695              : 
    1696        12004 :  do ifreq=1,self%nw
    1697        12000 :    if (self%distrib%procf(ifreq) /= myproc) cycle
    1698      9000000 :    do jfreq=1,self%nw-1
    1699      8997000 :      if (jfreq == ifreq) cycle
    1700     17991002 :      do iatom=1,natom
    1701      8994001 :        lpawu = selfhdc(iatom)%lpawu
    1702      8994001 :        if (lpawu == -1) cycle
    1703              :        self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = self%oper(ifreq)%matlu(iatom)%mat(:,:,:) - &
    1704              :                      & cmplx(aimag(self%oper(jfreq)%matlu(iatom)%mat(:,:,:)) / (self%omega(ifreq)-self%omega(jfreq)) &
    1705    296805032 :                      & * (self%omega(jfreq+1)-self%omega(jfreq)),zero,kind=dp)
    1706              :      end do  ! iatom
    1707              :    end do  ! jfreq
    1708         6004 :    do iatom=1,natom
    1709         3000 :      lpawu = selfhdc(iatom)%lpawu
    1710         3000 :      if (lpawu == -1) cycle
    1711              :      self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = cmplx(dble(self%oper(ifreq)%matlu(iatom)%mat(:,:,:))/pi,&
    1712       108000 :          & aimag(self%oper(ifreq)%matlu(iatom)%mat(:,:,:)),kind=dp) + selflimit(iatom)%mat(:,:,:)
    1713              :      ! write(6,*) "TWO FACTOR IS PUT BECAUSE OF MAXENT CODE ??"
    1714              :      !self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = self%oper(ifreq)%matlu(iatom)%mat(:,:,:) * half
    1715              :       !                       & aimag(self%oper(ifreq)%matlu(iatom)%mat(:,:,:)),kind=dp) * half
    1716              :    end do ! iatom
    1717              :  end do ! ifreq
    1718              : 
    1719            4 :  call gather_oper(self%oper(:),self%distrib,paw_dmft,opt_ksloc=2)
    1720              : 
    1721            4 :  if (myproc == 0) then
    1722              : 
    1723            1 :    unt = get_unit()
    1724            1 :    open(unit=unt,file=trim(filapp)//"_DFTDMFT_Self_realaxis.dat",status='unknown',form='formatted')
    1725            1 :    rewind(unt)
    1726            1 :    write(unt,'(4a)') "# Self-energy on the real axis, with the real part computed using Kramers-Kronig relations.",ch10, &
    1727            2 :                      "# Real Frequency (Ha.)         Real part                Imaginary part",ch10
    1728            1 :    tag_is = ""
    1729            2 :    do iatom=1,natom
    1730            1 :      lpawu = selfhdc(iatom)%lpawu
    1731            1 :      if (lpawu == -1) cycle
    1732            1 :      write(tag_at,'(i4)') iatom
    1733            1 :      ndim = 2*lpawu + 1
    1734            3 :      do isppol=1,nsppol
    1735            1 :        if (nsppol == 2) tag_is = trim(adjustl(" for spin " // merge("up  ","down",isppol==1))) // "and"
    1736            3 :        do ispinor=1,nspinor
    1737            3 :          do ispinor1=1,nspinor
    1738            7 :            do im=1,ndim
    1739            5 :              write(tag_im,'(i2)') im + (ispinor-1)*ndim
    1740           31 :              do im1=1,ndim
    1741           25 :                write(tag_im1,'(i2)') im1 + (ispinor1-1)*ndim
    1742           25 :                write(unt,'(9a)') "## Sigma_{",trim(adjustl(tag_im)),",",trim(adjustl(tag_im1)),"}",trim(adjustl(tag_is))," for atom ",trim(adjustl(tag_at)),ch10
    1743        75025 :                do ifreq=1,self%nw
    1744        75000 :                  write(unt,'(2x,393(es24.16e3,2x))') self%omega(ifreq),&
    1745        75000 :                    & dble(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)), &
    1746       150025 :                    & aimag(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol))
    1747              :                end do ! ifreq
    1748           30 :                write(unt,*)
    1749              :              end do ! im1
    1750              :            end do ! im
    1751              :          end do ! ispinor1
    1752              :        end do ! ispinor
    1753              :      end do ! isppol
    1754              :    end do ! iatom
    1755              : 
    1756            1 :    close(unt)
    1757              : 
    1758              :  end if ! master node
    1759              : 
    1760              :  !do iatom=1,natom
    1761              :  !  lpawu = self%oper(1)%matlu(iatom)%lpawu
    1762              :  !  if (lpawu == -1) cycle
    1763              :  !  ndim = 2*lpawu + 1
    1764              :  !  do isppol=1,nsppol
    1765              :  !      do ispinor=1,nspinor
    1766              :  !        do ispinor1=1,nspinor
    1767              :  !          do im=1,ndim
    1768              :  !            do im1=1,ndim
    1769              :                !write(6,*)
    1770              :                !"realpart",real(selflimit(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
    1771              :  !              do ifreq=1,self%nw
    1772              :  !                selftemp_re(ifreq)=zero
    1773              :  !                selftemp_imag(ifreq)=aimag(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
    1774              :   !               do jfreq=1,self%nw-1
    1775              :   !                 if(jfreq==ifreq) cycle
    1776              : !                   selftemp_re(ifreq)=selftemp_re(ifreq) -   &
    1777              : ! &
    1778              : ! aimag(self%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))  &
    1779              : ! &                   *(self%omega(ifreq)-self%omega(jfreq)) &
    1780              : ! &                   /((self%omega(ifreq)-self%omega(jfreq))**2+delta**2)&
    1781              : ! &                   *(self%omega(jfreq+1)-self%omega(jfreq))
    1782              :    !                selftemp_re(ifreq)=selftemp_re(ifreq) -   &
    1783              :  !&
    1784              :  !aimag(self%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))  &
    1785              :  !&                   /(self%omega(ifreq)-self%omega(jfreq)) *
    1786              :  !(self%omega(jfreq+1)-self%omega(jfreq))
    1787              :  !                enddo
    1788              :  !                selftemp_re(ifreq)=selftemp_re(ifreq)/pi
    1789              :                  !write(671,*)
    1790              :                  !self%omega(ifreq),selftemp_re(ifreq),selftemp_imag(ifreq)
    1791              :   !             enddo
    1792              : !                 TEST*************************
    1793              : !               do ifreq=1,self%nw
    1794              : !                 selftemp_imag(ifreq)=zero
    1795              : !                 do jfreq=1,self%nw-1
    1796              : !                   if(jfreq==ifreq) cycle
    1797              : !!                   selftemp_re(ifreq)=selftemp_re(ifreq) -   &
    1798              : !! &
    1799              : !aimag(self%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))  &
    1800              : !! &                   *(self%omega(ifreq)-self%omega(jfreq)) &
    1801              : !! &                   /((self%omega(ifreq)-self%omega(jfreq))**2+delta**2)&
    1802              : !! &                   *(self%omega(jfreq+1)-self%omega(jfreq))
    1803              : !                   selftemp_imag(ifreq)=selftemp_imag(ifreq) +    &
    1804              : ! &                   selftemp_re(jfreq)  &
    1805              : ! &                   /(self%omega(ifreq)-self%omega(jfreq)) *
    1806              : ! (self%omega(jfreq+1)-self%omega(jfreq))
    1807              : !                 enddo
    1808              : !                 selftemp_imag(ifreq)=selftemp_imag(ifreq)/pi
    1809              : !                 write(672,*)
    1810              : !                 self%omega(ifreq),selftemp_re(ifreq),selftemp_imag(ifreq)
    1811              : !               enddo
    1812              : !                 TEST*************************
    1813              :               ! write(6,*) "TWO FACTOR IS PUT BECAUSE OF MAXENT CODE ??"
    1814              :   !             do ifreq=1,self%nw
    1815              : !                 write(68,*)
    1816              : !                 self%omega(ifreq),selftemp_re(ifreq),selftemp_imag(ifreq)
    1817              :  !                selftemp_re(ifreq)=selftemp_re(ifreq)+ &
    1818              :  !&                 real(selflimit(iatom)%mat(im,im1,isppol,ispinor,ispinor1)- &
    1819              :  !&                 selfhdc(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
    1820              :  !                self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
    1821              :  ! &
    1822              :  ! =cmplx(selftemp_re(ifreq),selftemp_imag(ifreq),kind=dp)/two
    1823              :   !&                       =cmplx(0.d0,selftemp_imag(ifreq),kind=dp)/two
    1824              : !  &                       =cmplx(selftemp_re(ifreq),0.d0,kind=dp)/two
    1825              :   !               self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
    1826              :   !&                       =cmplx(selftemp_re(ifreq),0.d0,kind=dp)/two
    1827              :   !&                       =cmplx(0.d0,0.d0,kind=dp)/two
    1828              : !    The factor two is here to compensate for the factor two in OmegaMaxent..
    1829              : !  &                       =cmplx(selftemp_re(ifreq),0.0,kind=dp)
    1830              :   !               write(67,*)
    1831              :   !               self%omega(ifreq),real(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))&
    1832              :   !               ,aimag(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
    1833              :   !             enddo
    1834              :    !            write(67,*)
    1835              :                !write(68,*)
    1836              :                !!!!!!!!!! Z renormalization
    1837              : !               i0=389
    1838              : !               slope=(selftemp_re(i0+1)-selftemp_re(i0))/&
    1839              : !                     (self%omega(i0+1)-self%omega(i0))
    1840              : !               y0= selftemp_re(i0)
    1841              : !               do ifreq=1,self%nw
    1842              : !                 selftemp_re(ifreq)=slope * (self%omega(ifreq)-self%omega(i0))
    1843              : !                 + y0
    1844              : !                 selftemp_imag(ifreq)=zero
    1845              : !                 self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
    1846              : !  &
    1847              : !  =cmplx(selftemp_re(ifreq),selftemp_imag(ifreq),kind=dp)/two
    1848              : !                 write(6777,*)
    1849              : !                 self%omega(ifreq),real(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)),aimag(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
    1850              : !               enddo
    1851              :                !!!!!!!!!!
    1852              : !             enddo
    1853              : !           enddo
    1854              : !         enddo
    1855              : !       enddo
    1856              : !     enddo ! isppol
    1857              : ! end do ! iatom
    1858              : 
    1859            4 : end subroutine kramerskronig_self
    1860              : !!***
    1861              : 
    1862              : !!****f* m_self/selfreal2imag_self
    1863              : !! NAME
    1864              : !! selfreal2imag_self
    1865              : !!
    1866              : !! FUNCTION
    1867              : !!  Print self on imaginary axis from real axis
    1868              : !!
    1869              : !! INPUTS
    1870              : !!  selfr = self on real axis
    1871              : !!  self  = self on imaginary axis
    1872              : !!  filapp = name of the filename
    1873              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    1874              : !!
    1875              : !! OUTPUT
    1876              : !!  self%qmc_shift in self <type(self_type)> = Self-energy
    1877              : !!
    1878              : !! SOURCE
    1879              : 
    1880            4 : subroutine selfreal2imag_self(selfr,self,filapp,paw_dmft)
    1881              : 
    1882              : !Arguments ------------------------------------
    1883              : !type
    1884              :  type(self_type), intent(in) :: selfr,self
    1885              :  character(len=fnlen), intent(in) :: filapp
    1886              :  type(paw_dmft_type), intent(in) :: paw_dmft
    1887              : !Local variables-------------------------------
    1888              :  integer :: iatom,ifreq,im,im1,ispinor,ispinor1,isppol,jfreq
    1889              :  integer :: lpawu,myproc,natom,ndim,nspinor,nsppol,unt
    1890              :  logical :: triqs
    1891              :  complex(dp) :: omega
    1892              :  !real(dp) :: delta
    1893            4 :  type(self_type) :: selftempmatsub
    1894              :  character(len=2) :: tag_im,tag_im1
    1895              :  character(len=4) :: tag_at
    1896              :  character(len=50) :: tag_is
    1897            4 :  type(matlu_type), allocatable :: matlu_tmp(:)
    1898              : ! *********************************************************************
    1899              : 
    1900              :  !delta=0.0000000
    1901            4 :  call initialize_self(selftempmatsub,paw_dmft)
    1902              : 
    1903            4 :  myproc  = paw_dmft%myproc
    1904            4 :  natom   = self%hdc%natom
    1905            4 :  nspinor = self%hdc%nspinor
    1906            4 :  nsppol  = self%hdc%nsppol
    1907              : !  Compute limit of Real Part and put in double counting energy.
    1908              : ! call copy_matlu(selfhdc,self%hdc%matlu,natom)
    1909              :      !write(6,*) "self3",aimag(selfr%oper(489)%matlu(1)%mat(1,1,1,1,1))
    1910              : 
    1911            4 :  triqs = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
    1912              : 
    1913            4 :  if (triqs) then
    1914            0 :    ABI_MALLOC(matlu_tmp,(natom))
    1915            0 :    call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),matlu_tmp(:))
    1916              :  end if ! triqs
    1917              : 
    1918         4996 :  do ifreq=1,self%nw
    1919         4992 :    if (self%distrib%procf(ifreq) /= myproc) cycle
    1920         1248 :    omega = cmplx(zero,self%omega(ifreq),kind=dp)
    1921      3744000 :    do jfreq=1,selfr%nw-1
    1922      7486752 :      do iatom=1,natom
    1923      3742752 :        lpawu = paw_dmft%lpawu(iatom)
    1924      3742752 :        if (lpawu == -1) cycle
    1925              :        selftempmatsub%oper(ifreq)%matlu(iatom)%mat(:,:,:) = selftempmatsub%oper(ifreq)%matlu(iatom)%mat(:,:,:) - &
    1926              :            & aimag(selfr%oper(jfreq)%matlu(iatom)%mat(:,:,:)) / &
    1927    123510816 :            & (omega-selfr%omega(jfreq)) * (selfr%omega(jfreq+1)-selfr%omega(jfreq))
    1928              :      end do ! iatom
    1929              :    end do ! jfreq
    1930         1248 :    call fac_matlu(selftempmatsub%oper(ifreq)%matlu(:),natom,cone/pi)
    1931         1252 :    if (triqs) then ! add the missing high-frequency moment when using TRIQS
    1932            0 :      call add_matlu(selftempmatsub%oper(ifreq)%matlu(:),self%moments(1)%matlu(:),matlu_tmp(:),natom,1)
    1933            0 :      call copy_matlu(matlu_tmp(:),selftempmatsub%oper(ifreq)%matlu(:),natom)
    1934              :    end if ! triqs
    1935              :  end do ! ifreq
    1936              : 
    1937            4 :  if (triqs) then
    1938            0 :    call destroy_matlu(matlu_tmp(:),natom)
    1939            0 :    ABI_FREE(matlu_tmp)
    1940              :  end if ! triqs
    1941              : 
    1942            4 :  call gather_oper(selftempmatsub%oper(:),self%distrib,paw_dmft,opt_ksloc=2)
    1943              : 
    1944            4 :  if (myproc == 0) then
    1945            1 :    unt = get_unit()
    1946            1 :    open(unit=unt,file=trim(filapp)//"_DFTDMFT_Self_backtransform.dat",status='unknown',form='formatted')
    1947            1 :    write(unt,'(6a)') "# Hilbert transform of the analytically continued self-energy. To be compared with the actual",ch10, &
    1948            2 :              & "# self-energy on the imaginary axis in the cubic basis.",ch10,"# Matsubara Frequency (Ha.)       Real part                Imaginary part",ch10
    1949            1 :    tag_is = ""
    1950            2 :    do iatom=1,natom
    1951            1 :      lpawu = self%hdc%matlu(iatom)%lpawu
    1952            1 :      if (lpawu == -1) cycle
    1953            1 :      write(tag_at,'(i4)') iatom
    1954            1 :      ndim = 2*lpawu + 1
    1955            3 :      do isppol=1,nsppol
    1956            1 :        if (nsppol == 2) tag_is = trim(adjustl(" for spin " // merge("up  ","down",isppol==1))) // "and"
    1957            3 :        do ispinor=1,nspinor
    1958            3 :          do ispinor1=1,nspinor
    1959            7 :            do im=1,ndim
    1960            5 :              write(tag_im,'(i2)') im + (ispinor-1)*ndim
    1961           31 :              do im1=1,ndim
    1962           25 :                write(tag_im1,'(i2)') im1 + (ispinor1-1)*ndim
    1963              :                !do jfreq=1,selfr%nw-1
    1964              :                !  write(6700,*)  selfr%omega(jfreq),aimag(selfr%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
    1965              :                !enddo
    1966              :                !  write(6700,*)
    1967           25 :                write(unt,'(9a)') "## Sigma_{",trim(adjustl(tag_im)),",",trim(adjustl(tag_im1)),"}",trim(adjustl(tag_is))," for atom ",trim(adjustl(tag_at)),ch10
    1968        31225 :                do ifreq=1,self%nw
    1969        31200 :                  write(unt,'(2x,393(es24.16e3,2x))') self%omega(ifreq),&
    1970        31200 :                    & dble(selftempmatsub%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
    1971        62425 :                    & aimag(selftempmatsub%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol))
    1972              :                end do ! ifreq
    1973           30 :                write(unt,*)
    1974              :              end do ! im1
    1975              :            end do ! im
    1976              :          end do ! ispinor1
    1977              :        end do ! ispinor
    1978              :      end do ! isppol
    1979              :    end do ! iatom
    1980            1 :    close(unt)
    1981              :  end if ! master node
    1982              : 
    1983            4 :  call destroy_self(selftempmatsub)
    1984              : 
    1985            4 : end subroutine selfreal2imag_self
    1986              : !!***
    1987              : 
    1988            0 : END MODULE m_self
    1989              : !!***
        

Generated by: LCOV version 2.3-1