LCOV - code coverage report
Current view: top level - src/62_ctqmc - m_BathOperator.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.6 % 406 319
Test Date: 2026-09-20 15:27:41 Functions: 68.4 % 19 13

            Line data    Source code
       1              : 
       2              : #if defined HAVE_CONFIG_H
       3              : #include "config.h"
       4              : #endif
       5              : !!****m* ABINIT/m_BathOperator
       6              : !! NAME
       7              : !!  m_BathOperator
       8              : !!
       9              : !! FUNCTION
      10              : !!  Manage all stuff related to the bath for the
      11              : !!  simgle Anderson Impurity Model
      12              : !!
      13              : !! COPYRIGHT
      14              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
      15              : !!  This file is distributed under the terms of the
      16              : !!  GNU General Public License, see ~abinit/COPYING
      17              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      18              : !!
      19              : !! NOTES
      20              : !!
      21              : !! SOURCE
      22              : 
      23              : #include "defs.h"
      24              : MODULE m_BathOperator
      25              : USE m_MatrixHyb
      26              : USE m_Vector
      27              : USE m_VectorInt
      28              : USE m_Global
      29              : USE m_ListCdagC
      30              : 
      31              : IMPLICIT NONE
      32              : 
      33              : !!***
      34              : 
      35              : PRIVATE
      36              : 
      37              : !!****t* m_BathOperator/BathOperator
      38              : !! NAME
      39              : !!  BathOperator
      40              : !!
      41              : !! FUNCTION
      42              : !!  This structured datatype contains the necessary data
      43              : !!
      44              : !! COPYRIGHT
      45              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
      46              : !!  This file is distributed under the terms of the
      47              : !!  GNU General Public License, see ~abinit/COPYING
      48              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      49              : !!
      50              : !! SOURCE
      51              : 
      52              : TYPE, PUBLIC :: BathOperator
      53              :   LOGICAL _PRIVATE :: set         = .FALSE.
      54              :   LOGICAL          :: MAddFlag    = .FALSE. ! Set to true if we can compute a new M (see updateDetXX)
      55              :   LOGICAL          :: MRemoveFlag = .FALSE. ! Set to true if we can compute a new M (see updateDetXX)
      56              :   LOGICAL _PRIVATE :: antiShift   = .FALSE. ! shift when M is updated with antiseg
      57              :   LOGICAL _PRIVATE :: doCheck     = .FALSE.
      58              :   INTEGER _PRIVATE :: flavors
      59              :   INTEGER          :: activeFlavor
      60              :   INTEGER _PRIVATE :: samples
      61              :   INTEGER _PRIVATE :: sizeHybrid
      62              :   INTEGER _PRIVATE :: updatePosRow
      63              :   INTEGER _PRIVATE :: updatePosCol
      64              :   INTEGER _PRIVATE :: iTech
      65              :   INTEGER _PRIVATE :: checkNumber
      66              :   DOUBLE PRECISION _PRIVATE                   :: beta
      67              :   DOUBLE PRECISION _PRIVATE                   :: dt
      68              :   DOUBLE PRECISION _PRIVATE                   :: inv_dt
      69              :   DOUBLE PRECISION _PRIVATE                   :: meanError
      70              :   DOUBLE PRECISION _PRIVATE                   :: S
      71              :   DOUBLE PRECISION _PRIVATE                   :: Stau
      72              :   DOUBLE PRECISION _PRIVATE                   :: Stilde
      73              :   TYPE(Vector)     _PRIVATE                   :: R
      74              :   TYPE(Vector)     _PRIVATE                   :: Q
      75              :   TYPE(Vector)     _PRIVATE                   :: Rtau
      76              :   TYPE(Vector)     _PRIVATE                   :: Qtau
      77              :   DOUBLE PRECISION, ALLOCATABLE, DIMENSION(:,:) _PRIVATE :: F ! sample,Flavors
      78              :   TYPE(MatrixHyb) , ALLOCATABLE, DIMENSION(:)            :: M  ! Flavors
      79              :   TYPE(MatrixHyb) , ALLOCATABLE, DIMENSION(:)   _PRIVATE :: M_update  ! Flavors
      80              : END TYPE BathOperator
      81              : !!***
      82              : 
      83              : PUBLIC  :: BathOperator_init
      84              : PUBLIC  :: BathOperator_reset
      85              : PUBLIC  :: BathOperator_activateParticle
      86              : PRIVATE :: BathOperator_hybrid
      87              : PUBLIC  :: BathOperator_getDetAdd
      88              : PUBLIC  :: BathOperator_getDetRemove
      89              : PUBLIC  :: BathOperator_getDetF
      90              : PUBLIC  :: BathOperator_setMAdd
      91              : PUBLIC  :: BathOperator_setMRemove
      92              : PUBLIC  :: BathOperator_swap
      93              : PUBLIC  :: BathOperator_initF
      94              : PUBLIC  :: BathOperator_setF
      95              : PUBLIC  :: BathOperator_printF
      96              : PUBLIC  :: BathOperator_printM
      97              : PUBLIC  :: BathOperator_destroy
      98              : PUBLIC  :: BathOperator_doCheck
      99              : PRIVATE :: BathOperator_checkM
     100              : PUBLIC  :: BathOperator_getError
     101              : 
     102              : CONTAINS
     103              : !!***
     104              : 
     105              : !!****f* ABINIT/m_BathOperator/BathOperator_init
     106              : !! NAME
     107              : !!  BathOperator_init
     108              : !!
     109              : !! FUNCTION
     110              : !!  Initialize and allocate data
     111              : !!
     112              : !! COPYRIGHT
     113              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     114              : !!  This file is distributed under the terms of the
     115              : !!  GNU General Public License, see ~abinit/COPYING
     116              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     117              : !!
     118              : !! INPUTS
     119              : !!  this=bath object
     120              : !!  flavors=numbers of flavors we have (including spin)
     121              : !!  samples=Time slices in the input file
     122              : !!  beta=inverse temperature
     123              : !!  iTech=imaginary time or frequencies
     124              : !!  It is imposes to imaginary time
     125              : !!
     126              : !! OUTPUT
     127              : !!
     128              : !! SIDE EFFECTS
     129              : !!
     130              : !! NOTES
     131              : !!
     132              : !! SOURCE
     133              : 
     134          102 : SUBROUTINE BathOperator_init(this, flavors, samples, beta, iTech)
     135              : 
     136              : !Arguments ------------------------------------
     137              :   TYPE(BathOperator), INTENT(INOUT) :: this
     138              :   INTEGER           , INTENT(IN   ) :: flavors
     139              :   INTEGER           , INTENT(IN   ) :: samples
     140              :   DOUBLE PRECISION  , INTENT(IN   ) :: beta
     141              : !Local variables ------------------------------
     142              :   INTEGER           , INTENT(IN   ) :: iTech
     143              :   INTEGER                           :: it
     144              : 
     145          102 :   this%MAddFlag     = .FALSE.
     146          102 :   this%MRemoveFlag  = .FALSE.
     147          102 :   this%flavors      = flavors
     148          102 :   this%beta         = beta
     149          102 :   this%samples      = samples
     150          102 :   this%sizeHybrid   = samples + 1
     151          102 :   this%dt      = beta / DBLE(samples)
     152          102 :   this%inv_dt  = DBLE(samples) / beta
     153          102 :   this%activeFlavor= 0
     154          102 :   this%updatePosRow = 0
     155          102 :   this%updatePosCol = 0
     156          102 :   this%iTech        = iTech
     157              : !#ifdef CTQMC_CHECK
     158          102 :   this%checkNumber  = 0
     159          102 :   this%meanError    = 0.d0
     160          102 :   this%doCheck = .FALSE.
     161              : !#endif
     162              : 
     163          102 :   FREEIF(this%F)
     164          408 :   MALLOC(this%F,(1:this%sizeHybrid+1,1:flavors))
     165          102 :   DT_FREEIF(this%M)
     166         1382 :   DT_MALLOC(this%M,(1:flavors))
     167          102 :   DT_FREEIF(this%M_update)
     168         1280 :   DT_MALLOC(this%M_update,(1:flavors))
     169              : 
     170          102 :   CALL Vector_init(this%R,100)
     171          102 :   CALL Vector_init(this%Q,100)
     172          102 :   CALL Vector_init(this%Rtau,100)
     173          102 :   CALL Vector_init(this%Qtau,100)
     174              : 
     175         1178 :   DO it = 1, flavors
     176         1076 :     CALL MatrixHyb_init(this%M(it),this%iTech,size=Global_SIZE,Wmax=samples) !FIXME Should be consistent with ListCagC
     177         1178 :     CALL MatrixHyb_init(this%M_update(it),this%iTech,size=Global_SIZE,Wmax=samples) !FIXME Should be consistent with ListCagC
     178              :   END DO
     179       327130 :   this%F       = 0.d0
     180          102 :   this%set     = .TRUE.
     181              : 
     182          102 : END SUBROUTINE BathOperator_init
     183              : !!***
     184              : 
     185              : !!****f* ABINIT/m_BathOperator/BathOperator_reset
     186              : !! NAME
     187              : !!  BathOperator_reset
     188              : !!
     189              : !! FUNCTION
     190              : !!  Reset all internal variables
     191              : !!
     192              : !! COPYRIGHT
     193              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     194              : !!  This file is distributed under the terms of the
     195              : !!  GNU General Public License, see ~abinit/COPYING
     196              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     197              : !!
     198              : !! INPUTS
     199              : !!  this=bath operator to reset
     200              : !!
     201              : !! OUTPUT
     202              : !!
     203              : !! SIDE EFFECTS
     204              : !!
     205              : !! NOTES
     206              : !!
     207              : !! SOURCE
     208              : 
     209           49 : SUBROUTINE BathOperator_reset(this)
     210              : 
     211              : !Arguments ------------------------------------
     212              :   TYPE(BathOperator), INTENT(INOUT) :: this
     213              : !Local variables ------------------------------
     214              :   INTEGER                           :: it
     215           49 :   this%MAddFlag     = .FALSE.
     216           49 :   this%MRemoveFlag  = .FALSE.
     217           49 :   this%activeFlavor = 0
     218           49 :   this%updatePosRow = 0
     219           49 :   this%updatePosCol = 0
     220              : !#ifdef CTQMC_CHECK
     221           49 :   this%checkNumber  = 0
     222           49 :   this%meanError    = 0.d0
     223              : !#endif
     224           49 :   this%doCheck = .FALSE.
     225           49 :   CALL Vector_clear(this%R)
     226           49 :   CALL Vector_clear(this%Q)
     227           49 :   CALL Vector_clear(this%Rtau)
     228           49 :   CALL Vector_clear(this%Qtau)
     229              : 
     230          567 :   DO it = 1, this%flavors
     231          567 :     CALL MatrixHyb_clear(this%M(it)) !FIXME Should be consistent with ListCagC
     232              :   END DO
     233       153503 :   this%F       = 0.d0
     234              : 
     235           49 : END SUBROUTINE BathOperator_reset
     236              : !!***
     237              : 
     238              : !!****f* ABINIT/m_BathOperator/BathOperator_activateParticle
     239              : !! NAME
     240              : !!  BathOperator_activateParticle
     241              : !!
     242              : !! FUNCTION
     243              : !!  Just save on wicht flavor we are working
     244              : !!  It is better to use the macro defined in defs.h
     245              : !!
     246              : !! COPYRIGHT
     247              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     248              : !!  This file is distributed under the terms of the
     249              : !!  GNU General Public License, see ~abinit/COPYING
     250              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     251              : !!
     252              : !! INPUTS
     253              : !!  this=bath operator
     254              : !!  flavor=the flavor to activate
     255              : !!
     256              : !! OUTPUT
     257              : !!
     258              : !! SIDE EFFECTS
     259              : !!
     260              : !! NOTES
     261              : !!
     262              : !! SOURCE
     263              : 
     264            0 : SUBROUTINE BathOperator_activateParticle(this,flavor)
     265              : 
     266              : !Arguments ------------------------------------
     267              :   TYPE(BathOperator), INTENT(INOUT) :: this
     268              : !Local variables ------------------------------
     269              :   INTEGER           , INTENT(IN   ) :: flavor
     270              : 
     271            0 :   IF ( flavor .GT. this%flavors ) &
     272            0 :     CALL ERROR("BathOperator_activateParticle : out of range      ")
     273            0 :   IF ( this%set .EQV. .TRUE. .AND. ALLOCATED(this%M) ) THEN
     274            0 :     this%activeFlavor =  flavor
     275            0 :     this%MAddFlag     = .FALSE.
     276            0 :     this%MRemoveFlag  = .FALSE.
     277              :   ELSE
     278            0 :     CALL ERROR("BathOperator_activateParticle : not allocated      ")
     279              :   END IF
     280            0 : END SUBROUTINE BathOperator_activateParticle
     281              : !!***
     282              : 
     283              : !!****f* ABINIT/m_BathOperator/BathOperator_hybrid
     284              : !! NAME
     285              : !!  BathOperator_hybrid
     286              : !!
     287              : !! FUNCTION
     288              : !!  Compute the hybridization for the active flavor
     289              : !!  at time time
     290              : !!
     291              : !! COPYRIGHT
     292              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     293              : !!  This file is distributed under the terms of the
     294              : !!  GNU General Public License, see ~abinit/COPYING
     295              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     296              : !!
     297              : !! INPUTS
     298              : !!  this=bath operator
     299              : !!  time=time  F(time)
     300              : !!
     301              : !! OUTPUT
     302              : !!
     303              : !! SIDE EFFECTS
     304              : !!
     305              : !! NOTES
     306              : !!
     307              : !! SOURCE
     308              : 
     309              : DOUBLE PRECISION FUNCTION BathOperator_hybrid(this,time)
     310              : 
     311              :   TYPE(BathOperator), INTENT(IN) :: this
     312              :   DOUBLE PRECISION  , INTENT(IN) :: time
     313              : #include "BathOperator_hybrid.h"
     314              : 
     315              :   IF ( this%activeFlavor .LE. 0 ) &
     316              :     CALL ERROR("BathOperator_hybrid : no active hybrid func        ")
     317              : #include "BathOperator_hybrid"
     318              :   BathOperator_hybrid = hybrid
     319              : 
     320              : END FUNCTION BathOperator_hybrid
     321              : !!***
     322              : 
     323              : !!****f* ABINIT/m_BathOperator/BathOperator_getDetAdd
     324              : !! NAME
     325              : !!  BathOperator_getDetAdd
     326              : !!
     327              : !! FUNCTION
     328              : !!  Compute the determinant ratio when a (anti)segment
     329              : !!  is trying to be added and store some array for setMadd
     330              : !!
     331              : !! COPYRIGHT
     332              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     333              : !!  This file is distributed under the terms of the
     334              : !!  GNU General Public License, see ~abinit/COPYING
     335              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     336              : !!
     337              : !! INPUTS
     338              : !!  this=bath operator
     339              : !!  CdagC_1=segment to be added
     340              : !!  position=ordered position of the Cdag time
     341              : !!  particle=full list of CdagC for activeFlavor
     342              : !!
     343              : !! OUTPUT
     344              : !!  BathOperator_getDetAdd=the det
     345              : !!
     346              : !! SIDE EFFECTS
     347              : !!
     348              : !! NOTES
     349              : !!
     350              : !! SOURCE
     351    511203414 : DOUBLE PRECISION  FUNCTION BathOperator_getDetAdd(this,CdagC_1, position, particle)
     352              : 
     353              : !Arguments ------------------------------------
     354              :   TYPE(BathOperator)      , INTENT(INOUT) :: this
     355              :   DOUBLE PRECISION, DIMENSION(1:2), INTENT(IN   ) :: CdagC_1
     356              :   INTEGER                 , INTENT(IN   ) :: position
     357              :   TYPE(ListCdagC), INTENT(IN   ) :: particle
     358              : !Local variables-------------------------------
     359              :   INTEGER                                 :: it1
     360              :   INTEGER                                 :: it2
     361              :   INTEGER                                 :: it3
     362              :   INTEGER                                 :: tail
     363              :   INTEGER                                 :: new_tail
     364              :   DOUBLE PRECISION                        :: C
     365              :   DOUBLE PRECISION                        :: Cbeta
     366              :   DOUBLE PRECISION                        :: Cibeta
     367              :   DOUBLE PRECISION                        :: Cdag
     368              :   DOUBLE PRECISION                        :: Cdagbeta
     369              :   DOUBLE PRECISION                        :: beta
     370              :   DOUBLE PRECISION                        :: ratio
     371              :   DOUBLE PRECISION                        :: time
     372              : !  TYPE(CdagC)    , POINTER, DIMENSION(:)  :: list => NULL()
     373              : #include "BathOperator_hybrid.h"
     374              : 
     375    511203414 :   this%antiShift = .FALSE.
     376    511203414 :   beta     = this%beta
     377    511203414 :   C        =  CdagC_1(C_)
     378              : !  Cbeta    = C.MOD.beta
     379    511203414 :   MODCYCLE(C,beta,Cbeta)
     380    511203414 :   Cdag     =  CdagC_1(Cdag_)
     381              : !  cdagbeta = Cdag.MOD.beta
     382    511203414 :   MODCYCLE(Cdag,beta,CdagBeta)
     383              : !  IF ( Cdag .GE. beta ) &
     384              : !    CALL ERROR("BathOperator_getDetAdd : bad case ...              ")
     385    511203414 :   IF ( this%activeFlavor .LE. 0 ) &
     386            0 :     CALL ERROR("BathOperator_getDetAdd : no active hybrid function ")
     387              : 
     388    511203414 :   tail =  particle%tail
     389    511203414 :   new_tail = tail+1
     390              : !  list => particle%list
     391              : 
     392              :   IF ( ((C .GT. Cdag) .AND. (position .EQ. -1)) &
     393    511203414 :        .OR. ((C .LT. Cdag) .AND. (tail .EQ. 0))) THEN ! Possible only if it is a segment
     394     88942177 :     this%updatePosRow = tail + 1
     395     88942177 :     this%updatePosCol = tail + 1
     396              :   ELSE
     397    422261237 :     this%updatePosRow  = ABS(position)
     398    422261237 :     this%updatePosCol  = ABS(position)
     399              :   END IF
     400              : 
     401              :   ! If antisegment, the det ratio has to be by -1 ( sign of the signature of one
     402              :   ! permutation line in the this
     403    511203414 :   IF ( C .LT. Cdag .AND. tail .GT. 0) THEN ! if antiseg
     404              :   !  ratio = -ratio
     405     45290271 :     this%updatePosRow  = (this%updatePosRow + 1) !position in [1;tail]
     406     45290271 :     IF ( CdagBeta .LT. particle%list(this%updatePosCol,Cdag_) ) this%antiShift = .TRUE.
     407              :   END IF
     408              : 
     409              : !  CALL Vector_setSize(this%R,tail)
     410              : !  CALL Vector_setSize(this%Q,tail)
     411    511203414 :   Vector_QuickResize(this%R,new_tail)
     412    511203414 :   Vector_QuickResize(this%Q,new_tail)
     413    511203414 :   Vector_QuickResize(this%Rtau,new_tail)
     414    511203414 :   Vector_QuickResize(this%Qtau,new_tail)
     415              : 
     416   1239633524 :   DO it1 = 1, tail
     417    728430110 :     it2 = it1 + ( 1+SIGN(1,it1-this%updatePosRow) )/2
     418    728430110 :     it3 = it1 + ( 1+SIGN(1,it1-this%updatePoscol) )/2
     419              : 
     420    728430110 :     this%Rtau%vec(it2)= C - particle%list(it1,Cdag_)
     421              :     !this%Rtau%vec(it1)= C - particle%list(it1,Cdag_)
     422    728430110 :     time = Cbeta - particle%list(it1,Cdag_)
     423              : #include "BathOperator_hybrid"
     424    728430110 :     this%R%vec(it1) = hybrid
     425              : !    this%R%vec(it) = BathOperator_hybrid(this, Cbeta - list(it)%Cdag)
     426              : !    Cibeta = list(it)%C.MOD.beta
     427    728430110 :     MODCYCLE(particle%list(it1,C_),beta,Cibeta)
     428    728430110 :     time = Cibeta - Cdagbeta
     429    728430110 :     this%Qtau%vec(it3)= time
     430              :     !this%Qtau%vec(it1)= time
     431              : #include "BathOperator_hybrid"
     432   1239633524 :     this%Q%vec(it1) = hybrid
     433              :     !this%Q%vec(it3) = hybrid
     434              : !    Q(it) = BathOperator_hybrid(this, Cibeta - Cdagbeta)
     435              :   END DO
     436              :   ! Compute S
     437    511203414 :   this%Stau = C - Cdagbeta
     438    511203414 :   this%Rtau%vec(this%updatePosRow) = this%Stau
     439    511203414 :   this%Qtau%vec(this%updatePosCol) = this%Rtau%vec(this%updatePosRow)
     440              : 
     441    511203414 :   time = Cbeta-Cdagbeta
     442              : #include "BathOperator_hybrid"
     443    511203414 :   this%S = hybrid
     444              : 
     445              :   !ratio = this%S - DOT_PRODUCT(MATMUL(this%R%vec(1:tail),this%M(this%activeFlavor)%mat(1:tail,1:tail)),this%Q%vec(1:tail))
     446    511203414 :   ratio = 0.d0
     447   1239633524 :   DO it1 = 1, tail
     448              :     time = 0.d0
     449   4091562908 :     DO it2 = 1, tail
     450   4091562908 :       time = time + this%R%vec(it2) * this%M(this%activeFlavor)%mat(it2,it1)
     451              :     END DO
     452   1239633524 :     ratio = ratio + this%Q%vec(it1) * time
     453              :   END DO
     454    511203414 :   ratio = this%S - ratio
     455              : 
     456    511203414 :   this%Stilde = 1.d0 / ratio
     457              : 
     458              :   ! This IF is the LAST "NON CORRECTION" in my opinion this should not appears.
     459              : !  IF ( MAX(C,Cdag) .GT. this%beta ) THEN
     460              : !    WRITE(*,*) this%Stilde
     461              : !    this%Stilde = - ABS(this%Stilde)
     462              : !  END IF
     463              : 
     464              :   ! If antisegment, the det ratio has to be by -1 ( sign of the signature of one
     465              :   ! permutation line in the this)
     466    511203414 :   IF ( C .LT. Cdag .AND. tail .GT. 0) THEN ! if antiseg
     467     45290271 :     ratio = -ratio
     468              :   ENDIF
     469              : 
     470    511203414 :   BathOperator_getDetAdd = ratio
     471    511203414 :   this%MAddFlag   = .TRUE.
     472              : !#ifdef CTQMC_CHECK
     473              : !  this%ListCdagC = particle
     474              : !!write(*,*) this%Stilde
     475              : !!write(*,*) this%antishift
     476              : !!write(*,*)    this%updatePosRow
     477              : !!write(*,*)    this%updatePosCol
     478              : !#endif
     479              : 
     480    511203414 : END FUNCTION BathOperator_getDetAdd
     481              : !!***
     482              : 
     483              : !!****f* ABINIT/m_BathOperator/BathOperator_getDetRemove
     484              : !! NAME
     485              : !!  BathOperator_getDetRemove
     486              : !!
     487              : !! FUNCTION
     488              : !!  Compute the determinant ratio when a (anti)segment
     489              : !!  is trying to be removed
     490              : !!
     491              : !! COPYRIGHT
     492              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     493              : !!  This file is distributed under the terms of the
     494              : !!  GNU General Public License, see ~abinit/COPYING
     495              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     496              : !!
     497              : !! INPUTS
     498              : !!  this=bath operator
     499              : !!  position=position of segment to be removed
     500              : !!
     501              : !! OUTPUT
     502              : !!  BathOperator_getDetRemove=the det
     503              : !!
     504              : !! SIDE EFFECTS
     505              : !!
     506              : !! NOTES
     507              : !!
     508              : !! SOURCE
     509              : 
     510    573945019 : DOUBLE PRECISION FUNCTION BathOperator_getDetRemove(this,position)
     511              : 
     512              : !Arguments ------------------------------------
     513              :   TYPE(BathOperator), INTENT(INOUT) :: this
     514              : !Local arguments-------------------------------
     515              :   INTEGER           , INTENT(IN   ) :: position
     516              :   INTEGER                           :: ABSposition
     517              :   INTEGER                           :: tail
     518              : 
     519    573945019 :   IF ( this%activeFlavor .LE. 0 ) &
     520            0 :     CALL ERROR("BathOperator_getDetRemove : no active hybrid fun  ")
     521              : 
     522    573945019 :   this%antiShift = .FALSE.
     523    573945019 :   tail         = this%M(this%activeFlavor)%tail
     524    573945019 :   ABSposition  = ABS(position)
     525    573945019 :   IF ( ABSposition .GT. tail ) &
     526            0 :     CALL ERROR("BathOperator_getDetRemove : position > M size     ")
     527    573945019 :   this%updatePosCol = ABSposition
     528    573945019 :   this%antiShift    = .FALSE.
     529    573945019 :   IF ( position .GT. 0 ) THEN
     530    286970080 :     this%updatePosRow = ABSposition
     531              :   ELSE
     532    286974939 :     this%updatePosRow = ABSposition+1
     533    286974939 :     IF ( ABSposition .EQ. tail ) THEN
     534    182719745 :       this%antiShift = .TRUE.
     535    182719745 :       this%updatePosRow = 1 !ABSposition - 1
     536              : !      this%updatePosRow = ABSposition
     537              : !      IF ( this%updatePosCol .EQ. 0) this%updatePosCol = tail
     538              :     END IF
     539              :   ENDIF
     540    573945019 :   this%Stilde                 = this%M(this%activeflavor)%mat(this%updatePosRow,this%updatePosCol)
     541    573945019 :   this%MRemoveFlag            = .TRUE.
     542    573945019 :   BathOperator_getDetRemove = this%Stilde
     543              : 
     544              :   ! If remove an antiseg , the det ratio has to be multiplied by -1
     545    573945019 :   IF ( position .LT. 0 .AND. tail .GT. 1 ) &
     546    160672199 :     BathOperator_getDetRemove = - BathOperator_getDetRemove
     547              : !#ifdef CTQMC_CHECK
     548              : !  this%ListCdagC = particle
     549              : !!write(*,*) this%updatePosRow, this%updatePosCol, position
     550              : !!CALL ListCdagC_print(particle)
     551              : !#endif
     552              : 
     553    573945019 : END FUNCTION BathOperator_getDetRemove
     554              : !!***
     555              : 
     556              : !!****f* ABINIT/m_BathOperator/BathOperator_getDetF
     557              : !! NAME
     558              : !!  BathOperator_getDetF
     559              : !!
     560              : !! FUNCTION
     561              : !!  Compute the determinant of the F this
     562              : !!  using the hybridization of flavor and the
     563              : !!  segments of particle
     564              : !!
     565              : !! COPYRIGHT
     566              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     567              : !!  This file is distributed under the terms of the
     568              : !!  GNU General Public License, see ~abinit/COPYING
     569              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     570              : !!
     571              : !! INPUTS
     572              : !!  this=bath operator
     573              : !!  flavor=hybridization function to take
     574              : !!  particles=segments to use
     575              : !!
     576              : !! OUTPUT
     577              : !!  BathOperator_getDetF=the det
     578              : !!
     579              : !! SIDE EFFECTS
     580              : !!
     581              : !! NOTES
     582              : !!
     583              : !! SOURCE
     584              : 
     585       457160 : DOUBLE PRECISION FUNCTION BathOperator_getDetF(this,flavor,particle)
     586              : 
     587              : !Arguments ------------------------------------
     588              :   TYPE(BathOperator)       , INTENT(INOUT)      :: this
     589              :   INTEGER                  , INTENT(IN   )  :: flavor
     590              :   TYPE(ListCdagC), OPTIONAL, INTENT(IN   )  :: particle
     591              : !Local arguments-------------------------------
     592              :   INTEGER :: iCdag
     593              :   INTEGER :: iC
     594              :   INTEGER :: tail
     595              :   DOUBLE PRECISION :: time
     596              :   DOUBLE PRECISION :: tC
     597              :   DOUBLE PRECISION :: tCdag
     598              :   DOUBLE PRECISION :: beta
     599              :   DOUBLE PRECISION :: mbeta_two
     600              :   DOUBLE PRECISION :: signe
     601              :   DOUBLE PRECISION :: inv_dt
     602              : #include "BathOperator_hybrid.h"
     603              : 
     604       457160 :   BathOperator_getDetF = 1.d0 ! pour eviter des divisions par 0
     605       457160 :   IF ( PRESENT( particle ) ) THEN
     606       228580 :     tail = particle%tail
     607       228580 :     activeF = flavor
     608       228580 :     beta = this%beta
     609       228580 :     mbeta_two = -beta*0.5d0
     610       228580 :     inv_dt =  this%inv_dt
     611       228580 :     CALL MatrixHyb_setSize(this%M_update(flavor),tail)
     612       499199 :     DO iCdag = 1, tail
     613       270619 :       tCdag  = particle%list(iCdag,Cdag_)
     614      1192942 :       DO iC  = 1, tail
     615              :         !tC   = particle%list(C_,iC).MOD.beta
     616       693743 :         MODCYCLE(particle%list(iC,C_),beta,tC)
     617       693743 :         time = tC - tCdag
     618              : #include "BathOperator_hybrid"
     619       964362 :         this%M_update(flavor)%mat(iC,iCdag) = hybrid
     620              :       END DO
     621              :     END DO
     622              :     ! mat_tau needs to be transpose of ordered time mat (way of measuring
     623              :     ! G(tau))
     624       499199 :     DO iC  = 1, tail
     625       270619 :       tC   = particle%list(iC,C_)
     626      1192942 :       DO iCdag = 1, tail
     627       693743 :         tCdag  = particle%list(iCdag,Cdag_)
     628       693743 :         time = tC - tCdag
     629       693743 :         signe = SIGN(1.d0,time)
     630       693743 :         time = time + (signe-1.d0)*mbeta_two
     631       964362 :         this%M_update(flavor)%mat_tau(iCdag,iC) = INT( ( time * inv_dt ) + 1.5d0 )
     632              :       END DO
     633              :     END DO
     634       228580 :     CALL MatrixHyb_inverse(this%M_update(flavor),BathOperator_getDetF) ! calcul le det de la matrice et l'inverse
     635              :   ELSE
     636       228580 :     CALL MatrixHyb_getDet(this%M(flavor),BathOperator_getDetF) ! det M = 1/detF !
     637       228580 :     BathOperator_getDetF = 1.d0 / BathOperator_getDetF
     638              :   ENDIF
     639       457160 : END FUNCTION BathOperator_getDetF
     640              : !!***
     641              : 
     642              : !!****f* ABINIT/m_BathOperator/BathOperator_setMAdd
     643              : !! NAME
     644              : !!  BathOperator_setMAdd
     645              : !!
     646              : !! FUNCTION
     647              : !!  Update de M this inserting a row and a column
     648              : !!
     649              : !! COPYRIGHT
     650              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     651              : !!  This file is distributed under the terms of the
     652              : !!  GNU General Public License, see ~abinit/COPYING
     653              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     654              : !!
     655              : !! INPUTS
     656              : !!  this=bath operator
     657              : !!  particle=segments of active flavor
     658              : !!
     659              : !! OUTPUT
     660              : !!
     661              : !! SIDE EFFECTS
     662              : !!
     663              : !! NOTES
     664              : !!
     665              : !! SOURCE
     666              : 
     667     85920850 : SUBROUTINE BathOperator_setMAdd(this,particle)
     668              : 
     669              : !Arguments ------------------------------------
     670              :   TYPE(BathOperator), INTENT(INOUT) :: this
     671              :   TYPE(ListCdagC)   , INTENT(IN   ) :: particle
     672              : !Local variables ------------------------------
     673              :   INTEGER                           :: tail
     674              :   INTEGER                           :: new_tail
     675              :   INTEGER                           :: col
     676              :   INTEGER                           :: col_move
     677              :   INTEGER                           :: row_move
     678              :   INTEGER                           :: row
     679              :   INTEGER                           :: positionRow
     680              :   INTEGER                           :: positionCol
     681              :   INTEGER                           :: aF
     682              :   DOUBLE PRECISION                  :: Stilde
     683              :   DOUBLE PRECISION                  :: time
     684              :   DOUBLE PRECISION                  :: mbeta_two
     685              :   DOUBLE PRECISION                  :: inv_dt
     686     85920850 :   TYPE(Vector) :: vec_tmp
     687     85920850 :   TYPE(VectorInt) :: vecI_tmp
     688              :   INTEGER :: m
     689              :   INTEGER :: count
     690              :   INTEGER :: i
     691              :   INTEGER :: j
     692              :   INTEGER :: p
     693              : 
     694     85920850 :   IF ( this%MAddFlag .EQV. .FALSE. ) &
     695            0 :     CALL ERROR("BathOperator_setMAdd : MAddFlag turn off           ")
     696     85920850 :   af = this%activeFlavor
     697     85920850 :   IF ( aF .LE. 0 ) &
     698            0 :     CALL ERROR("BathOperator_setMAdd : no active hybrid function   ")
     699     85920850 :   tail     =  this%M(aF)%tail
     700     85920850 :   new_tail =  tail + 1
     701              : !CALL this_print(M)
     702              : 
     703     85920850 :   positionRow =  this%updatePosRow
     704     85920850 :   positionCol =  this%updatePosCol
     705     85920850 :   Stilde      =  this%Stilde
     706              : !  write(6,*) "before", positionRow, positionCol
     707              :   !CALL MatrixHyb_print(this%M(aF),opt_print=1)
     708     85920850 :   CALL MatrixHyb_setSize(this%M(aF),new_tail)
     709              : 
     710              :   ! Compute Qtilde with Q
     711              :   !this%Q%vec(1:tail) = (-1.d0) * MATMUL(this%M(aF)%mat(1:tail,1:tail),this%Q%vec(1:tail)) * Stilde
     712   2632197880 :   this%Q%vec(1:tail) = MATMUL(this%M(aF)%mat(1:tail,1:tail),this%Q%vec(1:tail))
     713              :   !this%Q%vec(PositionRow:new_tail) = EOSHIFT(this%Q%vec(PositionRow:new_tail), SHIFT=-1, BOUNDARY=-1.d0, DIM=1)
     714              : !  this%Qtau%vec(PositionCol:new_tail) = EOSHIFT(this%Qtau%vec(PositionCol:new_tail), SHIFT=-1, BOUNDARY=1.d0, DIM=1)
     715              : !  this%Qtau%vec(PositionCol) = this%Stau
     716              : 
     717              :   !Compute Rtilde with R and without multiplying by Stilde
     718              :   !this%R%vec(1:tail) = (-1.d0) * MATMUL(this%R%vec(1:tail),this%M(aF)%mat(1:tail,1:tail))
     719   2632197880 :   this%R%vec(1:tail) = MATMUL(this%R%vec(1:tail),this%M(aF)%mat(1:tail,1:tail))
     720              :   !this%R%vec(PositionCol:new_tail) = EOSHIFT(this%R%vec(PositionCol:new_tail), SHIFT=-1, BOUNDARY=-1.d0, DIM=1)
     721              : !  this%Rtau%vec(PositionRow:new_tail) = EOSHIFT(this%Rtau%vec(PositionRow:new_tail), SHIFT=-1, BOUNDARY=1.d0, DIM=1)
     722              : !  this%Rtau%vec(PositionRow) = this%Stau
     723              : 
     724              :   !Compute the new M this
     725              :   !this%M(aF)%mat(PositionRow:new_tail,1:new_tail) = &
     726              :   !                   EOSHIFT(this%M(aF)%mat(PositionRow:new_tail,1:new_tail),SHIFT=-1, BOUNDARY=0.d0, DIM=1)
     727              :   !this%M(aF)%mat(1:new_tail,PositionCol:new_tail) = &
     728              :   !                   EOSHIFT(this%M(aF)%mat(1:new_tail,PositionCol:new_tail),SHIFT=-1, BOUNDARY=0.d0, DIM=2)
     729              : ! ! this%M(aF)%mat(1:new_tail,1:new_tail) =  this%M(aF)%mat(1:new_tail,1:new_tail) + &
     730              : ! ! Stilde * MATMUL(RESHAPE(this%Q%vec(1:new_tail),(/ new_tail,1 /)),RESHAPE(this%R%vec(1:new_tail),(/ 1,new_tail /)))
     731              : 
     732              :   !this%M(aF)%mat_tau(PositionRow:new_tail,1:new_tail) = &
     733              :   !                   EOSHIFT(this%M(aF)%mat_tau(PositionRow:new_tail,1:new_tail),SHIFT=-1, BOUNDARY=0, DIM=1)
     734              :   !this%M(aF)%mat_tau(1:new_tail,PositionCol:new_tail) = &
     735              :   !                   EOSHIFT(this%M(aF)%mat_tau(1:new_tail,PositionCol:new_tail),SHIFT=-1, BOUNDARY=0, DIM=2)
     736              : 
     737     85920850 :   mbeta_two = -this%beta*0.5d0
     738     85920850 :   inv_dt = this%inv_dt
     739              :   !Shift mat_tau
     740              :   !update old m
     741    360855297 :   DO col=tail,1,-1
     742    274934447 :     col_move = col +  ( 1+SIGN(1,col-PositionCol) )/2
     743   2082328986 :     DO row=tail,1,-1
     744   1721473689 :       row_move = row +  ( 1+SIGN(1,row-PositionRow) )/2
     745   1721473689 :       this%M(aF)%mat_tau(row_move,col_move) = this%M(aF)%mat_tau(row,col)
     746   1996408136 :       this%M(aF)%mat(row_move,col_move) = this%M(aF)%mat(row,col) + this%Q%vec(row)*this%R%vec(col) * Stilde
     747              :     END DO
     748              :   END DO
     749              :   ! Add new stuff for new row
     750    360855297 :   DO row = 1, tail
     751    274934447 :     row_move = row +  ( 1+SIGN(1,row-PositionRow) )/2
     752    274934447 :     this%M(aF)%mat(row_move,PositionCol) = -this%Q%vec(row)*Stilde
     753    274934447 :     time = this%Rtau%vec(row)
     754    274934447 :     time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     755    360855297 :     this%M(aF)%mat_tau(row,PositionCol) = INT ( (time*inv_dt) +1.5d0 )
     756              :   END DO
     757              :   ! Add last time missing in the loops
     758     85920850 :   time = this%Rtau%vec(new_tail)
     759     85920850 :   time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     760     85920850 :   this%M(aF)%mat_tau(new_tail,PositionCol) = INT ( (time*inv_dt) +1.5d0 )
     761              :   ! Add new stuff for new col
     762    360855297 :   DO col = 1, tail
     763    274934447 :     col_move = col +  ( 1+SIGN(1,col-PositionCol) )/2
     764    274934447 :     this%M(aF)%mat(PositionRow,col_move) = -this%R%vec(col)*Stilde
     765    274934447 :     time = this%Qtau%vec(col)
     766    274934447 :     time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     767    360855297 :     this%M(aF)%mat_tau(PositionRow,col) = INT ( (time*inv_dt) +1.5d0 )
     768              :   END DO
     769              :   ! Add last time missing in the loops
     770     85920850 :   time = this%Qtau%vec(new_tail)
     771     85920850 :   time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     772     85920850 :   this%M(aF)%mat_tau(PositionRow,new_tail) = INT ( (time*inv_dt) +1.5d0 )
     773              : 
     774     85920850 :   this%M(aF)%mat(PositionRow,PositionCol) = Stilde
     775              : 
     776              :   !CALL MatrixHyb_print(this%M(aF),opt_print=1)
     777              : 
     778              : !  DO col = 1, new_tail
     779              : !    time = this%Rtau%vec(col)
     780              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     781              : !    this%M(aF)%mat_tau(col,PositionCol) = INT ( (time*inv_dt) +1.5d0 )
     782              : !    time = this%Qtau%vec(col)
     783              : !    time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     784              : !    this%M(aF)%mat_tau(PositionRow,Col) = INT ( (time*inv_dt) +1.5d0 )
     785              : !    time = this%R%vec(col)*Stilde
     786              : !    DO row = 1, new_tail
     787              : !      this%M(aF)%mat(row,col) = this%M(aF)%mat(row,col) + this%Q%vec(row)*time
     788              : !    END DO
     789              : !  END DO
     790              : 
     791              :   !col_move = new_tail
     792              :   !col      = tail
     793              :   !DO col_move = new_tail, 1, -1
     794              :   !  IF ( col_move .EQ. positionCol ) THEN
     795              :   !    ! on calcule rajoute Q tilde
     796              :   !    !row_move = new_tail
     797              :   !    row      = tail
     798              :   !    DO row_move = new_tail, 1, -1
     799              :   !      ! calcul itau
     800              :   !      IF ( row_move .EQ. positionRow ) THEN
     801              :   !        this%M(aF)%mat(row_move,col_move) = Stilde
     802              :   !        !time = this%Stau
     803              :   !      ELSE
     804              :   !        this%M(aF)%mat(row_move,col_move) = -this%Q%vec(row)*Stilde
     805              :   !        !time = this%Rtau%vec(row_move)
     806              :   !        row      = row      - 1
     807              :   !      END IF
     808              :   !      !time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     809              :   !      !this%M(aF)%mat_tau(row_move,col_move) = INT ( (time*inv_dt) +1.5d0 )
     810              :   !    END DO
     811              :   !    ! realignement des indices
     812              :   !  ELSE
     813              :   !    ! on calcule Ptilde
     814              :   !    !row_move = new_tail
     815              :   !    row      = tail
     816              :   !    DO row_move = new_tail, 1, -1
     817              :   !      IF ( row_move .EQ. positionRow ) THEN
     818              :   !        this%M(aF)%mat(row_move,col_move) = -this%R%vec(col) * Stilde
     819              :   !        ! calcul itau
     820              :   !        !time = this%Qtau%vec(col_move)
     821              :   !        !time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
     822              :   !        !this%M(aF)%mat_tau(row_move,col_move) = INT ( (time*inv_dt) +1.5d0 )
     823              :   !      ELSE
     824              :   !        this%M(aF)%mat(row_move,col_move) = this%M(aF)%mat(row,col) + this%Q%vec(row)*this%R%vec(col)*Stilde
     825              :   !        ! copy itau
     826              :   !        !this%M(aF)%mat_tau(row_move,col_move) = this%M(aF)%mat_tau(row,col)
     827              :   !        row      = row      - 1
     828              :   !      END IF
     829              :   !    END DO
     830              :   !    col      = col      - 1
     831              :   !  END IF
     832              :   !END DO
     833              : !  write(6,*) "after"
     834              : !  CALL MatrixHyb_print(this%M(aF),opt_print=1)
     835              : !CALL this_inverse(M)
     836              : !CALL MatrixHyb_print(M)
     837              : !CALL this_inverse(M)
     838              : 
     839     85920850 :   IF ( this%antiShift .EQV. .TRUE. ) THEN ! antisegment
     840      2859166 :     CALL Vector_init(vec_tmp,new_tail)
     841      2859166 :     CALL VectorInt_init(vecI_tmp,new_tail)
     842              :   ! Shift if necessary according to this%antishift
     843              :   ! shift DIM=2 (col)
     844      2859166 :     p = new_tail - 1
     845      2859166 :     m = 1
     846      2859166 :     count = 0
     847      5718332 :     DO WHILE ( count .NE. new_tail )
     848     16457108 :       vec_tmp%vec(1:new_tail) = this%M(aF)%mat(1:new_tail,m)
     849     16457108 :       vecI_tmp%vec(1:new_tail) = this%M(aF)%mat_tau(1:new_tail,m)
     850      2859166 :       i = m
     851              :       !j = m+p
     852      2859166 :       MODCYCLE(m+p, new_tail, j)
     853     13597942 :       DO WHILE (j .NE. m)
     854     83824528 :         this%M(aF)%mat(1:new_tail,i) = this%M(aF)%mat(1:new_tail,j)
     855     83824528 :         this%M(aF)%mat_tau(1:new_tail,i) = this%M(aF)%mat_tau(1:new_tail,j)
     856     10738776 :         i = j
     857     10738776 :         MODCYCLE(j+p, new_tail, j)
     858     10738776 :         count = count+1
     859              :       END DO
     860     16457108 :       this%M(aF)%mat(1:new_tail,i) = vec_tmp%vec(1:new_tail)
     861     16457108 :       this%M(aF)%mat_tau(1:new_tail,i) = vecI_tmp%vec(1:new_tail)
     862      2859166 :       count = count+1
     863      2859166 :       m = m+1
     864              :     END DO
     865              :     ! shift DIM=1 (row)
     866      5718332 :     p = new_tail - 1
     867              :     m = 1
     868              :     count = 0
     869      5718332 :     DO WHILE ( count .NE. new_tail)
     870     16457108 :       vec_tmp%vec(1:new_tail) = this%M(aF)%mat(m,1:new_tail)
     871     16457108 :       vecI_tmp%vec(1:new_tail) = this%M(aF)%mat_tau(m,1:new_tail)
     872      2859166 :       i = m
     873              :       !j = m+p
     874      2859166 :       MODCYCLE(m+p, new_tail, j)
     875     13597942 :       DO WHILE ( j .NE. m )
     876     83824528 :         this%M(aF)%mat(i,1:new_tail) = this%M(aF)%mat(j,1:new_tail)
     877     83824528 :         this%M(aF)%mat_tau(i,1:new_tail) = this%M(aF)%mat_tau(j,1:new_tail)
     878     10738776 :         i = j
     879     10738776 :         MODCYCLE(j+p, new_tail, j)
     880     10738776 :         count = count+1
     881              :       END DO
     882     16457108 :       this%M(aF)%mat(i,1:new_tail) = vec_tmp%vec(1:new_tail)
     883     16457108 :       this%M(aF)%mat_tau(i,1:new_tail) = vecI_tmp%vec(1:new_tail)
     884      2859166 :       count = count+1
     885      2859166 :       m = m+1
     886              :     END DO
     887      2859166 :     CALL Vector_destroy(vec_tmp)
     888      2859166 :     CALL VectorInt_destroy(vecI_tmp)
     889              :     !this%M(aF)%mat(1:new_tail,1:new_tail) = CSHIFT(this%M(aF)%mat(1:new_tail,1:new_tail), SHIFT=-1, DIM=1) ! Shift to the bottom
     890              :     !this%M(aF)%mat(1:new_tail,1:new_tail) = CSHIFT(this%M(aF)%mat(1:new_tail,1:new_tail), SHIFT=-1, DIM=2) ! Shift to the right
     891              :     !this%M(aF)%mat_tau(1:new_tail,1:new_tail) = CSHIFT(this%M(aF)%mat_tau(1:new_tail,1:new_tail), SHIFT=-1, DIM=1) ! Shift to the bottom
     892              :     !this%M(aF)%mat_tau(1:new_tail,1:new_tail) = CSHIFT(this%M(aF)%mat_tau(1:new_tail,1:new_tail), SHIFT=-1, DIM=2) ! Shift to the right
     893              : !CALL this_print(M)
     894              :   END IF
     895              : 
     896     85920850 :   IF ( this%doCheck .EQV. .TRUE.) THEN
     897              : !#ifdef CTQMC_CHECK
     898            0 :   CALL BathOperator_checkM(this,particle)
     899              : !#endif
     900              :   END IF
     901              : 
     902     85920850 :   this%MAddFlag = .FALSE.
     903              : 
     904     85920850 : END SUBROUTINE BathOperator_setMAdd
     905              : !!***
     906              : 
     907              : !!****f* ABINIT/m_BathOperator/BathOperator_setMRemove
     908              : !! NAME
     909              : !!  BathOperator_setMRemove
     910              : !!
     911              : !! FUNCTION
     912              : !!  delete one row and one column of the M this
     913              : !!
     914              : !! COPYRIGHT
     915              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
     916              : !!  This file is distributed under the terms of the
     917              : !!  GNU General Public License, see ~abinit/COPYING
     918              : !!  or http://www.gnu.org/copyleft/gpl.txt .
     919              : !!
     920              : !! INPUTS
     921              : !!  this=bath operator
     922              : !!  particle=segments of the active flavor
     923              : !!
     924              : !! OUTPUT
     925              : !!
     926              : !! SIDE EFFECTS
     927              : !!
     928              : !! NOTES
     929              : !!
     930              : !! SOURCE
     931              : 
     932     85918401 : SUBROUTINE BathOperator_setMRemove(this,particle)
     933              : 
     934              : !Arguments ------------------------------------
     935              :   TYPE(BathOperator), INTENT(INOUT)  :: this
     936              :   TYPE(ListCdagC)   , INTENT(IN   )  :: particle
     937              : !Local variables ------------------------------
     938              :   INTEGER                            :: tail
     939              :   INTEGER                            :: new_tail
     940              :   INTEGER                            :: col
     941              :   INTEGER                            :: col_move
     942              :   INTEGER                            :: row_move
     943              :   INTEGER                            :: row
     944              :   INTEGER                            :: positionCol
     945              :   INTEGER                            :: positionRow
     946              :   INTEGER                            :: aF
     947              :   INTEGER                              :: m
     948              :   INTEGER                              :: count
     949              :   INTEGER                              :: i
     950              :   INTEGER                              :: j
     951              :   INTEGER                              :: p
     952              :   DOUBLE PRECISION                   :: invStilde
     953              :   DOUBLE PRECISION                   :: invStilde2
     954     85918401 :   TYPE(VectorInt) :: vecI_tmp
     955     85918401 :   TYPE(Vector)    :: vec_tmp
     956              : 
     957     85918401 :   IF ( this%MRemoveFlag .EQV. .FALSE. ) &
     958            0 :     CALL ERROR("BathOperator_setMRemove : MRemoveFlag turn off     ")
     959     85918401 :   af = this%activeFlavor
     960     85918401 :   IF ( aF .LE. 0 ) &
     961            0 :     CALL ERROR("BathOperator_setMRemove : no active hybrid func    ")
     962     85918401 :   tail        =  this%M(aF)%tail
     963     85918401 :   new_tail    =  tail - 1
     964     85918401 :   positionCol =  this%updatePosCol
     965     85918401 :   positionRow =  this%updatePosRow
     966     85918401 :   invStilde   = 1.d0 / this%Stilde
     967              : 
     968              : !  write(6,*) "before", positionRow, positionCol
     969              : !  CALL MatrixHyb_print(this%M(aF),opt_print=1)
     970              : 
     971              : !  IF ( new_tail .EQ. 0 ) THEN
     972              : !!    IF ( this%antiShift .EQV. .TRUE.  ) THEN
     973              : !!      this%M(aF)%mat(1,1) = 1.d0/BathOperator_Hybrid(this, this%beta)
     974              : !!      this%MRemoveFlag = .FALSE.
     975              : !!      RETURN
     976              : !!    END IF
     977              : !    CALL MatrixHyb_clear(this%M(aF))
     978              : !    this%MRemoveFlag = .FALSE.
     979              : !    RETURN
     980              : !  END IF
     981              : 
     982              : !  CALL Vector_setSize(this%Q,new_tail)
     983              : !  CALL Vector_setSize(this%R,new_tail)
     984     85918401 :   Vector_QuickResize(this%Q,new_tail)
     985     85918401 :   Vector_QuickResize(this%R,new_tail)
     986              : 
     987              : !  We use R and Q as this%R%vec and this%Q%vec
     988              : !  this%R%vec => this%R
     989              : !  this%Q%vec => this%Q
     990              : 
     991              :   !row      = 1
     992              :   !row_move = 1
     993              :   !col      = 1
     994              :   !col_move = 1
     995    360844149 :   DO row_move = 1, new_tail
     996              :     !IF ( row .EQ. positionRow ) row = row + 1
     997              :     !IF ( col .EQ. positionCol ) col = col + 1
     998    274925748 :     col = row_move + (1+SIGN(1,row_move-positionCol))/2
     999    274925748 :     row = row_move + (1+SIGN(1,row_move-positionRow))/2
    1000    274925748 :     this%R%vec(row_move) = this%M(aF)%mat(positionRow,col)
    1001    360844149 :     this%Q%vec(row_move) = this%M(aF)%mat(row,positionCol)
    1002              :     !row      = row + 1
    1003              :     !col      = col + 1
    1004              :   END DO
    1005              : !!    this%R%vec(1:positionCol-1) = this%M(aF)%mat(positionRow,1:positionCol-1)
    1006              : !!    this%R%vec(positionCol:new_tail) = this%M(aF)%mat(positionRow,positionCol+1:tail)
    1007              : !!    this%Q%vec(1:positionRow-1) = this%M(aF)%mat(1:positionRow-1,positionCol)
    1008              : !!    this%Q%vec(positionRow:new_tail) = this%M(aF)%mat(positionRow+1:tail,positionCol)
    1009              : !write(*,*) positionRow, positionCol
    1010              : !CALL MatrixHyb_print(M)
    1011              : !CALL Vector_print(this%R)
    1012              : !CALL Vector_print(this%Q)
    1013              : !CALL ListCdagC_print(this%ListCdagC)
    1014              : 
    1015              :   !col      = 1
    1016    360844149 :   DO col_move = 1, new_tail
    1017              :     !IF ( col_move .EQ. positionCol ) col = col + 1
    1018    274925748 :     col = col_move + (1+SIGN(1,col_move-positionCol))/2
    1019              :     !row      = 1
    1020    274925748 :     invStilde2 = invStilde * this%R%vec(col_move)
    1021   2082266517 :     DO row_move = 1, new_tail
    1022              :       !IF ( row_move .EQ. positionRow ) row = row + 1
    1023   1721422368 :       row = row_move + (1+SIGN(1,row_move-positionRow))/2
    1024              :       this%M(aF)%mat(row_move,col_move) = this%M(aF)%mat(row,col) &
    1025   1721422368 :                                       - this%Q%vec(row_move)*invStilde2
    1026   1996348116 :       this%M(aF)%mat_tau(row_move,col_move) = this%M(aF)%mat_tau(row,col)
    1027              :       !row      = row      + 1
    1028              :     END DO
    1029              :     !col      = col      + 1
    1030              :   END DO
    1031     85918401 :   CALL MatrixHyb_setSize(this%M(aF),new_tail)
    1032              : 
    1033     85918401 :   IF ( this%antiShift .EQV. .TRUE. ) THEN ! antisegment
    1034              :     ! Shift if necessary according to this%antishift
    1035              :     ! shift DIM=2 (col)
    1036      2896336 :     CALL Vector_init(vec_tmp,new_tail)
    1037      2896336 :     CALL VectorInt_init(vecI_tmp,new_tail)
    1038      2896336 :     p = 1
    1039      2896336 :     m = 1
    1040      2896336 :     count = 0
    1041      5756133 :     DO WHILE ( count .NE. new_tail )
    1042     13597195 :       vec_tmp%vec(1:new_tail) = this%M(aF)%mat(1:new_tail,m)
    1043     13597195 :       vecI_tmp%vec(1:new_tail) = this%M(aF)%mat_tau(1:new_tail,m)
    1044      2859797 :       i = m
    1045              :       !j = m+p
    1046      2859797 :       MODCYCLE(m+p, new_tail, j)
    1047     10737398 :       DO WHILE (j .NE. m)
    1048     59469081 :         this%M(aF)%mat(1:new_tail,i) = this%M(aF)%mat(1:new_tail,j)
    1049     59469081 :         this%M(aF)%mat_tau(1:new_tail,i) = this%M(aF)%mat_tau(1:new_tail,j)
    1050      7877601 :         i = j
    1051      7877601 :         MODCYCLE(j+p, new_tail, j)
    1052      7877601 :         count = count+1
    1053              :       END DO
    1054     13597195 :       this%M(aF)%mat(1:new_tail,i) = vec_tmp%vec(1:new_tail)
    1055     13597195 :       this%M(aF)%mat_tau(1:new_tail,i) = vecI_tmp%vec(1:new_tail)
    1056      2859797 :       count = count+1
    1057      2859797 :       m = m+1
    1058              :     END DO
    1059      2896336 :     CALL Vector_destroy(vec_tmp)
    1060      2896336 :     CALL VectorInt_destroy(vecI_tmp)
    1061              :     !this%M(aF)%mat(1:new_tail,1:new_tail) = &
    1062              :     !           CSHIFT(this%M(aF)%mat(1:new_tail,1:new_tail), SHIFT=1, DIM=2) ! Shift to the top
    1063              :     !this%M(aF)%mat_tau(1:new_tail,1:new_tail) = &
    1064              :     !           CSHIFT(this%M(aF)%mat_tau(1:new_tail,1:new_tail), SHIFT=1, DIM=2) ! Shift to the top
    1065              :   END IF
    1066              : !  write(6,*) "after "
    1067              : !  CALL MatrixHyb_print(this%M(aF),opt_print=1)
    1068              : 
    1069     85918401 :   IF ( this%doCheck .EQV. .TRUE. ) THEN
    1070              : !#ifdef CTQMC_CHECK
    1071            0 :   CALL BathOperator_checkM(this,particle)
    1072              : !#endif
    1073              :   END IF
    1074              : 
    1075     85918401 :   this%MRemoveFlag = .FALSE.
    1076              : 
    1077     85918401 : END SUBROUTINE BathOperator_setMRemove
    1078              : !!***
    1079              : 
    1080              : !!****f* ABINIT/m_BathOperator/BathOperator_swap
    1081              : !! NAME
    1082              : !!  BathOperator_swap
    1083              : !!
    1084              : !! FUNCTION
    1085              : !!  Recompute 2 M this swaping the segments
    1086              : !!
    1087              : !! COPYRIGHT
    1088              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1089              : !!  This file is distributed under the terms of the
    1090              : !!  GNU General Public License, see ~abinit/COPYING
    1091              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1092              : !!
    1093              : !! INPUTS
    1094              : !!  this=bath operator
    1095              : !!  iflavor1=flavor to swap with the next one
    1096              : !!  iflavor2=favor to swap with the previous one
    1097              : !!
    1098              : !! OUTPUT
    1099              : !!
    1100              : !! SIDE EFFECTS
    1101              : !!
    1102              : !! NOTES
    1103              : !!
    1104              : !! SOURCE
    1105              : 
    1106        95797 : SUBROUTINE BathOperator_swap(this, flavor1, flavor2)
    1107              : 
    1108              : !Arguments ------------------------------------
    1109              :   TYPE(BathOperator), INTENT(INOUT) :: this
    1110              :   INTEGER           , INTENT(IN   ) :: flavor1
    1111              :   INTEGER           , INTENT(IN   ) :: flavor2
    1112              : 
    1113              :   !CALL MatrixHyb_print(this%M(flavor1),234)
    1114        95797 :   this%M(flavor1) = this%M_update(flavor1)
    1115              :   !CALL MatrixHyb_print(this%M(flavor1),234)
    1116              :   !CALL MatrixHyb_print(this%M(flavor2),234)
    1117        95797 :   this%M(flavor2) = this%M_update(flavor2)
    1118              :   !CALL MatrixHyb_print(this%M(flavor2),234)
    1119              : 
    1120        95797 : END SUBROUTINE BathOperator_swap
    1121              : !!***
    1122              : 
    1123              : !!****f* ABINIT/m_BathOperator/BathOperator_initF
    1124              : !! NAME
    1125              : !!  BathOperator_initF
    1126              : !!
    1127              : !! FUNCTION
    1128              : !!  Copy input hybridization functions from a file
    1129              : !!
    1130              : !! COPYRIGHT
    1131              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1132              : !!  This file is distributed under the terms of the
    1133              : !!  GNU General Public License, see ~abinit/COPYING
    1134              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1135              : !!
    1136              : !! INPUTS
    1137              : !!  this=bath operator
    1138              : !!  ifstream=file stream to read F
    1139              : !!
    1140              : !! OUTPUT
    1141              : !!  argout(sizeout)=description
    1142              : !!
    1143              : !! SIDE EFFECTS
    1144              : !!
    1145              : !! NOTES
    1146              : !!
    1147              : !! SOURCE
    1148              : 
    1149            0 : SUBROUTINE BathOperator_initF(this,ifstream)
    1150              : 
    1151              : !Arguments ----------------------
    1152              :   TYPE(BathOperator), INTENT(INOUT) :: this
    1153              :   INTEGER           , INTENT(IN   ) :: ifstream
    1154              : !Local variables ----------------
    1155              :   INTEGER                           :: flavor
    1156              :   INTEGER                           :: sample
    1157              : 
    1158            0 :   IF ( this%set .EQV. .FALSE. ) &
    1159            0 :     CALL ERROR("BathOperator_initF : BathOperator not set         ")
    1160              : 
    1161            0 :   DO flavor=1,this%flavors
    1162            0 :     DO sample = 1, this%sizeHybrid
    1163            0 :       READ(ifstream,*) this%F(sample,flavor)
    1164              :     END DO
    1165              :   END DO
    1166            0 : END SUBROUTINE BathOperator_initF
    1167              : !!***
    1168              : 
    1169              : !!****f* ABINIT/m_BathOperator/BathOperator_setF
    1170              : !! NAME
    1171              : !!  BathOperator_setF
    1172              : !!
    1173              : !! FUNCTION
    1174              : !!  Copy F from input array
    1175              : !!
    1176              : !! COPYRIGHT
    1177              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1178              : !!  This file is distributed under the terms of the
    1179              : !!  GNU General Public License, see ~abinit/COPYING
    1180              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1181              : !!
    1182              : !! INPUTS
    1183              : !!  this=bath operator
    1184              : !!  F=array of the hybridization function
    1185              : !!
    1186              : !! OUTPUT
    1187              : !!
    1188              : !! SIDE EFFECTS
    1189              : !!
    1190              : !! NOTES
    1191              : !!
    1192              : !! SOURCE
    1193              : 
    1194           49 : SUBROUTINE BathOperator_setF(this,F)
    1195              : 
    1196              : !Arguments ------------------------------------
    1197              :   TYPE(BathOperator)               , INTENT(INOUT) :: this
    1198              :   DOUBLE PRECISION, DIMENSION(:,:) , INTENT(IN   ) :: F
    1199              : !Arguments ------------------------------------
    1200              :   INTEGER                                          :: flavor
    1201              :   INTEGER                                          :: sample
    1202              :   INTEGER                                          :: length
    1203              : 
    1204           49 :   IF ( this%set .EQV. .FALSE. ) &
    1205            0 :     CALL ERROR("BathOperator_setF : BathOperator not set          ")
    1206              : 
    1207          147 :  length  = SIZE(F)
    1208           49 :   IF ( length .NE. (this%flavors * this%sizeHybrid) ) &
    1209            0 :     CALL ERROR("BathOperator_setF : wrong input F                 ")
    1210              : 
    1211          567 :   DO flavor=1,this%flavors
    1212       152985 :     DO sample = 1, this%sizeHybrid
    1213       152936 :     this%F(sample,flavor) = F(sample,flavor)
    1214              :     END DO
    1215              :   END DO
    1216           49 : END SUBROUTINE BathOperator_setF
    1217              : !!***
    1218              : 
    1219              : !!****f* ABINIT/m_BathOperator/BathOperator_printF
    1220              : !! NAME
    1221              : !!  BathOperator_printF
    1222              : !!
    1223              : !! FUNCTION
    1224              : !!  print F function
    1225              : !!
    1226              : !! COPYRIGHT
    1227              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1228              : !!  This file is distributed under the terms of the
    1229              : !!  GNU General Public License, see ~abinit/COPYING
    1230              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1231              : !!
    1232              : !! INPUTS
    1233              : !!  this=bath operator
    1234              : !!  ostream=file stream to write in
    1235              : !!
    1236              : !! OUTPUT
    1237              : !!
    1238              : !! SIDE EFFECTS
    1239              : !!
    1240              : !! NOTES
    1241              : !!
    1242              : !! SOURCE
    1243              : 
    1244            0 : SUBROUTINE BathOperator_printF(this,ostream)
    1245              : 
    1246              : !Arguments ------------------------------------
    1247              :   TYPE(BathOperator), INTENT(INOUT) :: this
    1248              :   INTEGER,OPTIONAL  , INTENT(IN   ) :: ostream
    1249              : !Local variables ------------------------------
    1250              :   CHARACTER(LEN=4)                  :: aflavor
    1251              :   CHARACTER(LEN=50)                  :: string
    1252              :   INTEGER                           :: flavor
    1253              :   INTEGER                           :: sample
    1254              :   INTEGER                           :: ostream_val
    1255              : 
    1256            0 :   IF ( PRESENT(ostream) ) THEN
    1257            0 :     ostream_val = ostream
    1258              :   ELSE
    1259            0 :     ostream_val = 65
    1260            0 :     OPEN(UNIT=ostream_val, FILE="F.dat")
    1261              :   END IF
    1262              : 
    1263            0 :   WRITE(aflavor,'(I4)') this%flavors+1
    1264            0 :   string = '(1x,'//TRIM(ADJUSTL(aflavor))//'E22.14)'
    1265            0 :   DO sample = 1, this%sizeHybrid
    1266            0 :     WRITE(ostream_val,string) (sample-1)*this%dt, (this%F(sample,flavor), flavor=1,this%flavors)
    1267              :   END DO
    1268              :   !CALL FLUSH(ostream_val)
    1269              : 
    1270            0 :   IF ( .NOT. PRESENT(ostream) ) &
    1271            0 :     CLOSE(ostream_val)
    1272              : 
    1273            0 : END SUBROUTINE BathOperator_printF
    1274              : !!***
    1275              : 
    1276              : !!****f* ABINIT/m_BathOperator/BathOperator_printM
    1277              : !! NAME
    1278              : !!  BathOperator_printM
    1279              : !!
    1280              : !! FUNCTION
    1281              : !!  print M =F^{-1} this
    1282              : !!
    1283              : !! COPYRIGHT
    1284              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1285              : !!  This file is distributed under the terms of the
    1286              : !!  GNU General Public License, see ~abinit/COPYING
    1287              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1288              : !!
    1289              : !! INPUTS
    1290              : !!  this=bath operator
    1291              : !!  ostream=file stream to write in
    1292              : !!
    1293              : !! OUTPUT
    1294              : !!  argout(sizeout)=description
    1295              : !!
    1296              : !! SIDE EFFECTS
    1297              : !!
    1298              : !! NOTES
    1299              : !!
    1300              : !! SOURCE
    1301              : 
    1302            0 : SUBROUTINE BathOperator_printM(this,ostream)
    1303              : 
    1304              : !Arguments ------------------------------------
    1305              :   TYPE(BathOperator), INTENT(IN) :: this
    1306              :   INTEGER, OPTIONAL , INTENT(IN) :: ostream
    1307              : !Local variables ------------------------------
    1308              :   INTEGER                        :: ostream_val
    1309              : 
    1310            0 :   IF ( this%activeFlavor .LE. 0 ) &
    1311            0 :     CALL ERROR("BathOperator_printM : no active hybrid function    ")
    1312            0 :   ostream_val = 6
    1313            0 :   IF ( PRESENT(ostream) ) ostream_val = ostream
    1314            0 :   CALL MatrixHyb_print(this%M(this%activeFlavor),ostream_val)
    1315            0 : END SUBROUTINE BathOperator_printM
    1316              : !!***
    1317              : 
    1318              : !!****f* ABINIT/m_BathOperator/ BathOperator_destroy
    1319              : !! NAME
    1320              : !!   BathOperator_destroy
    1321              : !!
    1322              : !! FUNCTION
    1323              : !!  Deallocate and reset every thing
    1324              : !!
    1325              : !! COPYRIGHT
    1326              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1327              : !!  This file is distributed under the terms of the
    1328              : !!  GNU General Public License, see ~abinit/COPYING
    1329              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1330              : !!
    1331              : !! INPUTS
    1332              : !!  this=bath operator
    1333              : !!
    1334              : !! OUTPUT
    1335              : !!
    1336              : !! SIDE EFFECTS
    1337              : !!
    1338              : !! NOTES
    1339              : !!
    1340              : !! SOURCE
    1341              : 
    1342          102 : SUBROUTINE  BathOperator_destroy(this)
    1343              : 
    1344              :   TYPE(BathOperator), INTENT(INOUT) :: this
    1345              :   INTEGER  :: it
    1346              : 
    1347         1178 :   DO it = 1, this%flavors
    1348         1076 :     CALL MatrixHyb_destroy(this%M(it))
    1349         1178 :     CALL MatrixHyb_destroy(this%M_update(it))
    1350              :   END DO
    1351              : 
    1352          102 :   CALL Vector_destroy(this%R)
    1353          102 :   CALL Vector_destroy(this%Q)
    1354          102 :   CALL Vector_destroy(this%Rtau)
    1355          102 :   CALL Vector_destroy(this%Qtau)
    1356          102 :   FREEIF(this%F)
    1357         1178 :   DT_FREEIF(this%M)
    1358         1178 :   DT_FREEIF(this%M_update)
    1359              : 
    1360          102 :   this%MAddFlag     = .FALSE.
    1361          102 :   this%MRemoveFlag  = .FALSE.
    1362          102 :   this%flavors      = 0
    1363          102 :   this%beta         = 0.d0
    1364          102 :   this%dt      = 0.d0
    1365          102 :   this%inv_dt  = 0.d0
    1366          102 :   this%samples      = 0
    1367          102 :   this%sizeHybrid   = 0
    1368          102 :   this%activeFlavor = 0
    1369          102 :   this%updatePosRow = 0
    1370          102 :   this%updatePosCol = 0
    1371              : 
    1372          102 : END SUBROUTINE BathOperator_destroy
    1373              : !!***
    1374              : 
    1375              : !!****f* ABINIT/m_BathOperator/BathOperator_doCheck
    1376              : !! NAME
    1377              : !!  BathOperator_doCheck
    1378              : !!
    1379              : !! FUNCTION
    1380              : !!  Just store if we perfom check for updates of M
    1381              : !!
    1382              : !! COPYRIGHT
    1383              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1384              : !!  This file is distributed under the terms of the
    1385              : !!  GNU General Public License, see ~abinit/COPYING
    1386              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1387              : !!
    1388              : !! INPUTS
    1389              : !!  this=bath operator
    1390              : !!  opt_check=second bit should be one
    1391              : !!
    1392              : !! OUTPUT
    1393              : !!
    1394              : !! SIDE EFFECTS
    1395              : !!
    1396              : !! NOTES
    1397              : !!
    1398              : !! SOURCE
    1399              : 
    1400           49 : SUBROUTINE BathOperator_doCheck(this,opt_check)
    1401              : 
    1402              : !Arguments ------------------------------------
    1403              :   TYPE(BathOperator) , INTENT(INOUT) :: this
    1404              :   INTEGER            , INTENT(IN   ) :: opt_check
    1405              : 
    1406           49 :   IF ( opt_check .GE. 2 ) &
    1407            0 :     this%doCheck = .TRUE.
    1408           49 : END SUBROUTINE BathOperator_doCheck
    1409              : !!***
    1410              : 
    1411              : !!****f* ABINIT/m_BathOperator/BathOperator_checkM
    1412              : !! NAME
    1413              : !!  BathOperator_checkM
    1414              : !!
    1415              : !! FUNCTION
    1416              : !!  compute from scratch the M this and compar it
    1417              : !!  with the already computed M this
    1418              : !!
    1419              : !! COPYRIGHT
    1420              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1421              : !!  This file is distributed under the terms of the
    1422              : !!  GNU General Public License, see ~abinit/COPYING
    1423              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1424              : !!
    1425              : !! INPUTS
    1426              : !!  this=bath operator
    1427              : !!  particle=list of all segments of the active flavor
    1428              : !!
    1429              : !! OUTPUT
    1430              : !!
    1431              : !! SIDE EFFECTS
    1432              : !!
    1433              : !! NOTES
    1434              : !!
    1435              : !! SOURCE
    1436              : 
    1437            0 : SUBROUTINE BathOperator_checkM(this,particle)
    1438              : 
    1439              : !Arguments ------------------------------------
    1440              :   TYPE(BathOperator) , INTENT(INOUT) :: this
    1441              :   TYPE(ListCdagC)    , INTENT(IN   ) :: particle
    1442              : !Local variables ------------------------------
    1443              : !  TYPE(MatrixHyb)                    :: checkMatrix
    1444              :   LOGICAL :: checkTau
    1445              :   INTEGER :: tail
    1446              :   INTEGER :: iC
    1447              :   INTEGER :: iCdag
    1448              :   INTEGER :: aF
    1449              :   CHARACTER(LEN=4) :: a
    1450              :   DOUBLE PRECISION :: time
    1451              :   DOUBLE PRECISION :: beta
    1452              :   DOUBLE PRECISION :: mbeta_two
    1453              :   DOUBLE PRECISION :: erreur
    1454              :   DOUBLE PRECISION :: tc
    1455              :   DOUBLE PRECISION :: tCdag
    1456              :   DOUBLE PRECISION :: sumMmat
    1457              :   DOUBLE PRECISION :: sumCheck
    1458              : #include "BathOperator_hybrid.h"
    1459              : 
    1460            0 :   aF = this%activeFlavor
    1461              :   !Construction de la this
    1462            0 :   tail = particle%tail
    1463              : !  CALL MatrixHyb_init(checkMatrix,this%iTech,size=tail,Wmax=this%samples)
    1464              : !  CALL MatrixHyb_setSize(checkMatrix,tail)
    1465            0 :   CALL MatrixHyb_setSize(this%M_update(aF),tail)
    1466            0 :   beta   =  this%beta
    1467            0 :   mbeta_two = -beta*0.5d0
    1468            0 :   this%checkNumber = this%checkNumber + 1
    1469            0 :   IF ( tail .NE. this%M(aF)%tail ) THEN
    1470            0 :     CALL WARN("BathOperator_checkM : tails are different          ")
    1471            0 :     RETURN
    1472              :   END IF
    1473              : 
    1474              : !CALL ListCdagC_print(particle)
    1475            0 :   DO iCdag = 1, tail
    1476            0 :     tCdag  = particle%list(iCdag,Cdag_)
    1477            0 :     DO iC  = 1, tail
    1478              :       !tC   = particle%list(C_,iC).MOD.beta
    1479            0 :       MODCYCLE(particle%list(iC,C_),beta,tC)
    1480            0 :       time = tC - tCdag
    1481              : #include "BathOperator_hybrid"
    1482            0 :       this%M_update(aF)%mat(iC,iCdag) = hybrid
    1483              : 
    1484            0 :       time = time + ( SIGN(1.d0,time) - 1.d0 )*mbeta_two
    1485            0 :       this%M_update(aF)%mat_tau(iCdag,iC) = INT ( (time*this%inv_dt) +1.5d0 )
    1486              :     END DO
    1487              :   END DO
    1488              : 
    1489              : !    CALL MatrixHyb_Print(checkMatrix)
    1490              :   !Inversion de la this
    1491            0 :   CALL MatrixHyb_inverse(this%M_update(aF))
    1492              : !    CALL MatrixHyb_Print(checkMatrix)
    1493              : 
    1494              :   !Comparaison
    1495            0 :   sumMmat =0.d0
    1496            0 :   sumCheck=0.d0
    1497            0 :   erreur = 0.d0
    1498            0 :   checkTau = .FALSE.
    1499            0 :   DO iCdag = 1, tail
    1500            0 :     Do iC =1, tail
    1501            0 :       this%M_update(aF)%mat(iC,iCdag) = ABS((this%M_update(aF)%mat(iC, iCdag) - this%M(aF)%mat(iC,iCdag))/this%M(aF)%mat(iC,iCdag))
    1502              :       IF ( this%M_update(aF)%mat(iC,iCdag) .GT. erreur ) erreur = this%M_update(aF)%mat(ic,iCdag)
    1503            0 :       IF ( this%M_update(aF)%mat_tau(iC,iCdag) .NE. this%M(aF)%mat_tau(iC,iCdag) ) checkTau = .TRUE.
    1504              :     END DO
    1505              :   END DO
    1506              : 
    1507            0 :   IF ( checkTau .EQV. .TRUE. ) THEN
    1508            0 :     CALL WARN("BathOperator_checkM : mat_tau differs should be")
    1509            0 :     CALL MatrixHyb_print(this%M_update(aF),opt_print=1)
    1510            0 :     CALL WARN("BathOperator_checkM : whereas it is")
    1511            0 :     CALL MatrixHyb_print(this%M(aF),opt_print=1)
    1512              :   END IF
    1513            0 :   this%meanError = this%meanError + erreur
    1514            0 :   IF ( erreur .GT. 1.d0 ) THEN
    1515            0 :     WRITE(a,'(I4)') INT(erreur*100.d0)
    1516              : !    CALL MatrixHyb_Print(this%M(aF)
    1517            0 :     CALL WARN("BathOperator_checkM : "//a//"%                        ")
    1518              :   END IF
    1519              : !  CALL MatrixHyb_destroy(checkMatrix)
    1520              : END SUBROUTINE BathOperator_checkM
    1521              : !!***
    1522              : 
    1523              : !!****f* ABINIT/m_BathOperator/BathOperator_getError
    1524              : !! NAME
    1525              : !!  BathOperator_getError
    1526              : !!
    1527              : !! FUNCTION
    1528              : !!  compute a percentage error / checkM
    1529              : !!
    1530              : !! COPYRIGHT
    1531              : !!  Copyright (C) 2013-2026 ABINIT group (J. Bieder)
    1532              : !!  This file is distributed under the terms of the
    1533              : !!  GNU General Public License, see ~abinit/COPYING
    1534              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    1535              : !!
    1536              : !! INPUTS
    1537              : !!  this=bath operator
    1538              : !!
    1539              : !! OUTPUT
    1540              : !!  BathOperator_getError=Error in percent
    1541              : !!
    1542              : !! SIDE EFFECTS
    1543              : !!
    1544              : !! NOTES
    1545              : !!
    1546              : !! SOURCE
    1547              : 
    1548            0 : DOUBLE PRECISION FUNCTION BathOperator_getError(this)
    1549              : 
    1550              :   TYPE(BathOperator), INTENT(IN) :: this
    1551              : 
    1552            0 :   IF ( this%doCheck .EQV. .TRUE. ) THEN
    1553            0 :     BathOperator_getError = this%meanError / DBLE(this%checkNumber)
    1554              :   ELSE
    1555              :     BathOperator_getError = 0.d0
    1556              :   END IF
    1557            0 : END FUNCTION BathOperator_getError
    1558              : !!***
    1559              : !#endif
    1560              : 
    1561     85920850 : END MODULE m_BathOperator
    1562              : !!***
        

Generated by: LCOV version 2.3-1