LCOV - code coverage report
Current view: top level - src/62_ctqmc - m_BathOperatoroffdiagComplex.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 497 0
Test Date: 2026-09-20 15:27:41 Functions: 0.0 % 21 0

            Line data    Source code
       1              : 
       2              : #if defined HAVE_CONFIG_H
       3              : #include "config.h"
       4              : #endif
       5              : 
       6              : !!****m* ABINIT/m_BathOperatoroffdiagComplex
       7              : !! NAME
       8              : !!  m_BathOperatoroffdiagComplex
       9              : !!
      10              : !! FUNCTION
      11              : !!  Manage all stuff related to the bath for the
      12              : !!  simgle Anderson Impurity Model
      13              : !!
      14              : !! COPYRIGHT
      15              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder, J. Denier, B. Amadon)
      16              : !!  This file is distributed under the terms of the
      17              : !!  GNU General Public License, see ~abinit/COPYING
      18              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      19              : !!
      20              : !! NOTES
      21              : !!
      22              : !! SOURCE
      23              : 
      24              : #include "defs.h"
      25              : MODULE m_BathOperatoroffdiagComplex
      26              : USE m_MatrixHybComplex
      27              : USE m_VectorComplex
      28              : USE m_Vector
      29              : USE m_VectorInt
      30              : USE m_Global
      31              : USE m_ListCdagC
      32              : IMPLICIT NONE
      33              : 
      34              : ! subroutines
      35              :  public :: BathOperatoroffdiagComplex_init
      36              :  public :: BathOperatoroffdiagComplex_reset
      37              :  public :: BathOperatoroffdiagComplex_activateParticle
      38              :  public :: BathOperatoroffdiagComplex_setMAdd
      39              :  public :: BathOperatoroffdiagComplex_setMRemove
      40              :  public :: BathOperatoroffdiagComplex_swap
      41              :  public :: BathOperatoroffdiagComplex_initF
      42              :  public :: BathOperatoroffdiagComplex_setF
      43              :  public :: BathOperatoroffdiagComplex_printF
      44              :  public :: BathOperatoroffdiagComplex_printM
      45              :  public :: BathOperatoroffdiagComplex_destroy
      46              :  public :: BathOperatoroffdiagComplex_doCheck
      47              :  public :: BathOperatoroffdiagComplex_checkM
      48              : 
      49              : ! functions
      50              : ! public :: BathOperatoroffdiagComplex_hybrid
      51              :  public :: BathOperatoroffdiagComplex_getDetAdd
      52              :  public :: BathOperatoroffdiagComplex_getDetRemove
      53              :  public :: BathOperatoroffdiagComplex_getDetF
      54              :  public :: BathOperatoroffdiagComplex_getError
      55              : !!***
      56              : 
      57              : !!****t* m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex
      58              : !! NAME
      59              : !!  BathOperatoroffdiagComplex
      60              : !!
      61              : !! FUNCTION
      62              : !!  This structured datatype contains the necessary data
      63              : !!
      64              : !! COPYRIGHT
      65              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
      66              : !!  This file is distributed under the terms of the
      67              : !!  GNU General Public License, see ~abinit/COPYING
      68              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      69              : !!
      70              : !! SOURCE
      71              : 
      72              : TYPE BathOperatoroffdiagComplex
      73              :   LOGICAL :: set         = .FALSE.
      74              :   ! True if the BathOperatoroffdiagComplex is initialized in BathOperatoroffdiagComplex_init
      75              : 
      76              :   LOGICAL :: MAddFlag    = .FALSE.
      77              :   ! Set to true if we can compute a new M (see updateDetXX) (ie in
      78              :   ! BathOperatoroffdiagComplex_getDetAdd)
      79              : 
      80              :   LOGICAL :: MRemoveFlag = .FALSE.
      81              :   ! Set to true if we can compute a new M (see updateDetXX) (ie in
      82              :   ! BathOperatoroffdiagComplex_getDetRemove)
      83              : 
      84              :   LOGICAL :: antiShift   = .FALSE.
      85              :   ! shift when M is updated with antiseg
      86              : 
      87              :   LOGICAL :: doCheck     = .FALSE.
      88              :   ! TRUE is checks are activated
      89              : 
      90              :   INTEGER :: opt_nondiag = 0
      91              : ! if opt_nondiag = 1 F is non diagonal.
      92              : 
      93              :   INTEGER :: flavors
      94              : ! number of flavors
      95              : ! if opt_nondiag = 0 , flavors= number of flavor
      96              : ! if opt_nondiag = 1 , flavors= 1
      97              : 
      98              :   INTEGER :: activeFlavor
      99              :   ! Active flavor on which a segment is added/suppressed...
     100              : 
     101              :   INTEGER :: samples
     102              :   ! Number of time slices (given in the input file)
     103              : 
     104              :   INTEGER :: sizeHybrid
     105              :   ! Number of time slices (given in the input file) + 1 (=qmc_l+1)
     106              : 
     107              :   INTEGER :: updatePosRow
     108              :   ! Gives the position of new Row to add
     109              :   ! Modified in  BathOperatoroffdiagComplex_getDetAdd and  BathOperatoroffdiagComplex_getDetRemove
     110              :   ! could be the Row in the Full matrix for the non diag implementation
     111              : 
     112              :   INTEGER :: updatePosCol
     113              :   ! Gives the position of new Col to add
     114              :   ! Modified in  BathOperatoroffdiagComplex_getDetAdd and  BathOperatoroffdiagComplex_getDetRemove
     115              : 
     116              :   INTEGER :: iTech
     117              :   ! iTech is an integer which precise the technics used to compute the
     118              :   ! Green's function (in time or frequency)
     119              : 
     120              :   INTEGER :: sumtails
     121              :   !  size of the full F matrix (sums of tails(iflavor) over iflavor)
     122              : 
     123              :   INTEGER,          ALLOCATABLE, DIMENSION(:) :: tails
     124              :   ! tails(iflavor) is the current number of segments for the flavor iflavor
     125              : 
     126              :   INTEGER,          ALLOCATABLE, DIMENSION(:) :: Fshift
     127              :   ! Fshift(iflavor) is the sum of number of segments for all flavors iflavor2
     128              :   ! such that iflavor< iflavor
     129              :   ! It is thus the shift in the F matrix to have the first segment of the flavor
     130              :   ! iflavor
     131              :   ! Fshift(nflavor+1) is the total nb of tails (=sumtails)
     132              : 
     133              :   DOUBLE PRECISION                            :: beta
     134              :   ! Inverse of Temperature
     135              :   !
     136              : 
     137              :   DOUBLE PRECISION                            :: dt
     138              :   ! dt=beta/samples
     139              : 
     140              :   DOUBLE PRECISION                            :: inv_dt
     141              :   ! inv_dt=1/dt
     142              : 
     143              :   COMPLEX(KIND=8), ALLOCATABLE, DIMENSION(:,:,:)   :: F ! qmc_l+2,Flavors
     144              :   ! Hybridization function F(1:op%sizeHybrid+1,1:flavors,1:flavors)
     145              : 
     146              :   COMPLEX(KIND=8)                            :: S
     147              :   ! Sherman Morrison notations
     148              : 
     149              :   COMPLEX(KIND=8)                            :: Stau
     150              :   ! Sherman Morrison notations
     151              : 
     152              :   COMPLEX(KIND=8)                            :: Stilde
     153              :   ! Sherman Morrison notations
     154              : 
     155              :   TYPE(VectorComplex)                                :: R
     156              :   ! Sherman Morrison notations R%vec(size).
     157              :   ! computed for each flavor (As matrices are made of Blocks for each
     158              :   ! flavor because the code is restricted to diagonal F matrices)
     159              : 
     160              :   TYPE(VectorComplex)                                :: Q
     161              :   ! Sherman Morrison notations
     162              :   ! computed for each flavor (As matrices are made of Blocks for each
     163              :   ! flavor because the code is restricted to diagonal F matrices)
     164              : 
     165              :   TYPE(Vector)                                :: Rtau
     166              :   ! Sherman Morrison notations
     167              :   ! Rtau gives the time length for each elements of R
     168              :   ! computed for each flavor (As matrices are made of Blocks for each
     169              :   ! flavor because the code is restricted to diagonal F matrices)
     170              : 
     171              :   TYPE(Vector)                                :: Qtau
     172              :   ! Sherman Morrison notations
     173              :   ! Qtau gives the time length for each elements of Q
     174              :   ! computed for each flavor (As matrices are made of Blocks for each
     175              :   ! flavor because the code is restricted to diagonal F matrices)
     176              : 
     177              :   TYPE(MatrixHybComplex)                             :: M  ! Flavors
     178              :   ! inverse of  Hybridization matrix  M%mat(global_size,global_size)
     179              :   ! contains the value of the hybridization for all flavor and segments times,
     180              :   ! the times (mat_tau), and possibly the
     181              :   ! frequency
     182              : 
     183              :   TYPE(MatrixHybComplex)                             :: M_update  ! Flavors
     184              :   !  used in BathOperatoroffdiagComplex_getdetF and in BathOperatoroffdiagComplex_checkM
     185              :   ! for checks
     186              : 
     187              : !#ifdef CTQMC_CHECK
     188              :   INTEGER                                     :: checkNumber
     189              :   DOUBLE PRECISION                            :: meanError
     190              : !  TYPE(ListCdagC)                             :: ListCdagC
     191              : !#endif
     192              : END TYPE BathOperatoroffdiagComplex
     193              : !!***
     194              : 
     195              : CONTAINS
     196              : !!***
     197              : 
     198              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_init
     199              : !! NAME
     200              : !!  BathOperatoroffdiagComplex_init
     201              : !!
     202              : !! FUNCTION
     203              : !!  Initialize and allocate data
     204              : !!
     205              : !! COPYRIGHT
     206              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
     207              : !!  This file is distributed under the terms of the
     208              : !!  GNU General Public License, see ~abinit/COPYING
     209              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     210              : !!
     211              : !! INPUTS
     212              : !!  op=bath object
     213              : !!  flavors=numbers of flavors we have (including spin)
     214              : !!  samples=Time slices in the input file
     215              : !!  beta=inverse temperature
     216              : !!  iTech=imaginary time or frequencies
     217              : !!  It is imposes to imaginary time
     218              : !!
     219              : !! OUTPUT
     220              : !!
     221              : !! SIDE EFFECTS
     222              : !!
     223              : !! NOTES
     224              : !!
     225              : !! SOURCE
     226              : 
     227            0 : SUBROUTINE BathOperatoroffdiagComplex_init(op, flavors, samples, beta, iTech,opt_nondiag)
     228              : 
     229              : !Arguments ------------------------------------
     230              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
     231              :   INTEGER           , INTENT(IN   ) :: flavors
     232              :   INTEGER           , INTENT(IN   ) :: samples
     233              :   INTEGER           , INTENT(IN   ) :: opt_nondiag
     234              :   DOUBLE PRECISION  , INTENT(IN   ) :: beta
     235              : !Local variables ------------------------------
     236              :   INTEGER           , INTENT(IN   ) :: iTech
     237              :   !INTEGER                           :: it
     238              : 
     239            0 :   op%MAddFlag     = .FALSE.
     240            0 :   op%MRemoveFlag  = .FALSE.
     241            0 :   op%flavors      = flavors
     242            0 :   op%opt_nondiag  = opt_nondiag
     243            0 :   op%beta         = beta
     244            0 :   op%samples      = samples
     245            0 :   op%sizeHybrid   = samples + 1
     246            0 :   op%dt      = beta / DBLE(samples)
     247            0 :   op%inv_dt  = DBLE(samples) / beta
     248            0 :   op%activeFlavor= 0
     249            0 :   op%updatePosRow = 0
     250            0 :   op%updatePosCol = 0
     251            0 :   op%iTech        = iTech
     252              : !#ifdef CTQMC_CHECK
     253            0 :   op%checkNumber  = 0
     254            0 :   op%meanError    = 0.d0
     255            0 :   op%doCheck = .FALSE.
     256              : !#endif
     257              : 
     258            0 :   FREEIF(op%F)
     259            0 :   MALLOC(op%F,(1:op%sizeHybrid+1,1:flavors,1:flavors))
     260            0 :   DT_FREEIF(op%tails)
     261              : #ifdef FC_LLVM
     262              :   ! LLVM 16 doesn't recognize this macro here
     263              :   DT_MALLOC(op%tails, (1:op%flavors))
     264              : #else
     265            0 :   DT_MALLOC(op%tails,(1:op%flavors))
     266              : #endif
     267            0 :   op%tails=0
     268            0 :   DT_FREEIF(op%Fshift)
     269              : #ifdef FC_LLVM
     270              :   ! LLVM 16 doesn't recognize this macro here
     271              :   DT_MALLOC(op%Fshift, (1:op%flavors+1))
     272              : #else
     273            0 :   DT_MALLOC(op%Fshift,(1:op%flavors+1))
     274              : #endif
     275            0 :   op%Fshift=0
     276              : 
     277            0 :   CALL VectorComplex_init(op%R,100*op%flavors)
     278            0 :   CALL VectorComplex_init(op%Q,100*op%flavors)
     279            0 :   CALL Vector_init(op%Rtau,100*op%flavors)
     280            0 :   CALL Vector_init(op%Qtau,100*op%flavors)
     281              : 
     282            0 :   CALL MatrixHybComplex_init(op%M,op%iTech,size=Global_SIZE*op%flavors,Wmax=samples) !FIXME Should be consistent with ListCagC
     283            0 :   CALL MatrixHybComplex_init(op%M_update,op%iTech,size=Global_SIZE*op%flavors,Wmax=samples) !FIXME Should be consistent with ListCagC
     284            0 :   op%F       = cmplx(0.d0,0.d0,kind=8)
     285            0 :   op%set     = .TRUE.
     286              : 
     287            0 : END SUBROUTINE BathOperatoroffdiagComplex_init
     288              : !!***
     289              : 
     290              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_reset
     291              : !! NAME
     292              : !!  BathOperatoroffdiagComplex_reset
     293              : !!
     294              : !! FUNCTION
     295              : !!  Reset all internal variables
     296              : !!
     297              : !! COPYRIGHT
     298              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
     299              : !!  This file is distributed under the terms of the
     300              : !!  GNU General Public License, see ~abinit/COPYING
     301              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     302              : !!
     303              : !! INPUTS
     304              : !!  op=bath operator to reset
     305              : !!
     306              : !! OUTPUT
     307              : !!
     308              : !! SIDE EFFECTS
     309              : !!
     310              : !! NOTES
     311              : !!
     312              : !! SOURCE
     313              : 
     314            0 : SUBROUTINE BathOperatoroffdiagComplex_reset(op)
     315              : 
     316              : !Arguments ------------------------------------
     317              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
     318              : !Local variables ------------------------------
     319              :   INTEGER                           :: iflavor
     320            0 :   op%MAddFlag     = .FALSE.
     321            0 :   op%MRemoveFlag  = .FALSE.
     322            0 :   op%activeFlavor = 0
     323            0 :   op%updatePosRow = 0
     324            0 :   op%updatePosCol = 0
     325              : !#ifdef CTQMC_CHECK
     326            0 :   op%checkNumber  = 0
     327            0 :   op%meanError    = 0.d0
     328            0 :   op%sumtails    = 0
     329              : !#endif
     330            0 :   op%doCheck = .FALSE.
     331            0 :   CALL VectorComplex_clear(op%R)
     332            0 :   CALL VectorComplex_clear(op%Q)
     333            0 :   CALL Vector_clear(op%Rtau)
     334            0 :   CALL Vector_clear(op%Qtau)
     335              : 
     336            0 :   CALL MatrixHybComplex_clear(op%M) !FIXME Should be consistent with ListCagC
     337            0 :   op%F       = cmplx(0.d0,0.d0,kind=8)
     338            0 :   do iflavor=1,op%flavors
     339            0 :     op%tails(iflavor)=0
     340            0 :     op%Fshift(iflavor)=0
     341              :   enddo
     342              : 
     343            0 : END SUBROUTINE BathOperatoroffdiagComplex_reset
     344              : !!***
     345              : 
     346              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_activateParticle
     347              : !! NAME
     348              : !!  BathOperatoroffdiagComplex_activateParticle
     349              : !!
     350              : !! FUNCTION
     351              : !!  Just save on wicht flavor we are working
     352              : !!  It is better to use the macro defined in defs.h
     353              : !!
     354              : !! COPYRIGHT
     355              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
     356              : !!  This file is distributed under the terms of the
     357              : !!  GNU General Public License, see ~abinit/COPYING
     358              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     359              : !!
     360              : !! INPUTS
     361              : !!  op=bath operator
     362              : !!  flavor=the flavor to activate
     363              : !!
     364              : !! OUTPUT
     365              : !!
     366              : !! SIDE EFFECTS
     367              : !!
     368              : !! NOTES
     369              : !!
     370              : !! SOURCE
     371              : 
     372            0 : SUBROUTINE BathOperatoroffdiagComplex_activateParticle(op,flavor)
     373              : 
     374              : !Arguments ------------------------------------
     375              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
     376              : !Local variables ------------------------------
     377              :   INTEGER           , INTENT(IN   ) :: flavor
     378              : 
     379            0 :   IF ( flavor .GT. op%flavors ) &
     380            0 :     CALL ERROR("BathOperatoroffdiagComplex_activateParticle : out of range      ")
     381            0 :   IF ( op%set .EQV. .TRUE. ) THEN
     382            0 :     op%activeFlavor =  flavor
     383            0 :     op%MAddFlag     = .FALSE.
     384            0 :     op%MRemoveFlag  = .FALSE.
     385              :   ELSE
     386            0 :     CALL ERROR("BathOperatoroffdiagComplex_activateParticle : not allocated      ")
     387              :   END IF
     388            0 : END SUBROUTINE BathOperatoroffdiagComplex_activateParticle
     389              : !!***
     390              : 
     391              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_getDetAdd
     392              : !! NAME
     393              : !!  BathOperatoroffdiagComplex_getDetAdd
     394              : !!
     395              : !! FUNCTION
     396              : !!  Compute the determinant ratio when a (anti)segment
     397              : !!  is trying to be added and store some array for setMAdd
     398              : !!
     399              : !! COPYRIGHT
     400              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
     401              : !!  This file is distributed under the terms of the
     402              : !!  GNU General Public License, see ~abinit/COPYING
     403              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     404              : !!
     405              : !! INPUTS
     406              : !!  op=bath operator
     407              : !!  CdagC_1=segment to be added
     408              : !!  position=ordered position of the Cdag time
     409              : !!  particle=full list of CdagC for activeFlavor
     410              : !!
     411              : !! OUTPUT
     412              : !!  BathOperatoroffdiagComplex_getDetAdd=the det
     413              : !!
     414              : !! SIDE EFFECTS
     415              : !!
     416              : !! NOTES
     417              : !!
     418              : !! SOURCE
     419            0 : COMPLEX(KIND=8)  FUNCTION BathOperatoroffdiagComplex_getDetAdd(op,CdagC_1, position, particle)
     420              : 
     421              : !Arguments ------------------------------------
     422              :   TYPE(BathOperatoroffdiagComplex)      , INTENT(INOUT) :: op
     423              :   DOUBLE PRECISION, DIMENSION(1:2), INTENT(IN   ) :: CdagC_1
     424              :   INTEGER                 , INTENT(IN   ) :: position
     425              :   TYPE(ListCdagC), INTENT(IN   ) :: particle(:)
     426              : !Local variables-------------------------------
     427              :   INTEGER                                 :: it1
     428              :   INTEGER                                 :: it2
     429              :   INTEGER                                 :: it3,iflavor,iflavora,iflavorb
     430              :   INTEGER                                 :: iflavorbegin,iflavorend
     431              :   INTEGER                                 :: tail,tailbegin,tailend
     432              :   INTEGER                                 :: tcheck
     433              :   INTEGER                                 :: new_tail
     434              :   DOUBLE PRECISION                        :: C
     435              :   DOUBLE PRECISION                        :: Cbeta
     436              :   DOUBLE PRECISION                        :: Cibeta
     437              :   DOUBLE PRECISION                        :: Cdag
     438              :   DOUBLE PRECISION                        :: Cdagbeta
     439              :   DOUBLE PRECISION                        :: beta
     440              :   COMPLEX(KIND=8)                         :: ratio
     441              :   DOUBLE PRECISION                        :: time
     442              :   COMPLEX(KIND=8)                         :: timec
     443              : !  TYPE(CdagC)    , POINTER, DIMENSION(:)  :: list => NULL()
     444              : #include "BathOperatoroffdiagComplex_hybrid.h"
     445              : 
     446            0 :   op%antiShift = .FALSE.
     447            0 :   beta     = op%beta
     448            0 :   C        =  CdagC_1(C_)
     449              : !  Cbeta    = C.MOD.beta
     450            0 :   MODCYCLE(C,beta,Cbeta)
     451            0 :   Cdag     =  CdagC_1(Cdag_)
     452              : !  cdagbeta = Cdag.MOD.beta
     453            0 :   MODCYCLE(Cdag,beta,Cdagbeta)
     454              : !  IF ( Cdag .GE. beta ) &
     455              : !    CALL ERROR("BathOperatoroffdiagComplex_getDetAdd : bad case ...              ")
     456            0 :   IF ( op%activeFlavor .LE. 0 ) &
     457            0 :     CALL ERROR("BathOperatoroffdiagComplex_getDetAdd : no active hybrid function ")
     458              : 
     459            0 :   IF ( size(particle)/=op%flavors ) &
     460            0 :     CALL ERROR("BathOperatoroffdiagComplex_getDetAdd : size of particle is erroneous ")
     461              : 
     462              :  ! tail is now the complete size of the F matrix Fshift(nflavors+1)
     463            0 :   tail =  op%sumtails
     464            0 :   new_tail = tail+1
     465              : !  list => particle%list
     466              : 
     467            0 :   if(op%opt_nondiag==1) then
     468            0 :     iflavorbegin = 1
     469            0 :     iflavorend   = op%flavors
     470            0 :     tailbegin    = 1
     471            0 :     tailend      = tail
     472              :   else
     473              :   !sui!write(6,*) "Bathoperator opt_nondiag=0"
     474            0 :     iflavorbegin = op%activeflavor
     475            0 :     iflavorend   = op%activeflavor
     476            0 :     tailbegin    = op%Fshift(op%activeflavor)+1
     477            0 :     tailend      = op%Fshift(op%activeflavor)+op%tails(op%activeflavor)
     478              :   endif
     479              : 
     480              :   IF ( ((C .GT. Cdag) .AND. (position .EQ. -1)) &  ! Segment added at the end of the segment
     481            0 :        .OR. ((C .LT. Cdag) .AND. (tail .EQ. 0))) THEN ! empty orbital case: only adding a segment is possible
     482              :    ! If ones add a segment to an empty orbital or a segment at the end
     483              :    ! of a segment, then:
     484            0 :     op%updatePosRow = op%tails(op%activeFlavor) + 1
     485            0 :     op%updatePosCol = op%tails(op%activeFlavor) + 1
     486              :   ELSE
     487              :    ! For all the other cases, ABS(position) is the true position.
     488            0 :     op%updatePosRow  = ABS(position)
     489            0 :     op%updatePosCol  = ABS(position)
     490              :   END IF
     491              :     !write(6,*) "       BathOperatoroffdiagComplex_getDetAdd : op%updatePosRow",op%updatePosRow
     492              :     !write(6,*) "       BathOperatoroffdiagComplex_getDetAdd : op%updatePosCol",op%updatePosCol
     493              :     !write(6,*) "       BathOperatoroffdiagComplex_getDetAdd : C,Cdag",C,Cdag
     494              : 
     495            0 :   IF ( C .LT. Cdag .AND. op%tails(op%activeFlavor) .GT. 0) THEN ! only if an antisegment is added
     496              :   !  ratio = -ratio
     497            0 :     op%updatePosRow  = (op%updatePosRow + 1) !position in [1;tail]
     498              :   ! If the antisegment created is such that a segment with tcdagger> tc
     499              :   ! is suppressed
     500              :     !write(6,*) "       BathOperatoroffdiagComplex_getDetAdd : op%updatePosRow",op%updatePosRow
     501              :     !write(6,*) "       BathOperatoroffdiagComplex_getDetAdd : op%updatePosCol",op%updatePosCol
     502            0 :     IF ( Cdagbeta .LT. particle(op%activeFlavor)%list(op%updatePosCol,Cdag_) ) op%antiShift = .TRUE.
     503              :   END IF
     504              : 
     505              : !  CALL VectorComplex_setSize(op%R,tail)
     506              : !  CALL VectorComplex_setSize(op%Q,tail)
     507            0 :   VectorComplex_QuickResize(op%R,new_tail)
     508            0 :   VectorComplex_QuickResize(op%Q,new_tail)
     509            0 :   Vector_QuickResize(op%Rtau,new_tail)
     510            0 :   Vector_QuickResize(op%Qtau,new_tail)
     511              : 
     512              : !  This loop compute all Row and Col except op%updatePosRow
     513            0 :   tcheck=0
     514            0 :   DO iflavor = iflavorbegin,iflavorend
     515              :     !write(6,*) "       BathOperatoroffdiagComplex_getDetAdd : tails(iflavor)",iflavor,op%tails(iflavor)
     516            0 :   DO it1 = 1, op%tails(iflavor)
     517            0 :     tcheck=tcheck+1
     518            0 :     it2 = it1
     519            0 :     it3 = it1
     520            0 :     IF ( iflavor .GE. op%activeFlavor ) THEN
     521            0 :       it2 = it1 + 1
     522            0 :       it3 = it1 + 1
     523            0 :       IF ( iflavor .EQ. op%activeFlavor .AND. it1 .LT. op%updatePosRow ) it2 = it1
     524            0 :       IF ( iflavor .EQ. op%activeFlavor .AND. it1 .LT. op%updatePosCol ) it3 = it1
     525              :     !it2 = it1 + ( 1+SIGN(1,it1-op%updatePosRow) )/2
     526              :     !it3 = it1 + ( 1+SIGN(1,it1-op%updatePoscol) )/2
     527              :     ! if it1>=op%updatePosRow and iflavor> activeflavor, then it2=it1+1
     528              :     ! if it1< op%updatePosRow and iflavor> activeflavor, then it2=it1
     529              :     END IF
     530              : 
     531              :     !!write(6,*) size(op%Rtau%vec)
     532              :     !!write(6,*) size(particle(iflavor)%list,1)
     533              :     !!write(6,*) size(particle(iflavor)%list,2)
     534              :     !!write(6,*) size(op%Fshift)
     535              :     !!write(6,*) it1,Cdag_,op%Fshift(iflavor)+it2
     536            0 :     op%Rtau%vec(op%Fshift(iflavor)+it2)= C - particle(iflavor)%list(it1,Cdag_)
     537              :     !   the following line happend only for nondiag case
     538            0 :     IF(op%Rtau%vec(op%Fshift(iflavor)+it2) .GT. beta) op%Rtau%vec(op%Fshift(iflavor)+it2)=op%Rtau%vec(op%Fshift(iflavor)+it2)-beta
     539              :     !op%Rtau%vec(it1)= C - particle%list(it1,Cdag_)
     540            0 :     time = Cbeta - particle(iflavor)%list(it1,Cdag_)
     541            0 :     if(op%Rtau%vec(op%Fshift(iflavor)+it2)>beta) then
     542              :     !write(6,*) "Rtau sup beta",op%Rtau%vec(op%Fshift(iflavor)+it2),C,particle(iflavor)%list(it1,Cdag_)
     543              :     !write(6,*) time
     544            0 :     stop
     545              :     endif
     546              : 
     547              : ! "BathOperatoroffdiagComplex_hybrid" interpolates between known values of F for the
     548              : !  selected time.
     549            0 :     iflavora=iflavor
     550            0 :     iflavorb=op%activeFlavor
     551              : #include "BathOperatoroffdiagComplex_hybrid"
     552              : 
     553            0 :     op%R%vec(op%Fshift(iflavor)+it1) = hybrid
     554              : !    op%R%vec(it) = BathOperatoroffdiagComplex_hybrid(op, Cbeta - list(it)%Cdag)
     555              : !    Cibeta = list(it)%C.MOD.beta
     556            0 :     MODCYCLE(particle(iflavor)%list(it1,C_),beta,Cibeta)
     557            0 :     time = Cibeta - Cdagbeta
     558            0 :     op%Qtau%vec(op%Fshift(iflavor)+it3)= time
     559              :     !op%Qtau%vec(it1)= time
     560              : 
     561            0 :     iflavora=op%activeFlavor
     562            0 :     iflavorb=iflavor
     563              : #include "BathOperatoroffdiagComplex_hybrid"
     564            0 :     op%Q%vec(op%Fshift(iflavor)+it1) = hybrid
     565              : 
     566              :     !op%Q%vec(it3) = hybrid
     567              : !    Q(it) = BathOperatoroffdiagComplex_hybrid(op, Cibeta - Cdagbeta)
     568              :   END DO
     569              :   END DO
     570            0 :   if(tcheck.ne.tail) then
     571              :     !write(6,*) " PRB in the loop tail tcheck",tail,tcheck
     572            0 :     stop
     573              :   endif
     574              : 
     575              :   ! Compute S
     576            0 :   op%Stau = C - Cdagbeta
     577            0 :   op%Rtau%vec(op%Fshift(op%activeFlavor)+op%updatePosRow) = op%Stau
     578            0 :     if(op%Rtau%vec(op%Fshift(op%activeFlavor)+op%updatePosRow)>beta) then
     579              :     !write(6,*) "Rtau sup beta", op%Stau,C,Cdagbeta
     580            0 :     stop
     581              :     endif
     582            0 :   op%Qtau%vec(op%Fshift(op%activeFlavor)+op%updatePosCol) = op%Rtau%vec(op%Fshift(op%activeFlavor)+op%updatePosRow)
     583              :   !write(6,*) "              getdetAdd op%Stau",op%Stau
     584              : 
     585            0 :   time = Cbeta-Cdagbeta
     586              :   !write(6,*) "              getdetAdd time",time
     587            0 :   iflavora=op%activeFlavor
     588            0 :   iflavorb=op%activeFlavor
     589              :   !write(6,*) "time",time
     590              : #include "BathOperatoroffdiagComplex_hybrid"
     591              :   !write(6,*) "hybrid",hybrid
     592            0 :   op%S = hybrid
     593              :   !write(6,*) "              getdetAdd hybrid=op%S",hybrid
     594              : 
     595              :   !ratio = op%S - DOT_PRODUCT(MATMUL(op%R%vec(1:tail),op%M(op%activeFlavor)%mat(1:tail,1:tail)),op%Q%vec(1:tail))
     596              : 
     597              :   ! product of matrix R and M(k) is computed now:
     598            0 :   ratio = cmplx(0.d0,0.d0,kind=8)
     599            0 :   DO it1 = tailbegin, tailend
     600              :     timec = cmplx(0.d0,0.d0,kind=8)
     601            0 :     DO it2 = tailbegin, tailend
     602            0 :       timec = timec + op%R%vec(it2) * op%M%mat(it2,it1)
     603              :     END DO
     604            0 :     ratio = ratio + op%Q%vec(it1) * timec
     605              :   END DO
     606              :   !sui!write(6,*) "        = R Matrix",tail
     607              :   !sui!write(6,*) "        R      ",(op%R%vec(it1),it1=1,tail)
     608              :   !sui!write(6,*) "        = Q Matrix",tail
     609              :   !sui!do it1=1,tail
     610              :   !sui!write(6,*) "        Q      ",op%Q%vec(it1)
     611              :   !sui!enddo
     612              :   !sui!write(6,*) "        = M Matrix",tail
     613              :   !sui!do it2=1,tail
     614              :   !sui!write(6,*) "        M      ",(op%M%mat(it2,it1),it1=1,tail)
     615              :   !sui!enddo
     616              :   !sui!write(6,*) "        RMQ    =", ratio
     617              :   !sui!write(6,*) "         S     =", op%S
     618            0 :  ratio = op%S - ratio
     619              :  !sui!write(6,*) "         S-RMQ =", ratio
     620              :  !sui!write(6,*) "              getdetAdd ratio",ratio
     621              : 
     622            0 :   op%Stilde = 1.d0 / ratio
     623              :   ! If antisegment, the det ratio has to be multiplied by -1 ( sign of the signature of one
     624              :   ! permutation line in the matrix)
     625            0 :   IF ( C .LT. Cdag .AND. op%tails(op%activeFlavor) .GT. 0) THEN ! only if an antisegment is added
     626            0 :     ratio=-ratio
     627              :   ENDIF
     628              : 
     629              :   ! This IF is the LAST "NON CORRECTION" in my opinion this should not appears.
     630              : !  IF ( MAX(C,Cdag) .GT. op%beta ) THEN
     631              : !    WRITE(*,*) op%Stilde
     632              : !    op%Stilde = - ABS(op%Stilde)
     633              : !  END IF
     634            0 :   BathOperatoroffdiagComplex_getDetAdd = ratio
     635              :       !write(6,*) " getdetAdd",ratio,BathOperatoroffdiagComplex_getDetAdd
     636            0 :   op%MAddFlag   = .TRUE.
     637              : !#ifdef CTQMC_CHECK
     638              : !  op%ListCdagC = particle
     639              : !!write(*,*) op%Stilde
     640              : !!write(*,*) op%antishift
     641              : !!write(*,*)    op%updatePosRow
     642              : !!write(*,*)    op%updatePosCol
     643              : !#endif
     644              : 
     645            0 : END FUNCTION BathOperatoroffdiagComplex_getDetAdd
     646              : !!***
     647              : 
     648              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_getDetRemove
     649              : !! NAME
     650              : !!  BathOperatoroffdiagComplex_getDetRemove
     651              : !!
     652              : !! FUNCTION
     653              : !!  Compute the determinant ratio when a (anti)segment
     654              : !!  is trying to be removed
     655              : !!
     656              : !! COPYRIGHT
     657              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
     658              : !!  This file is distributed under the terms of the
     659              : !!  GNU General Public License, see ~abinit/COPYING
     660              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     661              : !!
     662              : !! INPUTS
     663              : !!  op=bath operator
     664              : !!  position=position of segment to be removed
     665              : !!
     666              : !! OUTPUT
     667              : !!  BathOperatoroffdiagComplex_getDetRemove=the det
     668              : !!
     669              : !! SIDE EFFECTS
     670              : !!
     671              : !! NOTES
     672              : !!
     673              : !! SOURCE
     674              : 
     675            0 : COMPLEX(KIND=8) FUNCTION BathOperatoroffdiagComplex_getDetRemove(op,position)
     676              : 
     677              : !Arguments ------------------------------------
     678              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
     679              : !Local arguments-------------------------------
     680              :   INTEGER           , INTENT(IN   ) :: position
     681              :   INTEGER                           :: ABSposition
     682              :   INTEGER                           :: tail !,it,it1
     683              : 
     684            0 :   IF ( op%activeFlavor .LE. 0 ) &
     685            0 :     CALL ERROR("BathOperatoroffdiagComplex_getDetRemove : no active hybrid fun  ")
     686              : 
     687            0 :   op%antiShift = .FALSE.
     688            0 :   tail         = op%sumtails
     689            0 :   ABSposition  = ABS(position)
     690            0 :   IF ( ABSposition .GT. op%tails(op%activeFlavor) ) &
     691            0 :     CALL ERROR("BathOperatoroffdiagComplex_getDetRemove : position > M size     ")
     692            0 :   op%updatePosCol = ABSposition
     693            0 :   op%antiShift    = .FALSE.
     694            0 :   IF ( position .GT. 0 ) THEN
     695            0 :     op%updatePosRow = ABSposition
     696              :   ELSE
     697            0 :     op%updatePosRow = ABSposition+1
     698            0 :     IF ( ABSposition .EQ. op%tails(op%activeFlavor) ) THEN
     699            0 :       op%antiShift = .TRUE.
     700            0 :       op%updatePosRow = 1 !ABSposition - 1
     701              : !      op%updatePosRow = ABSposition
     702              : !      IF ( op%updatePosCol .EQ. 0) op%updatePosCol = tail
     703              :     END IF
     704              :   ENDIF
     705              :   op%Stilde                 = op%M%mat(op%Fshift(op%activeFlavor)+&
     706            0 : &                     op%updatePosRow,op%Fshift(op%activeFlavor)+op%updatePosCol)
     707              : !sui!write(6,*) "Fshift",op%Fshift(op%activeFlavor)
     708              : !sui!write(6,*) "updatepos",op%updatePosRow,op%updatePosCol
     709              : 
     710              : 
     711            0 :   op%MRemoveFlag            = .TRUE.
     712              :        !write(6,*) "        getdetRemove",op%Stilde
     713            0 :   BathOperatoroffdiagComplex_getDetRemove = op%Stilde
     714            0 :   if(position<0.and.op%tails(op%activeFlavor)>1) then
     715            0 :     BathOperatoroffdiagComplex_getDetRemove = -op%Stilde
     716              :   endif
     717              :   !do it=1,op%sumtails
     718              :   !!sui!write(6,*) "        getdetRemove M",(op%M%mat(it,it1),it1=1,op%sumtails)
     719              :   !enddo
     720              : !#ifdef CTQMC_CHECK
     721              : !  op%ListCdagC = particle
     722              : !!write(*,*) op%updatePosRow, op%updatePosCol, position
     723              : !!CALL ListCdagC_print(particle)
     724              : !#endif
     725              : 
     726            0 : END FUNCTION BathOperatoroffdiagComplex_getDetRemove
     727              : !!***
     728              : 
     729              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_getDetF
     730              : !! NAME
     731              : !!  BathOperatoroffdiagComplex_getDetF
     732              : !!
     733              : !! FUNCTION
     734              : !!  Compute the determinant of the F matrix
     735              : !!  using the hybridization of flavor and the
     736              : !!  segments of particle
     737              : !!  used for Gloval moves only
     738              : !!
     739              : !! COPYRIGHT
     740              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
     741              : !!  This file is distributed under the terms of the
     742              : !!  GNU General Public License, see ~abinit/COPYING
     743              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     744              : !!
     745              : !! INPUTS
     746              : !!  op=bath operator
     747              : !!  flavor=hybridization function to take
     748              : !!  particles=segments to use
     749              : !!
     750              : !! OUTPUT
     751              : !!  BathOperatoroffdiagComplex_getDetF=the det
     752              : !!
     753              : !! SIDE EFFECTS
     754              : !!
     755              : !! NOTES
     756              : !!
     757              : !! SOURCE
     758              : 
     759            0 : COMPLEX(KIND=8) FUNCTION BathOperatoroffdiagComplex_getDetF(op,particle,option)
     760              : 
     761              : !Arguments ------------------------------------
     762              :   TYPE(BathOperatoroffdiagComplex)       , INTENT(INOUT)      :: op
     763              :   TYPE(ListCdagC), OPTIONAL, INTENT(IN   )  :: particle(:)
     764              :   INTEGER , optional :: option
     765              : !Local arguments-------------------------------
     766              :   INTEGER :: iCdag
     767              :   INTEGER :: iC
     768              :   INTEGER :: tail
     769              :   DOUBLE PRECISION :: time
     770              :   DOUBLE PRECISION :: tC
     771              :   DOUBLE PRECISION :: tCdag
     772              :   DOUBLE PRECISION :: beta
     773              :   DOUBLE PRECISION :: mbeta_two
     774              :   DOUBLE PRECISION :: signe
     775              :   DOUBLE PRECISION :: inv_dt
     776              :   INTEGER :: iflavor,iflavora
     777              :   INTEGER :: iflavordag,iflavorb
     778              : #include "BathOperatoroffdiagComplex_hybrid.h"
     779              : 
     780            0 :   BathOperatoroffdiagComplex_getDetF = cmplx(1.d0,0.d0,kind=8) ! pour eviter des divisions par 0
     781            0 :   IF ( PRESENT( particle ) ) THEN
     782            0 :     tail = op%sumtails
     783            0 :     beta = op%beta
     784            0 :     mbeta_two = -beta*0.5d0
     785            0 :     inv_dt =  op%inv_dt
     786            0 :     CALL MatrixHybComplex_setSize(op%M_update,tail)
     787            0 :     DO iflavordag=1,op%flavors
     788            0 :     DO iCdag = 1, op%tails(iflavordag)
     789            0 :       tCdag  = particle(iflavordag)%list(iCdag,Cdag_)
     790            0 :       DO iflavor=1,op%flavors
     791            0 :       DO iC  = 1, op%tails(iflavor)
     792              :         !tC   = particle%list(C_,iC).MOD.beta
     793            0 :         MODCYCLE(particle(iflavor)%list(iC,C_),beta,tC)
     794            0 :         time = tC - tCdag
     795            0 :         iflavora=iflavordag
     796            0 :         iflavorb=iflavor
     797              : #include "BathOperatoroffdiagComplex_hybrid"
     798            0 :         op%M_update%mat(op%Fshift(iflavor)+iC,op%Fshift(iflavordag)+iCdag) = hybrid
     799              :       END DO
     800              :       END DO
     801              :     END DO
     802              :     END DO
     803              :     ! mat_tau needs to be transpose of ordered time mat (way of measuring
     804              :     ! G(tau))
     805            0 :     DO iflavor=1,op%flavors
     806            0 :     DO iC  = 1, tail
     807            0 :       tC   = particle(iflavor)%list(iC,C_)
     808            0 :       DO iflavordag=1,op%flavors
     809            0 :       DO iCdag = 1, tail
     810              :     !sui!write(6,*) iCdag,Cdag_,size(particle(iflavordag)%list,1)
     811              :       !stop
     812            0 :         tCdag  = particle(iflavordag)%list(iCdag,Cdag_)
     813            0 :         time = tC - tCdag
     814            0 :         signe = SIGN(1.d0,time)
     815            0 :         time = time + (signe-1.d0)*mbeta_two
     816            0 :         op%M_update%mat_tau(op%Fshift(iflavordag)+iCdag,op%Fshift(iflavor)+iC) = INT( ( time * inv_dt ) + 1.5d0 )
     817              :       END DO
     818              :       END DO
     819              :     END DO
     820              :     END DO
     821            0 :     CALL MatrixHybComplex_inverse(op%M_update,BathOperatoroffdiagComplex_getDetF) ! calcul le det de la matrice et l'inverse
     822              :   ELSE
     823            0 :     if(present(option)) then
     824            0 :       CALL MatrixHybComplex_getDet(op%M_update,BathOperatoroffdiagComplex_getDetF) ! det M = 1/detF !
     825              :     else
     826            0 :       CALL MatrixHybComplex_getDet(op%M,BathOperatoroffdiagComplex_getDetF) ! det M = 1/detF !
     827              :     endif
     828            0 :     BathOperatoroffdiagComplex_getDetF = 1.d0 / BathOperatoroffdiagComplex_getDetF
     829              :   ENDIF
     830            0 : END FUNCTION BathOperatoroffdiagComplex_getDetF
     831              : !!***
     832              : 
     833              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_setMAdd
     834              : !! NAME
     835              : !!  BathOperatoroffdiagComplex_setMAdd
     836              : !!
     837              : !! FUNCTION
     838              : !!  Update de M matrix inserting a row and a column
     839              : !!
     840              : !! COPYRIGHT
     841              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
     842              : !!  This file is distributed under the terms of the
     843              : !!  GNU General Public License, see ~abinit/COPYING
     844              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     845              : !!
     846              : !! INPUTS
     847              : !!  op=bath operator
     848              : !!  particle=segments of active flavor
     849              : !!
     850              : !! OUTPUT
     851              : !!
     852              : !! SIDE EFFECTS
     853              : !!
     854              : !! NOTES
     855              : !!
     856              : !! SOURCE
     857              : 
     858            0 : SUBROUTINE BathOperatoroffdiagComplex_setMAdd(op,particle)
     859              : 
     860              : !Arguments ------------------------------------
     861              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
     862              :   TYPE(ListCdagC)   , INTENT(IN   ) :: particle(:)
     863              : !Local variables ------------------------------
     864              :   INTEGER                           :: tail
     865              :   INTEGER                           :: new_tail
     866              :   INTEGER                           :: col
     867              :   INTEGER                           :: col_move
     868              :   INTEGER                           :: row_move
     869              :   INTEGER                           :: row
     870              :   INTEGER                           :: positionRow
     871              :   INTEGER                           :: positionCol
     872              :   INTEGER                           :: aF,indice
     873              :   INTEGER                           :: tailb,taile
     874              :   COMPLEX(KIND=8)                   :: Stilde
     875              :   DOUBLE PRECISION                  :: time
     876              :   DOUBLE PRECISION                  :: mbeta_two
     877              :   DOUBLE PRECISION                  :: inv_dt
     878            0 :   TYPE(VectorComplex) :: vec_tmp
     879            0 :   TYPE(VectorInt) :: vecI_tmp
     880              :   INTEGER :: m
     881              :   INTEGER :: count
     882              :   INTEGER :: i
     883              :   INTEGER :: j
     884              :   INTEGER :: p,it !,it1
     885              : 
     886              : 
     887              : 
     888              : ! ---  op%MAddFlag is put to .TRUE. in BathOperatoroffdiagComplex_getDetAdd.
     889            0 :   IF ( op%MAddFlag .EQV. .FALSE. ) &
     890            0 :     CALL ERROR("BathOperatoroffdiagComplex_setMAdd : MAddFlag turn off           ")
     891              : 
     892              : ! ---  op%activeFlavor is put in ctqmc_loop
     893            0 :   aF = op%activeFlavor
     894            0 :   IF ( aF .LE. 0 ) &
     895            0 :     CALL ERROR("BathOperatoroffdiagComplex_setMAdd : no active hybrid function   ")
     896              : 
     897              : !!  do it=1,op%sumtails
     898              :     !write(6,*) "        setMAdd begin M",(op%M%mat(it,it1),it1=1,op%sumtails)
     899              : !!  enddo
     900              : !!  do it=1,op%sumtails
     901              :     !write(6,*) "        setMAdd begin M%mat_tau",(op%M%mat_tau(it,it1),it1=1,op%sumtails)
     902              : !!  enddo
     903              : !  old tail
     904              :   !write(6,*) "       BathOperatoroffdiagComplex_setMAdd op%sumtails",op%sumtails
     905            0 :   tail = op%sumtails
     906            0 :   new_tail =  tail + 1
     907            0 :   op%tails(aF)= op%tails(aF) + 1
     908            0 :   DO indice = aF +1, op%flavors+1
     909            0 :     op%Fshift(indice) = op%Fshift(indice) + 1
     910              :   END DO
     911            0 :   op%sumtails = op%Fshift(op%flavors) + op%tails(op%flavors) !last slot of Fshift is the tail of full matrix
     912              :   !write(6,*) "       BathOperatoroffdiagComplex_setMAdd op%sumtails",op%sumtails
     913              :   !write(6,*) "        setMAdd actualized Fshift",(op%Fshift(it),it=1,op%flavors+1)
     914              :   !write(6,*) "        setMAdd actualized tails",(op%tails(it),it=1,op%flavors)
     915              :   !CALL matrix_print(M)
     916              : 
     917            0 :   if(op%opt_nondiag==1) then
     918              :     tailb        = 1
     919              :     taile        = tail
     920              :   else
     921              :   !sui!write(6,*) "Bathoperator a opt_nondiag=0"
     922            0 :     tailb        = op%Fshift(aF)+1
     923            0 :     taile        = op%Fshift(aF)+op%tails(aF)
     924              :   endif
     925              : 
     926              : ! ---  data obtained from BathOperatoroffdiagComplex_getDetAdd
     927            0 :   PositionRow =  op%updatePosRow + op%Fshift(aF) ! position in the full matrix
     928            0 :   PositionCol =  op%updatePosCol + op%Fshift(aF) ! position in the full matrix
     929            0 :   Stilde      =  op%Stilde
     930              : 
     931              : !  !write(6,*) "before", positionRow, positionCol
     932              :   !CALL MatrixHybComplex_print(op%M(aF),opt_print=1)
     933              : ! ---  MatrixHybComplex_setSize
     934              :   !write(6,*) "       BathOperatoroffdiagComplex_setMAdd before setsize",size(op%M%mat,1)
     935            0 :   CALL MatrixHybComplex_setSize(op%M,new_tail)
     936              :   !write(6,*) "       BathOperatoroffdiagComplex_setMAdd after setsize",size(op%M%mat,1)
     937              : 
     938              :   ! Compute Qtilde with Q
     939              :   !op%Q%vec(1:tail) = (-1.d0) * MATMUL(op%M(aF)%mat(1:tail,1:tail),op%Q%vec(1:tail)) * Stilde
     940              : 
     941              : ! ---  M*Q => Q
     942            0 :   op%Q%vec(tailb:taile) = MATMUL(op%M%mat(tailb:taile,tailb:taile),op%Q%vec(tailb:taile))
     943              : 
     944              :   !op%Q%vec(PositionRow:new_tail) = EOSHIFT(op%Q%vec(PositionRow:new_tail), SHIFT=-1, BOUNDARY=-1.d0, DIM=1)
     945              : !  op%Qtau%vec(PositionCol:new_tail) = EOSHIFT(op%Qtau%vec(PositionCol:new_tail), SHIFT=-1, BOUNDARY=1.d0, DIM=1)
     946              : !  op%Qtau%vec(PositionCol) = op%Stau
     947              : 
     948              :   !Compute Rtilde with R and without multiplying by Stilde
     949              :   !op%R%vec(1:tail) = (-1.d0) * MATMUL(op%R%vec(1:tail),op%M(aF)%mat(1:tail,1:tail))
     950              : 
     951              : ! ---  R*M => R
     952            0 :   op%R%vec(tailb:taile) = MATMUL(op%R%vec(tailb:taile),op%M%mat(tailb:taile,tailb:taile))
     953              : 
     954              :   !op%R%vec(PositionCol:new_tail) = EOSHIFT(op%R%vec(PositionCol:new_tail), SHIFT=-1, BOUNDARY=-1.d0, DIM=1)
     955              : !  op%Rtau%vec(PositionRow:new_tail) = EOSHIFT(op%Rtau%vec(PositionRow:new_tail), SHIFT=-1, BOUNDARY=1.d0, DIM=1)
     956              : !  op%Rtau%vec(PositionRow) = op%Stau
     957              : 
     958              :   !Compute the new M matrix
     959              :   !op%M(aF)%mat(PositionRow:new_tail,1:new_tail) = &
     960              :   !                   EOSHIFT(op%M(aF)%mat(PositionRow:new_tail,1:new_tail),SHIFT=-1, BOUNDARY=0.d0, DIM=1)
     961              :   !op%M(aF)%mat(1:n12 characters (ABI_MALLOC) instead of 4 (FREE)ew_tail,PositionCol:new_tail) = &
     962              :   !                   EOSHIFT(op%M(aF)%mat(1:new_tail,PositionCol:new_tail),SHIFT=-1, BOUNDARY=0.d0, DIM=2)
     963              : ! ! op%M(aF)%mat(1:new_tail,1:new_tail) =  op%M(aF)%mat(1:new_tail,1:new_tail) + &
     964              : ! ! Stilde * MATMUL(RESHAPE(op%Q%vec(1:new_tail),(/ new_tail,1 /)),RESHAPE(op%R%vec(1:new_tail),(/ 1,new_tail /)))
     965              : 
     966              :   !op%M(aF)%mat_tau(PositionRow:new_tail,1:new_tail) = &
     967              :   !                   EOSHIFT(op%M(aF)%mat_tau(PositionRow:new_tail,1:new_tail),SHIFT=-1, BOUNDARY=0, DIM=1)
     968              :   !op%M(aF)%mat_tau(1:new_tail,PositionCol:new_tail) = &
     969              :   !                   EOSHIFT(op%M(aF)%mat_tau(1:new_tail,PositionCol:new_tail),SHIFT=-1, BOUNDARY=0, DIM=2)
     970              : 
     971            0 :   mbeta_two = -op%beta*0.5d0
     972            0 :   inv_dt = op%inv_dt
     973              : 
     974              : ! ------ Shift mat_tau and update old M=Ptilde
     975            0 :   DO col=tail,1,-1  ! decreasing order to avoid overwrite of data
     976            0 :     col_move = col +  ( 1+SIGN(1,col-PositionCol) )/2
     977              :     ! if col>= PositionCol col_move=col+1
     978              :     ! if col<  PositionCol col_move=col
     979            0 :     DO row=tail,1,-1
     980            0 :       row_move = row +  ( 1+SIGN(1,row-PositionRow) )/2
     981              : ! ---  times for Ptilde are kept unchanged. But we have to copy it at the right place
     982              :       op%M%mat_tau(row_move,col_move) =  &
     983            0 :       op%M%mat_tau(row,col)
     984              : ! ---  Update Ptilde with the same indices as mat_tau
     985              : ! ---  M + M*Q Stilde R*M => Ptilde => M
     986              :       !if(row>=tailb.and.row<=taile.and.col>=tailb.and.col<=taile) then
     987              :         op%M%mat(row_move,col_move) =  &
     988            0 :         op%M%mat(row,col) + op%Q%vec(row)*op%R%vec(col) * Stilde
     989              :       !else
     990              :       !  op%M%mat(row_move,col_move) = op%M%mat(row,col)
     991              :       !endif
     992              :     END DO
     993              :   END DO
     994              : 
     995              : ! ------ Add new stuff for new row
     996            0 :   DO row = 1, tail
     997            0 :     row_move = row +  ( 1+SIGN(1,row-PositionRow) )/2
     998              : ! ---  M*Q Stilde => Qtilde => M with the good indices
     999              :     !if(row>=tailb.and.row<=taile) then
    1000            0 :       op%M%mat(row_move,PositionCol) = -op%Q%vec(row)*Stilde
    1001              :     !else
    1002              :     !  op%M%mat(row_move,PositionCol) = op%M%mat(row,PositionCol)
    1003              :     !endif
    1004              : 
    1005            0 :     time = op%Rtau%vec(row) !  pourquoi Rtau et pas Qtau ici ?
    1006            0 :     time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1007              :     ! if time>=0 time=time
    1008              :     ! if time< 0 time=time + beta
    1009              : ! ---  mat_tau=int(time*L/beta+1.5)
    1010            0 :     op%M%mat_tau(row,PositionCol) = INT ( (time*inv_dt) +1.5d0 )
    1011              :     !write(6,*) "     setMadd new row", op%Rtau%vec(row),op%M%mat_tau(row,PositionCol)
    1012              : !    if(op%M%mat_tau(row,PositionCol)>301) then
    1013              : !      !write(6,*) ">301 a", time,inv_dt, op%M%mat_tau(row,PositionCol)
    1014              : !    time = op%Rtau%vec(row) !  pourquoi Rtau et pas Qtau ici ?
    1015              : !      !write(6,*) time,mbeta_two
    1016              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1017              : !      !write(6,*) time
    1018              : !      !write(6,*) INT ( (time*inv_dt) +1.5d0 )
    1019              : !      stop
    1020              : !    endif
    1021              :   END DO
    1022              :   ! Add last time missing in the loops
    1023            0 :   time = op%Rtau%vec(new_tail)
    1024            0 :   time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1025            0 :   op%M%mat_tau(new_tail,PositionCol) = INT ( (time*inv_dt) +1.5d0 )
    1026              :     !write(6,*) "     setMadd last time", op%Rtau%vec(new_tail),op%M%mat_tau(new_tail,PositionCol)
    1027              : !    if(op%M%mat_tau(new_tail,PositionCol)>301) then
    1028              : !      !write(6,*) ">301 b", time,inv_dt, op%M%mat_tau(new_tail,PositionCol)
    1029              : !    time = op%Rtau%vec(new_tail) !  pourquoi Rtau et pas Qtau ici ?
    1030              : !      !write(6,*) time,mbeta_two
    1031              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1032              : !      !write(6,*) time
    1033              : !      !write(6,*) INT ( (time*inv_dt) +1.5d0 )
    1034              : !      stop
    1035              : !    endif
    1036              : 
    1037              :   ! Add new stuff for new col
    1038            0 :   DO col = 1, tail
    1039            0 :     col_move = col +  ( 1+SIGN(1,col-PositionCol) )/2
    1040              : ! ---   Stilde RN => Rtilde => M
    1041              :     !if(col>=tailb.and.col<=taile) then
    1042            0 :       op%M%mat(PositionRow,col_move) = -op%R%vec(col)*Stilde
    1043              :     !else
    1044              :     !  op%M%mat(PositionRow,col_move) = op%M%mat(PositionRow,col)
    1045              :     !endif
    1046            0 :     time = op%Qtau%vec(col)
    1047            0 :     time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1048            0 :     op%M%mat_tau(PositionRow,col) = INT ( (time*inv_dt) +1.5d0 )
    1049              :     !write(6,*) "     setMadd new col", op%Qtau%vec(col),op%M%mat_tau(PositionRow,col)
    1050              : !    if(op%M%mat_tau(PositionRow,col)>301) then
    1051              : !      !write(6,*) ">301 c", time,inv_dt, op%M%mat_tau(PositionRow,col)
    1052              : !    time = op%Qtau%vec(col) !  pourquoi Rtau et pas Qtau ici ?
    1053              : !      !write(6,*) time,mbeta_two
    1054              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1055              : !      !write(6,*) time
    1056              : !      !write(6,*) INT ( (time*inv_dt) +1.5d0 )
    1057              : !      stop
    1058              : !    endif
    1059              :   END DO
    1060              :   ! Add last time missing in the loops
    1061            0 :   time = op%Qtau%vec(new_tail)
    1062            0 :   time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1063            0 :   op%M%mat_tau(PositionRow,new_tail) = INT ( (time*inv_dt) +1.5d0 )
    1064              :     !write(6,*) "     setMadd last time", op%Qtau%vec(new_tail),op%M%mat_tau(PositionRow,new_tail)
    1065              : !    if(op%M%mat_tau(PositionRow,new_tail)>301) then
    1066              : !      !write(6,*) ">301 d", time,inv_dt, op%M%mat_tau(PositionRow,new_tail)
    1067              : !    time = op%Qtau%vec(new_tail) !  pourquoi Rtau et pas Qtau ici ?
    1068              : !      !write(6,*) time,mbeta_two
    1069              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1070              : !      !write(6,*) time
    1071              : !      !write(6,*) INT ( (time*inv_dt) +1.5d0 )
    1072              : !      stop
    1073              : !    endif
    1074              : 
    1075            0 :   op%M%mat(PositionRow,PositionCol) = Stilde
    1076              : 
    1077              :   !CALL MatrixHybComplex_print(op%M,opt_print=1)
    1078              : 
    1079              : !  DO col = 1, new_tail
    1080              : !    time = op%Rtau%vec(col)
    1081              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1082              : !    op%M(aF)%mat_tau(col,PositionCol) = INT ( (time*inv_dt) +1.5d0 )
    1083              : !    time = op%Qtau%vec(col)
    1084              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1085              : !    op%M(aF)%mat_tau(PositionRow,Col) = INT ( (time*inv_dt) +1.5d0 )
    1086              : !    time = op%R%vec(col)*Stilde
    1087              : !    DO row = 1, new_tail
    1088              : !      op%M(aF)%mat(row,col) = op%M(aF)%mat(row,col) + op%Q%vec(row)*time
    1089              : !    END DO
    1090              : !  END DO
    1091              : 
    1092              :   !col_move = new_tail
    1093              :   !col      = tail
    1094              :   !DO col_move = new_tail, 1, -1
    1095              :   !  IF ( col_move .EQ. positionCol ) THEN
    1096              :   !    ! on calcule rajoute Q tilde
    1097              :   !    !row_move = new_tail
    1098              :   !    row      = tail
    1099              :   !    DO row_move = new_tail, 1, -1
    1100              :   !      ! calcul itau
    1101              :   !      IF ( row_move .EQ. positionRow ) THEN
    1102              :   !        op%M(aF)%mat(row_move,col_move) = Stilde
    1103              :   !        !time = op%Stau
    1104              :   !      ELSE
    1105              :   !        op%M(aF)%mat(row_move,col_move) = -op%Q%vec(row)*Stilde
    1106              :   !        !time = op%Rtau%vec(row_move)
    1107              :   !        row      = row      - 1
    1108              :   !      END IF
    1109              :   !      !time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1110              :   !      !op%M(aF)%mat_tau(row_move,col_move) = INT ( (time*inv_dt) +1.5d0 )
    1111              :   !    END DO
    1112              :   !    ! realignement des indices
    1113              :   !  ELSE
    1114              :   !    ! on calcule Ptilde
    1115              :   !    !row_move = new_tail
    1116              :   !    row      = tail
    1117              :   !    DO row_move = new_tail, 1, -1
    1118              :   !      IF ( row_move .EQ. positionRow ) THEN
    1119              :   !        op%M(aF)%mat(row_move,col_move) = -op%R%vec(col) * Stilde
    1120              :   !        ! calcul itau
    1121              :   !        !time = op%Qtau%vec(col_move)
    1122              :   !        !time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1123              :   !        !op%M(aF)%mat_tau(row_move,col_move) = INT ( (time*inv_dt) +1.5d0 )
    1124              :   !      ELSE
    1125              :   !        op%M(aF)%mat(row_move,col_move) = op%M(aF)%mat(row,col) + op%Q%vec(row)*op%R%vec(col)*Stilde
    1126              :   !        ! copy itau
    1127              :   !        !op%M(aF)%mat_tau(row_move,col_move) = op%M(aF)%mat_tau(row,col)
    1128              :   !        row      = row      - 1
    1129              :   !      END IF
    1130              :   !    END DO
    1131              :   !    col      = col      - 1
    1132              :   !  END IF
    1133              :   !END DO
    1134              : !  !write(6,*) "after"
    1135              : !  CALL MatrixHybComplex_print(op%M(aF),opt_print=1)
    1136              : !CALL matrix_inverse(M)
    1137              : !CALL MatrixHybComplex_print(M)
    1138              : !CALL matrix_inverse(M)
    1139              : 
    1140            0 :   IF ( op%antiShift .EQV. .TRUE. ) THEN ! antisegment
    1141              :   if(3==4) then
    1142              :     CALL VectorComplex_init(vec_tmp,new_tail)
    1143              :     CALL VectorInt_init(vecI_tmp,new_tail)
    1144              :   ! Shift if necessary according to op%antishift
    1145              :   ! shift DIM=2 (col)
    1146              : 
    1147              : ! For new_tail=4, the following lines transform
    1148              : ! M=(a,b,c,d) vith a,b,c,d column vectors into
    1149              : ! M=(d,a,b,c)
    1150              :     p = new_tail - 1  ! = tail
    1151              :     m = 1
    1152              : !   count increases in the loop from 0 to new_tail-1
    1153              :     count = 0
    1154              :     DO WHILE ( count .NE. new_tail )
    1155              :       ! put column b in vec_tmp
    1156              :       vec_tmp%vec(1:new_tail) = op%M%mat(1:new_tail,m)
    1157              :       vecI_tmp%vec(1:new_tail) = op%M%mat_tau(1:new_tail,m)
    1158              :       i = m
    1159              :       !j = m+p
    1160              :       MODCYCLE(m+p, new_tail, j)   ! j=m+p modulo new_tail
    1161              :       DO WHILE (j .NE. m)
    1162              :         op%M%mat(1:new_tail,i) = op%M%mat(1:new_tail,j)
    1163              :         op%M%mat_tau(1:new_tail,i) = op%M%mat_tau(1:new_tail,j)
    1164              :         i = j
    1165              :         MODCYCLE(j+p, new_tail, j)
    1166              :         count = count+1
    1167              :       END DO
    1168              :       op%M%mat(1:new_tail,i) = vec_tmp%vec(1:new_tail)
    1169              :       op%M%mat_tau(1:new_tail,i) = vecI_tmp%vec(1:new_tail)
    1170              :       count = count+1
    1171              :       m = m+1
    1172              :     END DO
    1173              :     ! shift DIM=1 (row)
    1174              : 
    1175              : !   below is similar to above but for rows instead of columns.
    1176              :     p = new_tail - 1
    1177              :     m = 1
    1178              :     count = 0
    1179              :     DO WHILE ( count .NE. new_tail)
    1180              :       vec_tmp%vec(1:new_tail) = op%M%mat(m,1:new_tail)
    1181              :       vecI_tmp%vec(1:new_tail) = op%M%mat_tau(m,1:new_tail)
    1182              :       i = m
    1183              :       !j = m+p
    1184              :       MODCYCLE(m+p, new_tail, j)
    1185              :       DO WHILE ( j .NE. m )
    1186              :         op%M%mat(i,1:new_tail) = op%M%mat(j,1:new_tail)
    1187              :         op%M%mat_tau(i,1:new_tail) = op%M%mat_tau(j,1:new_tail)
    1188              :         i = j
    1189              :         MODCYCLE(j+p, new_tail, j)
    1190              :         count = count+1
    1191              :       END DO
    1192              :       op%M%mat(i,1:new_tail) = vec_tmp%vec(1:new_tail)
    1193              :       op%M%mat_tau(i,1:new_tail) = vecI_tmp%vec(1:new_tail)
    1194              :       count = count+1
    1195              :       m = m+1
    1196              :     END DO
    1197              :     CALL VectorComplex_destroy(vec_tmp)
    1198              :     CALL VectorInt_destroy(vecI_tmp)
    1199              :   endif
    1200              :     !op%M(aF)%mat(1:new_tail,1:new_tail) = CSHIFT(op%M(aF)%mat(1:new_tail,1:new_tail), SHIFT=-1, DIM=1) ! Shift to the bottom
    1201              :     !op%M(aF)%mat(1:new_tail,1:new_tail) = CSHIFT(op%M(aF)%mat(1:new_tail,1:new_tail), SHIFT=-1, DIM=2) ! Shift to the right
    1202              :     !op%M(aF)%mat_tau(1:new_tail,1:new_tail) = CSHIFT(op%M(aF)%mat_tau(1:new_tail,1:new_tail), SHIFT=-1, DIM=1) ! Shift to the bottom
    1203              :     !op%M(aF)%mat_tau(1:new_tail,1:new_tail) = CSHIFT(op%M(aF)%mat_tau(1:new_tail,1:new_tail), SHIFT=-1, DIM=2) ! Shift to the right
    1204              :   !write(6,*) "        setMAdd size M%mat",size(op%M%mat,1),size(op%M%mat,2),new_tail
    1205              :   !write(6,*) "        setMAdd arguement M%mat",aF,op%Fshift(aF)
    1206              :   !write(6,*) "        setMAdd arguement M%mat",aF,op%Fshift(aF),op%Fshift(aF+1)
    1207            0 :   do it=1,op%sumtails
    1208              :     !write(6,*) "        setMAdd before antishift M%mat_tau",(op%M%mat_tau(it,it1),it1=1,op%sumtails)
    1209              :   enddo
    1210            0 :   if (new_tail>0.and.op%Fshift(aF+1)>op%Fshift(aF)) then
    1211              :     op%M%mat(op%Fshift(aF)+1:op%Fshift(aF+1) , 1:new_tail) = &
    1212            0 :         CSHIFT( op%M%mat(op%Fshift(aF)+1:op%Fshift(aF+1) , 1:new_tail) , SHIFT=-1 , DIM=1) ! Shift to the bottom
    1213              : 
    1214              :     op%M%mat(1:new_tail , op%Fshift(aF)+1:op%Fshift(aF+1)) = &
    1215            0 :         CSHIFT( op%M%mat(1:new_tail , op%Fshift(aF)+1:op%Fshift(aF+1)) , SHIFT=-1 , DIM=2) ! Shift to the right
    1216              : 
    1217              :     op%M%mat_tau(op%Fshift(aF)+1:op%Fshift(aF+1) , 1:new_tail) = &
    1218            0 :         CSHIFT( op%M%mat_tau(op%Fshift(aF)+1:op%Fshift(aF+1) , 1:new_tail) , SHIFT=-1 , DIM=1) ! Shift to the bottom
    1219              : 
    1220              :     op%M%mat_tau(1:new_tail , op%Fshift(aF)+1:op%Fshift(aF+1)) = &
    1221            0 :         CSHIFT( op%M%mat_tau(1:new_tail , op%Fshift(aF)+1:op%Fshift(aF+1)) , SHIFT=-1 , DIM=2) ! Shift to the right
    1222              :   end if
    1223              :   !CALL matrix_print(M)
    1224              :   END IF
    1225              : 
    1226              : !!  do it=1,op%sumtails
    1227              :     !write(6,*) "        setMAdd end M",(op%M%mat(it,it1),it1=1,op%sumtails)
    1228              : !!  enddo
    1229              :  !! do it=1,op%sumtails
    1230              : !!    !write(6,*) "        setMAdd end M%mat_tau",(op%M%mat_tau(it,it1),it1=1,op%sumtails)
    1231              :  !! enddo
    1232            0 :   IF ( op%doCheck .EQV. .TRUE.) THEN
    1233              : !#ifdef CTQMC_CHECK
    1234            0 :     CALL BathOperatoroffdiagComplex_checkM(op,particle)
    1235              : !#endif
    1236              :   END IF
    1237              : 
    1238            0 :   op%MAddFlag = .FALSE.
    1239              : 
    1240            0 : END SUBROUTINE BathOperatoroffdiagComplex_setMAdd
    1241              : !!***
    1242              : 
    1243              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_setMRemove
    1244              : !! NAME
    1245              : !!  BathOperatoroffdiagComplex_setMRemove
    1246              : !!
    1247              : !! FUNCTION
    1248              : !!  delete one row and one column of the M matrix
    1249              : !!
    1250              : !! COPYRIGHT
    1251              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1252              : !!  This file is distributed under the terms of the
    1253              : !!  GNU General Public License, see ~abinit/COPYING
    1254              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1255              : !!
    1256              : !! INPUTS
    1257              : !!  op=bath operator
    1258              : !!  particle=segments of the active flavor
    1259              : !!
    1260              : !! OUTPUT
    1261              : !!
    1262              : !! SIDE EFFECTS
    1263              : !!
    1264              : !! NOTES
    1265              : !!
    1266              : !! SOURCE
    1267              : 
    1268            0 : SUBROUTINE BathOperatoroffdiagComplex_setMRemove(op,particle)
    1269              : 
    1270              : !Arguments ------------------------------------
    1271              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT)  :: op
    1272              :   TYPE(ListCdagC)   , INTENT(IN   )  :: particle(:)
    1273              : !Local variables ------------------------------
    1274              :   INTEGER                            :: tail,tailb,taile
    1275              :   INTEGER                            :: new_tail
    1276              :   INTEGER                            :: col
    1277              :   INTEGER                            :: col_move
    1278              :   INTEGER                            :: row_move
    1279              :   INTEGER                            :: row
    1280              :   INTEGER                            :: positionCol
    1281              :   INTEGER                            :: positionRow
    1282              :   INTEGER                            :: aF,iaf
    1283              :   INTEGER                              :: m
    1284              :   INTEGER                              :: count
    1285              :   INTEGER                              :: i
    1286              :   INTEGER                              :: j,it !,it1
    1287              :   INTEGER                              :: p
    1288              :   COMPLEX(KIND=8)                   :: invStilde
    1289              :   COMPLEX(KIND=8)                   :: invStilde2
    1290            0 :   TYPE(VectorInt) :: vecI_tmp
    1291            0 :   TYPE(VectorComplex)    :: vec_tmp
    1292              : 
    1293            0 :   IF ( op%MRemoveFlag .EQV. .FALSE. ) &
    1294            0 :     CALL ERROR("BathOperatoroffdiagComplex_setMRemove : MRemoveFlag turn off     ")
    1295            0 :   aF = op%activeFlavor
    1296            0 :   IF ( aF .LE. 0 ) &
    1297            0 :     CALL ERROR("BathOperatoroffdiagComplex_setMRemove : no active hybrid func    ")
    1298            0 :   do it=1,op%sumtails
    1299              :     !write(6,*) "        setMRemove begin M",(op%M%mat(it,it1),it1=1,op%sumtails)
    1300              :   enddo
    1301            0 :   tail        =  op%sumtails
    1302            0 :   new_tail    =  tail - 1
    1303            0 :   op%tails(af)= op%tails(af) - 1
    1304            0 :   DO iaf=af+1 , op%flavors+1
    1305            0 :     op%Fshift(iaf) = op%Fshift(iaf) - 1
    1306              :   END DO
    1307            0 :   op%sumtails = op%Fshift(op%flavors) + op%tails(op%flavors)
    1308            0 :   positionCol =  op%updatePosCol + op%Fshift(af)
    1309            0 :   positionRow =  op%updatePosRow + op%Fshift(af)
    1310            0 :   invStilde   = 1.d0 / op%Stilde
    1311              :   if(op%opt_nondiag==1) then
    1312              :     tailb        = 1
    1313              :     taile        = new_tail
    1314              :   else
    1315              :   !sui!write(6,*) "Bathoperator c opt_nondiag=0"
    1316              :     tailb        = op%Fshift(aF)+1
    1317              :     taile        = op%Fshift(aF)+op%tails(aF)
    1318              :   endif
    1319              : 
    1320              : !  !write(6,*) "before", positionRow, positionCol
    1321              : !  CALL MatrixHybComplex_print(op%M(aF),opt_print=1)
    1322              : 
    1323              : !  IF ( new_tail .EQ. 0 ) THEN
    1324              : !!    IF ( op%antiShift .EQV. .TRUE.  ) THEN
    1325              : !!      op%M(aF)%mat(1,1) = 1.d0/BathOperatoroffdiagComplex_Hybrid(op, op%beta)
    1326              : !!      op%MRemoveFlag = .FALSE.
    1327              : !!      RETURN
    1328              : !!    END IF
    1329              : !    CALL MatrixHybComplex_clear(op%M(aF))
    1330              : !    op%MRemoveFlag = .FALSE.
    1331              : !    RETURN
    1332              : !  END IF
    1333              : 
    1334              : !  CALL VectorComplex_setSize(op%Q,new_tail)
    1335              : !  CALL VectorComplex_setSize(op%R,new_tail)
    1336            0 :   VectorComplex_QuickResize(op%Q,new_tail)
    1337            0 :   VectorComplex_QuickResize(op%R,new_tail)
    1338              : 
    1339              : !  We use R and Q as op%R%vec and op%Q%vec
    1340              : !  op%R%vec => op%R
    1341              : !  op%Q%vec => op%Q
    1342              : 
    1343            0 :   row      = 1
    1344              :   !row_move = 1
    1345            0 :   col      = 1
    1346              :   !col_move = 1
    1347            0 :   DO row_move = 1, new_tail
    1348            0 :     IF ( row .EQ. positionRow ) row = row + 1
    1349            0 :     IF ( col .EQ. positionCol ) col = col + 1
    1350              :     !col = row_move + (1+SIGN(1,row_move-positionCol))/2
    1351              :     !row = row_move + (1+SIGN(1,row_move-positionRow))/2
    1352            0 :     op%R%vec(row_move) = op%M%mat(positionRow,col)
    1353            0 :     op%Q%vec(row_move) = op%M%mat(row,positionCol)
    1354            0 :     row      = row + 1
    1355            0 :     col      = col + 1
    1356              :   END DO
    1357              : !!    op%R%vec(1:positionCol-1) = op%M(aF)%mat(positionRow,1:positionCol-1)
    1358              : !!    op%R%vec(positionCol:new_tail) = op%M(aF)%mat(positionRow,positionCol+1:tail)
    1359              : !!    op%Q%vec(1:positionRow-1) = op%M(aF)%mat(1:positionRow-1,positionCol)
    1360              : !!    op%Q%vec(positionRow:new_tail) = op%M(aF)%mat(positionRow+1:tail,positionCol)
    1361              : !write(*,*) positionRow, positionCol
    1362              : !CALL MatrixHybComplex_print(M)
    1363              : !CALL VectorComplex_print(op%R)
    1364              : !CALL VectorComplex_print(op%Q)
    1365              : !CALL ListCdagC_print(op%ListCdagC)
    1366              : 
    1367              :   col      = 1
    1368            0 :   DO col_move = 1, new_tail
    1369            0 :     IF ( col_move .EQ. positionCol ) col = col + 1
    1370              :     !col = col_move + (1+SIGN(1,col_move-positionCol))/2
    1371            0 :     row      = 1
    1372            0 :     invStilde2 = invStilde * op%R%vec(col_move)
    1373            0 :     DO row_move = 1, new_tail
    1374            0 :       IF ( row_move .EQ. positionRow ) row = row + 1
    1375              :       !row = row_move + (1+SIGN(1,row_move-positionRow))/2
    1376              : !    Compute for all rows and cols M <= M - Q 1/S R
    1377              :       !if(row_move>=tailb.and.row_move<=taile.and.col_move>=tailb.and.col_move<=taile) then
    1378              :         op%M%mat(row_move,col_move) = op%M%mat(row,col) &
    1379            0 :                                         - op%Q%vec(row_move)*invStilde2
    1380              :       !else
    1381              :       !  op%M%mat(row_move,col_move) = op%M%mat(row,col)
    1382              :       !endif
    1383            0 :       op%M%mat_tau(row_move,col_move) = op%M%mat_tau(row,col)
    1384            0 :       row      = row      + 1
    1385              :     END DO
    1386            0 :     col      = col      + 1
    1387              :   END DO
    1388            0 :   CALL MatrixHybComplex_setSize(op%M,new_tail)
    1389              : 
    1390            0 :   IF ( op%antiShift .EQV. .TRUE. ) THEN ! antisegment
    1391              :    if(3==4) then
    1392              :     ! Shift if necessary according to op%antishift
    1393              :     ! shift DIM=2 (col)
    1394              :     CALL VectorComplex_init(vec_tmp,new_tail)
    1395              :     CALL VectorInt_init(vecI_tmp,new_tail)
    1396              :     p = 1
    1397              :     m = 1
    1398              :     count = 0
    1399              :     DO WHILE ( count .NE. new_tail )
    1400              :       vec_tmp%vec(1:new_tail) = op%M%mat(1:new_tail,m)
    1401              :       vecI_tmp%vec(1:new_tail) = op%M%mat_tau(1:new_tail,m)
    1402              :       i = m
    1403              :       !j = m+p
    1404              :       MODCYCLE(m+p, new_tail, j)
    1405              :       DO WHILE (j .NE. m)
    1406              :         op%M%mat(1:new_tail,i) = op%M%mat(1:new_tail,j)
    1407              :         op%M%mat_tau(1:new_tail,i) = op%M%mat_tau(1:new_tail,j)
    1408              :         i = j
    1409              :         MODCYCLE(j+p, new_tail, j)
    1410              :         count = count+1
    1411              :       END DO
    1412              :       op%M%mat(1:new_tail,i) = vec_tmp%vec(1:new_tail)
    1413              :       op%M%mat_tau(1:new_tail,i) = vecI_tmp%vec(1:new_tail)
    1414              :       count = count+1
    1415              :       m = m+1
    1416              :     END DO
    1417              :     CALL VectorComplex_destroy(vec_tmp)
    1418              :     CALL VectorInt_destroy(vecI_tmp)
    1419              :     !op%M(aF)%mat(1:new_tail,1:new_tail) = &
    1420              :     !           CSHIFT(op%M(aF)%mat(1:new_tail,1:new_tail), SHIFT=1, DIM=2) ! Shift to the top
    1421              :     !op%M(aF)%mat_tau(1:new_tail,1:new_tail) = &
    1422              :     !           CSHIFT(op%M(aF)%mat_tau(1:new_tail,1:new_tail), SHIFT=1, DIM=2) ! Shift to the top
    1423              :    endif
    1424            0 :    if (new_tail>0.and.op%Fshift(af+1)>op%Fshift(af)) then
    1425              :     op%M%mat(1:new_tail,op%Fshift(af)+1:op%Fshift(af+1)) = &
    1426            0 :                CSHIFT(op%M%mat(1:new_tail,op%Fshift(af)+1:op%Fshift(af+1)), SHIFT=1, DIM=2) ! Shift to the top
    1427              :     op%M%mat_tau(1:new_tail,op%Fshift(af)+1:op%Fshift(af+1)) = &
    1428            0 :                CSHIFT(op%M%mat_tau(1:new_tail,op%Fshift(af)+1:op%Fshift(af+1)), SHIFT=1, DIM=2) ! Shift to the top
    1429              :    end if
    1430              :   END IF
    1431              : !  !write(6,*) "after "
    1432              : !  CALL MatrixHybComplex_print(op%M(aF),opt_print=1)
    1433              : 
    1434            0 :   IF ( op%doCheck .EQV. .TRUE. ) THEN
    1435              : !#ifdef CTQMC_CHECK
    1436            0 :   CALL BathOperatoroffdiagComplex_checkM(op,particle)
    1437              : !#endif
    1438              :   END IF
    1439            0 :   do it=1,op%sumtails
    1440              :     !write(6,*) "        setMRemove end M",(op%M%mat(it,it1),it1=1,op%sumtails)
    1441              :   enddo
    1442              : 
    1443            0 :   op%MRemoveFlag = .FALSE.
    1444              : 
    1445            0 : END SUBROUTINE BathOperatoroffdiagComplex_setMRemove
    1446              : !!***
    1447              : 
    1448              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_swap
    1449              : !! NAME
    1450              : !!  BathOperatoroffdiagComplex_swap
    1451              : !!
    1452              : !! FUNCTION
    1453              : !!  Recompute 2 M matrix swaping the segments (used for Global moves)
    1454              : !!
    1455              : !! COPYRIGHT
    1456              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1457              : !!  This file is distributed under the terms of the
    1458              : !!  GNU General Public License, see ~abinit/COPYING
    1459              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1460              : !!
    1461              : !! INPUTS
    1462              : !!  op=bath operator
    1463              : !!  iflavor1=flavor to swap with the next one
    1464              : !!  iflavor2=favor to swap with the previous one
    1465              : !!
    1466              : !! OUTPUT
    1467              : !!
    1468              : !! SIDE EFFECTS
    1469              : !!
    1470              : !! NOTES
    1471              : !!
    1472              : !! SOURCE
    1473              : 
    1474            0 : SUBROUTINE BathOperatoroffdiagComplex_swap(op, flavor1, flavor2)
    1475              : 
    1476              : !Arguments ------------------------------------
    1477              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
    1478              :   INTEGER           , INTENT(IN   ) :: flavor1
    1479              :   INTEGER           , INTENT(IN   ) :: flavor2
    1480              :   INTEGER            :: ii,iflavort,itmptail,flavora,flavorb
    1481            0 :   COMPLEX(KIND=8), ALLOCATABLE, DIMENSION(:,:) :: mat_temp
    1482            0 :   INTEGER         , ALLOCATABLE, DIMENSION(:,:) :: mat_tau_temp
    1483              : 
    1484            0 :   if(flavor1>flavor2) then
    1485              :     flavora=flavor2
    1486              :     flavorb=flavor1
    1487              :   else
    1488            0 :     flavora=flavor1
    1489            0 :     flavorb=flavor2
    1490              :   endif
    1491            0 :   MALLOC(mat_temp,(1:op%sumtails,1:op%sumtails))
    1492            0 :   MALLOC(mat_tau_temp,(1:op%sumtails,1:op%sumtails))
    1493              :   !mat_temp= op%M%mat
    1494              :   !mat_tau_temp= op%M%mat_tau
    1495              :   !it1=0
    1496              :   !do iflav1=1,op%flavors
    1497              :   !  do ii1=1,op%tails(iflav1)
    1498              :   !    it1=it1+1
    1499              :   !    it2=0
    1500              :   !    do iflav2=1,op%flavors
    1501              :   !      do ii2=1,op%tails(iflav1)
    1502              :   !        it2=it2+1
    1503              :   !        op%M%mat(it1,it2)=
    1504              :   !      enddo
    1505              :   !    enddo
    1506              :   !  enddo
    1507              :   !enddo
    1508              :   if(3==3) then
    1509            0 :     op%M=op%M_update
    1510            0 :     if (op%sumtails>0) then
    1511              : !     shift block flavorb at the place of flavora (column)
    1512            0 :       if (op%Fshift(flavorb+1)>op%Fshift(flavora)) then
    1513            0 :        do ii=1, op%tails(flavorb)
    1514              :         op%M%mat(op%Fshift(flavora)+1:op%Fshift(flavorb+1) , 1:op%sumtails) = &
    1515            0 :           CSHIFT( op%M%mat(op%Fshift(flavora)+1:op%Fshift(flavorb+1) , 1:op%sumtails) , SHIFT=-1 , DIM=1)
    1516              :         op%M%mat_tau(op%Fshift(flavora)+1:op%Fshift(flavorb+1) , 1:op%sumtails) = &
    1517            0 :           CSHIFT( op%M%mat_tau(op%Fshift(flavora)+1:op%Fshift(flavorb+1) , 1:op%sumtails) , SHIFT=-1 , DIM=1)
    1518              :        enddo
    1519              :       end if
    1520              : 
    1521              : !     shift block flavora at the place of flavorb (column)
    1522            0 :       if (op%Fshift(flavorb)>op%Fshift(flavora)) then
    1523            0 :        do ii=1, op%tails(flavora)
    1524              :         op%M%mat(op%Fshift(flavora)+op%tails(flavorb)+&
    1525              : &        1:op%Fshift(flavorb)+op%tails(flavorb) , 1:op%sumtails) = &
    1526              :           CSHIFT( op%M%mat( op%Fshift(flavora)+op%tails(flavorb)&
    1527            0 : &          +1:op%Fshift(flavorb)+op%tails(flavorb) , 1:op%sumtails) , SHIFT=1 , DIM=1)
    1528              :         op%M%mat_tau(op%Fshift(flavora)+op%tails(flavorb)+1:op%Fshift(flavorb)+&
    1529              : &        op%tails(flavorb) , 1:op%sumtails) = &
    1530              :           CSHIFT( op%M%mat_tau( op%Fshift(flavora)+op%tails(flavorb)+&
    1531            0 : &          1:op%Fshift(flavorb)+op%tails(flavorb) , 1:op%sumtails) , SHIFT=1 , DIM=1)
    1532              :        enddo
    1533              :       end if
    1534              : 
    1535              : !     shift block flavorb at the place of flavora (row)
    1536            0 :       if (op%Fshift(flavorb+1)>op%Fshift(flavora)) then
    1537            0 :        do ii=1, op%tails(flavorb)
    1538              :         op%M%mat(1:op%sumtails , op%Fshift(flavora)+1:op%Fshift(flavorb+1)) = &
    1539            0 :           CSHIFT( op%M%mat(1:op%sumtails , op%Fshift(flavora)+1:op%Fshift(flavorb+1)) , SHIFT=-1 , DIM=2)
    1540              :         op%M%mat_tau(1:op%sumtails , op%Fshift(flavora)+1:op%Fshift(flavorb+1)) = &
    1541            0 :           CSHIFT( op%M%mat_tau(1:op%sumtails , op%Fshift(flavora)+1:op%Fshift(flavorb+1)) , SHIFT=-1 , DIM=2)
    1542              :        enddo
    1543              :       end if
    1544              : 
    1545              : !     shift block flavora at the place of flavorb (row)
    1546            0 :       if (op%Fshift(flavorb)>op%Fshift(flavora)) then
    1547            0 :        do ii=1, op%tails(flavora)
    1548              :         op%M%mat(1:op%sumtails , op%Fshift(flavora)+op%tails(flavorb)+1:op%Fshift(flavorb)+op%tails(flavorb)) = &
    1549              :           CSHIFT( op%M%mat(1:op%sumtails ,op%Fshift(flavora)+op%tails(flavorb)&
    1550            0 : &          +1:op%Fshift(flavorb)+op%tails(flavorb)) , SHIFT=1 , DIM=2)
    1551              :         op%M%mat_tau(1:op%sumtails ,op%Fshift(flavora)+op%tails(flavorb)+&
    1552              : &        1:op%Fshift(flavorb)+op%tails(flavorb) ) = &
    1553              :           CSHIFT( op%M%mat_tau(1:op%sumtails ,op%Fshift(flavora)+&
    1554            0 : &          op%tails(flavorb)+1:op%Fshift(flavorb)+op%tails(flavorb) ) , SHIFT=1 , DIM=2)
    1555              :        enddo
    1556              :       end if
    1557              :     end if
    1558              :   endif
    1559              :   if(3==4) then
    1560              :     op%M=op%M_update
    1561              :   endif
    1562              : 
    1563              : 
    1564            0 :   do iflavort=flavora+1,flavorb
    1565            0 :     op%Fshift(iflavort)=op%Fshift(iflavort)+op%tails(flavorb)-op%tails(flavora)
    1566              :   enddo
    1567              : 
    1568            0 :   itmptail=op%tails(flavora)
    1569            0 :   op%tails(flavora)=op%tails(flavorb)
    1570            0 :   op%tails(flavorb)=itmptail
    1571            0 :   FREE(mat_temp)
    1572            0 :   FREE(mat_tau_temp)
    1573              : 
    1574            0 : END SUBROUTINE BathOperatoroffdiagComplex_swap
    1575              : !!***
    1576              : 
    1577              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_initF
    1578              : !! NAME
    1579              : !!  BathOperatoroffdiagComplex_initF
    1580              : !!
    1581              : !! FUNCTION
    1582              : !!  Copy input hybridization functions from a file
    1583              : !!
    1584              : !! COPYRIGHT
    1585              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1586              : !!  This file is distributed under the terms of the
    1587              : !!  GNU General Public License, see ~abinit/COPYING
    1588              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1589              : !!
    1590              : !! INPUTS
    1591              : !!  op=bath operator
    1592              : !!  ifstream=file stream to read F
    1593              : !!
    1594              : !! OUTPUT
    1595              : !!  argout(sizeout)=description
    1596              : !!
    1597              : !! SIDE EFFECTS
    1598              : !!
    1599              : !! NOTES
    1600              : !!
    1601              : !! SOURCE
    1602              : 
    1603            0 : SUBROUTINE BathOperatoroffdiagComplex_initF(op,ifstream)
    1604              : 
    1605              : !Arguments ----------------------
    1606              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
    1607              :   INTEGER           , INTENT(IN   ) :: ifstream
    1608              : !Local variables ----------------
    1609              :   INTEGER                           :: iflavor1
    1610              :   INTEGER                           :: iflavor2
    1611              :   INTEGER                           :: sample
    1612              : 
    1613            0 :   IF ( op%set .EQV. .FALSE. ) &
    1614            0 :     CALL ERROR("BathOperatoroffdiagComplex_initF : BathOperatoroffdiagComplex not set         ")
    1615              : 
    1616            0 :   DO iflavor1=1,op%flavors
    1617            0 :     DO iflavor2=2,op%flavors
    1618            0 :       DO sample = 1, op%sizeHybrid
    1619            0 :         READ(ifstream,*) op%F(sample,iflavor1,iflavor2)
    1620              :       END DO
    1621              :     END DO
    1622              :   END DO
    1623            0 : END SUBROUTINE BathOperatoroffdiagComplex_initF
    1624              : !!***
    1625              : 
    1626              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_setF
    1627              : !! NAME
    1628              : !!  BathOperatoroffdiagComplex_setF
    1629              : !!
    1630              : !! FUNCTION
    1631              : !!  Copy F from input array
    1632              : !!
    1633              : !! COPYRIGHT
    1634              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1635              : !!  This file is distributed under the terms of the
    1636              : !!  GNU General Public License, see ~abinit/COPYING
    1637              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1638              : !!
    1639              : !! INPUTS
    1640              : !!  op=bath operator
    1641              : !!  F=array of the hybridization function
    1642              : !!
    1643              : !! OUTPUT
    1644              : !!
    1645              : !! SIDE EFFECTS
    1646              : !!
    1647              : !! NOTES
    1648              : !!
    1649              : !! SOURCE
    1650              : 
    1651            0 : SUBROUTINE BathOperatoroffdiagComplex_setF(op,F)
    1652              : 
    1653              : !Arguments ------------------------------------
    1654              :   TYPE(BathOperatoroffdiagComplex)               , INTENT(INOUT) :: op
    1655              :   COMPLEX(KIND=8), DIMENSION(:,:,:) , INTENT(IN   ) :: F
    1656              : !Arguments ------------------------------------
    1657              :   INTEGER                                          :: iflavor1
    1658              :   INTEGER                                          :: iflavor2
    1659              :   INTEGER                                          :: sample
    1660              :   INTEGER                                          :: length
    1661              : 
    1662            0 :   IF ( op%set .EQV. .FALSE. ) &
    1663            0 :     CALL ERROR("BathOperatoroffdiagComplex_setF : BathOperatoroffdiagComplex not set          ")
    1664              : 
    1665            0 :  length  = SIZE(F)
    1666            0 :   IF ( length .NE. (op%flavors * op%flavors * op%sizeHybrid) ) &
    1667            0 :     CALL ERROR("BathOperatoroffdiagComplex_setF : wrong input F                 ")
    1668              : 
    1669            0 :   DO iflavor1=1,op%flavors
    1670            0 :     DO iflavor2=1,op%flavors
    1671            0 :       DO sample = 1, op%sizeHybrid
    1672            0 :       op%F(sample,iflavor1,iflavor2) = F(sample,iflavor1,iflavor2)
    1673              :       END DO
    1674              :     END DO
    1675              :   END DO
    1676            0 : END SUBROUTINE BathOperatoroffdiagComplex_setF
    1677              : !!***
    1678              : 
    1679              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_printF
    1680              : !! NAME
    1681              : !!  BathOperatoroffdiagComplex_printF
    1682              : !!
    1683              : !! FUNCTION
    1684              : !!  print F function
    1685              : !!
    1686              : !! COPYRIGHT
    1687              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1688              : !!  This file is distributed under the terms of the
    1689              : !!  GNU General Public License, see ~abinit/COPYING
    1690              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1691              : !!
    1692              : !! INPUTS
    1693              : !!  op=bath operator
    1694              : !!  ostream=file stream to write in
    1695              : !!
    1696              : !! OUTPUT
    1697              : !!
    1698              : !! SIDE EFFECTS
    1699              : !!
    1700              : !! NOTES
    1701              : !!
    1702              : !! SOURCE
    1703              : 
    1704            0 : SUBROUTINE BathOperatoroffdiagComplex_printF(op,ostream)
    1705              : 
    1706              : !Arguments ------------------------------------
    1707              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
    1708              :   INTEGER,OPTIONAL  , INTENT(IN   ) :: ostream
    1709              : !Local variables ------------------------------
    1710              :   CHARACTER(LEN=4)                  :: aflavor
    1711              :   CHARACTER(LEN=50)                  :: string
    1712              :   INTEGER                           :: iflavor1
    1713              :   INTEGER                           :: iflavor2
    1714              :   INTEGER                           :: sample
    1715              :   INTEGER                           :: ostream_val
    1716              : 
    1717            0 :   IF ( PRESENT(ostream) ) THEN
    1718            0 :     ostream_val = ostream
    1719              :   ELSE
    1720            0 :     ostream_val = 65
    1721            0 :     OPEN(UNIT=ostream_val, FILE="F.dat")
    1722              :   END IF
    1723              : 
    1724            0 :   WRITE(aflavor,'(I4)') (op%flavors*op%flavors+1)
    1725            0 :   string = '(1x,'//TRIM(ADJUSTL(aflavor))//'E22.14)'
    1726            0 :   DO sample = 1, op%sizeHybrid
    1727            0 :     WRITE(ostream_val,string) (sample-1)*op%dt, ((op%F(sample,iflavor1,iflavor2),&
    1728            0 :                                                  iflavor1=1,op%flavors),iflavor2=1,op%flavors)
    1729              :   END DO
    1730              :   !CALL FLUSH(ostream_val)
    1731              : 
    1732            0 :   IF ( .NOT. PRESENT(ostream) ) &
    1733            0 :     CLOSE(ostream_val)
    1734              : 
    1735            0 : END SUBROUTINE BathOperatoroffdiagComplex_printF
    1736              : !!***
    1737              : 
    1738              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_printM
    1739              : !! NAME
    1740              : !!  BathOperatoroffdiagComplex_printM
    1741              : !!
    1742              : !! FUNCTION
    1743              : !!  print M =F^{-1} matrix
    1744              : !!
    1745              : !! COPYRIGHT
    1746              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1747              : !!  This file is distributed under the terms of the
    1748              : !!  GNU General Public License, see ~abinit/COPYING
    1749              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1750              : !!
    1751              : !! INPUTS
    1752              : !!  op=bath operator
    1753              : !!  ostream=file stream to write in
    1754              : !!
    1755              : !! OUTPUT
    1756              : !!  argout(sizeout)=description
    1757              : !!
    1758              : !! SIDE EFFECTS
    1759              : !!
    1760              : !! NOTES
    1761              : !!
    1762              : !! SOURCE
    1763              : 
    1764            0 : SUBROUTINE BathOperatoroffdiagComplex_printM(op,ostream)
    1765              : 
    1766              : !Arguments ------------------------------------
    1767              :   TYPE(BathOperatoroffdiagComplex), INTENT(IN) :: op
    1768              :   INTEGER, OPTIONAL , INTENT(IN) :: ostream
    1769              : !Local variables ------------------------------
    1770              :   INTEGER                        :: ostream_val
    1771              : 
    1772            0 :   IF ( op%activeFlavor .LE. 0 ) &
    1773            0 :     CALL ERROR("BathOperatoroffdiagComplex_printM : no active hybrid function    ")
    1774            0 :   ostream_val = 6
    1775            0 :   IF ( PRESENT(ostream) ) ostream_val = ostream
    1776            0 :   CALL MatrixHybComplex_print(op%M,ostream_val)
    1777            0 : END SUBROUTINE BathOperatoroffdiagComplex_printM
    1778              : !!***
    1779              : 
    1780              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_printM_matrix
    1781              : !! NAME
    1782              : !!  BathOperatoroffdiagComplex_printM_matrix
    1783              : !!
    1784              : !! FUNCTION
    1785              : !!  print M =F^{-1} matrix
    1786              : !!
    1787              : !! COPYRIGHT
    1788              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1789              : !!  This file is distributed under the terms of the
    1790              : !!  GNU General Public License, see ~abinit/COPYING
    1791              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1792              : !!
    1793              : !! INPUTS
    1794              : !!  op=bath operator
    1795              : !!  ostream=file stream to write in
    1796              : !!
    1797              : !! OUTPUT
    1798              : !!  argout(sizeout)=description
    1799              : !!
    1800              : !! SIDE EFFECTS
    1801              : !!
    1802              : !! NOTES
    1803              : !!
    1804              : !! SOURCE
    1805              : 
    1806            0 : SUBROUTINE BathOperatoroffdiagComplex_printM_matrix(op,ostream)
    1807              : 
    1808              : !Arguments ------------------------------------
    1809              :   TYPE(BathOperatoroffdiagComplex), INTENT(IN) :: op
    1810              :   INTEGER, OPTIONAL , INTENT(IN) :: ostream
    1811              : !Local variables ------------------------------
    1812              :   INTEGER                        :: iflavor1
    1813              :   INTEGER                        :: i1,it1,it2
    1814              :   CHARACTER(LEN=22)              :: string
    1815              :   CHARACTER(LEN=22)              :: string2
    1816              :   CHARACTER(LEN=4 )              :: size
    1817              : 
    1818              :   ABI_UNUSED(ostream)
    1819              : 
    1820            0 :   WRITE(size,'(I4)') op%sumtails
    1821            0 :   string ='(i2,x,i3,a,'//TRIM(ADJUSTL(size))//'(E5.2,1x))'
    1822            0 :   string2 ='(6x,'//TRIM(ADJUSTL(size))//'(i6))'
    1823            0 :   open(unit=222, file="M_matrix.dat")
    1824            0 :   open(unit=223, file="M_matrix_tau.dat")
    1825            0 :   it1=0
    1826            0 :   write(222,string2) ((i1,i1=1,op%tails(iflavor1)),iflavor1=1,op%flavors)
    1827            0 :   do iflavor1=1, op%flavors
    1828            0 :     do i1=1, op%tails(iflavor1)
    1829            0 :       it1=it1+1
    1830            0 :       write(222,string) iflavor1,i1,'|',(op%M%mat(it1,it2),it2=1,op%sumtails)
    1831              :     enddo
    1832              :   enddo
    1833              : 
    1834              : 
    1835            0 : END SUBROUTINE BathOperatoroffdiagComplex_printM_matrix
    1836              : !!***
    1837              : 
    1838              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/ BathOperatoroffdiagComplex_destroy
    1839              : !! NAME
    1840              : !!   BathOperatoroffdiagComplex_destroy
    1841              : !!
    1842              : !! FUNCTION
    1843              : !!  Deallocate and reset every thing
    1844              : !!
    1845              : !! COPYRIGHT
    1846              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1847              : !!  This file is distributed under the terms of the
    1848              : !!  GNU General Public License, see ~abinit/COPYING
    1849              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1850              : !!
    1851              : !! INPUTS
    1852              : !!  op=bath operator
    1853              : !!
    1854              : !! OUTPUT
    1855              : !!
    1856              : !! SIDE EFFECTS
    1857              : !!
    1858              : !! NOTES
    1859              : !!
    1860              : !! SOURCE
    1861              : 
    1862            0 : SUBROUTINE  BathOperatoroffdiagComplex_destroy(op)
    1863              : 
    1864              :   TYPE(BathOperatoroffdiagComplex), INTENT(INOUT) :: op
    1865              : 
    1866            0 :   CALL MatrixHybComplex_destroy(op%M)
    1867            0 :   CALL MatrixHybComplex_destroy(op%M_update)
    1868              : 
    1869            0 :   CALL VectorComplex_destroy(op%R)
    1870            0 :   CALL VectorComplex_destroy(op%Q)
    1871            0 :   CALL Vector_destroy(op%Rtau)
    1872            0 :   CALL Vector_destroy(op%Qtau)
    1873            0 :   FREEIF(op%F)
    1874            0 :   FREEIF(op%Fshift)
    1875            0 :   FREEIF(op%tails)
    1876              : 
    1877            0 :   op%MAddFlag     = .FALSE.
    1878            0 :   op%MRemoveFlag  = .FALSE.
    1879            0 :   op%flavors      = 0
    1880            0 :   op%beta         = 0.d0
    1881            0 :   op%dt      = 0.d0
    1882            0 :   op%inv_dt  = 0.d0
    1883            0 :   op%samples      = 0
    1884            0 :   op%sizeHybrid   = 0
    1885            0 :   op%activeFlavor = 0
    1886            0 :   op%updatePosRow = 0
    1887            0 :   op%updatePosCol = 0
    1888              : 
    1889            0 : END SUBROUTINE BathOperatoroffdiagComplex_destroy
    1890              : !!***
    1891              : 
    1892              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_doCheck
    1893              : !! NAME
    1894              : !!  BathOperatoroffdiagComplex_doCheck
    1895              : !!
    1896              : !! FUNCTION
    1897              : !!  Just store if we perfom check for updates of M
    1898              : !!
    1899              : !! COPYRIGHT
    1900              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1901              : !!  This file is distributed under the terms of the
    1902              : !!  GNU General Public License, see ~abinit/COPYING
    1903              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1904              : !!
    1905              : !! INPUTS
    1906              : !!  op=bath operator
    1907              : !!  opt_check=second bit should be one
    1908              : !!
    1909              : !! OUTPUT
    1910              : !!
    1911              : !! SIDE EFFECTS
    1912              : !!
    1913              : !! NOTES
    1914              : !!
    1915              : !! SOURCE
    1916              : 
    1917            0 : SUBROUTINE BathOperatoroffdiagComplex_doCheck(op,opt_check)
    1918              : 
    1919              : !Arguments ------------------------------------
    1920              :   TYPE(BathOperatoroffdiagComplex) , INTENT(INOUT) :: op
    1921              :   INTEGER            , INTENT(IN   ) :: opt_check
    1922              : 
    1923            0 :   IF ( opt_check .GE. 2 ) &
    1924            0 :     op%doCheck = .TRUE.
    1925            0 : END SUBROUTINE BathOperatoroffdiagComplex_doCheck
    1926              : !!***
    1927              : 
    1928              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_checkM
    1929              : !! NAME
    1930              : !!  BathOperatoroffdiagComplex_checkM
    1931              : !!
    1932              : !! FUNCTION
    1933              : !!  compute from scratch the M matrix and compare it
    1934              : !!  with the already computed M matrix
    1935              : !!
    1936              : !! COPYRIGHT
    1937              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    1938              : !!  This file is distributed under the terms of the
    1939              : !!  GNU General Public License, see ~abinit/COPYING
    1940              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1941              : !!
    1942              : !! INPUTS
    1943              : !!  op=bath operator
    1944              : !!  particle=list of all segments of the active flavor
    1945              : !!
    1946              : !! OUTPUT
    1947              : !!
    1948              : !! SIDE EFFECTS
    1949              : !!
    1950              : !! NOTES
    1951              : !!
    1952              : !! SOURCE
    1953              : 
    1954            0 : SUBROUTINE BathOperatoroffdiagComplex_checkM(op,particle)
    1955              : 
    1956              : !Arguments ------------------------------------
    1957              :   TYPE(BathOperatoroffdiagComplex) , INTENT(INOUT) :: op
    1958              :   TYPE(ListCdagC)    , INTENT(IN   ) :: particle(:)
    1959              : !Local variables ------------------------------
    1960              : !  TYPE(MatrixHybComplex)                    :: checkMatrix
    1961              :   LOGICAL :: checkTau
    1962              :   INTEGER :: tail
    1963              :   INTEGER :: iC
    1964              :   INTEGER :: iCdag
    1965              :   INTEGER :: aF
    1966              :   INTEGER :: iflavora
    1967              :   INTEGER :: iflavorb,it !,it1
    1968              :   CHARACTER(LEN=6) :: a
    1969              :   DOUBLE PRECISION :: time
    1970              :   DOUBLE PRECISION :: beta
    1971              :   DOUBLE PRECISION :: mbeta_two
    1972              :   DOUBLE PRECISION :: errorabs
    1973              :   DOUBLE PRECISION :: errormax
    1974              :   DOUBLE PRECISION :: error1
    1975              :   DOUBLE PRECISION :: errorrel
    1976              :   DOUBLE PRECISION :: tc
    1977              :   DOUBLE PRECISION :: tCdag
    1978              :   COMPLEX(KIND=8) :: sumMmat
    1979              :   COMPLEX(KIND=8) :: sumCheck
    1980              : #include "BathOperatoroffdiagComplex_hybrid.h"
    1981              : 
    1982            0 :   aF = op%activeFlavor
    1983              :   !Construction de la matrix
    1984            0 :   tail = op%sumtails
    1985              : !  CALL MatrixHybComplex_init(checkMatrix,op%iTech,size=tail,Wmax=op%samples)
    1986              : !  CALL MatrixHybComplex_setSize(checkMatrix,tail)
    1987              : 
    1988              :   ! --- set size of the matrix
    1989            0 :   CALL MatrixHybComplex_setSize(op%M_update,tail)
    1990              : 
    1991              :   ! --- compute useful quantities
    1992            0 :   beta   =  op%beta
    1993            0 :   mbeta_two = -beta*0.5d0
    1994            0 :   op%checkNumber = op%checkNumber + 1
    1995            0 :   IF ( tail .NE. op%M%tail ) THEN
    1996            0 :     CALL WARN("BathOperatoroffdiagComplex_checkM : tails are different          ")
    1997            0 :     RETURN
    1998              :   END IF
    1999              : 
    2000            0 :   do it=1,op%sumtails
    2001              :     !write(6,*) "        checkM begin M_update%mat_tau",(op%M_update%mat_tau(it,it1),it1=1,op%sumtails)
    2002              :   enddo
    2003              :   ! --- build matrix
    2004              : !CALL ListCdagC_print(particle)
    2005            0 :   DO iflavora = 1, op%flavors
    2006            0 :   DO iCdag = 1, op%tails(iflavora)
    2007            0 :     tCdag  = particle(iflavora)%list(iCdag,Cdag_)
    2008              :       !write(6,*) "         checkM a",iflavora,tCdag
    2009            0 :     DO iflavorb = 1, op%flavors
    2010            0 :     DO iC  = 1, op%tails(iflavorb)
    2011              :       !tC   = particle%list(C_,iC).MOD.beta
    2012            0 :       MODCYCLE(particle(iflavorb)%list(iC,C_),beta,tC) ! tC is tC, or Tc-Beta if tc>beta
    2013              :       !write(6,*) "         checkM b",iflavorb,tC
    2014            0 :       time = tC - tCdag  ! time is positive or negative but lower than beta
    2015              :       !write(6,*) "         checkM time",time
    2016              : 
    2017              : #include "BathOperatoroffdiagComplex_hybrid"
    2018              : 
    2019            0 :       op%M_update%mat(op%Fshift(iflavorb)+iC,op%Fshift(iflavora)+iCdag) = hybrid
    2020              : 
    2021            0 :       time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    2022            0 :       op%M_update%mat_tau(op%Fshift(iflavora)+iCdag,op%Fshift(iflavorb)+iC) = INT ( (time*op%inv_dt) +1.5d0 )
    2023              :       !write(6,*) "         checkM mat_tau",INT ( (time*op%inv_dt) +1.5d0 )
    2024              :       !write(6,*) "         checkM shifts",op%Fshift(iflavorb),iCdag,op%Fshift(iflavora),iC
    2025              :     END DO ! iC
    2026              :     END DO ! iflavorb
    2027              :   END DO ! iCdag
    2028              :   END DO ! iflavora
    2029              : 
    2030              : !    CALL MatrixHybComplex_Print(checkMatrix)
    2031              :   ! --- Inverse matrix
    2032            0 :   CALL MatrixHybComplex_inverse(op%M_update)
    2033              : 
    2034              : !    CALL MatrixHybComplex_Print(checkMatrix)
    2035            0 :   do it=1,op%sumtails
    2036              :     !write(6,*) "        checkM end M_update%mat_tau",(op%M_update%mat_tau(it,it1),it1=1,op%sumtails)
    2037              :   enddo
    2038              :   do it=1,op%sumtails
    2039              :     !write(6,*) "        checkM end M_update",(op%M%mat(it,it1),it1=1,op%sumtails)
    2040              :   enddo
    2041              : 
    2042              :   ! --- Compare M_update and M to check if calculation of M is correct
    2043              :   sumMmat =cmplx(0.d0,0.d0,kind=8)
    2044              :   sumCheck=cmplx(0.d0,0.d0,kind=8)
    2045              :   error1 = 0.d0
    2046              :   errormax = 0.d0
    2047              :   checkTau = .FALSE.
    2048            0 :   DO iCdag = 1, tail
    2049            0 :     Do iC =1, tail
    2050              :         errorrel= ABS((op%M_update%mat(iC, iCdag) - &
    2051            0 :                   op%M%mat(iC,iCdag))/op%M_update%mat(iC,iCdag))
    2052              :         errorabs= ABS(op%M_update%mat(iC, iCdag) - &
    2053            0 :                   op%M%mat(iC,iCdag))
    2054            0 :         IF ( errorrel .gt. errormax .and. errorabs .gt. 0.001d0 ) errormax = errorrel
    2055              :                  ! write(6,*) "     checkM ", errorrel,errorabs
    2056            0 :         IF ( op%M_update%mat_tau(iC,iCdag) .NE. op%M%mat_tau(iC,iCdag) ) then
    2057            0 :                 checkTau = .TRUE.
    2058              :                 !write(6,*) "op%M_update%mat_tau(iC,iCdag), op%M%mat_tau(iC,iCdag)",op%M_update%mat_tau(iC,iCdag), op%M%mat_tau(iC,iCdag)
    2059              :                 !call flush(6)
    2060            0 :          CALL ERROR("BathOperatoroffdiagComplex_checkM : "//a//"%                        ")
    2061              :         ENDIF
    2062              : 
    2063              :     END DO
    2064              :   END DO
    2065              : 
    2066            0 :   IF ( checkTau .EQV. .TRUE. ) THEN
    2067            0 :     CALL WARN("BathOperatoroffdiagComplex_checkM : mat_tau differs should be")
    2068            0 :     CALL MatrixHybComplex_print(op%M_update,opt_print=1)
    2069            0 :     CALL WARN("BathOperatoroffdiagComplex_checkM : whereas it is")
    2070            0 :     CALL MatrixHybComplex_print(op%M,opt_print=1)
    2071              :   END IF
    2072            0 :   op%meanError = op%meanError + errormax
    2073            0 :   IF ( errormax .GT. 1.d0 ) THEN
    2074            0 :     WRITE(a,'(I4)') INT(error1*100.d0)
    2075              :     !write(6,'(I4)') INT(error1*100.d0)
    2076              : !    CALL MatrixHybComplex_Print(op%M)
    2077            0 :     CALL WARN("BathOperatoroffdiagComplex_checkM")
    2078              :   END IF
    2079              : !  CALL MatrixHybComplex_destroy(checkMatrix)
    2080              : END SUBROUTINE BathOperatoroffdiagComplex_checkM
    2081              : !!***
    2082              : 
    2083              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_recomputeM
    2084              : !! NAME
    2085              : !!  BathOperatoroffdiagComplex_recomputeM
    2086              : !!
    2087              : !! FUNCTION
    2088              : !!  compute from scratch the M matrix
    2089              : !!
    2090              : !! COPYRIGHT
    2091              : !!  Copyright (C) 2013-2025 ABINIT group (B. Amadon)
    2092              : !!  This file is distributed under the terms of the
    2093              : !!  GNU General Public License, see ~abinit/COPYING
    2094              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    2095              : !!
    2096              : !! INPUTS
    2097              : !!  op=bath operator
    2098              : !!  particle=list of all segments of the active flavor
    2099              : !!
    2100              : !! OUTPUT
    2101              : !!
    2102              : !! SIDE EFFECTS
    2103              : !!
    2104              : !! NOTES
    2105              : !!
    2106              : !! SOURCE
    2107              : 
    2108            0 : SUBROUTINE BathOperatoroffdiagComplex_recomputeM(op,particle,flav_i,flav_j)
    2109              : 
    2110              : !Arguments ------------------------------------
    2111              :   TYPE(BathOperatoroffdiagComplex) , INTENT(INOUT) :: op
    2112              :   TYPE(ListCdagC)    , INTENT(IN   ) :: particle(:)
    2113              :   INTEGER :: flav_i,flav_j
    2114              : !Local variables ------------------------------
    2115              : !  TYPE(MatrixHybComplex)                    :: checkMatrix
    2116              :   INTEGER :: tail
    2117              :   INTEGER :: iC
    2118              :   INTEGER :: iCdag
    2119              :   INTEGER :: aF
    2120              :   INTEGER :: iflavora
    2121              :   INTEGER :: iflavorb,it !,it1
    2122              :   INTEGER :: iflavora_imp
    2123              :   INTEGER :: iflavorb_imp
    2124              :   !CHARACTER(LEN=6) :: a
    2125              :   DOUBLE PRECISION :: time
    2126              :   DOUBLE PRECISION :: beta
    2127              :   DOUBLE PRECISION :: mbeta_two
    2128              :   DOUBLE PRECISION :: tc
    2129              :   DOUBLE PRECISION :: tCdag
    2130              :   !DOUBLE PRECISION :: sumMmat
    2131              :   !DOUBLE PRECISION :: sumCheck
    2132              : #include "BathOperatoroffdiagComplex_hybrid.h"
    2133              : 
    2134            0 :   aF = op%activeFlavor
    2135              :   !Construction de la matrix
    2136            0 :   tail = op%sumtails
    2137              : !  CALL MatrixHybComplex_init(checkMatrix,op%iTech,size=tail,Wmax=op%samples)
    2138              : !  CALL MatrixHybComplex_setSize(checkMatrix,tail)
    2139              : 
    2140              :   ! --- set size of the matrix
    2141            0 :   CALL MatrixHybComplex_setSize(op%M_update,tail)
    2142              : 
    2143              :   ! --- compute useful quantities
    2144            0 :   beta   =  op%beta
    2145            0 :   mbeta_two = -beta*0.5d0
    2146            0 :   op%checkNumber = op%checkNumber + 1
    2147            0 :   IF ( tail .NE. op%M%tail ) THEN
    2148            0 :     CALL WARN("BathOperatoroffdiagComplex_checkM : tails are different          ")
    2149            0 :     RETURN
    2150              :   END IF
    2151              : 
    2152            0 :   do it=1,op%sumtails
    2153              :     !write(6,*) "        checkM begin M_update%mat_tau",(op%M_update%mat_tau(it,it1),it1=1,op%sumtails)
    2154              :   enddo
    2155              :   ! --- build matrix
    2156              : !CALL ListCdagC_print(particle)
    2157            0 :   DO iflavora = 1, op%flavors
    2158            0 :     iflavora_imp=iflavora
    2159            0 :     if(iflavora==flav_i) iflavora_imp=flav_j
    2160            0 :     if(iflavora==flav_j) iflavora_imp=flav_i
    2161            0 :     DO iCdag = 1, op%tails(iflavora_imp)
    2162            0 :       tCdag  = particle(iflavora_imp)%list(iCdag,Cdag_)
    2163              :         !write(6,*) "         checkM a",iflavora,tCdag
    2164            0 :       DO iflavorb = 1, op%flavors
    2165            0 :         iflavorb_imp=iflavorb
    2166            0 :         if(iflavorb==flav_j) iflavorb_imp=flav_i
    2167            0 :         if(iflavorb==flav_i) iflavorb_imp=flav_j
    2168            0 :         DO iC  = 1, op%tails(iflavorb_imp)
    2169              :           !tC   = particle%list(C_,iC).MOD.beta
    2170            0 :           MODCYCLE(particle(iflavorb_imp)%list(iC,C_),beta,tC) ! tC is tC, or Tc-Beta if tc>beta
    2171              :           !write(6,*) "         checkM b",iflavorb,tC
    2172            0 :           time = tC - tCdag  ! time is positive or negative but lower than beta
    2173              :           !write(6,*) "         checkM time",time
    2174              : 
    2175              : #include "BathOperatoroffdiagComplex_hybrid"
    2176              : 
    2177            0 :           op%M_update%mat(op%Fshift(iflavorb_imp)+iC,op%Fshift(iflavora_imp)+iCdag) = hybrid
    2178              : 
    2179            0 :           time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    2180            0 :           op%M_update%mat_tau(op%Fshift(iflavora_imp)+iCdag,op%Fshift(iflavorb_imp)+iC) = INT ( (time*op%inv_dt) +1.5d0 )
    2181              :           !write(6,*) "         checkM mat_tau",INT ( (time*op%inv_dt) +1.5d0 )
    2182              :           !write(6,*) "         checkM shifts",op%Fshift(iflavorb),iCdag,op%Fshift(iflavora),iC
    2183              :         END DO ! iC
    2184              :       END DO ! iflavorb
    2185              :     END DO ! iCdag
    2186              :   END DO ! iflavora
    2187              : 
    2188              : !    CALL MatrixHybComplex_Print(checkMatrix)
    2189              :   ! --- Inverse matrix
    2190            0 :   CALL MatrixHybComplex_inverse(op%M_update)
    2191              : 
    2192              : !    CALL MatrixHybComplex_Print(checkMatrix)
    2193            0 :   do it=1,op%sumtails
    2194              :     !write(6,*) "        checkM end M_update%mat_tau",(op%M_update%mat_tau(it,it1),it1=1,op%sumtails)
    2195              :   enddo
    2196              :   do it=1,op%sumtails
    2197              :     !write(6,*) "        checkM end M_update",(op%M%mat(it,it1),it1=1,op%sumtails)
    2198              :   enddo
    2199              : 
    2200              :   ! --- Compare M_update and M to check if calculation of M is correct
    2201              : END SUBROUTINE BathOperatoroffdiagComplex_recomputeM
    2202              : !!***
    2203              : 
    2204              : !!****f* ABINIT/m_BathOperatoroffdiagComplex/BathOperatoroffdiagComplex_getError
    2205              : !! NAME
    2206              : !!  BathOperatoroffdiagComplex_getError
    2207              : !!
    2208              : !! FUNCTION
    2209              : !!  compute a percentage error / checkM
    2210              : !!
    2211              : !! COPYRIGHT
    2212              : !!  Copyright (C) 2013-2025 ABINIT group (J. Bieder)
    2213              : !!  This file is distributed under the terms of the
    2214              : !!  GNU General Public License, see ~abinit/COPYING
    2215              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    2216              : !!
    2217              : !! INPUTS
    2218              : !!  op=bath operator
    2219              : !!
    2220              : !! OUTPUT
    2221              : !!  BathOperatoroffdiagComplex_getError=Error in percent
    2222              : !!
    2223              : !! SIDE EFFECTS
    2224              : !!
    2225              : !! NOTES
    2226              : !!
    2227              : !! SOURCE
    2228              : 
    2229            0 : DOUBLE PRECISION FUNCTION BathOperatoroffdiagComplex_getError(op)
    2230              : 
    2231              :   TYPE(BathOperatoroffdiagComplex), INTENT(IN) :: op
    2232              : 
    2233            0 :   IF ( op%doCheck .EQV. .TRUE. ) THEN
    2234            0 :     BathOperatoroffdiagComplex_getError = op%meanError / DBLE(op%checkNumber)
    2235              :   ELSE
    2236              :     BathOperatoroffdiagComplex_getError = 0.d0
    2237              :   END IF
    2238            0 : END FUNCTION BathOperatoroffdiagComplex_getError
    2239              : !!***
    2240              : !#endif
    2241              : 
    2242            0 : END MODULE m_BathOperatoroffdiagComplex
    2243              : !!***
        

Generated by: LCOV version 2.3-1