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

Generated by: LCOV version 2.3-1