Branch data 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 : : !!***
|