Branch data Line data Source code
1 : : !!****m* ABINIT/m_green
2 : : !! NAME
3 : : !! m_green
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : ! nvtx related macro definition
23 : : #include "nvtx_macros.h"
24 : :
25 : : MODULE m_green
26 : :
27 : : use, intrinsic :: iso_c_binding, only: c_size_t
28 : : use defs_basis
29 : : use m_abicore
30 : : use m_errors
31 : :
32 : : use m_crystal, only : crystal_t
33 : : use m_fstrings, only : int2char4
34 : : use m_hide_lapack, only : xginv
35 : : use m_io_tools, only : open_file
36 : : use m_lib_four
37 : : use m_matlu, only : add_matlu,copy_matlu,destroy_matlu,diff_matlu,init_matlu,matlu_type,print_matlu, &
38 : : & prod_matlu,shift_matlu,sym_matlu,trace_matlu,trace_prod_matlu,xmpi_matlu,zero_matlu
39 : : use m_oper, only : copy_oper,copy_oper_from_ndat,copy_oper_to_ndat,destroy_oper,downfold_oper,gather_oper, &
40 : : & gather_oper_ks,init_oper,init_oper_ndat,inverse_oper,oper_type,print_oper,prod_oper, &
41 : : & trace_oper,trace_prod_oper,upfold_oper
42 : : use m_paw_dmft, only : construct_nwli_dmft,mpi_distrib_dmft_type,paw_dmft_type
43 : : use m_self, only : self_type
44 : : use m_splines
45 : : use m_time, only : timab
46 : : use m_xmpi, only : xmpi_barrier,xmpi_sum
47 : : use m_gputk
48 : : use m_abi_linalg
49 : :
50 : :
51 : : #ifdef HAVE_GPU_MARKERS
52 : : use m_nvtx_data
53 : : #endif
54 : :
55 : : implicit none
56 : :
57 : : private
58 : :
59 : : public :: init_green
60 : : public :: destroy_green
61 : : public :: init_green_tau
62 : : public :: destroy_green_tau
63 : : public :: print_green
64 : : public :: printocc_green
65 : : public :: compute_green
66 : : public :: integrate_green
67 : : public :: icip_green
68 : : public :: fourier_green
69 : : public :: check_fourier_green
70 : : public :: compa_occup_ks
71 : : public :: copy_green
72 : : public :: occup_green_tau
73 : : public :: add_int_fct
74 : : public :: int_fct
75 : : public :: fourier_fct
76 : : public :: spline_fct
77 : : public :: distrib_paral
78 : : public :: greendftcompute_green
79 : : public :: fermi_green
80 : : public :: newton
81 : : public :: local_ks_green
82 : : public :: compute_moments_ks
83 : : public :: compute_trace_moments_ks
84 : : public :: compute_moments_loc
85 : : public :: occup_fd
86 : : !!***
87 : :
88 : : !!****t* m_green/green_type
89 : : !! NAME
90 : : !! green_type
91 : : !!
92 : : !! FUNCTION
93 : : !! This structured datatype contains the necessary data
94 : : !!
95 : : !! SOURCE
96 : :
97 : : type, public :: green_type ! for each atom
98 : :
99 : : integer :: dmft_nwli
100 : : ! Linear index of the last imaginary frequency
101 : :
102 : : integer :: dmft_nwlo
103 : : ! Number of imaginary frequencies
104 : :
105 : : integer :: dmftqmc_l
106 : : ! Number of time slices for QMC
107 : :
108 : : integer :: fileprt_tau
109 : : ! 1 if file created
110 : :
111 : : integer :: fileprt_w
112 : : ! 1 if file created
113 : :
114 : : integer :: has_charge_matlu
115 : : ! =2 if calculation of LOCAL CORRELATED occupations is done
116 : :
117 : : integer :: has_charge_matlu_prev
118 : : ! =0 charge_matlu_prev not allocated
119 : : ! =1 charge_matlu_prev is allocated
120 : : ! =2 charge_matlu_prev is calculated (ie calculation of LOCAL CORRELATED occupations is done from
121 : : ! solver green function)
122 : :
123 : : integer :: has_charge_matlu_solver
124 : : ! =0 charge_matlu_solver not allocated
125 : : ! =1 charge_matlu_solver is allocated
126 : : ! =2 charge_matlu_solver is calculated (ie calculation of LOCAL CORRELATED occupations is done from
127 : : ! solver green function)
128 : :
129 : : integer :: has_greenmatlu_xsum
130 : : ! =1 green%oper%matlu xsum in compute_green
131 : : ! =0 green%oper%matlu non xsumed in compute_green
132 : : ! used in integrate_green to checked that green function was computed in
133 : : ! integrate_green.
134 : :
135 : : integer :: has_moments
136 : : ! =1 if the high-frequency moments are computed
137 : :
138 : : integer :: ichargeloc_cv
139 : :
140 : : integer :: ifermie_cv
141 : :
142 : : integer :: nmoments
143 : : ! Number of high-frequency moments which will be computed
144 : :
145 : : integer :: nw
146 : : ! Number of frequencies
147 : :
148 : : integer :: use_oper_tau_ks
149 : : ! 0 do not use oper_tau_ks
150 : : ! 1 use oper_tau_ks
151 : :
152 : : character(len=4) :: w_type
153 : : ! type of frequencies used
154 : :
155 : : !character(len=12) :: whichgreen
156 : : ! describe the type of green function computed (DFT, DMFT, ..)
157 : :
158 : : real(dp) :: charge_ks
159 : : ! Total charge computed from ks orbitals
160 : :
161 : : real(dp) :: ekin_imp
162 : : ! Kinetic energy of the impurity
163 : :
164 : : real(dp) :: fband_weiss
165 : : ! Tr(log(G0))
166 : :
167 : : real(dp) :: integral
168 : : ! Integral of the interaction energy divided by U
169 : :
170 : : real(dp) :: trace_log
171 : : ! Tr(log(G)) in KS space
172 : :
173 : : !integer, allocatable :: procb(:,:)
174 : :
175 : : !integer, allocatable :: proct(:,:)
176 : :
177 : : type(oper_type) :: occup
178 : : ! Occupation in different basis
179 : :
180 : : type(oper_type) :: occup_tau
181 : : ! Occupation in different basis
182 : :
183 : : complex(dp) :: trace_fermie(12)
184 : : ! Container to store useful quantities for a quick computation
185 : : ! of the moments during the Fermi level search
186 : :
187 : : real(dp), allocatable :: charge_matlu(:,:)
188 : : ! Total charge on correlated orbitals
189 : : ! todo_ba name of charge_matlu is misleading: should be changed
190 : :
191 : : real(dp), allocatable :: charge_matlu_prev(:,:)
192 : : ! Total charge on correlated orbitals from previous iteration
193 : :
194 : : real(dp), allocatable :: charge_matlu_solver(:,:)
195 : : ! Total charge on correlated orbitals obtained from solver by
196 : : ! integration over frequencies.
197 : :
198 : : real(dp), allocatable :: ecorr_qmc(:)
199 : : ! Correlation energy for a given atom in qmc
200 : :
201 : : real(dp), allocatable :: tau(:)
202 : : ! Value of time in imaginary space
203 : :
204 : : complex(dp), allocatable :: trace_moments_log_ks(:)
205 : : ! Trace of the moments of log(G)+log(iw*Id) in KS space
206 : :
207 : : complex(dp), allocatable :: trace_moments_log_loc(:)
208 : : ! Trace of the moments of log(G)+log(iw*Id) in local space
209 : :
210 : : type(oper_type), allocatable :: moments(:)
211 : : ! High-frequency moments
212 : :
213 : : type(oper_type), allocatable :: oper(:)
214 : : ! Green's function in different basis
215 : :
216 : : type(oper_type), allocatable :: oper_tau(:)
217 : : ! Green's function in different basis
218 : :
219 : : real(dp), contiguous, pointer :: omega(:) => null()
220 : : ! Value of frequencies
221 : :
222 : : type(mpi_distrib_dmft_type), pointer :: distrib => null()
223 : : ! Datastructure for MPI parallelization
224 : :
225 : : end type green_type
226 : :
227 : : !----------------------------------------------------------------------
228 : :
229 : :
230 : : CONTAINS
231 : : !!***
232 : :
233 : : !!****f* m_green/init_green
234 : : !! NAME
235 : : !! init_green
236 : : !!
237 : : !! FUNCTION
238 : : !! Allocate variables used in type green_type.
239 : : !!
240 : : !! INPUTS
241 : : !! green <type(green_type)>= green function data
242 : : !! energies_dmft = datastructure for dmft energy
243 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
244 : : !! opt_oper_ksloc (optional) = option for init_oper
245 : : !! wtype = "real" Green function will be computed for real frequencies
246 : : !! = "imag" Green function will be computed for imaginary frequencies
247 : : !! opt_moments = 1 : to allocate the high frequency moments
248 : : !! opt_moments_ksloc = option to init green%moments
249 : : !! opt_occup_ksloc = option to init green%occup
250 : : !!
251 : : !! OUTPUTS
252 : : !! green = variable of type green_type
253 : : !!
254 : : !! SOURCE
255 : :
256 : 551 : subroutine init_green(green,paw_dmft,opt_oper_ksloc,wtype,opt_moments,opt_moments_ksloc,opt_occup_ksloc)
257 : :
258 : : !Arguments ------------------------------------
259 : : type(green_type), intent(inout) :: green
260 : : type(paw_dmft_type), target, intent(in) :: paw_dmft
261 : : integer, optional, intent(in) :: opt_moments,opt_moments_ksloc,opt_occup_ksloc,opt_oper_ksloc
262 : : character(len=4), optional, intent(in) :: wtype
263 : : !Local variables ------------------------------------
264 : : integer :: i,ifreq,mkmem,natom,nsppol,nw,optmoments
265 : : integer :: optmoments_ksloc,optoccup_ksloc,optoper_ksloc,shift
266 : : !************************************************************************
267 : :
268 : 551 : optoper_ksloc = 2
269 [ + + ]: 551 : if (present(opt_oper_ksloc)) optoper_ksloc = opt_oper_ksloc
270 : :
271 : 551 : green%w_type = "imag"
272 [ + + ]: 551 : if (present(wtype)) green%w_type = wtype
273 : :
274 : 551 : optmoments = 0
275 [ + + ]: 551 : if (present(opt_moments)) optmoments = opt_moments
276 : :
277 : 551 : optoccup_ksloc = 3
278 [ + + ]: 551 : if (present(opt_occup_ksloc)) optoccup_ksloc = opt_occup_ksloc
279 : :
280 : 551 : optmoments_ksloc = 3
281 [ + + ]: 551 : if (present(opt_moments_ksloc)) optmoments_ksloc = opt_moments_ksloc
282 : :
283 [ + + ]: 551 : if (green%w_type == "imag") then
284 : 547 : nw = paw_dmft%dmft_nwlo
285 : 547 : green%omega => paw_dmft%omega_lo(:)
286 : 547 : green%distrib => paw_dmft%distrib
287 [ + - ]: 4 : else if (green%w_type == "real") then
288 : 4 : nw = size(paw_dmft%omega_r(:))
289 : 4 : green%omega => paw_dmft%omega_r(:)
290 : 4 : green%distrib => paw_dmft%distrib_r
291 : : end if ! w_type
292 : :
293 : 551 : natom = paw_dmft%natom
294 : 551 : nsppol = paw_dmft%nsppol
295 : :
296 : 551 : green%dmft_nwlo = paw_dmft%dmft_nwlo
297 : 551 : green%dmft_nwli = paw_dmft%dmft_nwli
298 : 551 : green%charge_ks = zero
299 [ + - - + : 2204 : ABI_MALLOC(green%charge_matlu,(nsppol+1,natom))
+ - - + +
- + - + -
- + - + -
+ ]
300 [ + + + + ]: 7109 : green%charge_matlu(:,:) = zero
301 : 551 : green%has_charge_matlu = 1
302 : 551 : green%has_greenmatlu_xsum = 0
303 : :
304 [ - + + - : 1653 : ABI_MALLOC(green%charge_matlu_solver,(nsppol+1,natom))
- + + - -
+ - + -
+ ]
305 [ + + + + ]: 7109 : green%charge_matlu_solver(:,:) = zero
306 : 551 : green%has_charge_matlu_solver = 1
307 : :
308 [ - + + - : 1653 : ABI_MALLOC(green%charge_matlu_prev,(nsppol+1,natom))
- + + - -
+ - + -
+ ]
309 [ + + + + ]: 7109 : green%charge_matlu_prev(:,:) = zero
310 : 551 : green%has_charge_matlu_prev = 1
311 : :
312 : 551 : call init_oper(paw_dmft,green%occup,opt_ksloc=optoccup_ksloc)
313 : :
314 : : ! build simple arrays to distribute the tasks in compute_green.
315 : : !ABI_MALLOC(green%procb,(nw,paw_dmft%nkpt))
316 : : !ABI_MALLOC(green%proct,(nw,0:paw_dmft%nproc-1))
317 : :
318 : : !call distrib_paral(paw_dmft%nkpt,paw_dmft%nproc,nw,nw_perproc,green%procb,green%proct)
319 : 551 : green%nw = nw
320 : :
321 : : ! need to distribute memory over frequencies
322 : :
323 : : !! begin of temporary modificatios
324 : : ! ABI_MALLOC(green%oper,(green%nw_perproc))
325 : : ! do ifreq=1,green%nw_perproc
326 : : ! call init_oper(paw_dmft,green%oper(ifreq),opt_ksloc=optoper_ksloc)
327 : : ! enddo
328 : : !
329 : : ! do ifreq=1,green%nw
330 : : ! if(green%proct(ifreq,myproc)==1) then
331 : : ! do ikpt = 1 , paw_dmft%nkpt
332 : : ! if (green%procb(ifreq,ikpt)==myproc) then
333 : : ! endif
334 : : ! enddo ! ikpt
335 : : ! endif ! parallelisation
336 : : ! enddo ! ifreq
337 : : !
338 : : !
339 : : !! end of temporary modificatios
340 [ - + + - : 132226 : ABI_MALLOC(green%oper,(nw))
+ - + - -
+ - + - +
+ + + - ]
341 [ + + ]: 131124 : do ifreq=1,nw
342 : 131124 : call init_oper(paw_dmft,green%oper(ifreq),opt_ksloc=optoper_ksloc)
343 : : end do ! ifreq
344 : 551 : green%ichargeloc_cv = 0
345 : 551 : green%ifermie_cv = 0
346 : :
347 [ + + ]: 551 : if (paw_dmft%dmft_solv >= 5) then
348 [ - + + - : 522 : ABI_MALLOC(green%ecorr_qmc,(natom))
+ - + - -
+ - + -
+ ]
349 [ + + ]: 488 : green%ecorr_qmc(:) = zero
350 : : end if
351 : :
352 : 551 : green%fileprt_tau = 0
353 : 551 : green%fileprt_w = 0
354 : :
355 : 551 : green%has_moments = optmoments
356 : :
357 : 551 : green%nmoments = 0
358 : :
359 [ - + ]: 551 : if (green%has_moments == 1) then
360 : 0 : green%nmoments = 5
361 : 0 : shift = green%distrib%shiftk
362 : 0 : mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
363 [ # # # # : 0 : ABI_MALLOC(green%moments,(green%nmoments))
# # # # ]
364 : 0 : call init_oper(paw_dmft,green%moments(1),nkpt=mkmem,shiftk=shift,opt_ksloc=2)
365 [ # # ]: 0 : do i=2,green%nmoments
366 : 0 : call init_oper(paw_dmft,green%moments(i),nkpt=mkmem,shiftk=shift,opt_ksloc=optmoments_ksloc)
367 : : end do ! i
368 [ # # ]: 0 : if (paw_dmft%dmft_triqs_entropy == 1) then
369 [ # # # # : 0 : ABI_MALLOC(green%trace_moments_log_ks,(green%nmoments-1))
# # # # #
# # # # #
# # ]
370 [ # # # # : 0 : ABI_MALLOC(green%trace_moments_log_loc,(green%nmoments-1))
# # # # #
# ]
371 : : end if ! entropy
372 : : end if ! moments
373 : :
374 : 551 : end subroutine init_green
375 : : !!***
376 : :
377 : : !!****f* m_green/init_green_tau
378 : : !! NAME
379 : : !! init_green_tau
380 : : !!
381 : : !! FUNCTION
382 : : !! Allocate variables used in type green_type.
383 : : !!
384 : : !! INPUTS
385 : : !! green <type(green_type)>= green function data
386 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
387 : : !!
388 : : !! OUTPUTS
389 : : !! green <type(green_type)>= green function data
390 : : !!
391 : : !! SOURCE
392 : :
393 : 37 : subroutine init_green_tau(green,paw_dmft)
394 : :
395 : : !Arguments ------------------------------------
396 : : type(green_type), intent(inout) :: green
397 : : type(paw_dmft_type), intent(in) :: paw_dmft
398 : : !Local variables ------------------------------------
399 : : integer :: itau,optksloc
400 : : !************************************************************************
401 : :
402 : 37 : green%use_oper_tau_ks = 0
403 : 37 : optksloc = 2
404 : :
405 : 37 : green%dmftqmc_l = paw_dmft%dmftqmc_l
406 [ - + + - : 111 : ABI_MALLOC(green%tau,(green%dmftqmc_l))
+ - + - -
+ - + -
+ ]
407 [ + + ]: 7779 : do itau=1,green%dmftqmc_l
408 : 7779 : green%tau(itau) = dble(itau-1) / dble(green%dmftqmc_l) / paw_dmft%temp
409 : : end do
410 : :
411 : 37 : call init_oper(paw_dmft,green%occup_tau,opt_ksloc=optksloc)
412 : :
413 [ - + + - : 7853 : ABI_MALLOC(green%oper_tau,(paw_dmft%dmftqmc_l))
+ - + - -
+ - + - +
+ + + - ]
414 [ + + ]: 7779 : do itau=1,green%dmftqmc_l
415 : 7779 : call init_oper(paw_dmft,green%oper_tau(itau),opt_ksloc=optksloc)
416 : : end do
417 : :
418 : 37 : end subroutine init_green_tau
419 : : !!***
420 : :
421 : : !!****f* m_green/destroy_green
422 : : !! NAME
423 : : !! destroy_green
424 : : !!
425 : : !! FUNCTION
426 : : !! Deallocate green
427 : : !!
428 : : !! INPUTS
429 : : !! green <type(green_type)>= green function data
430 : : !!
431 : : !! OUTPUT
432 : : !!
433 : : !! SOURCE
434 : :
435 : 551 : subroutine destroy_green(green)
436 : :
437 : : !Arguments ------------------------------------
438 : : type(green_type), intent(inout) :: green
439 : : !Local variables-------------------------------
440 : : integer :: i,ifreq
441 : : ! *********************************************************************
442 : :
443 : 551 : call destroy_oper(green%occup)
444 [ + - ]: 551 : if (allocated(green%oper)) then
445 [ + + ]: 131124 : do ifreq=1,green%nw
446 : 131124 : call destroy_oper(green%oper(ifreq))
447 : : end do ! ifreq
448 [ + - + + : 131124 : ABI_FREE(green%oper)
- + - - -
- - + -
+ ]
449 : : end if ! green%oper
450 : :
451 [ + - ]: 551 : ABI_SFREE(green%charge_matlu)
452 : 551 : green%has_charge_matlu = 0
453 : :
454 [ + - ]: 551 : ABI_SFREE(green%charge_matlu_prev)
455 : 551 : green%has_charge_matlu_prev = 0
456 : :
457 [ + - ]: 551 : ABI_SFREE(green%charge_matlu_solver)
458 : 551 : green%has_charge_matlu_solver = 0
459 : :
460 [ - + ]: 551 : ABI_SFREE(green%trace_moments_log_ks)
461 [ - + ]: 551 : ABI_SFREE(green%trace_moments_log_loc)
462 [ + + ]: 551 : ABI_SFREE(green%ecorr_qmc)
463 : :
464 [ - + ]: 551 : if (allocated(green%moments)) then
465 [ # # ]: 0 : do i=1,green%nmoments
466 : 0 : call destroy_oper(green%moments(i))
467 : : end do ! i
468 [ # # # # : 0 : ABI_FREE(green%moments)
# # # # #
# # # #
# ]
469 : : end if ! green%moments
470 : :
471 : : !ABI_SFREE(green%procb)
472 : : !ABI_SFREE(green%proct)
473 : 551 : green%distrib => null()
474 : 551 : green%omega => null()
475 : :
476 : 551 : end subroutine destroy_green
477 : : !!***
478 : :
479 : : !!****f* m_green/destroy_green_tau
480 : : !! NAME
481 : : !! destroy_green_tau
482 : : !!
483 : : !! FUNCTION
484 : : !! Deallocate green
485 : : !!
486 : : !! INPUTS
487 : : !! green <type(green_type)>= green function data
488 : : !!
489 : : !! OUTPUT
490 : : !!
491 : : !! SOURCE
492 : :
493 : 37 : subroutine destroy_green_tau(green)
494 : :
495 : : !Arguments ------------------------------------
496 : : type(green_type), intent(inout) :: green
497 : : ! integer, optional, intent(in) :: opt_ksloc
498 : : !Local variables-------------------------------
499 : : integer :: itau
500 : : ! integer :: optksloc
501 : : ! *********************************************************************
502 : : ! if(present(opt_ksloc)) then
503 : : ! optksloc=opt_ksloc
504 : : ! else
505 : : ! optksloc=3
506 : : ! endif
507 : :
508 : 37 : call destroy_oper(green%occup_tau)
509 [ + - ]: 37 : if (allocated(green%oper_tau)) then
510 [ + + ]: 7779 : do itau=1,green%dmftqmc_l
511 : 7779 : call destroy_oper(green%oper_tau(itau))
512 : : end do ! itau
513 [ + - + + : 7779 : ABI_FREE(green%oper_tau)
- + - - -
- - + -
+ ]
514 : : end if ! green%oper_tau
515 [ + - ]: 37 : ABI_SFREE(green%tau)
516 : :
517 : 37 : end subroutine destroy_green_tau
518 : : !!***
519 : :
520 : : !!****f* m_green/copy_green
521 : : !! NAME
522 : : !! copy_green
523 : : !!
524 : : !! FUNCTION
525 : : !! Copy one data structure green1 into green2
526 : : !!
527 : : !! INPUTS
528 : : !! green1 <type(green_type)>= green function data
529 : : !! green2 <type(green_type)>= green function data
530 : : !! opt_tw = option to specify which data to copy
531 : : !! 1: copy only green%occup_tau and green%oper_tau data
532 : : !! 2: copy only green%occup and green%oper data (frequency)
533 : : !!
534 : : !! OUTPUT
535 : : !!
536 : : !! SOURCE
537 : :
538 : 36 : subroutine copy_green(green1,green2,opt_tw)
539 : :
540 : : !Arguments ------------------------------------
541 : : type(green_type), intent(in) :: green1
542 : : type(green_type), intent(inout) :: green2
543 : : integer, intent(in) :: opt_tw
544 : : !Local variables-------------------------------
545 : : integer :: i,ifreq,itau
546 : : ! *********************************************************************
547 : :
548 [ + - ]: 36 : if (opt_tw == 2) then
549 : 36 : call copy_oper(green1%occup,green2%occup)
550 [ + + ]: 18029 : do ifreq=1,green1%nw
551 : 18029 : call copy_oper(green1%oper(ifreq),green2%oper(ifreq))
552 : : end do
553 [ - + ]: 36 : if (green1%has_moments == 1) then
554 [ # # ]: 0 : do i=1,green1%nmoments
555 : 0 : call copy_oper(green1%moments(i),green2%moments(i))
556 : : end do
557 : : end if
558 : : ! Indicate to integrate_green that xsum has been done
559 : : ! for matlu in compute_green.
560 [ + + ]: 36 : if (green1%has_greenmatlu_xsum == 1) green2%has_greenmatlu_xsum = 1
561 [ # # ]: 0 : else if (opt_tw == 1) then
562 : 0 : call copy_oper(green1%occup_tau,green2%occup_tau)
563 [ # # ]: 0 : do itau=1,green1%dmftqmc_l
564 : 0 : call copy_oper(green1%oper_tau(itau),green2%oper_tau(itau))
565 : : end do ! itau
566 : : end if ! opt_tw
567 : :
568 : 36 : end subroutine copy_green
569 : : !!***
570 : :
571 : : !!****f* m_green/printocc_green
572 : : !! NAME
573 : : !! printocc_green
574 : : !!
575 : : !! FUNCTION
576 : : !! Print occupations
577 : : !!
578 : : !! INPUTS
579 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
580 : : !! green <type(green_type)>= green function data
581 : : !! option= 1 :for G(w)
582 : : !! 2 :for G(tau)
583 : : !! 3 :for G(tau) and check % G(w)
584 : : !! 4
585 : : !! <5: write diagonal part of KS occupation matrix
586 : : !! 5: for G(w)
587 : : !! 6: for G(tau)
588 : : !! 7 :for G(tau) and check % G(w)
589 : : !! >8: write all elements of KS occup. matrix.
590 : : !! 9: for G(w)
591 : : !! pawprtvol: flag for print
592 : : !! opt_weissgreen = 1 for Weiss field
593 : : !! = 2 (default) for regular Green's function
594 : : !! chtype: to specify the type of occupations being printed
595 : : !!
596 : : !! OUTPUT
597 : : !!
598 : : !! SOURCE
599 : :
600 : 583 : subroutine printocc_green(green,option,paw_dmft,pawprtvol,opt_weissgreen,chtype)
601 : :
602 : : !Arguments ------------------------------------
603 : : type(paw_dmft_type), intent(in) :: paw_dmft
604 : : type(green_type), intent(in) :: green
605 : : integer, intent(in) :: option,pawprtvol
606 : : integer, optional, intent(in) :: opt_weissgreen
607 : : character(len=*), optional, intent(in) :: chtype
608 : : !Local variables-------------------------------
609 : : character(len=500) :: message
610 : : integer :: i_tau,optweissgreen
611 : : ! *********************************************************************
612 : :
613 : 583 : optweissgreen = 2
614 [ - + ]: 583 : if (present(opt_weissgreen)) optweissgreen = opt_weissgreen
615 : :
616 [ + + ]: 583 : if (mod(option,4) == 1) then
617 [ + - ]: 582 : if (optweissgreen == 2) then
618 [ + + ]: 582 : if (present(chtype)) then
619 : 478 : write(message,'(4a)') ch10," == The ",trim(chtype)," occupations are == "
620 : : else
621 : 104 : write(message,'(2a)') ch10," == The occupations (integral of the Green's function) are == "
622 : : end if ! present(chtype)
623 [ # # ]: 0 : else if (optweissgreen == 1) then
624 : 0 : write(message,'(2a)') ch10," == The integrals of the Weiss function are == "
625 : : end if ! optweissgreen
626 : 582 : call wrtout(std_out,message,'COLL')
627 : 582 : call print_oper(green%occup,option,paw_dmft,pawprtvol)
628 : : end if ! mod(option,4)=1
629 : :
630 [ + + ]: 583 : if (mod(option,4) >= 2) then
631 [ + - ]: 1 : if (optweissgreen == 2) then
632 : 1 : write(message,'(2a)') ch10," == The occupations (value of G(tau) for tau=0-) are == "
633 [ # # ]: 0 : else if (optweissgreen == 1) then
634 : 0 : write(message,'(2a)') ch10," == Values of G_0(tau) for tau=0- are == "
635 : : end if ! optweissgreen
636 : 1 : call wrtout(std_out,message,'COLL')
637 : 1 : call print_oper(green%occup_tau,option,paw_dmft,pawprtvol)
638 : : ! write(message,'(2a)') ch10," == check: occupations from Green functions are == "
639 : : ! call wrtout(std_out,message,'COLL')
640 : : ! call print_oper(green%occup,1,paw_dmft,pawprtvol)
641 [ - + ]: 1 : if (mod(option,4) >= 3) then
642 : : call diff_matlu("Local occup from integral of G(iw) ","Local occup from G(tau=0-) ",&
643 : 0 : & green%occup%matlu(:),green%occup_tau%matlu(:),paw_dmft%natom,1,tol4)
644 : 0 : write(message,'(2a)') ch10,&
645 : 0 : & ' ***** => Calculations of occupations in omega and tau spaces are coherent ****'
646 : 0 : call wrtout(std_out,message,'COLL')
647 : : end if ! mod(option,4)>=3
648 : : end if ! mod(option,4)>=2
649 : :
650 [ + + ]: 583 : if (present(chtype)) then
651 : : if (paw_dmft%prtvol >= 4 .and. &
652 : : & (chtype == "DFT+DMFT (end of DMFT loop)" .or. chtype == "converged DMFT") &
653 [ + + + + : 478 : & .and. green%occup%has_opermatlu == 1) then
- + + - ]
654 : 87 : write(message,'(4a)') ch10," == The DFT+DMFT occupation matrix for correlated electrons is == "
655 : 87 : call wrtout(ab_out,message,'COLL')
656 : 87 : call print_matlu(green%occup%matlu(:),paw_dmft%natom,pawprtvol,opt_ab_out=1)
657 : 87 : write(message,'(a)') " "
658 : 87 : call wrtout(ab_out,message,'COLL')
659 : : end if
660 : : end if ! present(chtype)
661 : :
662 [ + + ]: 583 : if (mod(option,4) >= 2) then
663 : 1 : i_tau = 1
664 [ - + ]: 1 : if (optweissgreen == 1) i_tau = -1
665 : 1 : call trace_matlu(green%occup_tau%matlu(:),paw_dmft%natom,itau=i_tau)
666 : : end if ! mod(option,4)>=2
667 : :
668 : 583 : end subroutine printocc_green
669 : : !!***
670 : :
671 : : !!****f* m_green/print_green
672 : : !! NAME
673 : : !! print_green
674 : : !!
675 : : !! FUNCTION
676 : : !! print green function
677 : : !!
678 : : !! INPUTS
679 : : !! char1 = character which describes the type of green function
680 : : !! green <type(green_type)>= green function data
681 : : !! option=1 print local green function
682 : : !! 2 print KS green function
683 : : !! 3 print both local and KS green function
684 : : !! 4 print spectral function is green%w_type="real"
685 : : !! 5 print k-resolved spectral function is green%w_type="real"
686 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
687 : : !! pawprtvol = printing option
688 : : !! opt_wt=1 print green function as a function of frequency
689 : : !! 2 print green function as a function of imaginary time
690 : : !! opt_decim= if present, write more decimals
691 : : !!
692 : : !! OUTPUT
693 : : !!
694 : : !! SOURCE
695 : :
696 : 1 : subroutine print_green(char1,green,option,paw_dmft,opt_wt,opt_decim)
697 : :
698 : : !Arguments ------------------------------------
699 : : type(paw_dmft_type), intent(in) :: paw_dmft
700 : : type(green_type), intent(inout) :: green
701 : : integer, intent(in) :: option
702 : : integer, optional, intent(in) :: opt_wt,opt_decim
703 : : character(len=*), intent(in) :: char1
704 : : !Local variables-------------------------------
705 : : integer :: iall,iatom,ib,ifreq,ikpt,im,ispinor
706 : : integer :: isppol,itau,lpawu,lsub,mbandc,natom
707 : : integer :: ndim,nkpt,nspinor,nsppol,optwt,spf_unt
708 : : integer :: spfkresolved_unt,spcorb_unt
709 : : !real(dp) :: ima,re
710 : : character(len=2000) :: message
711 : : character(len=fnlen) :: tmpfil
712 : : character(len=1) :: tag_is,tag_is2
713 : : character(len=10) :: tag_at
714 : : character(len=3) :: tag_ik
715 : 1 : integer, allocatable :: unitgreenfunc_arr(:),unitgreenloc_arr(:)
716 : 1 : complex(dp), allocatable :: sf(:,:),sf_corr(:),sf2(:)
717 : : ! *********************************************************************
718 : :
719 : 1 : optwt = 1
720 [ + - ]: 1 : if (present(opt_wt)) optwt = opt_wt
721 : :
722 : 1 : mbandc = paw_dmft%mbandc
723 : 1 : natom = paw_dmft%natom
724 : 1 : nkpt = paw_dmft%nkpt
725 : 1 : nspinor = paw_dmft%nspinor
726 : 1 : nsppol = paw_dmft%nsppol
727 : :
728 : : ! == Print local Green Function
729 [ - + ]: 1 : if (option == 1 .or. option == 3) then
730 [ # # # # : 0 : ABI_MALLOC(unitgreenfunc_arr,(natom*nsppol*nspinor))
# # # # #
# # # ]
731 : 0 : iall = 0
732 [ # # ]: 0 : do iatom=1,natom
733 : 0 : lpawu = paw_dmft%lpawu(iatom)
734 [ # # ]: 0 : if (lpawu == -1) cycle
735 : 0 : ndim = 2*lpawu + 1
736 : 0 : call int2char4(iatom,tag_at)
737 [ # # ]: 0 : ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
738 [ # # ]: 0 : do isppol=1,nsppol
739 : 0 : write(tag_is,'(i1)') isppol
740 [ # # ]: 0 : do ispinor=1,nspinor
741 : 0 : iall = iall + 1
742 : 0 : write(tag_is2,'(i1)') ispinor
743 : : ! == Create names
744 [ # # ]: 0 : if (optwt == 1) then
745 : : tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-omega_iatom'// &
746 [ # # ]: 0 : & trim(tag_at)//'_isppol'//tag_is//'_ispinor'//tag_is2
747 : : else
748 : : tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-tau_iatom'// &
749 [ # # ]: 0 : & trim(tag_at)//'_isppol'//tag_is//'_ispinor'//tag_is2
750 : : end if ! optwt
751 [ # # ]: 0 : if (iall <= 4) then
752 : 0 : write(message,'(3a)') ch10," == Print green function on file ",trim(tmpfil)
753 : 0 : call wrtout(std_out,message,'COLL')
754 [ # # ]: 0 : else if (iall == 5) then
755 : 0 : write(message,'(3a)') ch10," == following values are printed in files"
756 : 0 : call wrtout(std_out,message,'COLL')
757 : : end if ! iall
758 : 0 : unitgreenfunc_arr(iall) = 300 + iall - 1
759 [ # # # # : 0 : if ((optwt == 1 .or. green%fileprt_tau == 0) .or. (optwt == 2 .and. green%fileprt_tau == 1)) &
# # # # ]
760 : 0 : & open(unit=unitgreenfunc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted',position='append')
761 : :
762 : : ! == Write in files
763 : : ! rewind(unitgreenfunc_arr(iall))
764 : : ! write(message,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitgreenfunc_arr(iall)
765 : : ! call wrtout(std_out,message,'COLL')
766 : 0 : write(message,'(2a)') ch10,"# New record :"
767 : 0 : call wrtout(unitgreenfunc_arr(iall),message,'COLL')
768 [ # # ]: 0 : if (optwt == 1) then
769 [ # # ]: 0 : do ifreq=1,green%nw
770 [ # # ]: 0 : if (present(opt_decim)) then
771 : 0 : write(message,'(2x,30(e23.16,2x))') green%omega(ifreq), &
772 [ # # # # ]: 0 : & (green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol),im=1,ndim)
773 : : else
774 : 0 : write(message,'(2x,30(e10.3,2x))') green%omega(ifreq), &
775 [ # # # # ]: 0 : & (green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol),im=1,ndim)
776 : : end if ! opt_decim
777 : 0 : call wrtout(unitgreenfunc_arr(iall),message,'COLL')
778 : : !re=real(green%oper(ifreq)%matlu(iatom)%mat(1,1,isppol,ispinor,ispinor))
779 : : !ima=aimag(green%oper(ifreq)%matlu(iatom)%mat(1,1,isppol,ispinor,ispinor))
780 : : ! write(228,*) green%omega(ifreq),re/(re**2+ima**2),ima/(re**2+ima**2)+green%omega(ifreq)
781 : : end do ! ifreq
782 : : else
783 [ # # ]: 0 : do itau=1,green%dmftqmc_l
784 : 0 : write(message,'(2x,30(e10.3,2x))') green%tau(itau), &
785 [ # # # # ]: 0 : & (green%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol),im=1,ndim)
786 : 0 : call wrtout(unitgreenfunc_arr(iall),message,'COLL')
787 : : end do ! itau
788 : 0 : write(message,'(2x,30(e10.3,2x))') one/paw_dmft%temp,&
789 [ # # # # ]: 0 : & (-green%oper_tau(1)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)-one,im=1,ndim)
790 : 0 : call wrtout(unitgreenfunc_arr(iall),message,'COLL')
791 : : end if ! optwt
792 : 0 : close(unitgreenfunc_arr(iall))
793 : : end do ! ispinor
794 : : end do ! isppol
795 : : end do ! iatom
796 [ # # ]: 0 : ABI_FREE(unitgreenfunc_arr)
797 : : end if ! option=1 or 3
798 : :
799 : : ! == Print ks green function
800 [ - + - - ]: 1 : if ((option == 2 .or. option == 3) .and. green%oper(1)%has_operks == 1) then
801 [ # # # # : 0 : ABI_MALLOC(unitgreenloc_arr,(nsppol*nkpt))
# # # # #
# # # ]
802 : 0 : iall = 0
803 [ # # ]: 0 : do isppol=1,nsppol
804 : 0 : write(tag_is,'(i1)') isppol
805 [ # # ]: 0 : do ikpt=1,nkpt
806 : 0 : write(tag_ik,'(i3)') ikpt
807 : : ! do ib1 = 1, mbandc
808 : 0 : iall = iall + 1
809 : : ! == Create names
810 [ # # ]: 0 : if (optwt == 1) then
811 [ # # ]: 0 : tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-omega_isppol'//tag_is//'_ikpt'//trim(adjustl(tag_ik))
812 : : else
813 [ # # ]: 0 : tmpfil = trim(paw_dmft%filapp)//'Green-'//trim(char1)//'-tau_isppol'//tag_is//'_ikpt'//trim(adjustl(tag_ik))
814 : : end if ! optwt
815 [ # # ]: 0 : if (iall <= 4) then
816 : 0 : write(message,'(3a)') ch10," == Print green function on file ",trim(tmpfil)
817 : 0 : call wrtout(std_out,message,'COLL')
818 [ # # ]: 0 : else if (iall == 5) then
819 : 0 : write(message,'(3a)') ch10," == following values are printed in files"
820 : 0 : call wrtout(std_out,message,'COLL')
821 : : end if ! iall
822 : 0 : unitgreenloc_arr(iall) = 400 + iall - 1
823 : 0 : open(unit=unitgreenloc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted')
824 : : ! rewind(unitgreenloc_arr(iall))
825 : : ! write(message,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitgreenloc_arr(iall)
826 : : ! call wrtout(std_out,message,'COLL')
827 : :
828 : : ! == Write in files
829 : 0 : write(message,'(2a)') ch10,"# New record : First 20 bands"
830 : 0 : call wrtout(unitgreenloc_arr(iall),message,'COLL')
831 : : ! call flush(std_out)
832 [ # # ]: 0 : do lsub=1,mbandc/20+1
833 [ # # ]: 0 : if (optwt == 1) then
834 [ # # ]: 0 : do ifreq=1,green%nw
835 : : ! call flush(std_out)
836 : 0 : write(message,'(2x,50(e10.3,2x))') green%omega(ifreq), &
837 [ # # # # ]: 0 : & (green%oper(ifreq)%ks(ib,ib,ikpt,isppol),ib=20*(lsub-1)+1,min(20*lsub,mbandc))
838 : 0 : call wrtout(unitgreenloc_arr(iall),message,'COLL')
839 : : !re = dble(green%oper(ifreq)%ks(1,1,ikpt,isppol))
840 : : !ima = aimag(green%oper(ifreq)%ks(1,1,ikpt,isppol))
841 : : !if (ikpt == 1) write(229,*) green%omega(ifreq),re/(re**2+ima**2),ima/(re**2+ima**2)+green%omega(ifreq)
842 : : end do ! ifreq
843 [ # # ]: 0 : else if (green%use_oper_tau_ks == 1) then
844 [ # # ]: 0 : do itau=1,green%dmftqmc_l
845 : : ! call flush(std_out)
846 : 0 : write(message,'(2x,50(e10.3,2x))') green%tau(itau), &
847 [ # # # # ]: 0 : & (green%oper_tau(itau)%ks(ib,ib,ikpt,isppol),ib=20*(lsub-1)+1,min(20*lsub,mbandc))
848 : 0 : call wrtout(unitgreenloc_arr(iall),message,'COLL')
849 : : end do ! itau
850 : : end if ! optwt
851 [ # # ]: 0 : if (20*lsub < mbandc) write(message,'(2a,i5,a,i5)') ch10,"# Same record, Following bands : From ", &
852 : 0 : & 20*(lsub)," to ",min(20*(lsub+1),mbandc)
853 : 0 : call wrtout(unitgreenloc_arr(iall),message,'COLL')
854 : : end do ! lsub
855 : 0 : close(unitgreenloc_arr(iall))
856 : : end do ! ikpt
857 : : end do ! isppol
858 [ # # ]: 0 : ABI_FREE(unitgreenloc_arr)
859 : : end if ! option=2 or 3
860 : :
861 [ + - + - : 1 : if ((green%w_type == "real" .and. option >= 4) .and. green%oper(1)%has_operks == 1) then
+ - ]
862 : 1 : write(message,'(2a)') ch10," == About to print spectral function"
863 : 1 : call wrtout(std_out,message,'COLL')
864 [ - + ]: 1 : if (option == 4) then
865 [ # # ]: 0 : tmpfil = trim(paw_dmft%filapp)//'_SpFunc-'//trim(char1)
866 [ # # ]: 0 : if (open_file(tmpfil,message,newunit=spf_unt,status='unknown',form='formatted') /= 0) &
867 : 0 : & ABI_ERROR(message)
868 : 0 : write(spf_unt,'(3a)') "# This is the total spectral function (DOS).",ch10, &
869 : 0 : & "# Real frequency (Ha) Spectral function"
870 : :
871 : : end if ! option=4
872 [ + - ]: 1 : if (option == 5) then
873 [ + - ]: 1 : tmpfil = trim(paw_dmft%filapp)//'_DFTDMFT_SpectralFunction_kres' !//trim(char1)
874 [ - + ]: 1 : if (open_file(tmpfil,message,newunit=spfkresolved_unt,status='unknown',form='formatted') /= 0) &
875 : 0 : & ABI_ERROR(message)
876 : 1 : write(spfkresolved_unt,'(3a)') "# This is the k-resolved spectral function.",ch10, &
877 : 2 : & "# Real frequency (eV) Spectral function (eV^-1) ikpt"
878 [ - + + - : 4 : ABI_MALLOC(sf,(nkpt,green%nw))
- + + - +
- + - - +
- + ]
879 [ + + + + ]: 36001 : sf(:,:) = czero
880 [ + + ]: 3001 : do ifreq=1,green%nw
881 [ + + ]: 6001 : do isppol=1,nsppol
882 [ + + ]: 39000 : do ikpt=1,nkpt
883 [ + + ]: 333000 : do ib=1,mbandc
884 : 330000 : sf(ikpt,ifreq) = sf(ikpt,ifreq) + green%oper(ifreq)%ks(ib,ib,ikpt,isppol)
885 : : end do ! ib
886 : : end do ! ikpt
887 : : end do ! isppol
888 : : end do ! ifreq
889 [ + + ]: 12 : do ikpt=1,nkpt
890 [ + + ]: 33011 : do ifreq=1,green%nw
891 : 33000 : write(message,'(2x,2(es24.16e3,2x),i5)') green%omega(ifreq)*Ha_eV,(-aimag(sf(ikpt,ifreq)))/pi/Ha_eV,ikpt
892 : 33011 : call wrtout(spfkresolved_unt,message,'COLL')
893 : : end do ! ifreq
894 : 11 : write(message,*)
895 : 12 : call wrtout(spfkresolved_unt,message,'COLL')
896 : : end do ! ikpt
897 : 1 : write(message,*) ch10
898 : 1 : call wrtout(spfkresolved_unt,message,'COLL')
899 [ - + ]: 1 : ABI_FREE(sf)
900 : 1 : close(spfkresolved_unt)
901 : : !
902 : : ! do isppol = 1 , nsppol
903 : : ! do ikpt = 1, nkpt
904 : : ! do ib=1,mbandc
905 : : ! sf=czero
906 : : ! write(71,*)
907 : : ! write(71,*) "#", ikpt, ib
908 : : ! do ifreq=1,green%nw
909 : : ! sf(ifreq)=sf(ifreq)+green%oper(ifreq)%ks(isppol,ikpt,ib,ib)
910 : : ! write(71,*) green%omega(ifreq)*Ha_eV,(-aimag(sf(ifreq)))/pi/Ha_eV,ikpt
911 : : ! enddo
912 : : ! enddo
913 : : ! enddo
914 : : ! enddo
915 : : end if ! option=5
916 : :
917 [ - + ]: 1 : if (option == 4) then
918 [ # # # # : 0 : ABI_MALLOC(sf2,(green%nw))
# # # # #
# # # ]
919 [ # # ]: 0 : sf2(:) = czero
920 [ # # ]: 0 : do ifreq=1,green%nw
921 [ # # ]: 0 : do isppol=1,nsppol
922 [ # # ]: 0 : do ikpt=1,nkpt
923 [ # # ]: 0 : do ib=1,mbandc
924 : 0 : sf2(ifreq) = sf2(ifreq) + green%oper(ifreq)%ks(ib,ib,ikpt,isppol)*green%oper(1)%wtk(ikpt)
925 : : end do ! ib
926 : : end do ! ikpt
927 : : end do ! isppol
928 : : end do ! ifreq
929 [ # # ]: 0 : do ifreq=1,green%nw
930 : 0 : write(message,'(2x,2(es24.16e3,2x))') green%omega(ifreq),(-aimag(sf2(ifreq)))/pi
931 : 0 : call wrtout(spf_unt,message,'COLL')
932 : : end do ! ifreq
933 [ # # ]: 0 : ABI_FREE(sf2)
934 : 0 : close(spf_unt)
935 : : end if ! option=4
936 : :
937 [ + - ]: 1 : if (paw_dmft%dmft_kspectralfunc == 1) then
938 [ - + + - : 3 : ABI_MALLOC(sf_corr,(green%nw))
+ - + - -
+ - + ]
939 [ + + ]: 2 : do iatom=1,natom
940 : 1 : lpawu = paw_dmft%lpawu(iatom)
941 [ - + ]: 1 : if (lpawu == -1) cycle
942 [ + + ]: 3001 : sf_corr(:) = czero
943 : 1 : call int2char4(iatom,tag_at)
944 [ - + ]: 1 : ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
945 [ + - ]: 1 : tmpfil = trim(paw_dmft%filapp)//'_DFTDMFT_SpFunloc_iatom'//trim(tag_at)
946 [ - + ]: 1 : if (open_file(tmpfil,message,newunit=spcorb_unt,status='unknown',form='formatted') /= 0) &
947 : 0 : & ABI_ERROR(message)
948 : 1 : ndim = 2*lpawu + 1
949 : 1 : write(message,'(3a,3(i3),i6,2a,i2,2a)') "# nspinor,nsppol,ndim,nw",ch10,"#",nspinor,nsppol,ndim,green%nw,ch10, &
950 : 2 : & "# lpawu",lpawu,ch10,"# Frequency (Ha.) Spectral function"
951 : 1 : call wrtout(spcorb_unt,message,'COLL')
952 : 1 : ndim = nspinor * ndim
953 [ + + ]: 3001 : do ifreq=1,green%nw
954 [ + + ]: 6001 : do isppol=1,nsppol
955 [ + + ]: 21000 : do im=1,ndim
956 : 18000 : sf_corr(ifreq) = sf_corr(ifreq) + green%oper(ifreq)%matlu(iatom)%mat(im,im,isppol)
957 : : end do ! im
958 : : end do ! isppol
959 : : end do ! ifreq
960 [ + + ]: 3001 : do ifreq=1,green%nw
961 : 3000 : write(message,'(2x,2(es24.16e3,2x))') green%omega(ifreq),(-aimag(sf_corr(ifreq)))/pi
962 : 3001 : call wrtout(spcorb_unt,message,'COLL')
963 : : end do ! ifreq
964 : 2 : close(spcorb_unt)
965 : : end do ! iatom
966 [ - + ]: 1 : ABI_FREE(sf_corr)
967 : : end if ! dmft_kspectralfunc=1
968 : : end if ! (green%w_type == "real" .and. option >= 4) .and. green%oper(1)%has_operks == 1
969 : :
970 [ - + - - ]: 1 : if (optwt == 2 .and. (option == 1 .or. option == 3)) green%fileprt_tau = 1 ! file for G(tau) has been created here
971 : :
972 : 1 : end subroutine print_green
973 : : !!***
974 : :
975 : : !!****f* m_green/compute_green_batched_core
976 : : !! NAME
977 : : !! compute_green_batched_core
978 : : !!
979 : : !! FUNCTION
980 : : !! Variant for core loop of compute green function, useful for computation on GPU
981 : : !!
982 : : !! INPUTS
983 : : !! green <type(green_type)>= green function data
984 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
985 : : !! prtopt : option for printing
986 : : !! self <type(self_type)>= variables related to self-energy
987 : : !! opt_self = optional argument, if =1, upfold self-energy
988 : : !! opt_log = if 1, compute Tr(log(G))
989 : : !!
990 : : !! OUTPUT
991 : : !!
992 : : !! SOURCE
993 : 0 : subroutine compute_green_batched_core(green,paw_dmft,self,optself,optlog)
994 : :
995 : : use m_abi_linalg, only : abi_xgemm
996 : : use m_matlu, only : add_matlu,sym_matlu
997 : : use m_oper, only : downfold_oper,inverse_oper,upfold_oper
998 : : use m_time, only : timab
999 : :
1000 : : !Arguments ------------------------------------
1001 : : type(green_type), target, intent(inout) :: green
1002 : : type(paw_dmft_type), target, intent(in) :: paw_dmft
1003 : : type(self_type), intent(inout) :: self
1004 : : integer, intent(in) :: optlog,optself
1005 : : !Local variables-------------------------------
1006 : : logical :: oper_ndat_allocated
1007 : : integer :: diag,ib,ib1,ifreq,ikpt,info,isppol,lwork,mbandc,ifreq_beg,ifreq_end,idat
1008 : : integer :: me_kpt,mkmem,myproc,natom,nkpt,nmoments,nspinor,nsppol,gpu_option,ndat
1009 : : integer :: option,shift,shift_green,spacecomm,optoper_ksloc
1010 : : real(dp) :: fermilevel,wtk,temp
1011 : : complex(dp) :: green_tmp,trace_tmp
1012 : 0 : real(dp), allocatable :: eig(:),rwork(:),fac(:)
1013 : 0 : complex(dp), allocatable :: mat_tmp(:,:),work(:),omega_current(:)
1014 : 0 : type(oper_type), target :: green_oper_ndat
1015 : 0 : real(dp), contiguous, pointer :: eigen_dft(:,:,:)
1016 : 0 : complex(dp), contiguous, pointer :: ks(:,:,:,:),occup_ks(:,:,:,:)
1017 : : ! *********************************************************************
1018 : :
1019 : : ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_GREEN_BATCHED)
1020 : :
1021 : 0 : diag = 1 - optself
1022 : :
1023 : : ! Initialise spaceComm, myproc, and nproc
1024 : 0 : me_kpt = green%distrib%me_kpt
1025 : 0 : myproc = paw_dmft%myproc
1026 : 0 : spacecomm = paw_dmft%spacecomm
1027 : 0 : oper_ndat_allocated = .false.
1028 : :
1029 : : ! Initialise integers
1030 : 0 : mbandc = paw_dmft%mbandc
1031 : 0 : natom = paw_dmft%natom
1032 : 0 : nkpt = paw_dmft%nkpt
1033 : 0 : nspinor = paw_dmft%nspinor
1034 : 0 : nsppol = paw_dmft%nsppol
1035 : 0 : temp = paw_dmft%temp
1036 : 0 : gpu_option = paw_dmft%gpu_option
1037 : :
1038 : 0 : if (optlog == 1) then
1039 [ # # # # : 0 : ABI_MALLOC(eig,(mbandc))
# # # # #
# # # ]
1040 [ # # # # : 0 : ABI_MALLOC(work,(2*mbandc-1))
# # # # #
# # # #
# ]
1041 [ # # # # : 0 : ABI_MALLOC(rwork,(3*mbandc-2))
# # # # #
# # # #
# ]
1042 [ # # # # : 0 : ABI_MALLOC(mat_tmp,(mbandc,mbandc))
# # # # #
# # # # #
# # ]
1043 : 0 : call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),-1,rwork(:),info)
1044 : 0 : lwork = int(work(1))
1045 : 0 : ABI_FREE(work)
1046 [ # # # # : 0 : ABI_MALLOC(work,(lwork))
# # # # #
# # # ]
1047 : 0 : green%trace_log = zero
1048 : : end if ! optlog=1
1049 : :
1050 : 0 : fermilevel = paw_dmft%fermie
1051 : :
1052 : : ! option for downfold_oper
1053 : 0 : option = 1
1054 [ # # ]: 0 : if (diag == 1) option = 3
1055 : :
1056 : : ! ================================
1057 : : ! == Compute Green function G(k)
1058 : : ! ================================
1059 [ # # # # : 0 : green%occup%ks(:,:,:,:) = czero
# # # # ]
1060 : :
1061 : 0 : nmoments = 1
1062 : : if (green%has_moments == 1) then
1063 : : nmoments = green%nmoments
1064 : : end if ! moments
1065 : :
1066 : 0 : shift = green%distrib%shiftk
1067 : 0 : mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
1068 : 0 : shift_green = shift
1069 : 0 : ndat = green%distrib%nw_mem_kptparal(green%distrib%me_freq+1)
1070 [ # # ]: 0 : if (green%oper(1)%has_operks == 0) shift_green = 0
1071 : :
1072 [ # # ]: 0 : if(green%oper(1)%has_opermatlu==0) optoper_ksloc=1
1073 [ # # ]: 0 : if(green%oper(1)%has_opermatlu==1) optoper_ksloc=3
1074 : :
1075 [ # # ]: 0 : do ifreq=1,green%nw
1076 [ # # ]: 0 : if (green%distrib%proct(ifreq) == green%distrib%me_freq) then
1077 : 0 : ifreq_beg = ifreq; ifreq_end = ifreq_beg + ndat - 1
1078 : 0 : exit
1079 : : end if
1080 : : end do
1081 : :
1082 [ # # # # : 0 : ABI_MALLOC(omega_current,(green%nw))
# # # # #
# # # ]
1083 [ # # # # : 0 : ABI_MALLOC(fac,(green%nw))
# # # # #
# # # ]
1084 : : ! Initialise for compiler
1085 [ # # ]: 0 : omega_current = czero
1086 [ # # ]: 0 : do ifreq=1,green%nw
1087 : : !if(present(iii)) write(6,*) ch10,'ifreq self', ifreq,self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
1088 : : ! ====================================================
1089 : : ! First Upfold self-energy and double counting Self_imp -> self(k)
1090 : : ! ====================================================
1091 : : ! if(mod(ifreq-1,nproc)==myproc) then
1092 : : ! write(6,*) "compute_green ifreq",ifreq, mod(ifreq-1,nproc)==myproc,proct(ifreq,myproc)==1
1093 [ # # ]: 0 : if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
1094 [ # # ]: 0 : if (green%w_type == "imag") then
1095 : 0 : omega_current(ifreq) = cmplx(zero,green%omega(ifreq),kind=dp)
1096 : 0 : fac(ifreq) = two * paw_dmft%wgt_wlo(ifreq) * paw_dmft%temp
1097 [ # # ]: 0 : else if (green%w_type == "real") then
1098 : 0 : omega_current(ifreq) = cmplx(green%omega(ifreq),paw_dmft%temp,kind=dp)
1099 : : end if ! green%w_type
1100 : :
1101 [ # # ]: 0 : if (green%oper(ifreq)%has_operks == 0) then
1102 [ # # # # : 0 : ABI_MALLOC(green%oper(ifreq)%ks,(mbandc,mbandc,mkmem,nsppol))
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
1103 : 0 : green%oper(ifreq)%nkpt = mkmem
1104 : 0 : green%oper(ifreq)%paral = 1
1105 : 0 : green%oper(ifreq)%shiftk = shift
1106 : : end if
1107 [ # # ]: 0 : if(.not. oper_ndat_allocated) then
1108 : 0 : call init_oper_ndat(paw_dmft,green_oper_ndat,ndat,nkpt=green%oper(ifreq)%nkpt,opt_ksloc=optoper_ksloc,gpu_option=gpu_option)
1109 [ # # ]: 0 : if (green%oper(ifreq)%has_operks == 0) then
1110 : 0 : green_oper_ndat%paral = 1
1111 : 0 : green_oper_ndat%shiftk = shift
1112 : : end if
1113 : : oper_ndat_allocated=.true.
1114 : : end if
1115 : : end do ! ifreq
1116 : :
1117 [ # # ]: 0 : if (optself == 0) then
1118 [ # # ]: 0 : if(green_oper_ndat%gpu_option==ABI_GPU_DISABLED) then
1119 [ # # # # : 0 : green_oper_ndat%ks(:,:,:,:) = czero
# # # # ]
1120 [ # # ]: 0 : else if(green_oper_ndat%gpu_option==ABI_GPU_OPENMP) then
1121 : 0 : call gpu_set_to_zero_complex(green_oper_ndat%ks, int(nsppol,c_size_t)*ndat*mbandc*mbandc*mkmem)
1122 : : end if
1123 : 0 : call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.false.)
1124 : : else
1125 [ # # ]: 0 : do ifreq=ifreq_beg,ifreq_end
1126 : 0 : call add_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),green%oper(ifreq)%matlu(:),natom,-1)
1127 : : end do
1128 : 0 : call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.false.)
1129 : 0 : call upfold_oper(green_oper_ndat,paw_dmft,procb=green%distrib%procb(:),iproc=me_kpt,gpu_option=gpu_option)
1130 : : end if ! optself
1131 : :
1132 : 0 : ks => green_oper_ndat%ks
1133 : 0 : eigen_dft => paw_dmft%eigen_dft
1134 [ # # ]: 0 : if(gpu_option==ABI_GPU_DISABLED) then
1135 [ # # ]: 0 : do ifreq=ifreq_beg,ifreq_end
1136 [ # # ]: 0 : do isppol=1,nsppol
1137 [ # # ]: 0 : do ikpt=1,mkmem
1138 [ # # ]: 0 : do ib=1,mbandc
1139 : 0 : idat=ifreq-(ifreq_end-ndat)
1140 : 0 : green_tmp = omega_current(ifreq) + fermilevel - eigen_dft(ib,ikpt+shift,isppol)
1141 [ # # ]: 0 : if (optself == 0) then
1142 : 0 : ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = cone / green_tmp
1143 : : else
1144 : : ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = &
1145 : 0 : & ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) + green_tmp
1146 : : end if
1147 : : end do ! ib
1148 : : end do ! ikpt
1149 : : end do ! isppol
1150 : : end do ! ifreq
1151 : : else if(gpu_option==ABI_GPU_OPENMP) then
1152 : : #ifdef HAVE_OPENMP_OFFLOAD
1153 : : if (optself == 0) then
1154 : : !$OMP TARGET TEAMS DISTRIBUTE MAP(to:ks,eigen_dft) PRIVATE(ifreq,idat)
1155 : : do ifreq=ifreq_beg,ifreq_end
1156 : : idat=ifreq-(ifreq_end-ndat)
1157 : : !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(isppol,ikpt,ib,green_tmp)
1158 : : do isppol=1,nsppol
1159 : : do ikpt=1,mkmem
1160 : : do ib=1,mbandc
1161 : : green_tmp = omega_current(ifreq) + fermilevel - eigen_dft(ib,ikpt+shift,isppol)
1162 : : ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = cone / green_tmp
1163 : : end do ! ib
1164 : : end do ! ikpt
1165 : : end do ! isppol
1166 : : end do ! ifreq
1167 : : else
1168 : : !$OMP TARGET TEAMS DISTRIBUTE MAP(to:ks,eigen_dft) PRIVATE(ifreq,idat)
1169 : : do ifreq=ifreq_beg,ifreq_end
1170 : : idat=ifreq-(ifreq_end-ndat)
1171 : : !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(isppol,ikpt,ib,green_tmp)
1172 : : do isppol=1,nsppol
1173 : : do ikpt=1,mkmem
1174 : : do ib=1,mbandc
1175 : : green_tmp = omega_current(ifreq) + fermilevel - eigen_dft(ib,ikpt+shift,isppol)
1176 : : ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) = &
1177 : : & ks(ib,ib+(idat-1)*mbandc,ikpt+shift_green,isppol) + green_tmp
1178 : : end do ! ib
1179 : : end do ! ikpt
1180 : : end do ! isppol
1181 : : end do ! ifreq
1182 : : end if
1183 : : #endif
1184 : : end if
1185 : :
1186 [ # # ]: 0 : if (optself /= 0) then
1187 : 0 : call inverse_oper(green_oper_ndat,1,procb=green%distrib%procb(:),iproc=me_kpt,gpu_option=gpu_option)
1188 : : end if
1189 : :
1190 [ # # ]: 0 : if (optlog == 1) then
1191 : 0 : call copy_oper_from_ndat(green_oper_ndat,green%oper,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.true.)
1192 [ # # ]: 0 : do ifreq=1,green%nw
1193 [ # # ]: 0 : if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
1194 : : trace_tmp = czero
1195 [ # # ]: 0 : do isppol=1,nsppol
1196 [ # # ]: 0 : do ikpt=1,mkmem
1197 : 0 : wtk = green%oper(ifreq)%wtk(ikpt+shift)
1198 [ # # ]: 0 : if (optself == 0) then
1199 [ # # ]: 0 : do ib=1,mbandc
1200 : 0 : trace_tmp = trace_tmp + two*temp*wtk*log(green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol)*omega_current(ifreq))
1201 : : end do ! ib
1202 : : else
1203 : : ! Use Tr(log(G(iw))) + Tr(log(G(-iw))) = Tr(log(G(iw)G(iw)^H)) so that we can use the much faster zheev instead of
1204 : : ! zgeev. Even if G(iw) and G(iw)^H have no reason to commute, this equality still holds since we only care about the trace.
1205 : : call abi_xgemm("n","c",mbandc,mbandc,mbandc,cone,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol), &
1206 : 0 : & mbandc,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol),mbandc,czero,mat_tmp(:,:),mbandc)
1207 : 0 : call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),lwork,rwork(:),info)
1208 : : ! Do not use DOT_PRODUCT
1209 [ # # ]: 0 : trace_tmp = trace_tmp + sum(log(eig(:)*omega_current(ifreq)))*wtk*temp
1210 : : end if ! optself
1211 : : end do ! ikpt
1212 : : end do ! isppol
1213 [ # # ]: 0 : if (nsppol == 1 .and. nspinor == 1) trace_tmp = trace_tmp * two
1214 : 0 : green%trace_log = green%trace_log + dble(trace_tmp)
1215 : : end do ! ifreq
1216 : 0 : call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.true.)
1217 : : end if ! optlog=1
1218 : :
1219 [ # # ]: 0 : if (green%w_type /= "real") then
1220 : : ABI_NVTX_START_RANGE(NVTX_DMFT_ADD_INT_FCT)
1221 : 0 : occup_ks => green%occup%ks
1222 : 0 : ks => green_oper_ndat%ks
1223 [ # # ]: 0 : if(gpu_option==ABI_GPU_DISABLED) then
1224 [ # # ]: 0 : do ifreq=ifreq_beg,ifreq_end
1225 : :
1226 [ # # ]: 0 : do isppol=1,nsppol
1227 [ # # ]: 0 : do ikpt=1,mkmem
1228 [ # # ]: 0 : do ib1=1,mbandc
1229 : 0 : idat=ifreq-(ifreq_end-ndat)
1230 [ # # ]: 0 : if (diag == 1) then
1231 : : green%occup%ks(ib1,ib1,ikpt+shift,isppol) = green%occup%ks(ib1,ib1,ikpt+shift,isppol) + &
1232 : 0 : & fac(ifreq)*green_oper_ndat%ks(ib1,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
1233 : : else
1234 [ # # ]: 0 : do ib=1,mbandc
1235 : : green%occup%ks(ib,ib1,ikpt+shift,isppol) = green%occup%ks(ib,ib1,ikpt+shift,isppol) + &
1236 : 0 : & fac(ifreq)*green_oper_ndat%ks(ib,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
1237 : : end do ! ib
1238 : : end if ! diag
1239 : : end do ! ib1
1240 : : end do ! ikpt
1241 : : end do ! isppol
1242 : :
1243 : : end do ! ifreq
1244 : : else if(gpu_option==ABI_GPU_OPENMP) then
1245 : : #ifdef HAVE_OPENMP_OFFLOAD
1246 : : if (diag == 1) then
1247 : : !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
1248 : : !$OMP& MAP(tofrom:occup_ks) MAP(to:ks,fac) PRIVATE(isppol,ikpt)
1249 : : do isppol=1,nsppol
1250 : : do ikpt=1,mkmem
1251 : : !$OMP PARALLEL DO PRIVATE(ib1,ifreq,idat)
1252 : : do ib1=1,mbandc
1253 : : do ifreq=ifreq_beg,ifreq_end
1254 : : idat=ifreq-(ifreq_end-ndat)
1255 : : occup_ks(ib1,ib1,ikpt+shift,isppol) = occup_ks(ib1,ib1,ikpt+shift,isppol) + &
1256 : : & fac(ifreq)*ks(ib1,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
1257 : : end do ! ifreq
1258 : : end do ! ib1
1259 : : end do ! ikpt
1260 : : end do ! isppol
1261 : :
1262 : : else
1263 : :
1264 : : !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(3) &
1265 : : !$OMP& MAP(tofrom:occup_ks) MAP(to:ks,fac) PRIVATE(isppol,ikpt,ib1)
1266 : : do isppol=1,nsppol
1267 : : do ikpt=1,mkmem
1268 : : do ib1=1,mbandc
1269 : : !$OMP PARALLEL DO PRIVATE(ib,ifreq,idat)
1270 : : do ib=1,mbandc
1271 : : do ifreq=ifreq_beg,ifreq_end
1272 : : idat=ifreq-(ifreq_end-ndat)
1273 : : occup_ks(ib,ib1,ikpt+shift,isppol) = occup_ks(ib,ib1,ikpt+shift,isppol) + &
1274 : : & fac(ifreq)*ks(ib,ib1+(idat-1)*mbandc,ikpt+shift_green,isppol)
1275 : : end do ! ib
1276 : : end do ! ib1
1277 : : end do ! ikpt
1278 : : end do ! isppol
1279 : : end do ! ifreq
1280 : :
1281 : : end if ! diag
1282 : : #endif
1283 : : end if
1284 : : ABI_NVTX_END_RANGE()
1285 : : end if ! w_type/="real"
1286 : :
1287 [ # # # # ]: 0 : if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
1288 : : call downfold_oper(green_oper_ndat,paw_dmft,&
1289 : 0 : & procb=green%distrib%procb(:),iproc=me_kpt,option=option,gpu_option=gpu_option)
1290 : : end if ! lchipsiortho=1
1291 : :
1292 : : call copy_oper_from_ndat(green_oper_ndat,green%oper,ndat,green%nw,green%distrib%proct,&
1293 : 0 : & green%distrib%me_freq,green%oper(ifreq_beg)%has_operks /= 0)
1294 : :
1295 [ # # ]: 0 : do ifreq=1,green%nw
1296 [ # # ]: 0 : if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
1297 [ # # ]: 0 : if (green%oper(ifreq)%has_operks == 0) then
1298 [ # # ]: 0 : ABI_FREE(green%oper(ifreq)%ks)
1299 : : end if
1300 : : end do ! ifreq
1301 : :
1302 : 0 : call destroy_oper(green_oper_ndat)
1303 [ # # ]: 0 : ABI_FREE(omega_current)
1304 [ # # ]: 0 : ABI_FREE(fac)
1305 : :
1306 : : ABI_NVTX_END_RANGE()
1307 : :
1308 [ # # # # : 0 : end subroutine compute_green_batched_core
# # # # #
# # # # #
# # # # ]
1309 : : !!***
1310 : :
1311 : : !!****f* m_green/compute_green
1312 : : !! NAME
1313 : : !! compute_green
1314 : : !!
1315 : : !! FUNCTION
1316 : : !! compute green function from DFT and self-energy
1317 : : !!
1318 : : !! INPUTS
1319 : : !! green <type(green_type)>= green function data
1320 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
1321 : : !! prtopt : option for printing
1322 : : !! self <type(self_type)>= variables related to self-energy
1323 : : !! opt_self = optional argument, if =1, upfold self-energy
1324 : : !! opt_nonxsum = 0 : do usual xsum after calculation of green(freq)%ks
1325 : : !! = 1 : do not do xsum after calculation of green(freq)%ks: each proc as only a part
1326 : : !! of the data: this is useful where only the total number of electron will be computed.
1327 : : !! opt_nonxsum2 0 : green(ifreq)%matlu will be broadcasted
1328 : : !! 1 : green(ifreq)%matlu will not be broadcasted in compute_green: calc
1329 : : !! if occupations will not possible.
1330 : : !! (a keyword: compute_local_green would be in fact equivalent and more clear)
1331 : : !! opt_log = if 1, compute Tr(log(G))
1332 : : !! opt_restart_moments = if 1, activate quick restart for calculation of the high frequency moments
1333 : : !! (useful when compute_green is called after fermi_green)
1334 : : !!
1335 : : !! OUTPUT
1336 : : !!
1337 : : !! SOURCE
1338 : :
1339 : 4884 : subroutine compute_green(green,paw_dmft,prtopt,self,opt_self,opt_nonxsum,opt_nonxsum2,opt_log,opt_restart_moments)
1340 : :
1341 : : !Arguments ------------------------------------
1342 : : type(green_type), intent(inout) :: green
1343 : : type(paw_dmft_type), intent(in) :: paw_dmft
1344 : : !type(MPI_type), intent(in) :: mpi_enreg
1345 : : type(self_type), intent(inout) :: self
1346 : : integer, intent(in) :: prtopt
1347 : : integer, optional, intent(in) :: opt_log,opt_nonxsum,opt_nonxsum2,opt_restart_moments,opt_self
1348 : : !Local variables-------------------------------
1349 : : !logical :: lintegrate
1350 : : integer :: band_index,diag,i,ib,ierr,ifreq,ikpt,info,isppol,lwork,mbandc
1351 : : integer :: me_kpt,mkmem,myproc,natom,nband_k,nkpt,nmoments,nspinor,nsppol
1352 : : integer :: opt_quick_restart,option,optlog,optnonxsum,optnonxsum2,optself
1353 : : integer :: shift,shift_green,spacecomm,gpu_option
1354 : : real(dp) :: beta,correction,eigen,fac,fermilevel,freq2,temp,wtk
1355 : : complex(dp) :: green_tmp,omega_current,trace_tmp
1356 : : character(len=500) :: message
1357 : : real(dp) :: tsec(2)
1358 : 4884 : real(dp), allocatable :: eig(:),rwork(:)
1359 : 4884 : complex(dp), allocatable :: mat_tmp(:,:),omega_fac(:),work(:)
1360 : : #ifdef HAVE_OPENMP_OFFLOAD
1361 : : integer :: ndat
1362 : : type(oper_type), target :: green_oper_ndat
1363 : : #endif
1364 : : ! integer, allocatable :: procb(:,:),proct(:,:)
1365 : : ! *********************************************************************
1366 : :
1367 : : ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_GREEN)
1368 : : !lintegrate=.true.
1369 : : !if(lintegrate.and.green%w_type=="real") then
1370 : : !if(green%w_type=="real") then
1371 : : ! message = 'integrate_green not implemented for real frequency'
1372 : : ! ABI_BUG(message)
1373 : : !endif
1374 : 4884 : call timab(624,1,tsec(:))
1375 : 4884 : optself = 0
1376 [ + - ]: 4884 : if (present(opt_self)) optself = opt_self
1377 : 4884 : optnonxsum = 0
1378 [ + - ]: 4884 : if (present(opt_nonxsum)) optnonxsum = opt_nonxsum
1379 : 4884 : optnonxsum2 = 0
1380 [ + + ]: 4884 : if (present(opt_nonxsum2)) optnonxsum2 = opt_nonxsum2
1381 : 4884 : optlog = 0
1382 [ + + ]: 4884 : if (present(opt_log)) optlog = opt_log
1383 : 4884 : opt_quick_restart = 0
1384 [ + + ]: 4884 : if (present(opt_restart_moments)) opt_quick_restart = opt_restart_moments
1385 : :
1386 : 4884 : diag = 1 - optself
1387 : :
1388 [ + + ]: 4884 : if (prtopt > 0) then
1389 : 434 : write(message,'(2a)') ch10," === Compute Green's function "
1390 : 434 : call wrtout(std_out,message,'COLL')
1391 : : end if ! prtopt>0
1392 : :
1393 [ - + ]: 4884 : if (self%nw /= green%nw) then
1394 : 0 : message = ' BUG: frequencies for green and self not coherent'
1395 : 0 : ABI_BUG(message)
1396 : : end if
1397 : :
1398 : : ! Initialise spaceComm, myproc, and nproc
1399 : 4884 : me_kpt = green%distrib%me_kpt
1400 : 4884 : myproc = paw_dmft%myproc
1401 : : !nproc = paw_dmft%nproc
1402 : 4884 : spacecomm = paw_dmft%spacecomm
1403 : :
1404 : : ! Initialise integers
1405 : : !mband = paw_dmft%mband
1406 : 4884 : mbandc = paw_dmft%mbandc
1407 : 4884 : natom = paw_dmft%natom
1408 : 4884 : nkpt = paw_dmft%nkpt
1409 : 4884 : nspinor = paw_dmft%nspinor
1410 : 4884 : nsppol = paw_dmft%nsppol
1411 : 4884 : temp = paw_dmft%temp
1412 : 4884 : gpu_option = paw_dmft%gpu_option
1413 : :
1414 [ - + ]: 4884 : if (optlog == 1) then
1415 [ # # # # : 0 : ABI_MALLOC(eig,(mbandc))
# # # # #
# # # ]
1416 [ # # # # : 0 : ABI_MALLOC(work,(2*mbandc-1))
# # # # #
# # # #
# ]
1417 [ # # # # : 0 : ABI_MALLOC(rwork,(3*mbandc-2))
# # # # #
# # # #
# ]
1418 [ # # # # : 0 : ABI_MALLOC(mat_tmp,(mbandc,mbandc))
# # # # #
# # # # #
# # ]
1419 : 0 : call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),-1,rwork(:),info)
1420 : 0 : lwork = int(work(1))
1421 : 0 : ABI_FREE(work)
1422 [ # # # # : 0 : ABI_MALLOC(work,(lwork))
# # # # #
# # # ]
1423 : 0 : green%trace_log = zero
1424 : : end if ! optlog=1
1425 : :
1426 : : !icomp_chloc = 0
1427 : :
1428 : : option = 1
1429 : 4884 : fermilevel = paw_dmft%fermie
1430 : : if (option == 123) then
1431 : : fermilevel = two
1432 : : write(message,'(2a,e14.3,a)') ch10,' Warning (special case for check: fermi level=',fermilevel,')'
1433 : : call wrtout(std_out,message,'COLL')
1434 : : end if ! option=123
1435 : :
1436 [ + + ]: 4884 : option = merge(3,1,diag==1) ! option for downfold_oper
1437 : :
1438 : : ! ====================================================
1439 : : ! Upfold self-energy and double counting Self_imp -> self(k)
1440 : : ! ====================================================
1441 : : ! if(optself==1) then
1442 : : ! do ifreq=1,green%nw
1443 : : ! call upfold_oper(self%oper(ifreq),paw_dmft,1)
1444 : : ! enddo ! ifreq
1445 : : ! call upfold_oper(self%hdc,paw_dmft,1)
1446 : : ! endif
1447 : :
1448 : : ! ================================
1449 : : ! == Compute Green function G(k)
1450 : : ! ================================
1451 [ + + + + : 7124010 : green%occup%ks(:,:,:,:) = czero
+ + + + ]
1452 : :
1453 : 4884 : nmoments = 1
1454 [ - + ]: 4884 : if (green%has_moments == 1) then
1455 : 0 : nmoments = green%nmoments
1456 : : call compute_moments_ks(green,self,paw_dmft,opt_self=optself,opt_log=optlog, &
1457 : 0 : & opt_quick_restart=opt_quick_restart)
1458 [ # # # # ]: 0 : if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
1459 : 0 : call downfold_oper(green%moments(1),paw_dmft,option=2)
1460 [ # # ]: 0 : do i=2,green%nmoments
1461 : 0 : call downfold_oper(green%moments(i),paw_dmft,option=option)
1462 : : end do ! i
1463 [ # # ]: 0 : do i=1,green%nmoments
1464 : 0 : call xmpi_matlu(green%moments(i)%matlu(:),natom,green%distrib%comm_kpt)
1465 : 0 : call sym_matlu(green%moments(i)%matlu(:),paw_dmft)
1466 : : end do ! i
1467 : : end if ! lchipsiortho=1
1468 : : end if ! moments
1469 : :
1470 [ + + ]: 4884 : if (green%w_type /= "real") then
1471 [ - + + - : 14640 : ABI_MALLOC(omega_fac,(nmoments))
+ - + - -
+ - + ]
1472 [ + + ]: 9760 : do i=1,nmoments
1473 : 4880 : omega_fac(i) = czero
1474 [ + + ]: 991739 : do ifreq=green%nw,1,-1 ! NEVER change the summation order and DON'T use the intrinsic SUM
1475 : 991739 : omega_fac(i) = omega_fac(i) + paw_dmft%wgt_wlo(ifreq) / (paw_dmft%omega_lo(ifreq))**i
1476 : : end do
1477 : 4880 : omega_fac(i) = - two * temp * omega_fac(i) / (j_dpc)**i
1478 [ + - ]: 4880 : if (i == 1) omega_fac(i) = omega_fac(i) + half
1479 [ - + ]: 4880 : if (i == 2) omega_fac(i) = omega_fac(i) - cone/(four*temp)
1480 [ - + ]: 9760 : if (i == 4) omega_fac(i) = omega_fac(i) + cone/(dble(48)*(temp**3))
1481 : : end do ! i
1482 : : end if ! w_type
1483 : :
1484 : 4884 : shift = green%distrib%shiftk
1485 : 4884 : mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
1486 [ + + ]: 4884 : shift_green = merge(0,shift,green%oper(1)%has_operks==0)
1487 : :
1488 : :
1489 [ - + ]: 4884 : if(mkmem>0 .and. gpu_option==ABI_GPU_OPENMP) then
1490 : 0 : call compute_green_batched_core(green,paw_dmft,self,optself,optlog)
1491 [ + + ]: 4884 : else if(mkmem>0) then
1492 : : ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_GREEN_LOOP)
1493 : : ! Initialise for compiler
1494 : 4763 : omega_current = czero
1495 [ + + ]: 999750 : do ifreq=1,green%nw
1496 : : !if(present(iii)) write(6,*) ch10,'ifreq self', ifreq,self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
1497 : : ! ====================================================
1498 : : ! First Upfold self-energy and double counting Self_imp -> self(k)
1499 : : ! ====================================================
1500 : : ! if(mod(ifreq-1,nproc)==myproc) then
1501 : : ! write(6,*) "compute_green ifreq",ifreq, mod(ifreq-1,nproc)==myproc,proct(ifreq,myproc)==1
1502 [ + - ]: 994987 : if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
1503 [ + + ]: 994987 : if (green%w_type == "imag") then
1504 : 982987 : omega_current = cmplx(zero,green%omega(ifreq),kind=dp)
1505 : 982987 : fac = two * paw_dmft%wgt_wlo(ifreq) * temp
1506 [ + - ]: 12000 : else if (green%w_type == "real") then
1507 : 12000 : omega_current = cmplx(green%omega(ifreq),paw_dmft%temp,kind=dp)
1508 : : end if ! green%w_type
1509 : :
1510 [ + + ]: 994987 : if (green%oper(ifreq)%has_operks == 0) then
1511 [ - + + - : 5897922 : ABI_MALLOC(green%oper(ifreq)%ks,(mbandc,mbandc,mkmem,nsppol))
- + + - -
+ + - - +
+ - + - +
- - + - +
- + ]
1512 : 982987 : green%oper(ifreq)%nkpt = mkmem
1513 : 982987 : green%oper(ifreq)%paral = 1
1514 : 982987 : green%oper(ifreq)%shiftk = shift
1515 : : end if
1516 : :
1517 [ + + ]: 994987 : if (optself == 0) then
1518 [ + + + + : 24492174 : green%oper(ifreq)%ks(:,:,:,:) = czero
+ + + + ]
1519 : : else
1520 : 949905 : call add_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),green%oper(ifreq)%matlu(:),natom,-1)
1521 : : ! do iatom = 1 , natom
1522 : : !write(6,*) 'self matlu', ifreq, self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
1523 : : !write(6,*) 'self hdc ', ifreq, self%hdc%matlu(1)%mat(1,1,1,1,1)
1524 : : !write(6,*) 'self_minus_hdc_oper ', ifreq, self_minus_hdc_oper%matlu(1)%mat(1,1,1,1,1)
1525 : : ! enddo ! natom
1526 : : !if(paw_dmft%dmft_solv==4) then
1527 : : ! call shift_matlu(self_minus_hdc_oper%matlu,paw_dmft%natom,cmplx(self%qmc_shift,0.d0,kind=dp),-1)
1528 : : ! call shift_matlu(self_minus_hdc_oper%matlu,paw_dmft%natom,cmplx(self%qmc_xmu,0.d0,kind=dp),-1)
1529 : : !endif
1530 : 949905 : call upfold_oper(green%oper(ifreq),paw_dmft,procb=green%distrib%procb(:),iproc=me_kpt)
1531 : : end if ! optself
1532 : :
1533 [ + + ]: 2670781 : do isppol=1,nsppol
1534 [ + + ]: 11483801 : do ikpt=1,mkmem
1535 [ + + ]: 68181838 : do ib=1,mbandc
1536 : 57693024 : green_tmp = omega_current + fermilevel - paw_dmft%eigen_dft(ib,ikpt+shift,isppol)
1537 [ + + ]: 66506044 : if (optself == 0) then
1538 : 2856368 : green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol) = cone / green_tmp
1539 : : else
1540 : : green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol) = &
1541 : 54836656 : & green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol) + green_tmp
1542 : : end if
1543 : : end do ! ib
1544 : : end do ! ikpt
1545 : : end do ! isppol
1546 : :
1547 : : ! do ib1 = 1 , paw_dmft%mbandc
1548 : : ! do ib = 1 , paw_dmft%mbandc
1549 : : ! do ikpt = 1 , paw_dmft%nkpt
1550 : : ! do is = 1 , paw_dmft%nsppol
1551 : : ! if (green%procb(ifreq,ikpt)==myproc) then
1552 : : ! green%oper(ifreq)%ks(is,ikpt,ib,ib1)= &
1553 : : ! green_temp%ks(is,ikpt,ib,ib1)= &
1554 : : !& ( omega_current &
1555 : : !& + fermilevel &
1556 : : !& - paw_dmft%eigen_dft(is,ikpt,ib)) * Id(ib,ib1) &
1557 : : !& - self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
1558 : : !if(ikpt==2.and.ib==ib1) then
1559 : : ! write(6,*)
1560 : : ! "self",ib1,ib,ikpt,is,ifreq,self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
1561 : : !endif
1562 : : !& -
1563 : : !(self%oper(ifreq)%ks(is,ikpt,ib,ib1)-self%hdc%ks(is,ikpt,ib,ib1))
1564 : : ! if(prtopt>5) then
1565 : : ! if(ikpt==1.and.(ifreq==1.or.ifreq==3).and.ib==16.and.ib1==16)
1566 : : ! then
1567 : : ! write(std_out,*) 'omega_current
1568 : : ! ',omega_current
1569 : : ! write(std_out,*) 'fermilevel
1570 : : ! ',fermilevel
1571 : : ! write(std_out,*) ' paw_dmft%eigen_dft(is,ikpt,ib) ',
1572 : : ! paw_dmft%eigen_dft(is,ikpt,ib),Id(ib,ib1)
1573 : : ! write(std_out,*)
1574 : : ! 'self_minus_hdc_oper%ks(is,ikpt,ib,ib1)',self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
1575 : : ! write(std_out,*) 'green
1576 : : ! ',green%oper(ifreq)%ks(is,ikpt,ib,ib1)
1577 : : ! endif
1578 : : ! if(ib==1.and.ib1==3) then
1579 : : ! write(std_out,*) "ff compute",ikpt,ifreq,is,ikpt,ib,ib1
1580 : : ! write(std_out,*) "ff compute",ikpt,ifreq,
1581 : : ! green_temp%ks(is,ikpt,ib,ib1)
1582 : : ! write(std_out,*) "ff details",paw_dmft%eigen_dft(is,ikpt,ib)
1583 : : ! write(std_out,*) "ff details2",fermilevel
1584 : : ! write(std_out,*) "ff details3",Id(ib,ib1)
1585 : : ! ! write(std_out,*) "ff
1586 : : ! details4",self_minus_hdc_oper%ks(is,ikpt,ib,ib1)
1587 : : ! endif
1588 : : ! endif
1589 : : ! enddo ! is
1590 : : ! enddo ! ikpt
1591 : : !enddo ! ib
1592 : : !enddo ! ib1
1593 : :
1594 : : ! call print_oper(green%oper(ifreq),9,paw_dmft,3)
1595 : : ! write(std_out,*) 'after print_oper'
1596 : : ! if(ifreq==1.or.ifreq==3) then
1597 : : ! write(std_out,*) 'after print_oper', ifreq
1598 : : ! write(std_out,*) 'green1 ifreq %ks(1,1,16,16)',ifreq,green%oper(ifreq)%ks(1,1,16,16)
1599 : : ! endif
1600 : : ! write(std_out,*) 'before inverse_oper'
1601 [ + + ]: 994987 : if (optself /= 0) then
1602 : 949905 : call inverse_oper(green%oper(ifreq),1,procb=green%distrib%procb(:),iproc=me_kpt)
1603 : : end if
1604 : : !if(ifreq==1) then
1605 : : ! write(std_out,*) "1188",green_temp%ks(1,1,8,8)
1606 : : ! write(std_out,*) "1189",green_temp%ks(1,1,8,9)
1607 : : ! write(std_out,*) "1198",green_temp%ks(1,1,9,8)
1608 : : ! write(std_out,*) "1199",green_temp%ks(1,1,9,9)
1609 : : !endif
1610 [ - + ]: 994987 : if (optlog == 1) then
1611 : 0 : freq2 = paw_dmft%omega_lo(ifreq)**2
1612 : 0 : trace_tmp = czero
1613 [ # # ]: 0 : do isppol=1,nsppol
1614 [ # # ]: 0 : do ikpt=1,mkmem
1615 : 0 : wtk = green%oper(ifreq)%wtk(ikpt+shift)
1616 [ # # ]: 0 : if (optself == 0) then
1617 [ # # ]: 0 : do ib=1,mbandc
1618 : 0 : trace_tmp = trace_tmp + two*temp*wtk*log(green%oper(ifreq)%ks(ib,ib,ikpt+shift_green,isppol)*omega_current)
1619 : : end do ! ib
1620 : : else
1621 : : ! Use Tr(log(G(iw))) + Tr(log(G(-iw))) = Tr(log(G(iw)G(iw)^H)) so that we can use the much faster zheev instead of
1622 : : ! zgeev. Even if G(iw) and G(iw)^H have no reason to commute, this equality still holds since we only care about the trace.
1623 : : call abi_xgemm("n","c",mbandc,mbandc,mbandc,cone,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol), &
1624 : 0 : & mbandc,green%oper(ifreq)%ks(:,:,ikpt+shift_green,isppol),mbandc,czero,mat_tmp(:,:),mbandc)
1625 : 0 : call zheev("n","u",mbandc,mat_tmp(:,:),mbandc,eig(:),work(:),lwork,rwork(:),info)
1626 : : ! Do not use DOT_PRODUCT
1627 [ # # ]: 0 : trace_tmp = trace_tmp + sum(log(eig(:)*freq2))*wtk*temp
1628 : : end if ! optself
1629 : : end do ! ikpt
1630 : : end do ! isppol
1631 [ # # ]: 0 : if (nsppol == 1 .and. nspinor == 1) trace_tmp = trace_tmp * two
1632 : 0 : green%trace_log = green%trace_log + dble(trace_tmp)
1633 : : end if ! optlog=1
1634 : :
1635 : : !if(lintegrate) then
1636 : : ! accumulate integration
1637 [ + + ]: 994987 : if (green%w_type /= "real") then
1638 : :
1639 : : !do isppol=1,nsppol
1640 : : ! do ikpt=1,nkpt
1641 : : ! if (green%distrib%procb(ikpt+(isppol-1)*nkpt) /= me_spkpt) cycle
1642 : :
1643 : : !do ib1=1,mbandc
1644 : : ! do ib=1,mbandc
1645 : : ! if (green%procb(ifreq,ikpt)==myproc) then
1646 : : ! call
1647 : : ! add_int_fct(ifreq,green%oper(ifreq)%ks(ib,ib1,ikpt,isppol),ib==ib1,
1648 : : ! &
1649 : : ! & omega_current,2,green%occup%ks(ib,ib1,ikpt,isppol), &
1650 : : ! & paw_dmft%temp,paw_dmft%wgt_wlo(ifreq),paw_dmft%dmft_nwlo)
1651 : :
1652 : : !endif
1653 : : ! end do ! ib
1654 : : !end do ! ib1
1655 : : ! end do ! ikpt
1656 : : !end do ! isppol
1657 : :
1658 [ + + ]: 982987 : if (diag == 1) then
1659 [ + + ]: 402510 : do ib=1,mbandc
1660 : : green%occup%ks(ib,ib,1+shift:mkmem+shift,:) = green%occup%ks(ib,ib,1+shift:mkmem+shift,:) + &
1661 [ + + + + ]: 3835334 : & fac*green%oper(ifreq)%ks(ib,ib,1+shift_green:mkmem+shift_green,:)
1662 : : end do ! ib
1663 : : else
1664 : : green%occup%ks(:,:,1+shift:mkmem+shift,:) = green%occup%ks(:,:,1+shift:mkmem+shift,:) + &
1665 [ + + + + : 492153235 : & fac*green%oper(ifreq)%ks(:,:,1+shift_green:mkmem+shift_green,:)
+ + + + ]
1666 : : end if ! diag
1667 : :
1668 : : end if ! green%wtype
1669 : :
1670 : : ! write(std_out,*) 'after inverse_oper'
1671 : : ! if(ikpt==1.and.is==1.and.ib==1.and.ib1==1) then
1672 : : ! write(6,*) 'occup(is,ikpt,ib,ib1)',ifreq,green%occup%ks(1,1,1,1),green_temp%ks(1,1,1,1)
1673 : : ! endif
1674 : : ! write(std_out,*) 'green1afterinversion %ks(1,1,16,16)',ifreq,green%oper(ifreq)%ks(1,1,16,16)
1675 : : ! endif
1676 : : ! write(std_out,*) 'before flush'
1677 : : ! call flush(std_out)
1678 : : !endif
1679 : : ! ================================
1680 : : ! == Compute Local Green function
1681 : : ! ================================
1682 : : !write(message,'(2a)') ch10,' loc'
1683 : : !call wrtout(std_out,message,'COLL')
1684 : : !call flush(std_out)
1685 [ + + + + ]: 994987 : if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
1686 : 972414 : call downfold_oper(green%oper(ifreq),paw_dmft,procb=green%distrib%procb(:),iproc=me_kpt,option=option)
1687 : : !if(ifreq==1) then
1688 : : ! write(std_out,*) "4411",green_temp%matlu(1)%mat(4,4,1,1,1)
1689 : : ! write(std_out,*) "4512",green_temp%matlu(1)%mat(4,5,1,1,2)
1690 : : ! write(std_out,*) "5421",green_temp%matlu(1)%mat(5,4,1,2,1)
1691 : : ! write(std_out,*) "5522",green_temp%matlu(1)%mat(5,5,1,2,2)
1692 : : ! write(std_out,*) "(5512)",green_temp%matlu(1)%mat(5,5,1,1,2)
1693 : : !endif
1694 : : ! write(std_out,*) ifreq,nproc,'before if after loc_oper'
1695 : : ! if(ifreq==1.or.ifreq==11) then
1696 : : ! write(std_out,*) ifreq,nproc,'before sym'
1697 : : ! call print_matlu(green%oper(ifreq)%matlu,green%oper(ifreq)%natom,2,-1,0)
1698 : : ! ! ok
1699 : : ! endif
1700 : : ! call flush(std_out)
1701 : : end if ! lchipsiortho=1
1702 : : !call copy_matlu(green_temp%matlu,green%oper(ifreq)%matlu,natom)
1703 : : ! if(ifreq==1.and.ifreq==11) then
1704 : : ! write(std_out,*) ifreq,nproc,'after sym'
1705 : : ! call print_matlu(green%oper(ifreq)%matlu,green%oper(ifreq)%natom,2,-1,0)
1706 : : ! ! ok
1707 : : ! endif
1708 [ + + ]: 999750 : if (green%oper(ifreq)%has_operks == 0) then
1709 [ - + ]: 982987 : ABI_FREE(green%oper(ifreq)%ks)
1710 : : end if
1711 : : ! call flush(std_out)
1712 : : end do ! ifreq
1713 : : ABI_NVTX_END_RANGE()
1714 : : end if
1715 : :
1716 : :
1717 [ - + ]: 4884 : if (optlog == 1) then
1718 : :
1719 [ # # ]: 0 : ABI_FREE(eig)
1720 [ # # ]: 0 : ABI_FREE(work)
1721 [ # # ]: 0 : ABI_FREE(rwork)
1722 [ # # ]: 0 : ABI_FREE(mat_tmp)
1723 : :
1724 : 0 : call xmpi_sum(green%trace_log,spacecomm,ierr)
1725 : :
1726 : 0 : correction = - log(two) * mbandc * nsppol * temp
1727 : :
1728 : 0 : band_index = 0
1729 : 0 : beta = one / paw_dmft%temp
1730 [ # # ]: 0 : do isppol=1,nsppol
1731 [ # # ]: 0 : do ikpt=1,nkpt
1732 : 0 : nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
1733 [ # # ]: 0 : do ib=1,nband_k
1734 [ # # ]: 0 : if (paw_dmft%band_in(ib)) cycle
1735 : 0 : eigen = paw_dmft%eigen(ib+band_index)
1736 [ # # ]: 0 : if (eigen-fermilevel >= zero) then
1737 : 0 : correction = correction - temp*paw_dmft%wtk(ikpt)*log(one+exp(-beta*(eigen-fermilevel)))
1738 : : else
1739 : 0 : correction = correction - temp*paw_dmft%wtk(ikpt)*(log(one+exp(beta*(eigen-fermilevel)))-beta*(eigen-fermilevel))
1740 : : end if ! eigen-fermilevel>=0
1741 : : end do ! ib
1742 : 0 : band_index = band_index + nband_k
1743 : : end do ! ikpt
1744 : : end do ! isppol
1745 [ # # ]: 0 : if (nsppol == 1 .and. nspinor == 1) correction = correction * two
1746 : :
1747 : : ! Do not use DOT_PRODUCT
1748 : : green%trace_log = green%trace_log + correction + fermilevel*paw_dmft%nelectval + &
1749 [ # # ]: 0 : & dble(sum(green%trace_moments_log_ks(1:nmoments-1)*omega_fac(1:nmoments-1)))
1750 : :
1751 : : end if ! optlog=1
1752 : :
1753 : : ! =============================================
1754 : : ! Build total green function (sum over procs).
1755 : : ! =============================================
1756 : : !call xmpi_barrier(spacecomm)
1757 : : ! call xmpi_sum(green%oper(ifreq)%ks,spacecomm,ierr)
1758 : : ! print *, "myproc, proct, ifreq ------------------- ", myproc, ifreq
1759 : : ! do ikpt=1,paw_dmft%nkpt
1760 : : ! call xmpi_bcast(green%oper(ifreq)%ks(:,ikpt,:,:),procb(ifreq,ikpt),spacecomm,ierr)
1761 : : ! enddo
1762 : : !! or
1763 [ + + + - ]: 4884 : if (optnonxsum == 0 .and. green%oper(1)%has_operks == 1) then
1764 : 4 : call gather_oper(green%oper(:),green%distrib,paw_dmft,opt_ksloc=1,opt_diag=diag)
1765 [ # # ]: 0 : else if (optnonxsum == 0 .and. green%oper(1)%has_operks == 0) then
1766 : 0 : message = 'optnonxsum=0 and green%oper(1)%has_operks=0: not compatible'
1767 : 0 : ABI_BUG(message)
1768 : : end if ! optnonxsum
1769 : : ! endif
1770 : : ! enddo ! ifreq
1771 : : ! print *,"myproc", myproc
1772 [ + + ]: 4884 : if (optnonxsum2 == 0) then
1773 [ + + + + ]: 681 : if (paw_dmft%lchipsiortho == 1 .or. optself == 1) then
1774 : 587 : call gather_oper(green%oper(:),green%distrib,paw_dmft,opt_ksloc=2,opt_commkpt=1)
1775 : :
1776 [ + - ]: 587 : if(gpu_option==ABI_GPU_DISABLED) then
1777 [ + + ]: 149153 : do ifreq=1,green%nw
1778 [ + + ]: 148566 : if (green%distrib%procf(ifreq) /= myproc) cycle
1779 : 149153 : call sym_matlu(green%oper(ifreq)%matlu(:),paw_dmft)
1780 : : end do
1781 : : else if(gpu_option==ABI_GPU_OPENMP) then
1782 : : #ifdef HAVE_OPENMP_OFFLOAD
1783 : : !FIXME: Remove those CPU-GPU transfers once gather_oper has been ported to GPU
1784 : : ! 1) Init green_oper_ndat
1785 : : ndat = green%distrib%nw_mem_kptparal(green%distrib%me_freq+1)
1786 : : do ifreq=1,green%nw
1787 : : if (green%distrib%procf(ifreq) /= myproc) cycle
1788 : : call init_oper_ndat(paw_dmft,green_oper_ndat,ndat,nkpt=green%oper(ifreq)%nkpt,opt_ksloc=2,gpu_option=gpu_option)
1789 : : if (green%oper(ifreq)%has_operks == 0) then
1790 : : green_oper_ndat%paral = 1
1791 : : green_oper_ndat%shiftk = shift
1792 : : end if
1793 : : exit
1794 : : end do
1795 : : ! 2) Copy green%oper(:)%matlu into green_oper_ndat (CPU->GPU transfer)
1796 : : call copy_oper_to_ndat(green%oper,green_oper_ndat,ndat,green%nw,green%distrib%proct,green%distrib%me_freq,.false.)
1797 : :
1798 : : ! 3) Perform sym_matlu on green_oper_ndat (GPU enabled)
1799 : : call sym_matlu(green_oper_ndat%matlu(:),paw_dmft)
1800 : :
1801 : : ! 4) Copy back green%oper(:)%matlu from green_oper_ndat (GPU->CPU transfer)
1802 : : call copy_oper_from_ndat(green_oper_ndat,green%oper,ndat,green%nw,green%distrib%proct,&
1803 : : & green%distrib%me_freq,.false.)
1804 : : ! 5) Destroy green_oper_ndat
1805 : : call destroy_oper(green_oper_ndat)
1806 : : #endif
1807 : : end if
1808 : :
1809 : 587 : call gather_oper(green%oper(:),green%distrib,paw_dmft,opt_ksloc=2)
1810 : : end if
1811 : 681 : green%has_greenmatlu_xsum = 1
1812 [ + - ]: 4203 : else if (optnonxsum2 == 1) then
1813 : 4203 : green%has_greenmatlu_xsum = 0
1814 : : end if ! optnonxsum2
1815 : : ! if(ifreq==1.or.ifreq==11) then
1816 : : ! write(std_out,*) ifreq,nproc,'after xsum'
1817 : : ! call print_matlu(green%oper(ifreq)%matlu,green%oper(ifreq)%natom,2,-1,0)
1818 : : ! ! ok
1819 : : ! endif
1820 : : !end do ! ifreq
1821 : : !call xmpi_barrier(spacecomm)
1822 : : ! write(std_out,*) 'afterxsum sym %matlu(1)%mat(2,5,1,1,1) 1',green%oper(1)%matlu(1)%mat(2,5,1,1,1)
1823 : :
1824 [ + + ]: 4884 : if (green%w_type /= "real") then
1825 : :
1826 [ + + ]: 4880 : if (green%distrib%me_freq == 0) then
1827 : :
1828 [ + + ]: 68179 : do ib=1,mbandc
1829 [ + + + + ]: 355207 : green%occup%ks(ib,ib,1+shift:mkmem+shift,:) = green%occup%ks(ib,ib,1+shift:mkmem+shift,:) + omega_fac(1)
1830 : : end do ! ib
1831 : :
1832 [ - + ]: 4759 : do i=2,nmoments
1833 [ - - ]: 4759 : if (diag == 1) then
1834 [ # # ]: 0 : do ib=1,mbandc
1835 : : green%occup%ks(ib,ib,1+shift:mkmem+shift,:) = green%occup%ks(ib,ib,1+shift:mkmem+shift,:) + &
1836 [ # # # # ]: 0 : & omega_fac(i)*green%moments(i)%ks(ib,ib,:,:)
1837 : : end do ! ib
1838 : : else
1839 : : green%occup%ks(:,:,1+shift:mkmem+shift,:) = green%occup%ks(:,:,1+shift:mkmem+shift,:) + &
1840 [ # # # # : 0 : & omega_fac(i)*green%moments(i)%ks(:,:,:,:)
# # # # ]
1841 : : end if ! diag
1842 : : end do ! i
1843 : :
1844 : : end if ! me_freq = 0
1845 : :
1846 : 4880 : call gather_oper_ks(green%occup,green%distrib,paw_dmft,opt_diag=diag)
1847 : :
1848 : : end if ! w_type/="real"
1849 : :
1850 [ + + ]: 4884 : ABI_SFREE(omega_fac)
1851 : :
1852 [ + + ]: 4884 : if (prtopt /= 0 .and. prtopt > -100) then
1853 : 470 : write(message,'(2a)') ch10," === Green's function is computed"
1854 : 470 : call wrtout(std_out,message,'COLL')
1855 : : end if
1856 : :
1857 [ + + + + : 4884 : if (prtopt /= 0 .and. prtopt > -100 .and. (paw_dmft%lchipsiortho == 1 .or. optself == 1)) then
+ + ]
1858 : 376 : write(message,'(2a)') ch10,&
1859 : 752 : & " === Local Green's function has been computed and projected on local orbitals"
1860 : 376 : call wrtout(std_out,message,'COLL')
1861 : : end if
1862 : : ! useless test
1863 [ - + - - ]: 4884 : if (abs(prtopt) >= 4 .and. prtopt > -100) then
1864 : 0 : write(message,'(2a)') ch10," == Green's function is now printed for first frequency"
1865 : 0 : call wrtout(std_out,message,'COLL')
1866 : 0 : call print_oper(green%oper(1),9,paw_dmft,3)
1867 : 0 : write(message,'(2a)') ch10," == Green's function is now printed for second frequency"
1868 : 0 : call wrtout(std_out,message,'COLL')
1869 : 0 : call print_oper(green%oper(2),9,paw_dmft,3)
1870 [ # # ]: 0 : if (paw_dmft%dmft_nwlo >= 11) then
1871 : 0 : write(message,'(2a)') ch10," == Green's function is now printed for 11th frequency"
1872 : 0 : call wrtout(std_out,message,'COLL')
1873 : 0 : call print_oper(green%oper(11),9,paw_dmft,3)
1874 : : end if
1875 : : end if
1876 : : ! call flush(std_out)
1877 : :
1878 : : ABI_NVTX_END_RANGE()
1879 : 4884 : call timab(624,2,tsec(:))
1880 : :
1881 [ - + - + : 4884 : end subroutine compute_green
- + - + ]
1882 : : !!***
1883 : :
1884 : : !!****f* m_green/integrate_green
1885 : : !! NAME
1886 : : !! integrate_green
1887 : : !!
1888 : : !! FUNCTION
1889 : : !! Integrate green function
1890 : : !!
1891 : : !! INPUTS
1892 : : !! green <type(green_type)>=green function (green%oper(:))
1893 : : !! paw_dmft <type(m_paw_dmft)>= paw+dmft data
1894 : : !! prtopt : flag for printing
1895 : : !! opt_ksloc= 1: only integrate on the KS basis
1896 : : !! 2: do the integration on the local basis
1897 : : !! (This can work only if chipsi are renormalized!!!)
1898 : : !! 3: do both calculations and test the consistency of it
1899 : : !! -1: do the integration on the KS basis, but only
1900 : : !! compute diagonal part of the band-band density matrix
1901 : : !! in order to compute the total charge for fermi_green
1902 : : !! opt_after_solver= to be activated after a call to impurity_solve
1903 : : !! opt_diff= check the change in the local charge compared to the previous iteration
1904 : : !! opt_fill_occnd= 0 (default) : do not fill paw_dmft%occnd with the Green's function occupations
1905 : : !! = 1 : fill paw_dmft%occnd with the Green's function occupations
1906 : : !! opt_self= 0 : assume the green%ks is diagonal
1907 : : !! = 1 (default) : assume there is a self-energy and green%ks is non-diagonal
1908 : : !!
1909 : : !! OUTPUT
1910 : : !! green%occup = occupations
1911 : : !!
1912 : : !! SOURCE
1913 : :
1914 : 4984 : subroutine integrate_green(green,paw_dmft,prtopt,opt_ksloc,opt_after_solver,opt_diff,opt_fill_occnd,opt_self)
1915 : :
1916 : : !Arguments ------------------------------------
1917 : : type(green_type), intent(inout) :: green
1918 : : !type(MPI_type), intent(in) :: mpi_enreg
1919 : : type(paw_dmft_type), intent(inout) :: paw_dmft
1920 : : integer, intent(in) :: prtopt
1921 : : integer, optional, intent(in) :: opt_after_solver,opt_diff,opt_fill_occnd,opt_ksloc,opt_self
1922 : : !Local variables-------------------------------
1923 : : integer :: band_index,i,iatom,ib,ib1,icomp_chloc,ifreq,ikpt,isppol
1924 : : integer :: lpawu,mbandc,myproc,natom,nband_k,nkpt,nmoments,nspinor
1925 : : integer :: nsppol,optaftsolv,optdiff,optfilloccnd,option,optksloc,optself,optiondiff
1926 : : real(dp) :: correction,diff_chloc,fac,temp
1927 : : character(len=12) :: tag
1928 : : character(len=500) :: message
1929 : : real(dp) :: tsec(2)
1930 : 4984 : complex(dp), allocatable :: omega_fac(:),shift(:)
1931 : 4984 : type(matlu_type), allocatable :: matlu_temp(:)
1932 : : ! real(dp), allocatable :: charge_loc_old(:,:)
1933 : : ! type(oper_type) :: oper_c
1934 : : ! *********************************************************************
1935 : :
1936 : : DBG_ENTER("COLL")
1937 : 4984 : call timab(625,1,tsec(:))
1938 : : ABI_NVTX_START_RANGE(NVTX_DMFT_INTEGRATE_GREEN)
1939 : :
1940 [ + + ]: 4984 : if (prtopt > 0) then
1941 : 582 : write(message,'(2a,i3,13x,a)') ch10," === Integrate Green's function"
1942 : 582 : call wrtout(std_out,message,'COLL')
1943 : : end if
1944 [ - + ]: 4984 : if (green%w_type == "real") then
1945 : 0 : message = 'integrate_green not implemented for real frequency'
1946 : 0 : ABI_BUG(message)
1947 : : end if
1948 : :
1949 : 4984 : optfilloccnd = 0
1950 [ + + ]: 4984 : if (present(opt_fill_occnd)) optfilloccnd = opt_fill_occnd
1951 : :
1952 : 4984 : optself = 1
1953 [ + + ]: 4984 : if (present(opt_self)) optself = opt_self
1954 [ + + ]: 279 : option = merge(3,1,optself==0) ! option for downfold_oper
1955 : :
1956 : : ! Initialize spaceComm, myproc, and master
1957 : : !spacecomm=paw_dmft%spacecomm
1958 : 4984 : myproc = paw_dmft%myproc
1959 : : !nproc=paw_dmft%nproc
1960 : :
1961 : : ! Initialise integers
1962 : : !mband = paw_dmft%mband
1963 : 4984 : mbandc = paw_dmft%mbandc
1964 : 4984 : natom = paw_dmft%natom
1965 : 4984 : nkpt = paw_dmft%nkpt
1966 : 4984 : nspinor = paw_dmft%nspinor
1967 : 4984 : nsppol = paw_dmft%nsppol
1968 : 4984 : temp = paw_dmft%temp
1969 : :
1970 [ + - ]: 4984 : nmoments = merge(green%nmoments,1,green%has_moments==1)
1971 : :
1972 : : ! Initialize green%oper before calculation (important for xmpi_sum)
1973 : : ! allocate(charge_loc_old(paw_dmft%natom,paw_dmft%nsppol+1))
1974 : : ! if(.not.present(opt_diff)) then ! if integrate_green is called in m_dmft after calculation of self
1975 : : ! charge_loc_old=green%charge_matlu
1976 : : ! endif
1977 : 4984 : icomp_chloc = 0
1978 : 4984 : optdiff = 0
1979 [ + + ]: 4984 : if (present(opt_diff)) optdiff = opt_diff
1980 : :
1981 : : ! Choose what to compute
1982 : 4984 : optksloc = 3
1983 [ + + ]: 4984 : if (present(opt_ksloc)) optksloc = opt_ksloc
1984 : 4984 : optaftsolv = 0
1985 [ + + ]: 4984 : if (present(opt_after_solver)) optaftsolv = opt_after_solver
1986 : :
1987 [ + - - + ]: 103 : if (optaftsolv == 1 .and. abs(optksloc) /= 2) then
1988 : 0 : message = "integration of ks green function should not be done after call to solver : it has not been computed"
1989 : 0 : ABI_BUG(message)
1990 : : end if
1991 : :
1992 [ + + + - ]: 4984 : if (abs(optksloc) >= 2 .and. green%has_greenmatlu_xsum == 0) then
1993 : 0 : write(message,'(4a)') ch10,&
1994 : 0 : & "BUG: integrate_green is asked to integrate local green function",ch10,&
1995 : 0 : & " and local green function was non broadcasted in compute_green"
1996 : 0 : ABI_BUG(message)
1997 : : end if
1998 : :
1999 : : ! Allocations
2000 [ - + + - : 33684 : ABI_MALLOC(matlu_temp,(natom))
+ - + - -
+ - + +
+ ]
2001 : 4984 : call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),matlu_temp(:))
2002 : :
2003 : : ! =================================================
2004 : : ! == Integrate Local Green function ===============
2005 [ + + ]: 4984 : if (abs(optksloc)/2 == 1) then ! optksloc=2 or 3
2006 : : ! =================================================
2007 : :
2008 : : ! == Calculation of \int{G_{LL'}{\sigma\sigma',s}(R)(i\omega_n)}
2009 [ + + ]: 781 : if (paw_dmft%lchipsiortho == 1) then
2010 : : ! - Calculation of frequency sum over positive frequency
2011 : : !if (nspinor==1) option=1
2012 : : !if (nspinor==2) option=2
2013 : :
2014 : : !do atom=1, natom
2015 : : ! ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
2016 : : ! if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
2017 : : ! do ispinor1 = 1, nspinor
2018 : : ! do ispinor = 1, nspinor
2019 : : ! do is = 1 , nsppol
2020 : : ! do im=1,ndim
2021 : : ! do im1=1,ndim
2022 : : ! do ifreq=1,green%nw
2023 : : ! ff(ifreq)= &
2024 : : !& green%oper(ifreq)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
2025 : : ! write(std_out,*) green%omega(ifreq),ff(ifreq)," integrate
2026 : : ! green fw_lo"
2027 : : !if(present(iii).and.im==1.and.im1==1) write(std_out_default,*)
2028 : : !ch10,ifreq,ff(ifreq),"#ff"
2029 : : ! enddo
2030 : : ! call int_fct(ff,(im==im1).and.(ispinor==ispinor1),&
2031 : : !& option,paw_dmft,integral)
2032 : : ! call int_fct(ff,(im==im1).and.(ispinor==ispinor1),&
2033 : : !& 2,paw_dmft,integral) ! test_1
2034 : : ! green%occup%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)=integral
2035 : : !if(present(iii).and.im==1.and.im1==1) write(std_out_default,*)
2036 : : !ch10,'integral',im,im1,ifreq,integral
2037 : : ! if(im==2.and.im1==5.and.is==1.and.iatom==1) then
2038 : : ! write(std_out,*) " occup
2039 : : ! %matlu(1)%mat(2,5,1,1,1)",green%occup%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
2040 : : ! endif
2041 : : ! enddo
2042 : : ! enddo
2043 : : ! enddo ! ispinor1
2044 : : ! enddo ! ispinor
2045 : : ! enddo ! is
2046 : : ! matlu_temp(iatom)%mat=green%occup%matlu(iatom)%mat
2047 : : ! endif ! lpawu=/-1
2048 : : ! enddo ! iatom
2049 : :
2050 : 682 : call zero_matlu(green%occup%matlu(:),natom)
2051 : :
2052 [ - + + - : 2046 : ABI_MALLOC(omega_fac,(nmoments))
+ - + - -
+ - + ]
2053 : :
2054 [ + + ]: 1364 : do i=1,nmoments
2055 : 682 : omega_fac(i) = czero
2056 [ + + ]: 160113 : do ifreq=green%nw,1,-1 ! NEVER change the summation order and DON'T use the intrinsic SUM
2057 : 160113 : omega_fac(i) = omega_fac(i) + paw_dmft%wgt_wlo(ifreq) / (paw_dmft%omega_lo(ifreq))**i
2058 : : end do
2059 : 682 : omega_fac(i) = - two * temp * omega_fac(i) / (j_dpc)**i
2060 [ + - ]: 682 : if (i == 1) omega_fac(i) = omega_fac(i) + half
2061 [ - + ]: 682 : if (i == 2) omega_fac(i) = omega_fac(i) - cone/(four*temp)
2062 [ - + ]: 1364 : if (i == 4) omega_fac(i) = omega_fac(i) + cone/(dble(48)*(temp**3))
2063 : : end do ! i
2064 : :
2065 [ + + ]: 160113 : do ifreq=1,green%nw
2066 : :
2067 [ + + ]: 159431 : if (green%distrib%procf(ifreq) /= myproc) cycle
2068 : 54800 : fac = two * temp * paw_dmft%wgt_wlo(ifreq)
2069 [ + + ]: 161146 : do iatom=1,natom
2070 : 105664 : lpawu = paw_dmft%lpawu(iatom)
2071 [ + + ]: 105664 : if (lpawu == -1) cycle
2072 : : green%occup%matlu(iatom)%mat(:,:,:) = green%occup%matlu(iatom)%mat(:,:,:) + &
2073 [ + + + + : 3437655 : & fac*green%oper(ifreq)%matlu(iatom)%mat(:,:,:)
+ + ]
2074 : : end do ! iatom
2075 : :
2076 : : end do ! ifreq
2077 : :
2078 : 682 : call xmpi_matlu(green%occup%matlu(:),natom,paw_dmft%spacecomm)
2079 : :
2080 [ - + ]: 682 : if (green%has_moments == 1) then
2081 [ # # ]: 0 : do i=1,nmoments
2082 [ # # ]: 0 : do iatom=1,natom
2083 : 0 : lpawu = paw_dmft%lpawu(iatom)
2084 [ # # ]: 0 : if (lpawu == -1) cycle
2085 : : green%occup%matlu(iatom)%mat(:,:,:) = green%occup%matlu(iatom)%mat(:,:,:) + &
2086 [ # # # # : 0 : omega_fac(i)*green%moments(i)%matlu(iatom)%mat(:,:,:)
# # ]
2087 : : end do ! iatom
2088 : : end do ! i
2089 : : else
2090 [ - + + - : 2046 : ABI_MALLOC(shift,(natom))
+ - + - -
+ - + ]
2091 [ + + ]: 3060 : shift(:) = omega_fac(1)
2092 : 682 : call shift_matlu(green%occup%matlu(:),natom,shift(:),signe=-1)
2093 [ - + ]: 682 : ABI_FREE(shift)
2094 : : end if
2095 : :
2096 [ - + ]: 682 : ABI_FREE(omega_fac)
2097 : :
2098 : : ! Print density matrix if prtopt high
2099 [ + + ]: 682 : if (abs(prtopt) > 2) then
2100 : 105 : write(message,'(2a,i10,a)') ch10," = green%occup%matlu from int(gloc(w))"
2101 : 105 : call wrtout(std_out,message,'COLL')
2102 : 105 : call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
2103 : : end if ! abs(prtopt)>2
2104 : :
2105 : : ! - Symmetrize: continue sum over k-point: Full BZ
2106 : 682 : call sym_matlu(green%occup%matlu(:),paw_dmft)
2107 [ + + ]: 682 : if (abs(prtopt) > 2) then
2108 : 105 : write(message,'(2a,i10,a)') ch10, &
2109 : 210 : & " = green%occup%matlu from int(gloc(w)) with symmetrization"
2110 : 105 : call wrtout(std_out,message,'COLL')
2111 : 105 : call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
2112 : : end if ! abs(prtopt)>2
2113 : :
2114 : : ! - Post-treatment for summation over negative and positive frequencies:
2115 : : ! necessary in the case of nspinor==2 AND nspinor==1, but valid anywhere
2116 : : ! N(ll'sigmasigma')= (N(ll'sigmasigma')+ N*(l'lsigma'sigma))/2
2117 : : ! because [G_{LL'}^{sigma,sigma'}(iomega_n)]*= G_{L'L}^{sigma',sigma}(-iomega_n)
2118 [ + + ]: 3060 : do iatom=1,natom
2119 : 2378 : lpawu = paw_dmft%lpawu(iatom)
2120 [ + + ]: 2378 : if (lpawu == -1) cycle
2121 [ + + ]: 2018 : do isppol=1,nsppol
2122 : : green%occup%matlu(iatom)%mat(:,:,isppol) = (green%occup%matlu(iatom)%mat(:,:,isppol) + &
2123 [ + - + + : 71522 : & conjg(transpose(green%occup%matlu(iatom)%mat(:,:,isppol)))) * half
+ + + + +
+ ]
2124 : : end do ! isppol
2125 [ + + + + : 39028 : matlu_temp(iatom)%mat(:,:,:) = green%occup%matlu(iatom)%mat(:,:,:)
+ + ]
2126 : : end do ! iatom
2127 [ + + ]: 682 : if (abs(prtopt) > 2) then
2128 : 105 : write(message,'(2a,i10,a)') ch10, &
2129 : 210 : & " = green%occup%matlu from int(gloc(w)) symmetrized with post-treatment"
2130 : 105 : call wrtout(std_out,message,'COLL')
2131 : 105 : call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
2132 : : end if ! abs(prtopt)>2
2133 : :
2134 [ + + ]: 682 : if (optaftsolv == 0) then
2135 : 579 : call trace_oper(green%occup,green%charge_ks,green%charge_matlu(:,:),2)
2136 : 579 : green%has_charge_matlu = 2
2137 : 579 : green%has_charge_matlu_solver = 0
2138 : 579 : icomp_chloc = 1
2139 [ - + ]: 103 : else if (optaftsolv == 1) then ! .and. paw_dmft%dmft_solv /= 4) then
2140 : : ! else if(optaftsolv==1) then
2141 : : !if(paw_dmft%dmft_solv==4) then
2142 : : ! write(message,'(a,a,a)') ch10,&
2143 : : !& " = WARNING: Double Counting will be computed with solver charge.." ,&
2144 : : !& "might be problematic with Hirsch Fye QMC"
2145 : : ! call wrtout(std_out,message,'COLL')
2146 : : ! endif
2147 : : ! This is done only when called from impurity_solver with solver
2148 : : ! green function. (And if QMC is NOT used).
2149 [ + + - + ]: 103 : if (paw_dmft%dmft_solv >= 5 .and. green%has_charge_matlu_solver /= 2) then
2150 : 0 : write(message,'(2a,i3)') ch10,&
2151 : 0 : & " = BUG : has_charge_matlu_solver should be 2 and is",green%has_charge_matlu_solver
2152 : 0 : ABI_BUG(message)
2153 : : end if
2154 [ + + ]: 103 : if (paw_dmft%dmft_solv <= 4) then
2155 : 69 : call trace_oper(green%occup,green%charge_ks,green%charge_matlu_solver(:,:),2)
2156 : 69 : green%has_charge_matlu_solver = 2
2157 : : end if
2158 : : end if ! optaftsolv
2159 : : else
2160 : 99 : write(message,'(a,4x,3a,4x,a)') ch10,&
2161 : 99 : & " Local basis is not (yet) orthonormal:",&
2162 : 99 : & " local Green's function is thus not integrated",ch10,&
2163 : 198 : & " Local occupations are computed by downfolding the Kohn-Sham occupations instead"
2164 : 99 : call wrtout(std_out,message,'COLL')
2165 : : end if ! lchipsiortho=1
2166 : :
2167 : : end if ! optksloc
2168 : : ! =================================================
2169 : :
2170 : : ! =================================================
2171 : : ! == Integrate Kohn Sham Green function ===========
2172 [ + + ]: 4984 : if (mod(abs(optksloc),2) == 1) then ! optksloc=1 or 3 or -1
2173 : : ! green%occup%ks=czero ! important for xmpi_sum
2174 : : !! =================================================
2175 : : !! == Calculation of \int{G_{\nu\nu'}{k,s}(i\omega_n)}
2176 : : ! ff=czero
2177 : : ! do is = 1 , nsppol
2178 : : ! do ikpt = 1, nkpt
2179 : : !!020212 if(mod(ikpt-1,nproc)==myproc) then
2180 : : !!! print'(A,3I4)', "P ",myproc,is,ikpt
2181 : : ! do ib = 1, mbandc
2182 : : ! do ib1 = 1, mbandc
2183 : : ! if(optksloc==-1.and.(ib/=ib1)) cycle
2184 : : ! ff(:)=czero
2185 : : ! do ifreq=1,green%nw
2186 : : ! !! the following line is a quick and dirty tricks and should be removed when the data will
2187 : : ! !! be correctly distributed.
2188 : : !!! if((optnonxsum==1).and.(green%procb(ifreq,ikpt)==myproc)).or.(optnonxsum==0)) then
2189 : : ! if(green%procb(ifreq,ikpt)==myproc) then
2190 : : ! ff(ifreq)=green%oper(ifreq)%ks(is,ikpt,ib,ib1)
2191 : : !!! print'(A,5I4,3(2E15.5,3x))', "P1",myproc,is,ikpt,ib,ib1,ff(:)
2192 : : ! endif
2193 : : ! !endif
2194 : : ! enddo
2195 : : !! call int_fct(ff,ib==ib1,nspinor,paw_dmft,integral) ! here, option==1 even if nspinor==2
2196 : : !! green%occup%ks(is,ikpt,ib,ib1)=integral
2197 : : !!! print'(A,5I4,3(2E15.5,3x))', "PP",myproc,is,ikpt,ib,ib1,ff(:)
2198 : : ! call int_fct(ff,ib==ib1,2,paw_dmft,integral,green%procb(:,ikpt),myproc) ! here, option==1 even if nspinor==2
2199 : : !!020212 call int_fct(ff,ib==ib1,2,paw_dmft,integral) ! here, option==1 even if nspinor==2
2200 : : ! green%occup%ks(is,ikpt,ib,ib1)=integral
2201 : : !!! print'(A,5I4,2E15.8)', "P2",myproc,is,ikpt,ib,ib1,integral
2202 : : ! ! write(std_out,*) "integral",ikpt,green%occup%ks(is,ikpt,ib,ib1)
2203 : : ! ! endif
2204 : : !! write(std_out,'(a,4i6,e14.5,e14.5)') "ks",is,ikpt,ib,ib1,integral
2205 : : ! enddo ! ib1
2206 : : ! enddo ! ib
2207 : : !!020212 endif
2208 : : ! enddo ! ikpt
2209 : : ! enddo ! isppol
2210 : :
2211 : :
2212 : : ! call xmpi_barrier(spacecomm)
2213 : : ! call xmpi_sum(green%occup%ks,spacecomm,ierr)
2214 : :
2215 : :
2216 : : !! do is = 1 , nsppol
2217 : : !! do ikpt = 1, nkpt
2218 : : !! do ib = 1, mbandc
2219 : : !! do ib1 = 1, mbandc
2220 : : !! write(6,'(A,5I4,2E15.8)') "AAAFTERXSUM",myproc,is,ikpt,ib,ib1,green%occup%ks(is,ikpt,ib,ib1)
2221 : : !! print '(A,5I4,2E15.8)', "AFTERXSUM P",myproc,is,ikpt,ib,ib1,green%occup%ks(is,ikpt,ib,ib1)
2222 : : !! enddo ! ib1
2223 : : !! enddo ! ib
2224 : : !! enddo ! ikpt
2225 : : !! enddo ! isppol
2226 : : !write(std_out,*) "occup%ks ik1",green%occup%ks(1,1,1,3)
2227 : : !write(std_out,*) "occup%ks ik2",green%occup%ks(1,2,1,3)
2228 : : ! - Post-treatment for summation over negative and positive frequencies:
2229 : : ! necessary in the case of nspinor==2, but valid everywhere
2230 : : ! N(k,n_1,n_2)= (N(k,n_1,n_2)+ N*(k,n_2,n_1))/2
2231 : : ! because [G_{k}^{n_1,n_2}(iomega_n)]*= G_{k}^{n_2,n_1}(-iomega_n)
2232 [ + + ]: 11564 : do isppol=1,nsppol
2233 [ + + ]: 60270 : do ikpt=1,nkpt
2234 : : green%occup%ks(:,:,ikpt,isppol) = (green%occup%ks(:,:,ikpt,isppol)+ &
2235 [ + - + + : 14174846 : & conjg(transpose(green%occup%ks(:,:,ikpt,isppol)))) * half
+ + + + +
+ ]
2236 : : end do ! ikpt
2237 : : end do ! isppol
2238 : : !write(std_out,*) "occup%ks ik1 BB",green%occup%ks(1,1,1,3)
2239 : : !write(std_out,*) "occup%ks ik2 AA",green%occup%ks(1,2,1,3)
2240 [ + + ]: 4880 : if (optfilloccnd == 1) then
2241 : 199 : band_index = 0
2242 [ + + + + ]: 199 : fac = merge(two,one,nsppol==1.and.nspinor==1)
2243 [ + + ]: 486 : do isppol=1,nsppol
2244 [ + + ]: 2708 : do ikpt=1,nkpt
2245 [ + + ]: 23638 : do ib1=1,mbandc
2246 [ + + ]: 319390 : do ib=1,mbandc
2247 : : paw_dmft%occnd(1,paw_dmft%include_bands(ib),paw_dmft%include_bands(ib1),&
2248 : 295752 : & ikpt,isppol) = fac * dble(green%occup%ks(ib,ib1,ikpt,isppol))
2249 : : paw_dmft%occnd(2,paw_dmft%include_bands(ib),paw_dmft%include_bands(ib1),&
2250 : 317168 : & ikpt,isppol) = fac * aimag(green%occup%ks(ib,ib1,ikpt,isppol))
2251 : : end do ! ib
2252 : : end do ! ib1
2253 [ - + ]: 2509 : if (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7) then
2254 : 0 : nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
2255 [ # # ]: 0 : do ib=1,nband_k
2256 [ # # ]: 0 : if (paw_dmft%band_in(ib)) cycle
2257 [ # # # # ]: 0 : paw_dmft%occnd(:,:,ib,ikpt,isppol) = zero
2258 : : paw_dmft%occnd(1,ib,ib,ikpt,isppol) = fac * &
2259 : 0 : & occup_fd(paw_dmft%eigen(ib+band_index),paw_dmft%fermie,paw_dmft%temp)
2260 : : end do ! ib
2261 : 0 : band_index = band_index + nband_k
2262 : : end if ! use_all_bands
2263 : : end do ! ikpt
2264 : : end do ! isppol
2265 : : end if ! optfilloccnd
2266 : :
2267 [ + + ]: 4880 : if (optksloc > 0) then
2268 : : ! - Compute local occupations
2269 : : call downfold_oper(green%occup,paw_dmft,procb=green%distrib%procb(:), &
2270 : 677 : & iproc=green%distrib%me_kpt,option=option)
2271 : 677 : call xmpi_matlu(green%occup%matlu(:),natom,green%distrib%comm_kpt)
2272 [ + + ]: 677 : if (abs(prtopt) > 2) then
2273 : 106 : write(message,'(2a,i10,a)') ch10,&
2274 : 212 : & " = green%occup%matlu from projection of int(gks(w)) without symmetrization"
2275 : 106 : call wrtout(std_out,message,'COLL')
2276 : 106 : call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=-1)
2277 : : end if ! abs(prtopt)>2
2278 : :
2279 : : ! - Symmetrize: continue sum over k-point: Full BZ
2280 : 677 : call sym_matlu(green%occup%matlu(:),paw_dmft)
2281 [ + + ]: 677 : if (abs(prtopt) >= 2) then
2282 : : ! write(message,'(a,a,i10,a)') ch10,&
2283 : : !& " = green%occup%matlu from projection of int(gks(w)) with symetrization"
2284 : 478 : write(message,'(2a,i10,a)') ch10," == Occupation matrix from downfolded Kohn-Sham occupations"
2285 : 478 : call wrtout(std_out,message,'COLL')
2286 : 478 : call print_matlu(green%occup%matlu(:),natom,prtopt=3,opt_diag=0)
2287 : : end if ! abs(prtopt)>=2
2288 : :
2289 : : ! - If the trace of occup matrix in the LOCAL basis was not done
2290 : : ! before because lchipsiortho/=1 , do it now
2291 [ + + + + ]: 677 : if (paw_dmft%lchipsiortho /= 1 .and. abs(prtopt) > 0) then
2292 : 97 : call trace_oper(green%occup,green%charge_ks,green%charge_matlu(:,:),2)
2293 : 97 : green%has_charge_matlu = 2
2294 : 97 : icomp_chloc = 1
2295 : : end if ! lchipsiortho/=1 and abs(prtopt)>0
2296 : : end if ! optksloc>0: only diagonal elements of G\nunu' are computed
2297 : :
2298 : : ! - Compute trace over ks density matrix
2299 : 4880 : call trace_oper(green%occup,green%charge_ks,green%charge_matlu(:,:),1)
2300 [ - + ]: 4880 : if (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7) then
2301 : :
2302 : : band_index = 0
2303 : : correction = zero
2304 [ # # ]: 0 : do isppol=1,nsppol
2305 [ # # ]: 0 : do ikpt=1,nkpt
2306 : 0 : nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
2307 [ # # ]: 0 : do ib=1,nband_k
2308 [ # # ]: 0 : if (paw_dmft%band_in(ib)) cycle
2309 : : correction = correction + &
2310 : 0 : & occup_fd(paw_dmft%eigen(ib+band_index),paw_dmft%fermie,paw_dmft%temp)*green%occup%wtk(ikpt)
2311 : : end do ! ib
2312 : 0 : band_index = band_index + nband_k
2313 : : end do ! ikpt
2314 : : end do ! isppol
2315 [ # # # # ]: 0 : if (nsppol == 1 .and. nspinor == 1) correction = correction * two
2316 : 0 : green%charge_ks = green%charge_ks + correction
2317 : : end if ! use_all_bands
2318 [ + + ]: 4880 : if (abs(prtopt) > 0) then
2319 : 478 : write(tag,'(f12.6)') green%charge_ks
2320 : 478 : write(message,'(3a)') ch10,&
2321 : 956 : & " == Total number of electrons from integration of Kohn-Sham Green's function is : ",adjustl(tag)
2322 : 478 : call wrtout(std_out,message,'COLL')
2323 : 478 : write(tag,'(f12.6)') paw_dmft%nelectval
2324 [ + - ]: 478 : write(message,'(8x,3a)') " (should be ",trim(adjustl(tag)),")"
2325 : 478 : call wrtout(std_out,message,'COLL')
2326 : : end if ! abs(prtopt)>0
2327 : : end if ! optksloc
2328 : : ! =================================================
2329 : :
2330 : : ! =================================================
2331 : : ! Tests and compute precision on local charge
2332 : : ! =================================================
2333 : : ! - Check that if, renormalized psichi are used, occupations matrices
2334 : : ! obtained directly from local green function or, through kohn sham
2335 : : ! occupations are the same.
2336 [ + + + + ]: 4984 : if ((abs(optksloc) == 3) .and. (paw_dmft%lchipsiortho == 1)) then ! optksloc= 3
2337 : :
2338 [ + + ]: 578 : if(nspinor == 2) then
2339 : 8 : optiondiff = 2
2340 : : else
2341 : 570 : optiondiff = 1
2342 : : endif
2343 : : call diff_matlu("Local projection of Kohn-Sham occupations ",&
2344 : : & "Integration of local Green's function ",&
2345 : 578 : & green%occup%matlu(:),matlu_temp(:),natom,optiondiff,tol4)
2346 : 578 : write(message,'(2a)') ch10,&
2347 : 1156 : & " ***** => Calculations of Green's function in Kohn-Sham and local spaces are coherent ****"
2348 : 578 : call wrtout(std_out,message,'COLL')
2349 : : end if ! abs(optksloc)=3
2350 : :
2351 : : ! == Precision on charge_matlu (done only if local charge was computed ie not for optksloc=-1)
2352 [ + + + + : 4984 : if (icomp_chloc == 1 .and. paw_dmft%idmftloop >= 1 .and. optdiff == 1) then ! if the computation was done here.
+ + ]
2353 [ + + ]: 106 : if (green%has_charge_matlu_prev == 2) then
2354 : : diff_chloc = zero
2355 [ + + ]: 62 : do iatom=1,natom
2356 : 49 : lpawu = paw_dmft%lpawu(iatom)
2357 [ + + ]: 49 : if (lpawu == -1) cycle
2358 [ + + ]: 87 : do isppol=1,nsppol
2359 : : diff_chloc = diff_chloc + &
2360 : 98 : & (green%charge_matlu_prev(isppol,iatom)-green%charge_matlu(isppol,iatom))**2
2361 : : end do ! isppol
2362 : : end do ! iatom
2363 [ - + ]: 13 : if (sqrt(diff_chloc) < paw_dmft%dmft_lcpr) then
2364 : 0 : green%ichargeloc_cv = 1
2365 : 0 : write(message,'(a,8x,a,e9.2,a,8x,a)') ch10,"Change of correlated number of electron =<",&
2366 : 0 : & paw_dmft%dmft_lcpr,ch10,"DMFT Loop: Local charge is converged"
2367 : 0 : call wrtout(std_out,message,'COLL')
2368 : : else
2369 : 13 : green%ichargeloc_cv = 0
2370 : 13 : write(message,'(a,8x,a,e9.2,a,8x,a)') ch10,"Change of correlated number of electron >",&
2371 : 26 : & paw_dmft%dmft_lcpr,ch10,"DMFT Loop: Local charge is not converged"
2372 : 13 : call wrtout(std_out,message,'COLL')
2373 : : end if ! sqrt(diff_chloc)<dmft_lcpr
2374 : : end if ! green%has_charge_matlu_prev=2
2375 [ + + + + ]: 1370 : green%charge_matlu_prev(:,:) = green%charge_matlu(:,:)
2376 : 106 : green%has_charge_matlu_prev = 2
2377 : : end if ! icomp_chloc=1 and present(opt_diff) and idmftloop>=1
2378 : :
2379 : 4984 : call destroy_matlu(matlu_temp(:),natom)
2380 [ + - + + : 23716 : ABI_FREE(matlu_temp)
- + - + ]
2381 : : ! deallocate(charge_loc_old)
2382 : : ABI_NVTX_END_RANGE()
2383 : 4984 : call timab(625,2,tsec(:))
2384 : : DBG_EXIT("COLL")
2385 : :
2386 : 4984 : end subroutine integrate_green
2387 : : !!***
2388 : :
2389 : : !!****f* m_green/icip_green
2390 : : !! NAME
2391 : : !! icip_green
2392 : : !!
2393 : : !! FUNCTION
2394 : : !! init, compute, integrate and print lda green function
2395 : : !!
2396 : : !! INPUTS
2397 : : !! char1 = character which precises the type of green function computed.
2398 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
2399 : : !! green <type(green_type)>= green function data
2400 : : !! pawprtvol = option for printing
2401 : : !! self <type(self_type)>= variables related to self-energy
2402 : : !! opt_self = optional argument, if =1, upfold self-energy
2403 : : !! opt_moments = 1 to activate the computation of high-frequency moments
2404 : : !! opt_log = 1 to compute Tr(log(G))
2405 : : !!
2406 : : !! OUTPUT
2407 : : !!
2408 : : !! SOURCE
2409 : :
2410 : 279 : subroutine icip_green(char1,green,paw_dmft,pawprtvol,self,opt_self,opt_moments,opt_log)
2411 : :
2412 : : !Arguments ------------------------------------
2413 : : !type(MPI_type), intent(in) :: mpi_enreg
2414 : : type(green_type), intent(inout) :: green
2415 : : type(paw_dmft_type), intent(inout) :: paw_dmft
2416 : : type(self_type), intent(inout) :: self
2417 : : integer, intent(in) :: pawprtvol
2418 : : character(len=*), intent(in) :: char1
2419 : : integer, optional, intent(in) :: opt_log,opt_moments,opt_self
2420 : : !Local variables ------------------------------------
2421 : : integer :: option,optlog,optmoments,optself,optlocks,prtopt_for_integrate_green,opt_nonxsum_icip
2422 : : character(len=500) :: message
2423 : : ! *********************************************************************
2424 : :
2425 : : !green%whichgreen="DFT"
2426 : 279 : prtopt_for_integrate_green = 2
2427 : :
2428 : 279 : optself = 0
2429 [ + + ]: 279 : if (present(opt_self)) optself = opt_self
2430 : 279 : opt_nonxsum_icip = 1
2431 : : !if(paw_dmft%dmftcheck==1) then ! for fourier_green
2432 : : ! opt_nonxsum_icip=0
2433 : : !endif
2434 : :
2435 : 279 : optlog = 0
2436 [ + + ]: 279 : if (present(opt_log)) optlog = opt_log
2437 : :
2438 : 279 : optmoments = 0
2439 [ + - ]: 279 : if (present(opt_moments)) optmoments = opt_moments
2440 : :
2441 : 279 : call init_green(green,paw_dmft,opt_moments=optmoments)
2442 : :
2443 : : ! useless test ok
2444 : : ! call printocc_green(green,1,paw_dmft,2)
2445 : : ! write(std_out,*)" printocc_green zero finished "
2446 : :
2447 : : !== Compute green%oper(:)%ks
2448 : : !== Deduce green%oper(:)%matlu(:)%mat
2449 : 279 : call compute_green(green,paw_dmft,pawprtvol,self,opt_self=optself,opt_nonxsum=opt_nonxsum_icip,opt_log=optlog)
2450 [ - + ]: 279 : if (paw_dmft%dmft_prgn >= 1 .and. paw_dmft%dmft_prgn <= 2) then
2451 : 0 : optlocks = paw_dmft%dmft_prgn*2 + 1 ! if dmft_prgn==2 => do not print
2452 [ # # # # ]: 0 : if (paw_dmft%lchipsiortho == 1 .and. pawprtvol > -100) then
2453 : 0 : call print_green(char1,green,optlocks,paw_dmft)
2454 : : ! call print_green('inicip',green,1,paw_dmft,pawprtvol=1,opt_wt=1)
2455 : : end if
2456 : : end if
2457 : :
2458 : : !== Integrate green%oper(:)%ks
2459 : : !== Integrate green%oper(:)%matlu(:)%mat
2460 : 279 : call integrate_green(green,paw_dmft,prtopt_for_integrate_green,opt_ksloc=3,opt_self=optself)!,opt_nonxsum=opt_nonxsum_icip)
2461 : : !== Print green%oper(:)%ks
2462 : : !== Print green%oper(:)%matlu(:)%mat
2463 [ + + ]: 279 : if (char1 == "DFT") then
2464 : 93 : option = 1
2465 [ + - ]: 93 : if (self%oper(1)%matlu(1)%lpawu /= -1) then
2466 [ - + ]: 93 : if (abs(dble(self%oper(1)%matlu(1)%mat(1,1,1))) > tol7) then
2467 : : ! todo_ab: generalise this
2468 : 0 : write(message,'(2a)') ch10,&
2469 : 0 : & "Warning: a DFT calculation is carried out and self is not zero"
2470 : 0 : ABI_WARNING(message)
2471 : : ! call abi_abort('COLL')
2472 : : end if
2473 : : end if
2474 : : else
2475 : 186 : option = 5
2476 : : end if ! char1
2477 : :
2478 [ + - ]: 279 : if (pawprtvol > -100) then
2479 : 279 : call printocc_green(green,option,paw_dmft,3,chtype=char1)
2480 : : end if
2481 : :
2482 : 279 : end subroutine icip_green
2483 : : !!***
2484 : :
2485 : : !!****f* m_green/fourier_green
2486 : : !! NAME
2487 : : !! fourier_green
2488 : : !!
2489 : : !! FUNCTION
2490 : : !! integrate green function in the band index basis
2491 : : !!
2492 : : !! INPUTS
2493 : : !! cryst_struc <type(crystal_t)>= crystal structure data.
2494 : : !! green <type(green_type)>= green function data
2495 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
2496 : : !!
2497 : : !! OUTPUT
2498 : : !!
2499 : : !! SOURCE
2500 : :
2501 : 2 : subroutine fourier_green(cryst_struc,green,paw_dmft,opt_ksloc,opt_tw)
2502 : :
2503 : : !Arguments ------------------------------------
2504 : : !type
2505 : : type(crystal_t),intent(in) :: cryst_struc
2506 : : type(green_type),intent(inout) :: green
2507 : : !type(MPI_type), intent(in) :: mpi_enreg
2508 : : type(paw_dmft_type), intent(in) :: paw_dmft
2509 : : integer,intent(in) :: opt_ksloc,opt_tw ! fourier on ks or local
2510 : :
2511 : : !local variables-------------------------------
2512 : : integer :: iatom,ib,ib1,ierr,ifreq,ikpt,im,im1,iparal,is,ispinor,ispinor1,itau
2513 : : integer :: mband,mbandc,myproc,natom,ndim,nkpt,nproc,nspinor,nsppol,spacecomm!,opt_four
2514 : : character(len=500) :: message
2515 : : ! complex(dp):: ybcbeg,ybcend
2516 : : ! arrays
2517 : 2 : complex(dp), allocatable :: fw(:)
2518 : 2 : complex(dp), allocatable :: ft(:)
2519 : 2 : type(green_type) :: green_temp
2520 : : ! *********************************************************************
2521 : : ! ybcbeg=czero
2522 : : ! ybcend=czero
2523 : :
2524 : : ! define spaceComm, myproc, and nproc from world communicator
2525 : : ! and mpi_enreg
2526 : 2 : spacecomm=paw_dmft%spacecomm
2527 : 2 : myproc=paw_dmft%myproc
2528 : 2 : nproc=paw_dmft%nproc
2529 : :
2530 : : ! Initialise integers
2531 : 2 : mband = paw_dmft%mband
2532 : 2 : mbandc = paw_dmft%mbandc
2533 : 2 : nkpt = paw_dmft%nkpt
2534 : 2 : nspinor = paw_dmft%nspinor
2535 : 2 : nsppol = paw_dmft%nsppol
2536 : 2 : natom = cryst_struc%natom
2537 : :
2538 : : ! Only imaginary frequencies here
2539 [ - + ]: 2 : if(green%w_type=="real") then
2540 : 0 : message = 'fourier_green not implemented for real frequency'
2541 : 0 : ABI_BUG(message)
2542 : : endif
2543 : :
2544 : : ! Initialise temporary green function
2545 : 2 : call init_green(green_temp,paw_dmft)
2546 : 2 : call init_green_tau(green_temp,paw_dmft)
2547 : :
2548 : : !green%oper(:)%matlu(1)%mat(1,1,1,1,1)
2549 [ - + + - : 6 : ABI_MALLOC(fw,(green%nw))
+ - + - -
+ - + ]
2550 [ - + + - : 6 : ABI_MALLOC(ft,(green%dmftqmc_l))
+ - + - -
+ - + ]
2551 : :
2552 : : !==============================================
2553 : : ! == Inverse fourier transformation ===========
2554 : : !==============================================
2555 : :
2556 [ + + ]: 2 : if(opt_tw==-1) then
2557 : :
2558 : : ! = For Kohn Sham green function
2559 : : !==============================================
2560 [ - + - - ]: 1 : if(opt_ksloc==1.and.green%use_oper_tau_ks==1) then
2561 : :
2562 [ # # ]: 0 : do is = 1 , nsppol
2563 [ # # ]: 0 : do ikpt = 1, nkpt
2564 [ # # ]: 0 : do ib = 1, mbandc
2565 [ # # ]: 0 : do ib1 = 1, mbandc
2566 [ # # ]: 0 : do ifreq=1,green%nw
2567 : 0 : fw(ifreq)=green%oper(ifreq)%ks(ib,ib1,ikpt,is)
2568 : : enddo
2569 : 0 : call fourier_fct(fw,ft,ib==ib1,green%dmftqmc_l,-1,paw_dmft) ! inverse fourier
2570 [ # # ]: 0 : do itau=1,green%dmftqmc_l
2571 : 0 : green_temp%oper_tau(itau)%ks(ib,ib1,ikpt,is)=ft(itau)
2572 : : enddo
2573 [ # # ]: 0 : if(ib==ib1) then
2574 : 0 : green%occup_tau%ks(ib,ib1,ikpt,is)=ft(1)+one
2575 : : else
2576 : 0 : green%occup_tau%ks(ib,ib1,ikpt,is)=ft(1)
2577 : : endif
2578 : : enddo ! ib1
2579 : : enddo ! ib
2580 : : enddo ! ikpt
2581 : : enddo ! isppol
2582 : :
2583 : : ! = Post-treatment: necessary in the case of nspinor==2, but valid anywhere
2584 : : ! because G(tau)=G_{nu,nu'}(tau)+[G_{nu,nu'}(tau)]*
2585 : :
2586 [ # # ]: 0 : do is = 1 , nsppol
2587 [ # # ]: 0 : do ikpt = 1, nkpt
2588 [ # # ]: 0 : do ib = 1, mbandc
2589 [ # # ]: 0 : do ib1 = 1, mbandc
2590 [ # # ]: 0 : do itau=1,green%dmftqmc_l
2591 : : green%oper_tau(itau)%ks(ib,ib1,ikpt,is)=&
2592 : : & (green_temp%oper_tau(itau)%ks(ib,ib1,ikpt,is)+ &
2593 : 0 : & conjg(green_temp%oper_tau(itau)%ks(ib1,ib,ikpt,is)))/two
2594 [ # # ]: 0 : if(ib==ib1) then
2595 : 0 : green%occup_tau%ks(ib,ib1,ikpt,is)=green%oper_tau(1)%ks(ib,ib1,ikpt,is)+one
2596 : : else
2597 : 0 : green%occup_tau%ks(ib,ib1,ikpt,is)=green%oper_tau(1)%ks(ib,ib1,ikpt,is)
2598 : : endif
2599 : : enddo
2600 : : enddo ! ib1
2601 : : enddo ! ib
2602 : : enddo ! ikpt
2603 : : enddo ! isppol
2604 : 0 : call downfold_oper(green%occup_tau,paw_dmft)
2605 : 0 : call sym_matlu(green%occup_tau%matlu,paw_dmft)
2606 : 0 : write(message,'(a,a,i10,a)') ch10," green%occup_tau%matlu from green_occup_tau%ks"
2607 : 0 : call wrtout(std_out,message,'COLL')
2608 : 0 : call print_matlu(green%occup_tau%matlu,natom,prtopt=3)
2609 : : endif
2610 : :
2611 : : ! = For local green function
2612 : : !==============================================
2613 [ + - ]: 1 : if(opt_ksloc ==2) then
2614 : :
2615 : : iparal=0
2616 [ + + ]: 3 : do iatom=1, natom
2617 [ + + ]: 3 : if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
2618 : 1 : ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
2619 [ + + ]: 3 : do is = 1 , nsppol
2620 [ + + ]: 5 : do ispinor = 1, nspinor
2621 [ + + ]: 6 : do ispinor1 = 1, nspinor
2622 [ + + ]: 14 : do im=1,ndim
2623 [ + + ]: 62 : do im1=1,ndim
2624 : 50 : iparal=iparal+1
2625 [ + - ]: 60 : if(mod(iparal-1,nproc)==myproc) then
2626 [ + + ]: 1650 : do ifreq=1,green%nw
2627 : 1650 : fw(ifreq)=green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)
2628 : : enddo
2629 : : ! inverse fourier
2630 : : ! write(std_out,'(a)') "fourierbeforeposttreatement,ispinor,ispinor1,is,im,im1"
2631 : : ! write(std_out,'(a,5i4,f12.5,f12.5)') "fourier",ispinor,ispinor1,is,im,im1
2632 : : ! write(std_out,'(a,e12.5,e12.5)')&
2633 : : ! &"green%oper(4)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)"&
2634 : : !& ,green%oper(4)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
2635 : 50 : call fourier_fct(fw,ft,(im==im1).and.(ispinor==ispinor1),green%dmftqmc_l,-1,paw_dmft)
2636 [ + + ]: 3250 : do itau=1,green%dmftqmc_l
2637 : 3250 : green_temp%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=ft(itau)
2638 : : ! write(std_out,*) itau,green_temp%oper_tau(itau)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
2639 : : enddo
2640 : : ! if((im==im1).and.(ispinor==ispinor1)) then
2641 : : ! green%occup_tau%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)=ft(1)+one
2642 : : ! else
2643 : : ! green%occup_tau%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)=ft(1)
2644 : : ! endif
2645 : : endif ! iparal
2646 : : enddo
2647 : : enddo
2648 : : enddo ! ispinor1
2649 : : enddo ! ispinor
2650 : : enddo ! isppol
2651 : : endif ! lpawu.ne.-1
2652 : : enddo ! iatom
2653 : :
2654 : : ! Parallelisation must be finished here, because in the post
2655 : : ! treatment, value from different proc will be mixed.
2656 : 1 : call xmpi_barrier(spacecomm)
2657 [ + + ]: 3 : do iatom=1,natom
2658 [ + + ]: 2 : if (green%oper(1)%matlu(iatom)%lpawu==-1) cycle
2659 [ + + ]: 66 : do itau=1,green%dmftqmc_l
2660 : 66 : call xmpi_sum(green_temp%oper_tau(itau)%matlu(iatom)%mat,spacecomm,ierr)
2661 : : enddo
2662 : : enddo
2663 : 1 : call xmpi_barrier(spacecomm)
2664 : :
2665 : : ! = Post-treatment: necessary in the case of nspinor==2, but valid anywhere
2666 : : ! because G(tau)=G_{LL'}^{sigma,sigma'}(tau)+[G_{L'L}^{sigma',sigma}(tau)]*
2667 : :
2668 [ + - ]: 1 : if(nspinor>0) Then
2669 [ + + ]: 3 : do iatom=1, natom
2670 [ + + ]: 3 : if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
2671 : 1 : ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
2672 [ + + ]: 3 : do is = 1 , nsppol
2673 [ + + ]: 5 : do ispinor = 1, nspinor
2674 [ + + ]: 6 : do ispinor1 = 1, nspinor
2675 [ + + ]: 14 : do im=1,ndim
2676 [ + + ]: 62 : do im1=1,ndim
2677 : : ! write(std_out,'(a,5i4,f12.5,f12.5)') "fourier -1",ispinor,ispinor1,is,im,im1
2678 [ + + ]: 3260 : do itau=1,green%dmftqmc_l
2679 : : green%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=&
2680 : : & ((green_temp%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)+ &
2681 : 3200 : & conjg(green_temp%oper_tau(itau)%matlu(iatom)%mat(im1+(ispinor1-1)*ndim,im+(ispinor-1)*ndim,is))))/two
2682 : : ! write(std_out,*) itau,green%oper_tau(itau)%matlu(iatom)%mat(im,im1,is,ispinor,ispinor1)
2683 [ + + ]: 3250 : if((im==im1).and.(ispinor==ispinor1)) then
2684 : : green%occup_tau%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=&
2685 : 640 : & green%oper_tau(1)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)+one
2686 : : else
2687 : : green%occup_tau%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=&
2688 : 2560 : & green%oper_tau(1)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)
2689 : : endif ! test diag
2690 : : enddo ! itau
2691 : : enddo ! im1
2692 : : enddo ! im
2693 : : enddo ! ispinor1
2694 : : enddo ! ispinor
2695 : : enddo ! isppol
2696 : : endif
2697 : : enddo ! iatom
2698 : : endif ! nspinor>0
2699 : : endif ! opt_ksloc=2
2700 : : endif ! opt_tw==-1
2701 : :
2702 : :
2703 : : !==============================================
2704 : : ! == Direct fourier transformation
2705 : : !==============================================
2706 : : ! todo_ba ft useful only for diagonal elements ...
2707 : :
2708 [ + + ]: 2 : if(opt_tw==1) then
2709 : :
2710 : : ! = For local green function
2711 : : !==============================================
2712 [ + - ]: 1 : if(opt_ksloc ==2) then
2713 : :
2714 : : iparal=0
2715 [ + + ]: 3 : do iatom=1, natom
2716 : : ! put to zero (usefull at least for parallelism)
2717 [ + + ]: 3 : if(green%oper(1)%matlu(iatom)%lpawu.ne.-1) then
2718 [ + + ]: 33 : do ifreq=1,green%nw
2719 [ + + + + : 2017 : green%oper(ifreq)%matlu(iatom)%mat=czero
+ + ]
2720 : : enddo
2721 : 1 : ndim=2*green%oper(1)%matlu(iatom)%lpawu+1
2722 [ + + ]: 3 : do is = 1 , nsppol
2723 [ + + ]: 5 : do ispinor = 1, nspinor
2724 [ + + ]: 6 : do ispinor1 = 1, nspinor
2725 [ + + ]: 14 : do im=1,ndim
2726 [ + + ]: 62 : do im1=1,ndim
2727 : 50 : iparal=iparal+1
2728 [ + - ]: 60 : if(mod(iparal-1,nproc)==myproc) then
2729 [ + + ]: 3250 : do itau=1,green%dmftqmc_l
2730 : 3250 : ft(itau)=green%oper_tau(itau)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)
2731 : : enddo
2732 : : ! if(im==1.and.im1==1) write(std_out,*) "ft(itau=1)",is,ft(1) ! debug
2733 : 50 : call fourier_fct(fw,ft,(im==im1).and.(ispinor==ispinor1),green%dmftqmc_l,1,paw_dmft)
2734 [ + + ]: 1650 : do ifreq=1,green%nw
2735 : 1650 : green%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,is)=fw(ifreq)
2736 : : enddo
2737 : : ! if(im==1.and.im1==1) write(std_out,*) "fw(ifreq=1)",is,fw(1) ! debug
2738 : : endif
2739 : : enddo
2740 : : enddo
2741 : : enddo ! ispinor1
2742 : : enddo ! ispinor
2743 : : enddo ! isppol
2744 : : endif ! lpawu=/-1
2745 : : enddo ! iatom
2746 : 1 : call xmpi_barrier(spacecomm)
2747 [ + + ]: 3 : do iatom=1,natom
2748 [ + + ]: 2 : if (green%oper(1)%matlu(iatom)%lpawu==-1) cycle
2749 [ + + ]: 34 : do ifreq=1,green%nw
2750 : 34 : call xmpi_sum(green%oper(ifreq)%matlu(iatom)%mat,spacecomm,ierr)
2751 : : enddo
2752 : : enddo
2753 : : endif ! opt_ksloc=2
2754 : : endif ! opt_tw==-1
2755 [ - + ]: 2 : ABI_FREE(fw)
2756 [ - + ]: 2 : ABI_FREE(ft)
2757 : 2 : call destroy_green_tau(green_temp)
2758 : 2 : call destroy_green(green_temp)
2759 : :
2760 [ - + - - : 2 : end subroutine fourier_green
- - - + -
+ - - - -
- + - + -
+ - + - +
- + - + -
+ - + - -
- - - - -
- - - - +
- - - - -
- - - - -
- + - - -
- - - - -
- - ]
2761 : : !!***
2762 : :
2763 : :
2764 : : !!****f* m_green/check_fourier_green
2765 : : !! NAME
2766 : : !! check_fourier_green
2767 : : !!
2768 : : !! FUNCTION
2769 : : !! Check fourier transformations
2770 : : !!
2771 : : !! INPUTS
2772 : : !! cryst_struc <type(crystal_t)>= crystal structure data.
2773 : : !! green <type(green_type)>= green function data
2774 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
2775 : : !! pawang <type(pawang)>=paw angular mesh and related data
2776 : : !!
2777 : : !! OUTPUT
2778 : : !!
2779 : : !! SOURCE
2780 : :
2781 : 1 : subroutine check_fourier_green(cryst_struc,green,paw_dmft)
2782 : :
2783 : : !Arguments ------------------------------------
2784 : : !type
2785 : : type(crystal_t),intent(in) :: cryst_struc
2786 : : type(green_type),intent(inout) :: green
2787 : : !type(MPI_type), intent(in) :: mpi_enreg
2788 : : type(paw_dmft_type), intent(inout) :: paw_dmft
2789 : :
2790 : : !local variables-------------------------------
2791 : 1 : type(green_type) :: green_check
2792 : : character(len=500) :: message
2793 : : ! *********************************************************************
2794 : : ! Only imaginary frequencies here
2795 [ - + ]: 1 : if(green%w_type=="real") then
2796 : 0 : message = 'check_fourier_green not implemented for real frequency'
2797 : 0 : ABI_BUG(message)
2798 : : endif
2799 : :
2800 : 1 : call init_green(green_check,paw_dmft)
2801 : 1 : call init_green_tau(green_check,paw_dmft)
2802 : 1 : call copy_green(green,green_check,opt_tw=2)
2803 : :
2804 : 1 : write(message,'(2a,i3,13x,a)') ch10,' === Inverse Fourier Transform w->t of Weiss Field'
2805 : 1 : call wrtout(std_out,message,'COLL')
2806 : : call fourier_green(cryst_struc,green_check,paw_dmft,&
2807 : 1 : & opt_ksloc=2,opt_tw=-1)
2808 : :
2809 : 1 : write(message,'(3a)') ch10,' === Print (for check by user) of occupation matrix'&
2810 : 2 : & ,' after fourier transform with respect to initial one'
2811 : 1 : call wrtout(std_out,message,'COLL')
2812 : 1 : call printocc_green(green_check,6,paw_dmft,3)
2813 : :
2814 : 1 : write(message,'(2a,i3,13x,a)') ch10,' === Direct Fourier Transform t->w of Weiss Field'
2815 : 1 : call wrtout(std_out,message,'COLL')
2816 : : call fourier_green(cryst_struc,green_check,paw_dmft,&
2817 : 1 : & opt_ksloc=2,opt_tw=1)
2818 : : ! call print_matlu(green%oper(1)%matlu,paw_dmft%natom,1) ! debug
2819 : :
2820 : : call integrate_green(green_check,paw_dmft,&
2821 : 1 : & prtopt=2,opt_ksloc=2)
2822 : :
2823 : 1 : write(message,'(3a)') ch10,' === Print (for check by user) of occupation matrix'&
2824 : 2 : & ,' after double fourier transform with respect to initial one'
2825 : 1 : call wrtout(std_out,message,'COLL')
2826 : 1 : call printocc_green(green_check,5,paw_dmft,3)
2827 : :
2828 : 1 : call destroy_green_tau(green_check)
2829 : 1 : call destroy_green(green_check)
2830 : :
2831 [ - + - - : 1 : end subroutine check_fourier_green
- - - + -
+ - - - -
- + - + -
+ - + - +
- + - + -
+ - + - -
- - - - -
- - - - +
- - - - -
- - - - -
- + - - -
- - - - -
- - ]
2832 : : !!***
2833 : :
2834 : : !!****f* m_green/compa_occup_ks
2835 : : !! NAME
2836 : : !! compa_occup_ks
2837 : : !!
2838 : : !! FUNCTION
2839 : : !! Compare occupations to Fermi Dirac Occupations
2840 : : !!
2841 : : !! INPUTS
2842 : : !! green <type(green_type)>= green function data
2843 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
2844 : : !!
2845 : : !! OUTPUT
2846 : : !!
2847 : : !! SOURCE
2848 : :
2849 : 0 : subroutine compa_occup_ks(green,paw_dmft)
2850 : :
2851 : : !Arguments ------------------------------------
2852 : : !type
2853 : : type(green_type),intent(inout) :: green
2854 : : type(paw_dmft_type), intent(inout) :: paw_dmft
2855 : :
2856 : : !local variables-------------------------------
2857 : : character(len=500) :: message
2858 : : integer :: ib,ikpt,isppol
2859 : : integer :: ib_,ikpt_,isppol_
2860 : : integer :: ib__,ikpt__,isppol__
2861 : : real(dp) :: diffmax,occ1,occ2,occ_a,occ_b,diffrel,occ_aa,occ_bb
2862 : : ! *********************************************************************
2863 : 0 : diffmax=zero
2864 : 0 : diffrel=zero
2865 [ # # ]: 0 : do isppol=1,paw_dmft%nsppol
2866 [ # # ]: 0 : do ikpt=1,paw_dmft%nkpt
2867 [ # # ]: 0 : do ib=1,paw_dmft%mbandc
2868 : 0 : occ1=occup_fd(paw_dmft%eigen_dft(ib,ikpt,isppol),paw_dmft%fermie,paw_dmft%temp)
2869 : 0 : occ2=real(green%occup%ks(ib,ib,ikpt,isppol))
2870 [ # # ]: 0 : if(abs(occ1-occ2)>diffmax) then
2871 : 0 : diffmax=abs(occ1-occ2)
2872 : 0 : occ_a=occ1
2873 : 0 : occ_b=occ2
2874 : 0 : ib_=ib;isppol_=isppol;ikpt_=ikpt
2875 : : endif
2876 [ # # ]: 0 : if(abs(two*(occ1-occ2)/(occ1+occ2))>diffrel) then
2877 : 0 : diffrel=abs(two*(occ1-occ2)/(occ1+occ2))
2878 : 0 : occ_aa=occ1
2879 : 0 : occ_bb=occ2
2880 : 0 : ib__=ib;isppol__=isppol;ikpt__=ikpt
2881 : : endif
2882 : : enddo
2883 : : enddo
2884 : : enddo
2885 : :
2886 : :
2887 : 0 : write(message,'(2a)') ch10,' === Compare green function occupations and Fermi Dirac occupations'
2888 : 0 : call wrtout(std_out,message,'COLL')
2889 : 0 : write(message,'(2a,f12.5,2a,f12.5,2a,f12.5,2a,3i5)') ch10,' = Max difference is',diffmax,&
2890 : 0 : & ch10,' Corresponding Occupation from green function is',occ_b,&
2891 : 0 : & ch10,' Corresponding Occupation Fermi Dirac weight is',occ_a,&
2892 : 0 : & ch10,' (For polarization, k-point and band index) ',isppol_,ikpt_,ib_
2893 : 0 : call wrtout(std_out,message,'COLL')
2894 : 0 : write(message,'(2a,f12.5,2a,f12.5,2a,f12.5,2a,3i5)') ch10,' = Max relative difference is',diffrel,&
2895 : 0 : & ch10,' Corresponding Occupation from green function is',occ_bb,&
2896 : 0 : & ch10,' Corresponding Occupation Fermi Dirac weight is',occ_aa,&
2897 : 0 : & ch10,' (For polarization, k-point and band index) ',isppol__,ikpt__,ib__
2898 : 0 : call wrtout(std_out,message,'COLL')
2899 : :
2900 : 0 : end subroutine compa_occup_ks
2901 : : !!***
2902 : :
2903 : : !!****f* m_green/add_int_fct
2904 : : !! NAME
2905 : : !! add_int_fct
2906 : : !!
2907 : : !! FUNCTION
2908 : : !! Do integration in matsubara space
2909 : : !!
2910 : : !! COPYRIGHT
2911 : : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
2912 : : !! This file is distributed under the terms of the
2913 : : !! GNU General Public License, see ~abinit/COPYING
2914 : : !! or http://www.gnu.org/copyleft/gpl.txt .
2915 : : !!
2916 : : !! INPUTS
2917 : : !! ff= function is frequency space
2918 : : !! ldiag = option according to diagonal or non-diagonal elements
2919 : : !! option = nspinor
2920 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
2921 : : !! proct= for parallelism
2922 : : !!
2923 : : !! SIDE EFFECTS
2924 : : !! * integral = integral of ff over matsubara frequencies (there is an accumulation in the present routine, so intent(inout))
2925 : : !! * ft= function is time space
2926 : : !!
2927 : : !! SOURCE
2928 : 0 : subroutine add_int_fct(ifreq,ff,ldiag,omega_current,option,integral,temp,wgt_wlo,dmft_nwlo)
2929 : :
2930 : : !Arguments ------------------------------------
2931 : : !type
2932 : : integer,intent(in) :: ifreq
2933 : : logical,intent(in) :: ldiag
2934 : : integer,intent(in) :: option,dmft_nwlo
2935 : : complex(dp),intent(inout) :: integral
2936 : : complex(dp), intent(in) :: ff
2937 : : complex(dp), intent(in) :: omega_current
2938 : : real(dp), intent(in) :: temp, wgt_wlo
2939 : :
2940 : : !local variables-------------------------------
2941 : : real(dp) :: omega
2942 : : ! *********************************************************************
2943 : 0 : omega=aimag(omega_current)
2944 [ # # ]: 0 : if(ldiag) then
2945 : :
2946 [ # # ]: 0 : if(option==1) then ! nspinor==1
2947 : : ! write(500,*) paw_dmft%omega_lo(ifreq),real(ff(ifreq)),imag(ff(ifreq))
2948 : : integral=integral+2.d0*temp * &
2949 : : & real( ff-one / ( j_dpc*omega ) ) * &
2950 : 0 : & wgt_wlo
2951 [ # # ]: 0 : if(ifreq==dmft_nwlo) integral=integral+half
2952 : : ! integral=integral+half
2953 : : ! the if is here, to count only one time this correction
2954 : : endif
2955 : :
2956 [ # # ]: 0 : if(option==2) then ! nspinor==2
2957 : : integral=integral+2.d0*temp * &
2958 : : & ( ff-one / ( j_dpc*omega ) ) * &
2959 : 0 : & wgt_wlo
2960 [ # # ]: 0 : if(ifreq==dmft_nwlo) integral=integral+half
2961 : : ! integral=integral+half
2962 : : ! the if is here, to count only one time this correction
2963 : : endif
2964 : :
2965 : :
2966 : : else ! ldiag
2967 : :
2968 : : ! write(std_out,*) "nondiag"
2969 [ # # ]: 0 : if(option==1) then
2970 : : integral=integral+2.d0*temp * &
2971 : : & real( ff ) * &
2972 : 0 : & wgt_wlo
2973 : : endif
2974 [ # # ]: 0 : if(option==2) then
2975 : : integral=integral+2.d0*temp * &
2976 : : & ff * &
2977 : 0 : & wgt_wlo
2978 : : endif
2979 : : endif ! ldiag
2980 : :
2981 : 0 : end subroutine add_int_fct
2982 : : !!***
2983 : :
2984 : : !!****m* m_green/int_fct
2985 : : !! NAME
2986 : : !! int_fct
2987 : : !!
2988 : : !! FUNCTION
2989 : : !! Do integration in matsubara space
2990 : : !!
2991 : : !! COPYRIGHT
2992 : : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
2993 : : !! This file is distributed under the terms of the
2994 : : !! GNU General Public License, see ~abinit/COPYING
2995 : : !! or http://www.gnu.org/copyleft/gpl.txt .
2996 : : !!
2997 : : !! INPUTS
2998 : : !! ff= function is frequency space
2999 : : !! ldiag = option according to diagonal or non-diagonal elements
3000 : : !! option = nspinor
3001 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
3002 : : !! proct= for parallelism
3003 : : !!
3004 : : !! OUTPUT
3005 : : !! integral = integral of ff over matsubara frequencies
3006 : : !!
3007 : : !! SIDE EFFECTS
3008 : : !! ft= function is time space
3009 : : !!
3010 : : !! SOURCE
3011 : 0 : subroutine int_fct(ff,ldiag,option,paw_dmft,integral,procb,myproc)
3012 : :
3013 : : !Arguments ------------------------------------
3014 : : !type
3015 : : logical,intent(in) :: ldiag
3016 : : integer,intent(in) :: option
3017 : : complex(dp),intent(out) :: integral
3018 : : type(paw_dmft_type), intent(in) :: paw_dmft
3019 : : complex(dp), intent(in) :: ff(paw_dmft%dmft_nwlo)
3020 : : integer, optional, intent(in) :: procb(paw_dmft%dmft_nwlo)
3021 : : integer, optional, intent(in) :: myproc
3022 : :
3023 : : !local variables-------------------------------
3024 : 0 : logical, allocatable :: procb2(:)
3025 : : character(len=500) :: message
3026 : : integer :: ifreq
3027 : : ! *********************************************************************
3028 [ # # # # : 0 : ABI_MALLOC(procb2,(paw_dmft%dmft_nwlo))
# # # # #
# # # ]
3029 [ # # ]: 0 : if(present(procb).and.present(myproc)) then
3030 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
3031 : 0 : procb2(ifreq)=(procb(ifreq)==myproc)
3032 : : enddo
3033 [ # # ]: 0 : else if(present(procb).and..not.present(myproc)) then
3034 : 0 : write(message,'(a,a,2(e15.4))') ch10,&
3035 : 0 : & "BUG: procb is present and not myproc in int_fct"
3036 : 0 : ABI_BUG(message)
3037 [ # # ]: 0 : else if(.not.present(procb).and.present(myproc)) then
3038 : 0 : write(message,'(a,a,2(e15.4))') ch10,&
3039 : 0 : & "BUG: procb is not present and myproc is in int_fct"
3040 : 0 : ABI_BUG(message)
3041 : : else
3042 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
3043 : 0 : procb2(ifreq)=(1==1)
3044 : : enddo
3045 : : endif
3046 : :
3047 : 0 : integral=czero
3048 [ # # ]: 0 : if(ldiag) then
3049 : :
3050 [ # # ]: 0 : if(option==1) then ! nspinor==1
3051 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
3052 [ # # ]: 0 : if(procb2(ifreq)) then
3053 : : ! write(500,*) paw_dmft%omega_lo(ifreq),real(ff(ifreq)),imag(ff(ifreq))
3054 : : integral=integral+2.d0*paw_dmft%temp * &
3055 : : & real( ff(ifreq)-one / ( j_dpc*paw_dmft%omega_lo(ifreq) ) ) * &
3056 : 0 : & paw_dmft%wgt_wlo(ifreq)
3057 : : endif
3058 : : enddo
3059 [ # # ]: 0 : if(procb2(paw_dmft%dmft_nwlo)) integral=integral+half
3060 : : ! integral=integral+half
3061 : : ! the if is here, to count only one time this correction
3062 : : endif
3063 : :
3064 [ # # ]: 0 : if(option==2) then ! nspinor==2
3065 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
3066 [ # # ]: 0 : if(procb2(ifreq)) then
3067 : : integral=integral+2.d0*paw_dmft%temp * &
3068 : : & ( ff(ifreq)-one / ( j_dpc*paw_dmft%omega_lo(ifreq) ) ) * &
3069 : 0 : & paw_dmft%wgt_wlo(ifreq)
3070 : : endif
3071 : : enddo
3072 [ # # ]: 0 : if(procb2(paw_dmft%dmft_nwlo)) integral=integral+half
3073 : : ! integral=integral+half
3074 : : ! the if is here, to count only one time this correction
3075 : : endif
3076 : :
3077 : :
3078 : : else ! ldiag
3079 : :
3080 : : ! write(std_out,*) "nondiag"
3081 [ # # ]: 0 : if(option==1) then
3082 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
3083 [ # # ]: 0 : if(procb2(ifreq)) then
3084 : : integral=integral+2.d0*paw_dmft%temp * &
3085 : : & real( ff(ifreq) ) * &
3086 : 0 : & paw_dmft%wgt_wlo(ifreq)
3087 : : endif
3088 : : enddo
3089 : : endif
3090 [ # # ]: 0 : if(option==2) then
3091 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
3092 [ # # ]: 0 : if(procb2(ifreq)) then
3093 : : integral=integral+2.d0*paw_dmft%temp * &
3094 : : & ff(ifreq) * &
3095 : 0 : & paw_dmft%wgt_wlo(ifreq)
3096 : : endif
3097 : : enddo
3098 : : endif
3099 : : endif ! ldiag
3100 [ # # ]: 0 : ABI_FREE(procb2)
3101 : :
3102 : 0 : end subroutine int_fct
3103 : : !!***
3104 : :
3105 : : !!****f* m_green/fourier_fct
3106 : : !! NAME
3107 : : !! fourier_fct
3108 : : !!
3109 : : !! FUNCTION
3110 : : !! Do fourier transformation from matsubara space to imaginary time
3111 : : !! (A spline is performed )
3112 : : !!
3113 : : !! COPYRIGHT
3114 : : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
3115 : : !! This file is distributed under the terms of the
3116 : : !! GNU General Public License, see ~abinit/COPYING
3117 : : !! or http://www.gnu.org/copyleft/gpl.txt .
3118 : : !!
3119 : : !! INPUTS
3120 : : !! ldiag = option according to diagonal or non-diagonal elements
3121 : : !! opt_four = option for direct (1) or inverse (-1) fourier transform
3122 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
3123 : : !!
3124 : : !! OUTPUT
3125 : : !!
3126 : : !! SIDE EFFECTS
3127 : : !! fw= function is frequency space
3128 : : !! ft= function is time space
3129 : : !!
3130 : : !! SOURCE
3131 : 100 : subroutine fourier_fct(fw,ft,ldiag,ltau,opt_four,paw_dmft)
3132 : :
3133 : : !Arguments ------------------------------------
3134 : : !type
3135 : : logical,intent(in) :: ldiag
3136 : : integer,intent(in) :: ltau,opt_four
3137 : : type(paw_dmft_type), intent(in) :: paw_dmft
3138 : : complex(dp), intent(inout) :: fw(paw_dmft%dmft_nwlo)
3139 : : complex(dp), intent(inout) :: ft(ltau)
3140 : :
3141 : : !local variables-------------------------------
3142 : 100 : complex(dp), allocatable :: splined_li(:)
3143 : 100 : complex(dp), allocatable :: tospline_li(:)
3144 : : ! complex(dp), allocatable :: fw1(:)
3145 : 100 : real(dp), allocatable :: ftr(:)
3146 : : real(dp) :: beta
3147 : : complex(dp) :: xsto
3148 : : integer :: iflag,ifreq,itau,iwarn,log_direct
3149 : : character(len=500) :: message
3150 : 100 : real(dp), allocatable :: omega_li(:)
3151 : : ! *********************************************************************
3152 : 100 : beta=one/paw_dmft%temp
3153 : 100 : iflag=0
3154 : 100 : log_direct=1
3155 : :
3156 [ + + ]: 100 : if(ldiag) iflag=1
3157 : :
3158 : : ! == inverse fourier transform
3159 [ + + ]: 100 : if(opt_four==-1) then
3160 : :
3161 [ - + + - : 150 : ABI_MALLOC(splined_li,(paw_dmft%dmft_nwli))
+ - + - -
+ - + ]
3162 : : ! allocate(fw1(0:paw_dmft%dmft_nwlo-1))
3163 [ + - ]: 50 : if(paw_dmft%dmft_log_freq==1) then
3164 [ - + + - : 150 : ABI_MALLOC(omega_li,(1:paw_dmft%dmft_nwli))
+ - + - -
+ - + ]
3165 : 50 : call construct_nwli_dmft(paw_dmft,paw_dmft%dmft_nwli,omega_li)
3166 : : call spline_c(paw_dmft%dmft_nwlo,paw_dmft%dmft_nwli,paw_dmft%omega_lo,&
3167 : 50 : & omega_li,splined_li,fw)
3168 [ - + ]: 50 : ABI_FREE(omega_li)
3169 : : else
3170 [ # # # # : 0 : splined_li=fw
# # # # ]
3171 : : endif
3172 : 50 : call invfourier(splined_li,ft,paw_dmft%dmft_nwli,ltau,iflag,beta)
3173 : : ! deallocate(fw1)
3174 [ - + ]: 50 : ABI_FREE(splined_li)
3175 : :
3176 : : ! == direct fourier transform
3177 [ + - ]: 50 : else if(opt_four==1) then
3178 : :
3179 [ - + + - : 150 : ABI_MALLOC(ftr,(ltau))
+ - + - -
+ + - ]
3180 : :
3181 : 3250 : iwarn=0
3182 [ + + ]: 3250 : do itau=1,ltau
3183 [ - + ]: 3250 : if(abs(aimag(ft(itau)))>tol12) then
3184 [ # # ]: 0 : if(ldiag) then
3185 : 0 : write(message,'(a,a,2(e15.4))') ch10,&
3186 : 0 : & "green function is not real in imaginary time space",ft(itau)
3187 : 0 : ABI_ERROR(message)
3188 : : else
3189 : 0 : iwarn=iwarn+1
3190 : 0 : ftr(itau)=real(ft(itau))
3191 : 0 : xsto=ft(itau)
3192 : : endif
3193 : : else
3194 : 3200 : ftr(itau)=real(ft(itau))
3195 : : endif
3196 : : ! write(std_out,*) itau,ftr(itau)
3197 : : enddo
3198 : :
3199 [ - + + - : 150 : ABI_MALLOC(tospline_li,(paw_dmft%dmft_nwli))
+ - + - -
+ - + ]
3200 : : if (log_direct==1) then
3201 : : ! do not have a physical meaning..because the log frequency is not
3202 : : ! one of the linear frequency.
3203 : : ! if log frequencies are also one of linear frequency, it should be good
3204 [ + + ]: 1650 : do ifreq=1, paw_dmft%dmft_nwlo
3205 : 1650 : call nfourier2(ftr,fw(ifreq),iflag,paw_dmft%omega_lo(ifreq),ltau,beta)
3206 : : enddo
3207 : : else
3208 : : call nfourier(ftr,tospline_li,iflag,paw_dmft%dmft_nwli-1,ltau,beta)
3209 : : do ifreq=1,paw_dmft%dmft_nwli
3210 : : write(1112,*) paw_dmft%temp*pi*real(2*ifreq-1,kind=dp),real(tospline_li(ifreq),kind=dp),aimag(tospline_li(ifreq))
3211 : : !write(1112,*) paw_dmft%omega_li(ifreq),real(tospline_li(ifreq)),aimag(tospline_li(ifreq))
3212 : : enddo
3213 : : if(paw_dmft%dmft_log_freq==1) then
3214 : : ABI_MALLOC(omega_li,(1:paw_dmft%dmft_nwli))
3215 : : call construct_nwli_dmft(paw_dmft,paw_dmft%dmft_nwli,omega_li)
3216 : : call spline_c(paw_dmft%dmft_nwli,paw_dmft%dmft_nwlo,omega_li,&
3217 : : & paw_dmft%omega_lo,fw,tospline_li)
3218 : : ABI_FREE(omega_li)
3219 : : else
3220 : : fw=tospline_li
3221 : : endif
3222 : : endif
3223 : :
3224 [ - + ]: 50 : ABI_FREE(tospline_li)
3225 : :
3226 [ - + ]: 50 : ABI_FREE(ftr)
3227 [ - + ]: 50 : if(iwarn>0) then
3228 : 0 : write(message,'(a,a,2(e15.4))') ch10,&
3229 : 0 : & "WARNING: off-diag green function is not real in imaginary time space",xsto
3230 : 0 : call wrtout(std_out,message,'COLL')
3231 : : endif
3232 : :
3233 : : endif
3234 : :
3235 [ - + ]: 100 : end subroutine fourier_fct
3236 : : !!***
3237 : :
3238 : : !!****f* m_green/spline_fct
3239 : : !! NAME
3240 : : !! spline_fct
3241 : : !!
3242 : : !! FUNCTION
3243 : : !! Do fourier transformation from matsubara space to imaginary time
3244 : : !! (A spline is performed )
3245 : : !!
3246 : : !! COPYRIGHT
3247 : : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
3248 : : !! This file is distributed under the terms of the
3249 : : !! GNU General Public License, see ~abinit/COPYING
3250 : : !! or http://www.gnu.org/copyleft/gpl.txt .
3251 : : !!
3252 : : !! INPUTS
3253 : : !! opt_spline = option for the spline
3254 : : !! -1 log to linear.
3255 : : !! 1 linear to log.
3256 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
3257 : : !!
3258 : : !! OUTPUT
3259 : : !!
3260 : : !! SIDE EFFECTS
3261 : : !! fw= function is frequency space
3262 : : !! ft= function is time space
3263 : : !!
3264 : : !! SOURCE
3265 : :
3266 [ # # # # ]: 0 : subroutine spline_fct(fw1,fw2,opt_spline,paw_dmft)
3267 : :
3268 : : !Arguments ------------------------------------
3269 : : !type
3270 : : integer,intent(in) :: opt_spline
3271 : : type(paw_dmft_type), intent(in) :: paw_dmft
3272 : : complex(dp), intent(inout) :: fw1(:)
3273 : : complex(dp), intent(inout) :: fw2(:)
3274 : : integer :: size_fw1
3275 : : integer :: size_fw2
3276 : 0 : real(dp), allocatable :: omega_li(:)
3277 : : ! *********************************************************************
3278 : :
3279 : 0 : size_fw1 = size(fw1)
3280 : 0 : size_fw2 = size(fw2)
3281 : :
3282 : : ! == inverse fourier transform
3283 [ # # ]: 0 : if(opt_spline==-1) then
3284 : :
3285 : : ! allocate(fw1(0:paw_dmft%dmft_nwlo-1))
3286 [ # # ]: 0 : if(paw_dmft%dmft_log_freq==1) then
3287 [ # # # # : 0 : ABI_MALLOC(omega_li,(1:size_fw2))
# # # # #
# # # ]
3288 : 0 : call construct_nwli_dmft(paw_dmft,size_fw2,omega_li)
3289 : : call spline_c(size_fw1,size_fw2,paw_dmft%omega_lo(1:size_fw1),&
3290 [ # # # # : 0 : & omega_li(1:size_fw2),fw2,fw1)
# # # # #
# # # # #
# # ]
3291 [ # # ]: 0 : ABI_FREE(omega_li)
3292 : : else
3293 [ # # ]: 0 : fw2=fw1
3294 : : endif
3295 : :
3296 : : ! == direct fourier transform
3297 [ # # ]: 0 : else if(opt_spline==1) then
3298 : :
3299 : :
3300 [ # # ]: 0 : if(paw_dmft%dmft_log_freq==1) then
3301 [ # # # # : 0 : ABI_MALLOC(omega_li,(1:size_fw2))
# # # # #
# # # ]
3302 : 0 : call construct_nwli_dmft(paw_dmft,size_fw2,omega_li)
3303 : : call spline_c(size_fw2,size_fw1,omega_li(1:size_fw2),&
3304 [ # # # # : 0 : & paw_dmft%omega_lo(1:size_fw1),fw1,fw2)
# # # # #
# # # # #
# # ]
3305 [ # # ]: 0 : ABI_FREE(omega_li)
3306 : : else
3307 [ # # ]: 0 : fw1=fw2
3308 : : endif
3309 : :
3310 : : endif
3311 : :
3312 [ # # ]: 0 : end subroutine spline_fct
3313 : : !!***
3314 : :
3315 : : !!****f* m_green/occup_green_tau
3316 : : !! NAME
3317 : : !! occup_green_tau
3318 : : !!
3319 : : !! FUNCTION
3320 : : !! Compute occup_tau from green%oper_tau
3321 : : !!
3322 : : !! INPUTS
3323 : : !! green <type(green_type)>= green function data
3324 : : !!
3325 : : !! OUTPUT
3326 : : !!
3327 : : !! SOURCE
3328 : :
3329 : 68 : subroutine occup_green_tau(green)
3330 : :
3331 : : !Arguments ------------------------------------
3332 : : type(green_type), intent(inout) :: green
3333 : : !Local variables-------------------------------
3334 : : integer :: natom
3335 : 68 : complex(dp), allocatable :: shift(:)
3336 : : ! *********************************************************************
3337 : :
3338 : 68 : natom = green%oper_tau(1)%natom
3339 : :
3340 [ - + + - : 204 : ABI_MALLOC(shift,(natom))
+ - + - -
+ - + ]
3341 : :
3342 [ + + ]: 192 : shift(:) = - cone
3343 : :
3344 : 68 : call copy_matlu(green%oper_tau(1)%matlu(:),green%occup_tau%matlu(:),natom)
3345 : 68 : call shift_matlu(green%occup_tau%matlu(:),natom,shift(:))
3346 : :
3347 [ - + ]: 68 : ABI_FREE(shift)
3348 : :
3349 : 68 : end subroutine occup_green_tau
3350 : : !!***
3351 : :
3352 : : !!****f* m_green/occupfd
3353 : : !! NAME
3354 : : !! occupfd
3355 : : !!
3356 : : !! FUNCTION
3357 : : !!
3358 : : !! INPUTS
3359 : : !!
3360 : : !! OUTPUT
3361 : : !!
3362 : : !!
3363 : : !! SOURCE
3364 : :
3365 : : !function occupfd(eig,fermie,temp)
3366 : :
3367 : :
3368 : : !Arguments ------------------------------------
3369 : : !type
3370 : : ! Integrate analytic tail 1/(iw-mu)
3371 : : !real(dp),intent(in) :: eig,fermie,temp
3372 : : !real(dp) :: occupfd
3373 : : !Local variables-------------------------------
3374 : : ! *********************************************************************
3375 : :
3376 : : !if ((eig-fermie) > zero) then
3377 : : ! occupfd = exp(-(eig-fermie)/temp)/(one+exp(-(eig-fermie)/temp))
3378 : : !else
3379 : : ! occupfd = one / (one+exp((eig-fermie)/temp))
3380 : : !end if
3381 : :
3382 : : !end function occupfd
3383 : : !!***
3384 : :
3385 : : !!****f* m_green/distrib_paral
3386 : : !! NAME
3387 : : !! distrib_paral
3388 : : !!
3389 : : !! FUNCTION
3390 : : !!
3391 : : !! INPUTS
3392 : : !! nw : number of frequencies
3393 : : !! nkpt : number of k-points
3394 : : !! nproc : number of procs
3395 : : !!
3396 : : !! OUTPUT
3397 : : !! procb(iw,ikpt) : number of the proc that is in charge of the combination {iw,ikpt}.
3398 : : !! proct(iw,iproc) : 1 if the frequency "iw" should be computed by the proc "iproc"
3399 : : !! 0 if iw should not " "
3400 : : !! careful: if proct=1, it does not mean that each combination {iw,ikpt} is treated by this proc.
3401 : : !! SOURCE
3402 : :
3403 : 0 : subroutine distrib_paral(nkpt,nproc,nw,nw_perproc,procb,proct)
3404 : :
3405 : : !Arguments ------------------------------------
3406 : : !type
3407 : : ! Integrate analytic tail 1/(iw-mu)
3408 : : integer, intent(in) :: nw,nkpt,nproc
3409 : : integer, intent(out) :: nw_perproc
3410 : : integer, intent(out):: procb(nw,nkpt),proct(nw,0:nproc-1)
3411 : : !Local variables-------------------------------
3412 : : integer :: ikpt,iw,ir,ratio,m,iproc
3413 : 0 : integer, allocatable :: proca(:,:)
3414 : : ! *********************************************************************
3415 : :
3416 : :
3417 [ # # # # ]: 0 : proct(:,:)=0
3418 [ # # # # ]: 0 : procb(:,:)=-1
3419 : :
3420 [ # # ]: 0 : if(nproc.ge.2*nw) then
3421 : : !write(6,*) "AA"
3422 : 0 : ratio=nproc/nw
3423 [ # # # # : 0 : ABI_MALLOC(proca,(nw,nproc/nw))
# # # # #
# # # # #
# # ]
3424 [ # # ]: 0 : do ir=1,ratio
3425 [ # # ]: 0 : do iw=1,nw
3426 : 0 : proca(iw,ir)=iw+(ir-1)*nw-1
3427 : 0 : proct(iw,iw+(ir-1)*nw-1)=1
3428 : : enddo
3429 : : enddo
3430 : : ! do iw=1,nw
3431 : : ! write(6,*) " freq, procs"
3432 : : ! write(6,*) iw,proca(iw,:)
3433 : : ! enddo
3434 [ # # ]: 0 : do iw=1,nw
3435 [ # # ]: 0 : do ikpt=1,nkpt
3436 [ # # ]: 0 : if(ikpt.le.ratio) procb(iw,ikpt)=proca(iw,ikpt)
3437 [ # # ]: 0 : if(ikpt.ge.ratio) then
3438 : 0 : m=mod(ikpt,ratio)
3439 [ # # ]: 0 : if(m==0) then
3440 : 0 : procb(iw,ikpt)=proca(iw,ratio)
3441 : : else
3442 : 0 : procb(iw,ikpt)=proca(iw,m)
3443 : : endif
3444 : : endif
3445 : : ! write(6,*) " freq, k-point, proc"
3446 : : ! write(6,*) iw,ikpt,procb(iw,ikpt)
3447 : : enddo
3448 : : enddo
3449 : 0 : nw_perproc=1
3450 [ # # ]: 0 : ABI_FREE(proca)
3451 : :
3452 [ # # ]: 0 : else if (nproc.ge.nw) then
3453 : : !write(6,*) "BB"
3454 [ # # ]: 0 : do iw=1,nw
3455 [ # # ]: 0 : procb(iw,:)= iw
3456 : 0 : proct(iw,iw)=1
3457 : : enddo
3458 : : ! do iw=1,nw
3459 : : ! write(6,*) " freq, proc"
3460 : : ! write(6,*) iw, procb(iw,1)
3461 : : ! enddo
3462 : 0 : nw_perproc=1
3463 : :
3464 : : else if (nproc.le.nw) then
3465 : : !write(6,*) "CC"
3466 : 0 : ratio=nw/nproc
3467 : : !write(6,*) "ratio", ratio
3468 [ # # ]: 0 : do iproc=0,nproc-1
3469 [ # # ]: 0 : do iw=1,nw
3470 [ # # ]: 0 : if (mod(iw-1,nproc)==iproc) then
3471 [ # # ]: 0 : procb(iw,:)=iproc
3472 : 0 : proct(iw,iproc)=1
3473 : : endif
3474 : : enddo
3475 : : enddo
3476 : : ! do iw=1,nw
3477 : : ! write(6,*) "iw, iproc", iw, procb(iw,1)
3478 : : ! enddo
3479 : 0 : nw_perproc=ratio+1
3480 : : ! some procs will compute a number of frequency which is ratio and some
3481 : : ! other will compute a number of frequency which is ratio+1.
3482 : :
3483 : : ! do iw=1,nw
3484 : : ! write(6,*) " freq, proc"
3485 : : ! write(6,*) iw, procb(iw,1)
3486 : : ! enddo
3487 : : endif
3488 : :
3489 : : ! do iw=1,nw
3490 : : ! do iproc=0,nproc-1
3491 : : ! write(6,*) " freq, procs,?"
3492 : : ! write(6,*) iw,iproc,proct(iw,iproc)
3493 : : ! enddo
3494 : : ! enddo
3495 : :
3496 : :
3497 : :
3498 : 0 : end subroutine distrib_paral
3499 : : !!***
3500 : :
3501 : : !!****f* ABINIT/greendftcompute_green
3502 : : !! NAME
3503 : : !! greendftcompute_green
3504 : : !!
3505 : : !! FUNCTION
3506 : : !! Compute levels for ctqmc
3507 : : !!
3508 : : !! COPYRIGHT
3509 : : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
3510 : : !! This file is distributed under the terms of the
3511 : : !! GNU General Public License, see ~abinit/COPYING
3512 : : !! or http://www.gnu.org/copyleft/gpl.txt .
3513 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
3514 : : !!
3515 : : !! INPUTS
3516 : : !!
3517 : : !! OUTPUT
3518 : : !!
3519 : : !! SOURCE
3520 : :
3521 : 0 : subroutine greendftcompute_green(green,paw_dmft)
3522 : :
3523 : : !Arguments ------------------------------------
3524 : : !scalars
3525 : : type(paw_dmft_type), intent(in) :: paw_dmft
3526 : : type(green_type),intent(inout) :: green
3527 : :
3528 : : !Local variables ------------------------------
3529 : : ! scalars
3530 : : integer :: ifreq,iband,ikpt,isppol
3531 : : integer :: mbandc,natom,nspinor,nsppol,nkpt
3532 : : character(len=500) :: message
3533 : : ! arrays
3534 : : !************************************************************************
3535 : :
3536 : 0 : mbandc=paw_dmft%mbandc
3537 : 0 : nkpt=paw_dmft%nkpt
3538 : 0 : nsppol=paw_dmft%nsppol
3539 : 0 : nspinor=paw_dmft%nspinor
3540 : 0 : natom=paw_dmft%natom
3541 : :
3542 : : ! write(6,*) green%oper(1)%ks(1,1,1,1)
3543 [ # # ]: 0 : if(green%oper(1)%has_operks==0) then
3544 : 0 : ABI_ERROR("greendft%oper(1)%ks not allocated")
3545 : : endif
3546 : :
3547 : : !======================================
3548 : : !Get Green's function G=1/(iw_n+mu-e_nk)
3549 : : !======================================
3550 [ # # ]: 0 : do ifreq=1,green%nw
3551 [ # # ]: 0 : do iband=1,mbandc
3552 [ # # ]: 0 : do ikpt=1,nkpt
3553 [ # # ]: 0 : do isppol=1,nsppol
3554 : : ! write(6,*) green%oper(ifreq)%ks(isppol,ikpt,iband,iband)
3555 : : ! write(6,*) ifreq,iband,ikpt,isppol
3556 : : ! write(6,*) cmplx(0.d0,paw_dmft%omega_lo(ifreq),kind=dp)
3557 : : ! write(6,*) paw_dmft%fermie
3558 : : ! write(6,*) paw_dmft%eigen_dft(isppol,ikpt,iband)
3559 : : green%oper(ifreq)%ks(iband,iband,ikpt,isppol)=&
3560 : 0 : cone/(cmplx(0.d0,paw_dmft%omega_lo(ifreq),kind=dp)+paw_dmft%fermie-paw_dmft%eigen_dft(iband,ikpt,isppol))
3561 : : end do
3562 : : end do
3563 : : end do
3564 : :
3565 : :
3566 : : !======================================================================
3567 : : ! Compute local Green's function
3568 : : !======================================================================
3569 : 0 : call downfold_oper(green%oper(ifreq),paw_dmft)
3570 : :
3571 : : !======================================================================
3572 : : ! Symetrize
3573 : : !======================================================================
3574 : 0 : call sym_matlu(green%oper(ifreq)%matlu,paw_dmft)
3575 : : enddo
3576 : 0 : write(message,'(a,2x,a,f13.5)') ch10," == Print DFT Green's function for last frequency"
3577 : 0 : call wrtout(std_out,message,'COLL')
3578 : 0 : call print_matlu(green%oper(paw_dmft%dmft_nwlo)%matlu,natom,1)
3579 : :
3580 : 0 : end subroutine greendftcompute_green
3581 : : !!***
3582 : :
3583 : : !!****f* m_green/fermi_green
3584 : : !! NAME
3585 : : !! fermi_green
3586 : : !!
3587 : : !! FUNCTION
3588 : : !! Compute Fermi level for DMFT or DFT.
3589 : : !!
3590 : : !! COPYRIGHT
3591 : : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
3592 : : !! This file is distributed under the terms of the
3593 : : !! GNU General Public License, see ~abinit/COPYING
3594 : : !! or http://www.gnu.org/copyleft/gpl.txt .
3595 : : !!
3596 : : !! INPUTS
3597 : : !! green <type(green_type)>= green function data
3598 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
3599 : : !! self <type(self_type)>= variables related to self-energy
3600 : : !!
3601 : : !! OUTPUT
3602 : : !!
3603 : : !! SOURCE
3604 : :
3605 : 199 : subroutine fermi_green(green,paw_dmft,self)
3606 : :
3607 : : !Arguments ------------------------------------
3608 : : type(green_type), intent(inout) :: green
3609 : : type(paw_dmft_type), intent(inout) :: paw_dmft
3610 : : !type(MPI_type), intent(in) :: mpi_enreg
3611 : : type(self_type), intent(inout) :: self
3612 : : !Local variables-------------------------------
3613 : : integer :: ierr_hh,max_iter
3614 : : real(dp) :: f_precision,fermi_old,x_precision
3615 : : ! real(dp) :: hx
3616 : : character(len=13) :: tag
3617 : : character(len=500) :: message
3618 : : !************************************************************************
3619 : : !
3620 : : ABI_NVTX_START_RANGE(NVTX_DMFT_FERMI_GREEN)
3621 : 199 : write(message,'(a,8x,a)') ch10," == Compute Fermi level"
3622 : 199 : call wrtout(std_out,message,'COLL')
3623 : :
3624 : : !=============
3625 : : !headers
3626 : : !=============
3627 : 199 : write(message,'(2a)') ch10," |--- Newton method to search for Fermi level ------------|"
3628 : 199 : call wrtout(std_out,message,'COLL')
3629 : 199 : write(tag,'(f13.6)') paw_dmft%fermie
3630 : 199 : write(message,'(3a)') ch10," |--- Initial value for Fermi level ",adjustl(tag)
3631 : 199 : call wrtout(std_out,message,'COLL')
3632 : :
3633 : : !========================================
3634 : : !Define precision and nb of iterations
3635 : : !=========================================
3636 : 199 : fermi_old = paw_dmft%fermie
3637 : 199 : ierr_hh = 0
3638 : 199 : f_precision = paw_dmft%dmft_charge_prec
3639 : : !f_precision=0.01
3640 : 199 : x_precision = tol5
3641 : : !if(option==1) then
3642 : : !f_precision=(erreursurlacharge)/100d0
3643 : : !else
3644 : : !f_precision=tol11
3645 : : !endif
3646 : : !max_iter=1 ! for tests only
3647 : : !write(6,*) "for tests max_iter=1"
3648 : 199 : max_iter = 50
3649 : : !opt_noninter = 4
3650 : :
3651 : : ! Precompute some useful quantities so that the update of the moments can be done in constant time at each iteration
3652 : 199 : green%trace_fermie(1) = cmplx(paw_dmft%nsppol*paw_dmft%mbandc,zero,kind=dp)
3653 [ + + ]: 199 : if (paw_dmft%nsppol == 1 .and. paw_dmft%nspinor == 1) green%trace_fermie(1) = &
3654 : 108 : & green%trace_fermie(1) * two
3655 [ - + ]: 199 : if (green%has_moments == 1) then
3656 : 0 : call compute_trace_moments_ks(green,self,paw_dmft)
3657 : : end if
3658 : :
3659 : : !=====================
3660 : : !Call newton method
3661 : : !=====================
3662 : 199 : write(message,'(a,4x,a,e13.6)') ch10," Precision required :",f_precision
3663 : 199 : call wrtout(std_out,message,'COLL')
3664 [ + - ]: 199 : if (f_precision < ten) then
3665 : 199 : call newton(green,self,paw_dmft,paw_dmft%fermie,x_precision,max_iter,f_precision,ierr_hh)
3666 : : end if
3667 : :
3668 : : !===========================
3669 : : !Deals with errors signals
3670 : : !===========================
3671 [ - + ]: 199 : if (ierr_hh == -314) then
3672 : 0 : write(message,'(a)') "Warning, check Fermi level"
3673 : 0 : call wrtout(std_out,message,'COLL')
3674 : : ! call abi_abort('COLL')
3675 : 0 : write(message,'(2a,f13.6)') ch10," |--- Final value for Fermi level (check)",paw_dmft%fermie
3676 : 0 : call wrtout(std_out,message,'COLL')
3677 [ - + ]: 199 : else if (ierr_hh == -123) then
3678 : 0 : write(message,'(a,f13.6)') " Fermi level is set to",fermi_old
3679 : 0 : paw_dmft%fermie = fermi_old
3680 : 0 : call wrtout(std_out,message,'COLL')
3681 : :
3682 : : ! =====================================
3683 : : ! If fermi level search was successful
3684 : : ! =====================================
3685 : : else
3686 : 199 : write(tag,'(e13.6)') x_precision
3687 : 199 : write(message,'(a,4x,2a)') ch10," Precision achieved on Fermi Level : ",adjustl(tag)
3688 : 199 : call wrtout(std_out,message,'COLL')
3689 : 199 : write(tag,'(e13.6)') f_precision
3690 : 199 : write(message,'(4x,2a)') " Precision achieved on number of electrons : ",adjustl(tag)
3691 : 199 : call wrtout(std_out,message,'COLL')
3692 : 199 : write(tag,'(f13.6)') paw_dmft%fermie
3693 : 199 : write(message,'(3a)') ch10," |--- Final value for Fermi level ",adjustl(tag)
3694 : 199 : call wrtout(std_out,message,'COLL')
3695 : : end if ! ierr_hh
3696 : :
3697 : : !========================================================
3698 : : ! Check convergence of fermi level during DMFT iterations
3699 : : !========================================================
3700 [ + + ]: 199 : if (paw_dmft%idmftloop >= 2) then
3701 [ + + ]: 110 : if (abs(paw_dmft%fermie-fermi_old) <= paw_dmft%dmft_fermi_prec) then
3702 : : ! write(message,'(a,8x,a,e9.2,a,8x,a,e12.5)') ch10,"|fermie(n)-fermie(n-1)|=<",paw_dmft%dmft_fermi_prec,ch10,&
3703 : 1 : write(message,'(a,8x,a,e9.2,a,e9.2,a,8x,a,e12.5)') ch10,"|fermie(n)-fermie(n-1)|=",&
3704 : 1 : & abs(paw_dmft%fermie-fermi_old),"<",paw_dmft%dmft_fermi_prec,ch10,&
3705 : 2 : & "=> DMFT Loop: Fermi level is converged to:",paw_dmft%fermie
3706 : 1 : call wrtout(std_out,message,'COLL')
3707 : 1 : green%ifermie_cv = 1
3708 : : else
3709 : 109 : write(tag,'(f12.5)') paw_dmft%fermie
3710 : 109 : write(message,'(a,8x,2a)') ch10,"DMFT Loop: Fermi level is not converged: ",adjustl(tag)
3711 : 109 : call wrtout(std_out,message,'COLL')
3712 : 109 : green%ifermie_cv = 0
3713 : : end if ! convergence of Fermi level
3714 : : end if ! idmftloop>=2
3715 : 199 : write(message,'(2a)') ch10, " |---------------------------------------------------|"
3716 : 199 : call wrtout(std_out,message,'COLL')
3717 : : !
3718 : : !==========================================================
3719 : : !Recompute full green function including non diag elements
3720 : : !==========================================================
3721 : : !call compute_green(green,paw_dmft,0,self,opt_self=1,opt_nonxsum=1)
3722 : : !call integrate_green(green,paw_dmft,prtopt=0,opt_ksloc=3) !,opt_nonxsum=1)
3723 : :
3724 : : ABI_NVTX_END_RANGE()
3725 : : !return
3726 : 199 : end subroutine fermi_green
3727 : : !!***
3728 : :
3729 : : !!****f* m_green/newton
3730 : : !! NAME
3731 : : !! newton
3732 : : !!
3733 : : !! FUNCTION
3734 : : !! Compute root of a function with newton methods (newton/halley)
3735 : : !!
3736 : : !! COPYRIGHT
3737 : : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
3738 : : !! This file is distributed under the terms of the
3739 : : !! GNU General Public License, see ~abinit/COPYING
3740 : : !! or http://www.gnu.org/copyleft/gpl.txt .
3741 : : !!
3742 : : !! INPUTS
3743 : : !! green <type(green_type)>= green function data
3744 : : !! self <type(self_type)>= variables related to self-energy
3745 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
3746 : : !! x_input : input value for x
3747 : : !! max_iter : maximum number of iterations
3748 : : !! f_precision : required precision on function F
3749 : : !! opt_algo : 1 for Newton, 2 for Halley
3750 : : !!
3751 : : !! OUTPUT
3752 : : !! x_precision : output precision on x
3753 : : !! ierr_hh : different from zero if an error occurs
3754 : : !!
3755 : : !! SOURCE
3756 : :
3757 : 199 : subroutine newton(green,self,paw_dmft,x_input,x_precision,max_iter,&
3758 : : & f_precision,ierr_hh,opt_algo)
3759 : :
3760 : : !Arguments ------------------------------------
3761 : : type(green_type), intent(inout) :: green
3762 : : type(self_type), intent(inout) :: self
3763 : : !type(MPI_type), intent(in) :: mpi_enreg
3764 : : type(paw_dmft_type), intent(inout) :: paw_dmft
3765 : : integer, intent(in) :: max_iter
3766 : : integer, intent(out) :: ierr_hh
3767 : : real(dp), intent(in) :: f_precision
3768 : : real(dp), intent(inout) :: x_input,x_precision
3769 : : integer, optional, intent(in) :: opt_algo
3770 : : !Local variables-------------------------------
3771 : : integer :: iter,option
3772 : : logical :: dmft_optim,l_minus,l_plus
3773 : : real(dp) :: Fx,Fxdouble,Fxoptimum,Fxprime,nb_elec_x,step
3774 : : real(dp) :: x_minus,x_optimum,x_plus,xold
3775 : : character(len=500) :: message
3776 : : ! *********************************************************************
3777 : :
3778 : 199 : x_minus = - dble(10)
3779 : 199 : x_plus = - dble(11)
3780 : 199 : xold = - dble(12)
3781 : :
3782 : 199 : ierr_hh = 0
3783 : 199 : option = 1
3784 [ - + ]: 199 : if (present(opt_algo)) option = opt_algo
3785 : 199 : step = paw_dmft%dmft_fermi_step
3786 : :
3787 : : !write(std_out,*) "ldaprint",opt_noninter
3788 : :
3789 : : !--- Start of iterations
3790 : 199 : write(message,'(a,3a)') " Fermi level Charge Difference"
3791 : 199 : call wrtout(std_out,message,'COLL')
3792 : : !do iter=1, 40
3793 : : !x_input=float(iter)/100_dp
3794 : : !call function_and_deriv(cryst_struc,f_precision,green,iter,mpi_enreg,paw_dmft,pawang,self,&
3795 : : !& x_input,x_before,x_precision,Fx,Fxprime,Fxdouble,opt_noninter,option)
3796 : : !write(std_out,*) x_input,Fx
3797 : : !enddo
3798 : : !call abi_abort('COLL')
3799 : :
3800 : 199 : l_minus = .false.
3801 : 199 : l_plus = .false.
3802 : 199 : Fxoptimum = one
3803 : 199 : x_optimum = zero
3804 : :
3805 : 199 : dmft_optim = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
3806 : :
3807 [ - + ]: 199 : if (dmft_optim) xold = x_input
3808 : :
3809 : : !========================================
3810 : : ! Start iteration to find fermi level
3811 : : !========================================
3812 [ + - ]: 2394 : do iter=1,max_iter
3813 : :
3814 : : ! ========================================
3815 : : ! If zero is located between two values: apply newton method or dichotomy
3816 : : ! ========================================
3817 [ + + - + ]: 2394 : if ((l_minus .and. l_plus) .or. dmft_optim) then
3818 : :
3819 : : ! ==============================================
3820 : : ! Compute the function and derivatives for newton
3821 : : ! ==============================================
3822 : : call function_and_deriv(green,self,paw_dmft,x_input,x_precision, &
3823 : 1975 : & f_precision,Fx,Fxprime,Fxdouble,option)
3824 : :
3825 : : ! Apply stop criterion on Fx
3826 [ + + ]: 1975 : if (abs(Fx) < f_precision) then
3827 : : ! write(message,'(a,2f12.6)') "Fx,f_precision",Fx,f_precision
3828 : : ! call wrtout(std_out,message,'COLL')
3829 : 199 : x_precision = x_input - xold
3830 : 199 : return
3831 : : end if ! abs(Fx)<f_precision
3832 [ - + ]: 1776 : if (iter == max_iter) then
3833 : 0 : write(message,'(a,2f12.6)') " Fermi level could not be found"
3834 : 0 : call wrtout(std_out,message,'COLL')
3835 : 0 : x_input = x_optimum
3836 : 0 : ierr_hh = -123
3837 : 0 : return
3838 : : end if ! iter=max_iter
3839 : :
3840 : : ! Cannot divide by Fxprime if too small
3841 [ - + ]: 1776 : if (abs(Fxprime) <= tol15) then
3842 : 0 : ierr_hh = -314
3843 : 0 : write(message,'(a,f12.7)') "Fxprime=",Fxprime
3844 : 0 : call wrtout(std_out,message,'COLL')
3845 : 0 : return
3846 : : end if ! abs(Fxprime)<=tol15
3847 : :
3848 : 1776 : x_precision = x_input - xold
3849 : :
3850 : : ! ==============================================
3851 : : ! Newton/Halley's formula for next iteration
3852 : : ! ==============================================
3853 : 1776 : xold = x_input
3854 [ + - ]: 1776 : if (option == 1) then
3855 [ - + ]: 1776 : if (dmft_optim) then
3856 [ # # ]: 0 : x_input = x_input - sign(one,Fx)*merge(step,min(step,abs(Fx/Fxprime)),Fxprime<0)
3857 : : else
3858 : 1776 : x_input = x_input - Fx/Fxprime
3859 : : end if ! dmft_optim
3860 : : end if ! option=1
3861 [ - + ]: 1776 : if (option == 2) x_input = x_input - two*Fx*Fxprime/(two*(Fxprime**2)-Fx*Fxdouble)
3862 : :
3863 : : ! ==============================================
3864 : : ! If newton does not work well, use dichotomy.
3865 : : ! ==============================================
3866 : :
3867 [ - + ]: 1776 : if (dmft_optim) then
3868 [ # # ]: 0 : if (Fx < 0) then
3869 : 0 : l_minus = .true.
3870 : 0 : x_minus = xold
3871 : : end if
3872 [ # # ]: 0 : if (Fx > 0) then
3873 : 0 : l_plus = .true.
3874 : 0 : x_plus = xold
3875 : : end if
3876 : : end if ! dmft_optim
3877 : :
3878 [ + + + + : 1776 : if ((x_input < x_minus .or. x_input > x_plus) .and. (l_minus .and. l_plus)) then
+ - ]
3879 : :
3880 [ + - ]: 33 : if (.not. dmft_optim) then
3881 : 33 : call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,xold)
3882 : : end if
3883 : :
3884 : 33 : write(message,'(a,3f12.6)') " ---",x_input,Fx+paw_dmft%nelectval,Fx
3885 : 33 : call wrtout(std_out,message,'COLL')
3886 [ - + ]: 33 : if (.not. dmft_optim) then
3887 [ + + ]: 33 : if (Fx > 0) then
3888 : : x_plus = xold
3889 [ - + ]: 17 : else if (Fx < 0) then
3890 : 33 : x_minus = xold
3891 : : end if ! Fx>0
3892 : : end if
3893 : 33 : x_input = (x_plus+x_minus) * half
3894 : :
3895 : : end if ! x_input<x_minus or x_input>x_plus
3896 : : ! write(std_out,'(a,2f12.6)') " Q(xold) and dQ/dx=",Fx,Fxprime
3897 : : ! write(std_out,'(a,f12.6)') " => new Fermi level",x_input
3898 : : ! ========================================
3899 : : ! Locate zero between two values
3900 : : ! ========================================
3901 : : else
3902 : 419 : call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,x_input)
3903 : 419 : write(message,'(a,3f12.6)') " --",x_input,nb_elec_x,Fx
3904 : : ! Possible improvement for large systems, removed temporarely for
3905 : : ! automatic tests: more study is necessary: might worsen the convergency
3906 : : ! if(iter==1) then
3907 : : ! f_precision=max(abs(Fx/50),f_precision)
3908 : : ! write(message,'(a,4x,a,e12.6)') ch10," Precision required changed to:",f_precision
3909 : : ! call wrtout(std_out,message,'COLL')
3910 : : ! endif
3911 : 419 : call wrtout(std_out,message,'COLL')
3912 [ + + ]: 419 : if (Fx > 0) then
3913 : 217 : l_plus = .true.
3914 : 217 : x_plus = x_input
3915 : 217 : x_input = x_input - step
3916 [ + - ]: 202 : else if (Fx < 0) then
3917 : 202 : l_minus = .true.
3918 : 202 : x_minus = x_input
3919 : 202 : x_input = x_input + step
3920 : : end if ! Fx>0
3921 : :
3922 : : end if ! l_minus and l_plus
3923 : :
3924 [ + + - + ]: 2195 : if (abs(Fx) < abs(Fxoptimum) .or. (iter == 1 .and. dmft_optim)) then
3925 : 1169 : Fxoptimum = Fx
3926 [ + - ]: 1169 : x_optimum = merge(xold,x_input,dmft_optim)
3927 : : end if ! abs(Fx)<abs(Fxoptimum)
3928 : :
3929 : :
3930 : :
3931 : : ! if(myid==master) then
3932 : : ! write(std_out,'(a,i4,3f12.6)') "i,xnew,F,Fprime",i,x_input,Fx,Fxprime
3933 : : ! endif
3934 : :
3935 : :
3936 : : ! ! Apply stop criterion on x
3937 : : ! if(abs(x_input-xold) .le. x_input*x_precision) then
3938 : : ! ! write(std_out,'(a,4f12.6)') "x_input-xold, x_precision*x_input "&
3939 : : ! !& ,x_input-xold,x_precision*x_input,x_precision
3940 : : ! f_precision=Fx
3941 : : ! return
3942 : : ! endif
3943 : :
3944 : : end do ! iter
3945 : : !--- End of iterations
3946 : :
3947 : :
3948 : 0 : ierr_hh = 1
3949 : : !return
3950 : :
3951 : : CONTAINS !========================================================================================
3952 : : !-----------------------------------------------------------------------
3953 : : !!***
3954 : :
3955 : : !!****f* newton/function_and_deriv
3956 : : !! NAME
3957 : : !! function_and_deriv
3958 : : !!
3959 : : !! FUNCTION
3960 : : !! Compute value of a function and its numerical derivatives
3961 : : !!
3962 : : !! INPUTS
3963 : : !! green <type(green_type)>= green function data
3964 : : !! self <type(self_type)>= variables related to self-energy
3965 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
3966 : : !! x_input = input value for x
3967 : : !! option = 1 to only compute the first derivative
3968 : : !! = 2 to compute the two first derivatives.
3969 : : !!
3970 : : !! OUTPUTS
3971 : : !! Fx : Value of F(x)
3972 : : !! Fxprime : Value of F'(x)
3973 : : !! Fxdouble : Value of F''(x)
3974 : : !!
3975 : : !! SOURCE
3976 : :
3977 : 1975 : subroutine function_and_deriv(green,self,paw_dmft,x_input,x_precision, &
3978 : : & f_precision,Fx,Fxprime,Fxdouble,option)
3979 : :
3980 : : !Arguments ------------------------------------
3981 : : type(green_type), intent(inout) :: green
3982 : : type(self_type), intent(inout) :: self
3983 : : !type(MPI_type), intent(in) :: mpi_enreg
3984 : : type(paw_dmft_type), intent(inout) :: paw_dmft
3985 : : integer, intent(in) :: option
3986 : : real(dp), intent(in) :: f_precision,x_input,x_precision
3987 : : real(dp), intent(out) :: Fx,Fxprime,Fxdouble
3988 : : !Local variables-------------------------------
3989 : : logical :: dmft_optim
3990 : : real(dp) :: deltax,Fxminus,Fxplus,nb_elec_x,xminus,x0,xplus
3991 : : character(len=500) :: message
3992 : : ! *********************************************************************
3993 : :
3994 : 1975 : dmft_optim = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
3995 : :
3996 [ + - ]: 1975 : if (.not. dmft_optim) then
3997 : :
3998 : : ! Choose deltax: for numeric evaluation of derivative
3999 : : !if(iter==1) then
4000 : : ! deltax=0.02
4001 : : !end if
4002 : : ! deltax=max((x_input-x_old)/10.d0,min(0.00001_dp,x_precision/100_dp))
4003 : 1975 : deltax = min(tol5,x_precision/dble(100)) ! small but efficient
4004 : : ! endif
4005 : : ! write(std_out,*) "iter,x_input,deltax",iter,x_input,deltax
4006 : 1975 : x0 = x_input
4007 : 1975 : xminus = x0 - deltax
4008 : 1975 : xplus = x0 + deltax
4009 : :
4010 : 1975 : call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,x0)
4011 : :
4012 : 1975 : write(message,'(a,3f12.6)') " - ",x0,nb_elec_x,Fx
4013 : 1975 : call wrtout(std_out,message,'COLL')
4014 : :
4015 : : ! write(std_out,*) "Fx", Fx
4016 [ + + ]: 1975 : if (abs(Fx) < f_precision) return
4017 : :
4018 : 1776 : call compute_nb_elec(green,self,paw_dmft,Fxplus,nb_elec_x,xplus)
4019 : :
4020 : 1776 : write(message,'(a,3f12.6)') " - ",xplus,nb_elec_x,Fxplus
4021 : 1776 : call wrtout(std_out,message,'COLL')
4022 : :
4023 [ - + ]: 1776 : if (option == 2) then
4024 : 0 : call compute_nb_elec(green,self,paw_dmft,Fxminus,nb_elec_x,xminus)
4025 : :
4026 : 0 : write(message,'(a,3f12.6)') " - ",xminus,nb_elec_x,Fxminus
4027 : 0 : call wrtout(std_out,message,'COLL')
4028 : : end if ! option=2
4029 : :
4030 [ + - ]: 1776 : if (option == 1) then
4031 : 1776 : Fxprime = (Fxplus-Fx) / deltax
4032 [ # # ]: 0 : else if (option == 2) then
4033 : 0 : Fxprime = (Fxplus-Fxminus) / (two*deltax)
4034 : 0 : Fxdouble = (Fxplus+Fxminus-two*Fx) / (deltax**2)
4035 : : end if ! option
4036 : : ! write(std_out,*) "after computation of Fxprime",myid
4037 : :
4038 : : else
4039 : :
4040 : 0 : call compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,x_input,Fxprime=Fxprime)
4041 : :
4042 : 0 : write(message,'(a,3f12.6)') " - ",x_input,nb_elec_x,Fx
4043 : 0 : call wrtout(std_out,message,'COLL')
4044 : :
4045 : : end if ! dmft_optim
4046 : :
4047 [ - + ]: 1776 : if (Fxprime < zero) then
4048 : 0 : write(message,'(a,f12.6)') " Warning: slope of charge versus fermi level is negative !",Fxprime
4049 : 0 : call wrtout(std_out,message,'COLL')
4050 : : end if
4051 : :
4052 : : end subroutine function_and_deriv
4053 : : !!***
4054 : :
4055 : : !!****f* newton/compute_nb_elec
4056 : : !! NAME
4057 : : !! compute_nb_elec
4058 : : !!
4059 : : !! FUNCTION
4060 : : !! Compute nb of electrons as a function of Fermi level
4061 : : !!
4062 : : !! INPUTS
4063 : : !! fermie : input of energy
4064 : : !! opt_noninter
4065 : : !!
4066 : : !! OUTPUTS
4067 : : !! Fx : Value of F(x).
4068 : : !! nb_elec_x : Number of electrons for the value of x
4069 : : !!
4070 : : !! SOURCE
4071 : :
4072 : 4203 : subroutine compute_nb_elec(green,self,paw_dmft,Fx,nb_elec_x,fermie,Fxprime)
4073 : :
4074 : : !Arguments ------------------------------------
4075 : : type(green_type), intent(inout) :: green
4076 : : type(self_type), intent(inout) :: self
4077 : : !type(MPI_type), intent(in) :: mpi_enreg
4078 : : type(paw_dmft_type), intent(inout) :: paw_dmft
4079 : : !integer,intent(in) :: opt_noninter
4080 : : real(dp), intent(in) :: fermie
4081 : : real(dp), intent(out) :: Fx,nb_elec_x
4082 : : real(dp), optional, intent(out) :: Fxprime
4083 : : !Local variables-------------------------------
4084 : : integer :: band_index,i,ib,ierr,ifreq,ikpt,isppol,mbandc
4085 : : integer :: mkmem,nband_k,nkpt,nmoments,nspinor,nsppol,shift
4086 : : logical :: dmft_optim
4087 : : real(dp) :: correction,correction_prime,eig
4088 : : real(dp) :: fac,occ_prime,temp,wtk
4089 : : complex(dp) :: omega
4090 : 4203 : type(oper_type) :: oper_tmp
4091 : 4203 : complex(dp), allocatable :: omega_fac(:),trace_moments(:),trace_moments_prime(:)
4092 : : ! *********************************************************************
4093 : :
4094 : : ABI_NVTX_START_RANGE(NVTX_DMFT_COMPUTE_NB_ELEC)
4095 : 4203 : dmft_optim = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
4096 : :
4097 [ + - ]: 4203 : if (.not. dmft_optim) then
4098 : :
4099 : 4203 : paw_dmft%fermie = fermie
4100 : 4203 : call compute_green(green,paw_dmft,0,self,opt_self=1,opt_nonxsum=1,opt_nonxsum2=1)
4101 : 4203 : call integrate_green(green,paw_dmft,0,opt_ksloc=-1) !,opt_nonxsum=1)
4102 : : ! opt_ksloc=-1, compute total charge
4103 : :
4104 : : else
4105 : :
4106 : 0 : green%charge_ks = zero
4107 : :
4108 : 0 : mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
4109 : 0 : shift = green%distrib%shiftk
4110 [ # # ]: 0 : nmoments = merge(green%nmoments,1,green%has_moments==1)
4111 : :
4112 : 0 : mbandc = paw_dmft%mbandc
4113 : 0 : nkpt = paw_dmft%nkpt
4114 : 0 : nspinor = paw_dmft%nspinor
4115 : 0 : nsppol = paw_dmft%nsppol
4116 : 0 : temp = paw_dmft%temp
4117 : :
4118 [ # # # # : 0 : ABI_MALLOC(trace_moments,(nmoments))
# # # # #
# # # ]
4119 [ # # # # : 0 : ABI_MALLOC(trace_moments_prime,(nmoments))
# # # # ]
4120 : :
4121 : 0 : trace_moments(1) = green%trace_fermie(1)
4122 [ # # ]: 0 : trace_moments_prime(:) = czero
4123 : 0 : Fxprime = zero
4124 : :
4125 [ # # ]: 0 : if (green%has_moments == 1) then
4126 : 0 : call compute_trace_moments(fermie,green%trace_fermie(:),trace_moments(:),trace_moments_prime(:))
4127 : : end if
4128 : :
4129 : 0 : call init_oper(paw_dmft,oper_tmp,nkpt=mkmem,shiftk=shift)
4130 : :
4131 [ # # ]: 0 : do ifreq=1,green%nw
4132 [ # # ]: 0 : if (green%distrib%proct(ifreq) /= green%distrib%me_freq) cycle
4133 : 0 : omega = cmplx(zero,green%omega(ifreq),kind=dp)
4134 [ # # ]: 0 : fac = two * paw_dmft%wgt_wlo(ifreq) * merge(two*temp,temp,nsppol==1.and.nspinor==1)
4135 : :
4136 : 0 : call add_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),oper_tmp%matlu(:),paw_dmft%natom,-1)
4137 : 0 : call upfold_oper(oper_tmp,paw_dmft)
4138 : :
4139 [ # # ]: 0 : do isppol=1,nsppol
4140 [ # # ]: 0 : do ikpt=1,mkmem
4141 : 0 : wtk = paw_dmft%wtk(ikpt+shift)
4142 [ # # ]: 0 : do ib=1,mbandc
4143 : : oper_tmp%ks(ib,ib,ikpt,isppol) = oper_tmp%ks(ib,ib,ikpt,isppol) + omega + &
4144 : 0 : & fermie - paw_dmft%eigen_dft(ib,ikpt+shift,isppol)
4145 : : end do ! ib
4146 : 0 : call xginv(oper_tmp%ks(:,:,ikpt,isppol),mbandc)
4147 : :
4148 [ # # # # ]: 0 : Fxprime = Fxprime - dble(sum(oper_tmp%ks(:,:,ikpt,isppol)*transpose(oper_tmp%ks(:,:,ikpt,isppol))))*wtk*fac
4149 [ # # ]: 0 : do ib=1,mbandc
4150 : 0 : green%charge_ks = green%charge_ks + dble(oper_tmp%ks(ib,ib,ikpt,isppol))*wtk*fac
4151 : : end do ! ib
4152 : : end do ! ikpt
4153 : : end do ! isppol
4154 : :
4155 : : end do ! ifreq
4156 : :
4157 : 0 : call xmpi_sum(green%charge_ks,paw_dmft%spacecomm,ierr)
4158 : 0 : call xmpi_sum(Fxprime,paw_dmft%spacecomm,ierr)
4159 : :
4160 : 0 : call destroy_oper(oper_tmp)
4161 : :
4162 [ # # # # : 0 : ABI_MALLOC(omega_fac,(nmoments))
# # # # ]
4163 : :
4164 [ # # ]: 0 : do i=1,nmoments
4165 : 0 : omega_fac(i) = czero
4166 [ # # ]: 0 : do ifreq=green%nw,1,-1 ! NEVER change the summation order and DON'T use the intrinsic SUM
4167 : 0 : omega_fac(i) = omega_fac(i) + paw_dmft%wgt_wlo(ifreq) / (paw_dmft%omega_lo(ifreq))**i
4168 : : end do
4169 : 0 : omega_fac(i) = - two * temp * omega_fac(i) / (j_dpc)**i
4170 [ # # ]: 0 : if (i == 1) omega_fac(i) = omega_fac(i) + half
4171 [ # # ]: 0 : if (i == 2) omega_fac(i) = omega_fac(i) - cone/(four*temp)
4172 [ # # ]: 0 : if (i == 4) omega_fac(i) = omega_fac(i) + cone/(dble(48)*(temp**3))
4173 : : end do ! i
4174 : :
4175 : : ! Do not use DOT_PRODUCT
4176 [ # # ]: 0 : green%charge_ks = green%charge_ks + dble(sum(trace_moments(1:nmoments)*omega_fac(1:nmoments)))
4177 : : ! Do not use DOT_PRODUCT
4178 [ # # ]: 0 : Fxprime = Fxprime + dble(sum(trace_moments_prime(1:nmoments)*omega_fac(1:nmoments)))
4179 : :
4180 : 0 : ABI_FREE(trace_moments)
4181 [ # # ]: 0 : ABI_FREE(trace_moments_prime)
4182 [ # # ]: 0 : ABI_FREE(omega_fac)
4183 : :
4184 [ # # ]: 0 : if (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7) then
4185 : : band_index = 0
4186 : : correction = zero
4187 : : correction_prime = zero
4188 [ # # ]: 0 : do isppol=1,nsppol
4189 [ # # ]: 0 : do ikpt=1,nkpt
4190 : 0 : nband_k = paw_dmft%nband(ikpt+(isppol-1)*nkpt)
4191 : 0 : wtk = paw_dmft%wtk(ikpt)
4192 [ # # ]: 0 : do ib=1,nband_k
4193 [ # # ]: 0 : if (paw_dmft%band_in(ib)) cycle
4194 : 0 : eig = paw_dmft%eigen(ib+band_index)
4195 : 0 : correction = correction + occup_fd(eig,fermie,temp)*wtk
4196 [ # # ]: 0 : if ((eig-fermie) > zero) then
4197 : 0 : occ_prime = exp(-(eig-fermie)/temp) / (one+exp(-(eig-fermie)/temp))**2 / temp
4198 : : else
4199 : 0 : occ_prime = exp((eig-fermie)/temp) / (one+exp((eig-fermie)/temp))**2 / temp
4200 : : end if
4201 : 0 : correction_prime = correction_prime + occ_prime*wtk
4202 : : end do ! ib
4203 : 0 : band_index = band_index + nband_k
4204 : : end do ! ikpt
4205 : : end do ! isppol
4206 [ # # ]: 0 : if (nsppol == 1 .and. nspinor == 1) correction = correction * two
4207 : 0 : green%charge_ks = green%charge_ks + correction
4208 [ # # ]: 0 : if (nsppol == 1 .and. nspinor == 1) correction_prime = correction_prime * two
4209 : 0 : Fxprime = Fxprime + correction_prime
4210 : : end if ! use_all_bands
4211 : :
4212 : : end if ! dmft_optim
4213 : :
4214 : 4203 : nb_elec_x = green%charge_ks
4215 : 4203 : Fx = green%charge_ks - paw_dmft%nelectval
4216 : :
4217 : : ABI_NVTX_END_RANGE()
4218 [ - + - - : 4203 : end subroutine compute_nb_elec
- - - + ]
4219 : : !!***
4220 : :
4221 [ # # # # : 0 : subroutine compute_trace_moments(fermie,trace_fermie,trace_moments,trace_moments_prime)
# # ]
4222 : :
4223 : : !Arguments ------------------------------------
4224 : : real(dp), intent(in) :: fermie
4225 : : complex(dp), intent(in) :: trace_fermie(:)
4226 : : complex(dp), intent(inout) :: trace_moments(:),trace_moments_prime(:)
4227 : : !Local variables-------------------------------
4228 : : real(dp) :: fermie2,fermie3,fermie4
4229 : : ! *********************************************
4230 : :
4231 : 0 : fermie2 = fermie * fermie
4232 : 0 : fermie3 = fermie2 * fermie
4233 : 0 : fermie4 = fermie3 * fermie
4234 : :
4235 : 0 : trace_moments(2) = trace_fermie(2) - fermie*trace_fermie(1)
4236 : : trace_moments(3) = trace_fermie(3) + trace_fermie(4) - two*fermie*trace_fermie(2) + &
4237 : 0 : & fermie2*trace_fermie(1)
4238 : : trace_moments(4) = trace_fermie(5) + two*(trace_fermie(6)-fermie*trace_fermie(3)) + &
4239 : : & trace_fermie(7) - three*fermie*trace_fermie(4) + &
4240 : 0 : & three*fermie2*trace_fermie(2) - fermie3*trace_fermie(1)
4241 : : trace_moments(5) = trace_fermie(8) + two*(trace_fermie(9)-fermie*trace_fermie(5)) + &
4242 : : & trace_fermie(10) + three*(trace_fermie(11)-two*fermie*trace_fermie(6)+ &
4243 : : & fermie2*trace_fermie(3)) + trace_fermie(12) - four*fermie*trace_fermie(7) + &
4244 : : & six*fermie2*trace_fermie(4) - four*fermie3*trace_fermie(2) + &
4245 : 0 : & fermie4*trace_fermie(1)
4246 : :
4247 : 0 : trace_moments_prime(2) = - trace_fermie(1)
4248 : 0 : trace_moments_prime(3) = two * (fermie*trace_fermie(1)-trace_fermie(2))
4249 : : trace_moments_prime(4) = - two*trace_fermie(3) - three*trace_fermie(4) + &
4250 : 0 : & six*fermie*trace_fermie(2) - three*fermie2*trace_fermie(1)
4251 : : trace_moments_prime(5) = - two*trace_fermie(5) + three*(-two*trace_fermie(6)+ &
4252 : : & two*fermie*trace_fermie(3)) - four*trace_fermie(7) + &
4253 : : & dble(12)*fermie*trace_fermie(4) - dble(12)*fermie2*trace_fermie(2) + &
4254 : 0 : & four*fermie3*trace_fermie(1)
4255 : :
4256 : 0 : end subroutine compute_trace_moments
4257 : : !!***
4258 : :
4259 : : end subroutine newton
4260 : : !!***
4261 : :
4262 : : !!****f* m_green/local_ks_green
4263 : : !! NAME
4264 : : !! local_ks_green
4265 : : !!
4266 : : !! FUNCTION
4267 : : !! Compute the sum over k-point of ks green function.
4268 : : !! do the fourier transformation and print it
4269 : : !!
4270 : : !! COPYRIGHT
4271 : : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
4272 : : !! This file is distributed under the terms of the
4273 : : !! GNU General Public License, see ~abinit/COPYING
4274 : : !! or http://www.gnu.org/copyleft/gpl.txt .
4275 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
4276 : : !!
4277 : : !! INPUTS
4278 : : !! cryst_struc
4279 : : !! istep = step of iteration for DFT.
4280 : : !! dft_occup
4281 : : !! mpi_enreg=information about MPI parallelization
4282 : : !! paw_dmft = data for self-consistent DFT+DMFT calculations.
4283 : : !!
4284 : : !! OUTPUT
4285 : : !! paw_dmft = data for self-consistent DFT+DMFT calculations.
4286 : : !!
4287 : : !! SOURCE
4288 : :
4289 : 0 : subroutine local_ks_green(green,paw_dmft,prtopt)
4290 : :
4291 : : !Arguments ------------------------------------
4292 : : !scalars
4293 : : type(green_type), intent(in) :: green
4294 : : type(paw_dmft_type), intent(in) :: paw_dmft
4295 : : integer, intent(in) :: prtopt
4296 : :
4297 : : !Local variables ------------------------------
4298 : : character(len=500) :: message
4299 : : integer :: iband,ifreq,ikpt,isppol,itau,lsub,ltau,mbandc,nkpt,nsppol
4300 : : character(len=1) :: tag_is
4301 : : character(len=fnlen) :: tmpfil
4302 : 0 : integer,allocatable :: unitgreenlocks_arr(:)
4303 : : real(dp) :: beta
4304 : 0 : real(dp), allocatable :: tau(:)
4305 : 0 : complex(dp), allocatable :: loc_ks(:,:,:)
4306 : 0 : complex(dp), allocatable :: loc_ks_tau(:,:,:),fw(:),ft(:)
4307 : : !************************************************************************
4308 : 0 : mbandc=paw_dmft%mbandc
4309 : 0 : nkpt=paw_dmft%nkpt
4310 : 0 : nsppol=paw_dmft%nsppol
4311 : 0 : ltau=128
4312 [ # # ]: 0 : ABI_MALLOC(tau,(ltau))
4313 [ # # ]: 0 : do itau=1,ltau
4314 : 0 : tau(itau)=float(itau-1)/float(ltau)/paw_dmft%temp
4315 : : end do
4316 : 0 : beta=one/paw_dmft%temp
4317 : :
4318 : : !Only imaginary frequencies here
4319 [ # # ]: 0 : if(green%w_type=="real") then
4320 : 0 : message = ' compute_energy not implemented for real frequency'
4321 : 0 : ABI_BUG(message)
4322 : : end if
4323 : :
4324 : : !=========================================
4325 : : !Compute local band ks green function
4326 : : ! should be computed in compute_green: it would be less costly in memory.
4327 : : !=========================================
4328 [ # # # # : 0 : ABI_MALLOC(loc_ks,(nsppol,mbandc,paw_dmft%dmft_nwlo))
# # # # #
# # # # #
# # # # #
# ]
4329 [ # # ]: 0 : if(green%oper(1)%has_operks==1) then
4330 [ # # # # : 0 : loc_ks(:,:,:)=czero
# # ]
4331 [ # # ]: 0 : do isppol=1,nsppol
4332 [ # # ]: 0 : do iband=1,mbandc
4333 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
4334 [ # # ]: 0 : do ikpt=1,nkpt
4335 : : loc_ks(isppol,iband,ifreq)=loc_ks(isppol,iband,ifreq)+ &
4336 : 0 : & green%oper(ifreq)%ks(iband,iband,ikpt,isppol)*paw_dmft%wtk(ikpt)
4337 : : end do
4338 : : end do
4339 : : end do
4340 : : end do
4341 : : else
4342 : 0 : message = ' green fct is not computed in ks space'
4343 : 0 : ABI_BUG(message)
4344 : : end if
4345 : :
4346 : : !=========================================
4347 : : !Compute fourier transformation
4348 : : !=========================================
4349 : :
4350 [ # # # # : 0 : ABI_MALLOC(loc_ks_tau,(nsppol,mbandc,ltau))
# # # # #
# # # # #
# # # # #
# ]
4351 [ # # # # : 0 : ABI_MALLOC(fw,(paw_dmft%dmft_nwlo))
# # # # #
# # # ]
4352 [ # # # # : 0 : ABI_MALLOC(ft,(ltau))
# # # # #
# # # ]
4353 [ # # # # : 0 : loc_ks_tau(:,:,:)=czero
# # ]
4354 [ # # ]: 0 : do isppol=1,nsppol
4355 [ # # ]: 0 : do iband=1,mbandc
4356 [ # # ]: 0 : do ifreq=1,paw_dmft%dmft_nwlo
4357 : 0 : fw(ifreq)=loc_ks(isppol,iband,ifreq)
4358 : : end do
4359 : 0 : call fourier_fct(fw,ft,.true.,ltau,-1,paw_dmft) ! inverse fourier
4360 [ # # ]: 0 : do itau=1,ltau
4361 : 0 : loc_ks_tau(isppol,iband,itau)=ft(itau)
4362 : : end do
4363 : : end do
4364 : : end do
4365 [ # # ]: 0 : ABI_FREE(fw)
4366 [ # # ]: 0 : ABI_FREE(ft)
4367 [ # # ]: 0 : do isppol=1,nsppol
4368 [ # # ]: 0 : do iband=1,mbandc
4369 [ # # ]: 0 : do itau=1,ltau
4370 : 0 : loc_ks_tau(isppol,iband,itau)=(loc_ks_tau(isppol,iband,itau)+conjg(loc_ks_tau(isppol,iband,itau)))/two
4371 : : end do
4372 : : end do
4373 : : end do
4374 : :
4375 : : !=========================================
4376 : : !Print out ksloc green function
4377 : : !=========================================
4378 [ # # ]: 0 : if(abs(prtopt)==1) then
4379 [ # # # # : 0 : ABI_MALLOC(unitgreenlocks_arr,(nsppol))
# # # # #
# # # ]
4380 [ # # ]: 0 : do isppol=1,nsppol
4381 : 0 : write(tag_is,'(i1)')isppol
4382 [ # # ]: 0 : tmpfil = trim(paw_dmft%filapp)//'Gtau_locks_isppol'//tag_is
4383 : 0 : write(message,'(3a)') ch10," == Print green function on file ",trim(tmpfil)
4384 : 0 : call wrtout(std_out,message,'COLL')
4385 : 0 : unitgreenlocks_arr(isppol)=500+isppol-1
4386 : 0 : open (unit=unitgreenlocks_arr(isppol),file=trim(tmpfil),status='unknown',form='formatted')
4387 : 0 : rewind(unitgreenlocks_arr(isppol))
4388 : 0 : write(message,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitgreenlocks_arr(isppol)
4389 : 0 : write(message,'(a,a)') ch10,"# New record : First 40 bands"
4390 : 0 : call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
4391 [ # # ]: 0 : do lsub=1,mbandc/40+1
4392 [ # # ]: 0 : do itau=1, ltau
4393 : 0 : write(message,'(2x,50(e10.3,2x))') tau(itau), &
4394 [ # # # # ]: 0 : & (real(loc_ks_tau(isppol,iband,itau)),iband=40*(lsub-1)+1,min(40*lsub,mbandc))
4395 : 0 : call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
4396 : : end do
4397 : 0 : write(message,'(2x,50(e10.3,2x))') beta, &
4398 [ # # # # ]: 0 : & ((-one-real(loc_ks_tau(isppol,iband,1))),iband=40*(lsub-1)+1,min(40*lsub,mbandc))
4399 : 0 : call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
4400 [ # # ]: 0 : if(40*lsub<mbandc) then
4401 : : write(message,'(a,a,i5,a,i5)') &
4402 : 0 : & ch10,"# Same record, Following bands : From ", &
4403 : 0 : & 40*(lsub)," to ",min(40*(lsub+1),mbandc)
4404 : 0 : call wrtout(unitgreenlocks_arr(isppol),message,'COLL')
4405 : : end if
4406 : : end do
4407 : : ! call flush(unitgreenlocks_arr(isppol))
4408 : : end do
4409 [ # # ]: 0 : ABI_FREE(unitgreenlocks_arr)
4410 : : end if
4411 : :
4412 : : !Deallocations
4413 [ # # ]: 0 : ABI_FREE(loc_ks)
4414 [ # # ]: 0 : ABI_FREE(loc_ks_tau)
4415 [ # # ]: 0 : ABI_FREE(tau)
4416 : :
4417 : 0 : end subroutine local_ks_green
4418 : : !!***
4419 : :
4420 : : !!****f* m_green/compute_moments_ks
4421 : : !! NAME
4422 : : !! compute_moments_ks
4423 : : !!
4424 : : !! FUNCTION
4425 : : !! Compute the high-frequency moments of the Green's function in KS space
4426 : : !!
4427 : : !! COPYRIGHT
4428 : : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
4429 : : !! This file is distributed under the terms of the
4430 : : !! GNU General Public License, see ~abinit/COPYING
4431 : : !! or http://www.gnu.org/copyleft/gpl.txt .
4432 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
4433 : : !!
4434 : : !! INPUTS
4435 : : !! green <type(green_type)>= green function data
4436 : : !! self <type(self_type)>= variables related to self-energy
4437 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
4438 : : !! opt_self = 0 : do not use the self-energy
4439 : : !! = 1 (default) : use the self-energy, by upfolding its moments
4440 : : !! opt_log = 0 (default): the moments of G are computed in green%moments using self%moments
4441 : : !! = 1 : the trace of the moments of log(G)+log(iw*Id)=-log(Id+(mu-sigma)/iw) is computed in green%trace_moments_log_ks
4442 : : !! opt_quick_restart = 0 (default) : default behavior, recompute everything from scratch
4443 : : !! = 1 : use precomputed quantities from fermi_green : assume that self%moments(i>=2) have
4444 : : !! already been upfolded, that self%moments(1)-self%hdc has already been upfolded in
4445 : : !! green%moments(2), and that (self%moments(1)-self%hdc+eigen_dft)**2 has been computed
4446 : : !! in green%moments(3)
4447 : : !! The conventions are: green%moments(i) -> ith order moment of the Green's function in the usual case
4448 : : !! (the 1st one is not computed, since this is simply the identity)
4449 : : !! self%moments(i) -> (i-1)th order moment of the self-energy (the 1st one is not upfolded, since we directly
4450 : : !! upfold self%moments(1) - self%hdc
4451 : : !! where the ith order moment corresponds to the factor in front of 1/(jw_n)^i in the asymptotic expansion
4452 : : !!
4453 : : !! OUTPUT
4454 : : !!
4455 : : !! SOURCE
4456 : :
4457 : 0 : subroutine compute_moments_ks(green,self,paw_dmft,opt_self,opt_log,opt_quick_restart)
4458 : :
4459 : : !Arguments ------------------------------------
4460 : : !scalars
4461 : : type(green_type), intent(inout) :: green
4462 : : type(self_type), intent(inout) :: self
4463 : : type(paw_dmft_type), intent(in) :: paw_dmft
4464 : : integer, optional, intent(in) :: opt_log,opt_quick_restart,opt_self
4465 : : !Local variables ------------------------------
4466 : : integer :: diag,i,ib,ierr,mkmem,natom,nsppol
4467 : : integer :: optlog,optquickrestart,optself,shift
4468 : : real(dp) :: dum,mu,mu2,mu3,mu4
4469 : : complex(dp) :: trace_tmp
4470 [ # # # # : 0 : type(oper_type) :: oper(2)
# # # # #
# # # ]
4471 : 0 : real(dp), allocatable :: trace_loc(:,:)
4472 : : character(len=500) :: message
4473 : : !************************************************************************
4474 : :
4475 : 0 : optlog = 0
4476 [ # # ]: 0 : if (present(opt_log)) optlog = opt_log
4477 : :
4478 : 0 : optself = 1
4479 [ # # ]: 0 : if (present(opt_self)) optself = opt_self
4480 : :
4481 : 0 : optquickrestart = 0
4482 [ # # ]: 0 : if (present(opt_quick_restart)) optquickrestart = opt_quick_restart
4483 : :
4484 [ # # ]: 0 : if (optself == 0 .and. optquickrestart == 1) then
4485 : 0 : message = "Case optself=0 and optquickrestart=1 is not supposed to happen"
4486 : 0 : ABI_ERROR(message)
4487 : : end if
4488 : :
4489 : 0 : diag = 1 - optself
4490 : 0 : mkmem = green%moments(1)%nkpt
4491 : 0 : mu = paw_dmft%fermie
4492 : 0 : mu2 = mu * mu
4493 : 0 : mu3 = mu2 * mu
4494 : 0 : mu4 = mu3 * mu
4495 : 0 : natom = paw_dmft%natom
4496 : 0 : nsppol = paw_dmft%nsppol
4497 : 0 : shift = green%moments(1)%shiftk
4498 : :
4499 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 0) then
4500 [ # # # # : 0 : ABI_MALLOC(trace_loc,(nsppol+1,natom))
# # # # #
# # # # #
# # # # ]
4501 : : end if
4502 : :
4503 [ # # ]: 0 : if (optself == 1 .and. optquickrestart == 0) then
4504 : 0 : call add_matlu(self%moments(1)%matlu(:),self%hdc%matlu(:),green%moments(2)%matlu(:),natom,-1)
4505 : 0 : call upfold_oper(green%moments(2),paw_dmft)
4506 [ # # ]: 0 : do i=2,self%nmoments
4507 : 0 : call upfold_oper(self%moments(i),paw_dmft)
4508 : : end do ! i
4509 : : end if ! optself=1
4510 : :
4511 [ # # ]: 0 : do ib=1,paw_dmft%mbandc
4512 [ # # ]: 0 : if (optself == 1) then
4513 : : green%moments(2)%ks(ib,ib,:,:) = green%moments(2)%ks(ib,ib,:,:) + &
4514 [ # # # # ]: 0 : & paw_dmft%eigen_dft(ib,1+shift:mkmem+shift,:) - mu
4515 : : else
4516 [ # # # # ]: 0 : green%moments(2)%ks(ib,ib,:,:) = paw_dmft%eigen_dft(ib,1+shift:mkmem+shift,:) - mu
4517 : : end if
4518 : : ! Careful, we need to substract mu**2 below, not add it (think about it)
4519 [ # # # # : 0 : if (optquickrestart == 1) green%moments(3)%ks(ib,ib,:,:) = green%moments(3)%ks(ib,ib,:,:) - mu2
# # ]
4520 : : end do ! ib
4521 : :
4522 [ # # ]: 0 : if (optquickrestart == 1) then
4523 [ # # # # : 0 : green%moments(3)%ks(:,:,:,:) = green%moments(3)%ks(:,:,:,:) - two*mu*green%moments(2)%ks(:,:,:,:)
# # # # ]
4524 : : else
4525 : 0 : call prod_oper(green%moments(2),green%moments(2),green%moments(3),1,opt_diag=diag)
4526 : : end if ! optquickrestart
4527 [ # # ]: 0 : do i=3,green%nmoments-1
4528 : 0 : call prod_oper(green%moments(2),green%moments(i),green%moments(i+1),1,opt_diag=diag)
4529 : : end do ! i
4530 : :
4531 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 0) then
4532 [ # # ]: 0 : do i=1,green%nmoments-1
4533 : 0 : call trace_oper(green%moments(i+1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
4534 : 0 : green%trace_moments_log_ks(i) = trace_tmp / dble(i)
4535 : : end do ! i
4536 [ # # ]: 0 : if (optself == 1) then
4537 [ # # ]: 0 : do i=2,self%nmoments
4538 : 0 : call trace_oper(self%moments(i),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
4539 : 0 : green%trace_moments_log_ks(i) = green%trace_moments_log_ks(i) + trace_tmp
4540 : : end do ! i
4541 : : end if ! optself=1
4542 : : end if ! optlog=1 and optquickrestart=0
4543 : :
4544 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 1) then
4545 : 0 : green%trace_moments_log_ks(1) = green%trace_fermie(2) - mu*green%trace_fermie(1)
4546 : : green%trace_moments_log_ks(2) = green%trace_fermie(3) + &
4547 : 0 : & half*(green%trace_fermie(4)-two*mu*green%trace_fermie(2)+mu2*green%trace_fermie(1))
4548 : : green%trace_moments_log_ks(3) = green%trace_fermie(5) + green%trace_fermie(6) - &
4549 : : & mu*green%trace_fermie(3) + third*(green%trace_fermie(7)+ &
4550 : : & three*mu2*green%trace_fermie(2)-three*mu*green%trace_fermie(4)- &
4551 : 0 : & mu3*green%trace_fermie(1))
4552 : : green%trace_moments_log_ks(4) = green%trace_fermie(8) + green%trace_fermie(9) - &
4553 : : & mu*green%trace_fermie(5) + half*green%trace_fermie(10) + &
4554 : : & green%trace_fermie(11) - two*mu*green%trace_fermie(6) + mu2*green%trace_fermie(3) + &
4555 : : & quarter*(green%trace_fermie(12)-four*mu3*green%trace_fermie(2)+ &
4556 : : & six*mu2*green%trace_fermie(4)-four*mu*green%trace_fermie(7)+ &
4557 : 0 : & mu4*green%trace_fermie(1))
4558 : : end if ! optlog=1 and optquickrestart=1
4559 : :
4560 [ # # ]: 0 : if (optself == 1) then
4561 [ # # ]: 0 : do i=1,2
4562 : 0 : call init_oper(paw_dmft,oper(i),nkpt=mkmem,shiftk=shift,opt_ksloc=1)
4563 : : end do
4564 : 0 : call prod_oper(green%moments(2),self%moments(2),oper(1),1)
4565 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 0) then
4566 : 0 : call trace_oper(oper(1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
4567 : 0 : green%trace_moments_log_ks(3) = green%trace_moments_log_ks(3) + trace_tmp
4568 : : end if
4569 : 0 : call prod_oper(self%moments(2),green%moments(2),oper(2),1)
4570 [ # # # # : 0 : oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
# # # # ]
4571 [ # # # # : 0 : green%moments(4)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + green%moments(4)%ks(:,:,:,:)
# # # # ]
4572 : 0 : call prod_oper(oper(2),green%moments(2),oper(1),1)
4573 : 0 : call prod_oper(green%moments(3),self%moments(2),oper(2),1)
4574 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 0) then
4575 : 0 : call trace_oper(oper(2),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
4576 : 0 : green%trace_moments_log_ks(4) = green%trace_moments_log_ks(4) + trace_tmp
4577 : : end if
4578 [ # # # # : 0 : oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
# # # # ]
4579 : 0 : call prod_oper(green%moments(2),self%moments(3),oper(1),1)
4580 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 0) then
4581 : 0 : call trace_oper(oper(1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
4582 : 0 : green%trace_moments_log_ks(4) = green%trace_moments_log_ks(4) + trace_tmp
4583 : : end if
4584 [ # # # # : 0 : oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
# # # # ]
4585 : 0 : call prod_oper(self%moments(3),green%moments(2),oper(1),1)
4586 [ # # # # : 0 : oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
# # # # ]
4587 : 0 : call prod_oper(self%moments(2),self%moments(2),oper(1),1)
4588 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 0) then
4589 : 0 : call trace_oper(oper(1),dum,trace_loc(:,:),1,trace_ks_cmplx=trace_tmp)
4590 : 0 : green%trace_moments_log_ks(4) = green%trace_moments_log_ks(4) + trace_tmp*half
4591 : : end if
4592 [ # # # # : 0 : oper(2)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + oper(1)%ks(:,:,:,:)
# # # # ]
4593 [ # # # # : 0 : green%moments(5)%ks(:,:,:,:) = oper(2)%ks(:,:,:,:) + green%moments(5)%ks(:,:,:,:)
# # # # ]
4594 [ # # ]: 0 : do i=2,self%nmoments
4595 [ # # # # : 0 : green%moments(i+1)%ks(:,:,:,:) = green%moments(i+1)%ks(:,:,:,:) + self%moments(i)%ks(:,:,:,:)
# # # # ]
4596 : : end do ! i
4597 [ # # ]: 0 : do i=1,2
4598 : 0 : call destroy_oper(oper(i))
4599 : : end do
4600 : : end if ! optself>=1
4601 : :
4602 [ # # ]: 0 : if (optlog == 1 .and. optquickrestart == 0) then
4603 : 0 : call xmpi_sum(green%trace_moments_log_ks(1:green%nmoments-1),green%distrib%comm_kpt,ierr)
4604 : : end if
4605 : :
4606 [ # # ]: 0 : ABI_SFREE(trace_loc)
4607 : :
4608 : 0 : end subroutine compute_moments_ks
4609 : : !!***
4610 : :
4611 : : !!****f* m_green/compute_trace_moments_ks
4612 : : !! NAME
4613 : : !! compute_trace_moments_ks
4614 : : !!
4615 : : !! FUNCTION
4616 : : !! Precompute some useful quantities for the calculation of the trace of the moments (for
4617 : : !! Fermi level search)
4618 : : !!
4619 : : !! COPYRIGHT
4620 : : !! Copyright (C) 1999-2026 ABINIT group (BAmadon)
4621 : : !! This file is distributed under the terms of the
4622 : : !! GNU General Public License, see ~abinit/COPYING
4623 : : !! or http://www.gnu.org/copyleft/gpl.txt .
4624 : : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
4625 : : !!
4626 : : !! INPUTS
4627 : : !! green <type(green_type)>= green function data
4628 : : !! self <type(self_type)>= variables related to self-energy
4629 : : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
4630 : : !! The conventions are:
4631 : : !! trace_fermie(1) = nsppol*mbandc (=tr(Id))
4632 : : !! trace_fermie(2) = tr(m0) (with m0=self%moments(1)-self%hdc+eigen_dft*Id
4633 : : !! trace_fermie(3) = tr(self%moments(2))
4634 : : !! trace_fermie(4) = tr(m0**2)
4635 : : !! trace_fermie(5) = tr(self%moments(3))
4636 : : !! trace_fermie(6) = tr(m0*self%moments(2))
4637 : : !! trace_fermie(7) = tr(m0**3)
4638 : : !! trace_fermie(8) = tr(self%moments(4))
4639 : : !! trace_fermie(9) = tr(m0*self%moments(3))
4640 : : !! trace_fermie(10) = tr(self%moments(2)**2)
4641 : : !! trace_fermie(11) = tr(m0**2*self%moments(2))
4642 : : !! trace_fermie(12) = tr(m0**4)
4643 : : !!
4644 : : !! OUTPUT
4645 : : !!
4646 : : !! SOURCE
4647 : :
4648 : 0 : subroutine compute_trace_moments_ks(green,self,paw_dmft)
4649 : :
4650 : : !Arguments ------------------------------------
4651 : : !scalars
4652 : : type(green_type), intent(inout) :: green
4653 : : type(self_type), intent(inout) :: self
4654 : : type(paw_dmft_type), intent(in) :: paw_dmft
4655 : : !Local variables ------------------------------
4656 : : integer :: i,ib,ierr,mkmem,natom,nsppol,shift
4657 : : real(dp) :: dum
4658 : 0 : type(oper_type) :: oper_tmp
4659 : 0 : real(dp), allocatable :: trace_loc(:,:)
4660 : : !************************************************************************
4661 : :
4662 : 0 : mkmem = green%distrib%nkpt_mem(green%distrib%me_kpt+1)
4663 : 0 : natom = paw_dmft%natom
4664 : 0 : nsppol = paw_dmft%nsppol
4665 : 0 : shift = green%distrib%shiftk
4666 : :
4667 [ # # # # : 0 : ABI_MALLOC(trace_loc,(nsppol+1,natom))
# # # # #
# # # # #
# # # # ]
4668 : :
4669 : 0 : call init_oper(paw_dmft,oper_tmp,nkpt=mkmem,shiftk=shift,opt_ksloc=1)
4670 : :
4671 : 0 : call add_matlu(self%moments(1)%matlu(:),self%hdc%matlu(:),green%moments(2)%matlu(:),natom,-1)
4672 : 0 : call upfold_oper(green%moments(2),paw_dmft)
4673 [ # # ]: 0 : do i=2,self%nmoments
4674 : 0 : call upfold_oper(self%moments(i),paw_dmft)
4675 : : end do ! i
4676 : :
4677 [ # # # # : 0 : oper_tmp%ks(:,:,:,:) = green%moments(2)%ks(:,:,:,:)
# # # # ]
4678 : :
4679 [ # # ]: 0 : do ib=1,paw_dmft%mbandc
4680 [ # # # # ]: 0 : oper_tmp%ks(ib,ib,:,:) = oper_tmp%ks(ib,ib,:,:) + paw_dmft%eigen_dft(ib,1+shift:mkmem+shift,:)
4681 : : end do ! ib
4682 : :
4683 : 0 : call prod_oper(oper_tmp,oper_tmp,green%moments(3),1)
4684 : 0 : call trace_oper(oper_tmp,dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(2))
4685 : 0 : call trace_oper(self%moments(2),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(3))
4686 : 0 : call trace_oper(green%moments(3),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(4))
4687 : 0 : call trace_oper(self%moments(3),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(5))
4688 : 0 : call trace_prod_oper(oper_tmp,self%moments(2),green%trace_fermie(6))
4689 : 0 : call trace_prod_oper(oper_tmp,green%moments(3),green%trace_fermie(7))
4690 : 0 : call trace_oper(self%moments(4),dum,trace_loc(:,:),1,trace_ks_cmplx=green%trace_fermie(8))
4691 : 0 : call trace_prod_oper(oper_tmp,self%moments(3),green%trace_fermie(9))
4692 : 0 : call trace_prod_oper(self%moments(2),self%moments(2),green%trace_fermie(10))
4693 : 0 : call trace_prod_oper(green%moments(3),self%moments(2),green%trace_fermie(11))
4694 : 0 : call trace_prod_oper(green%moments(3),green%moments(3),green%trace_fermie(12))
4695 : :
4696 : 0 : call destroy_oper(oper_tmp)
4697 [ # # ]: 0 : ABI_FREE(trace_loc)
4698 : :
4699 : 0 : call xmpi_sum(green%trace_fermie(2:12),green%distrib%comm_kpt,ierr)
4700 : :
4701 [ # # # # : 0 : end subroutine compute_trace_moments_ks
# # # # ]
4702 : : !!***
4703 : :
4704 : : !!****f* m_green/compute_moments_loc
4705 : : !! NAME
4706 : : !! compute_moments_loc
4707 : : !!
4708 : : !! FUNCTION
4709 : : !! Computes the high-frequency moments in local space.
4710 : : !!
4711 : : !! INPUTS
4712 : : !! green <type(green_type)>= green function data
4713 : : !! self <type(self_type)>= variables related to self-energy
4714 : : !! energy_level = local energy levels
4715 : : !! weiss <type(green_type)>= weiss field
4716 : : !! option = 0 : computes the hybridization moments in weiss%moments up to 4th order (including
4717 : : !! the spurious 0th order moment, which is removed from the weiss field later),
4718 : : !! using the moments of the self-energy and Green's function as inputs
4719 : : !! = 1 : compute the self-energy moments in self%moments using the moments of the hybridization
4720 : : !! and the Green's function (assuming the spurious 0th order moment of the hybridization
4721 : : !! has been removed)
4722 : : !! opt_log = if set to 1, also computes the trace of the moments of log(G)+log(iw*Id) and
4723 : : !! log(G0)+log(iw*Id) in green%trace_moments_log_loc and weiss%trace_moments_log_loc
4724 : : !! shift_mu = shift to apply to the chemical potential for the moments of G0
4725 : : !!
4726 : : !! OUTPUTS
4727 : : !!
4728 : : !! SOURCE
4729 : :
4730 : 0 : subroutine compute_moments_loc(green,self,energy_level,weiss,option,opt_log,shift_mu)
4731 : :
4732 : : !Arguments ------------------------------------
4733 : : type(green_type), intent(inout) :: green,weiss
4734 : : type(self_type), intent(inout) :: self
4735 : : type(oper_type), target, intent(in) :: energy_level
4736 : : integer, intent(in) :: option
4737 : : integer, optional, intent(in) :: opt_log
4738 : : real(dp), optional, intent(in) :: shift_mu
4739 : : !Local variables ------------------------------
4740 : : integer :: i,natom,nspinor,nsppol,optlog
4741 : : complex(dp) :: trace
4742 : 0 : type(matlu_type), target, allocatable :: level_shift(:)
4743 : 0 : integer, allocatable :: lpawu(:)
4744 : 0 : complex(dp), allocatable :: shift(:),trace_loc(:)
4745 : 0 : type(matlu_type), allocatable :: matlu(:,:)
4746 : : !************************************************************************
4747 : :
4748 : 0 : optlog = 0
4749 [ # # ]: 0 : if (present(opt_log)) optlog = opt_log
4750 : :
4751 : 0 : natom = energy_level%natom
4752 : 0 : nspinor = energy_level%nspinor
4753 : 0 : nsppol = energy_level%nsppol
4754 : :
4755 [ # # # # : 0 : ABI_MALLOC(trace_loc,(natom))
# # # # #
# # # ]
4756 : :
4757 [ # # # # : 0 : ABI_MALLOC(lpawu,(natom))
# # # # #
# # # ]
4758 [ # # # # : 0 : ABI_MALLOC(matlu,(natom,6))
# # # # #
# # # # #
# # ]
4759 : :
4760 [ # # ]: 0 : lpawu(:) = energy_level%matlu(:)%lpawu ! to prevent the creation of a temporary array when calling init_matlu
4761 : :
4762 [ # # ]: 0 : do i=1,6
4763 : 0 : call init_matlu(natom,nspinor,nsppol,lpawu(:),matlu(:,i))
4764 : : end do
4765 : :
4766 [ # # ]: 0 : if (option == 0) then
4767 : 0 : call add_matlu(green%moments(2)%matlu(:),energy_level%matlu(:),matlu(:,1),natom,-1)
4768 : 0 : call add_matlu(matlu(:,1),self%moments(1)%matlu(:),weiss%moments(1)%matlu(:),natom,-1)
4769 : : else
4770 : 0 : call add_matlu(green%moments(2)%matlu(:),energy_level%matlu(:),self%moments(1)%matlu(:),natom,-1)
4771 : : end if ! option
4772 : :
4773 [ # # ]: 0 : if (optlog > 0) then
4774 : :
4775 [ # # # # : 0 : ABI_MALLOC(level_shift,(natom))
# # # # #
# # # #
# ]
4776 [ # # # # : 0 : ABI_MALLOC(shift,(natom))
# # # # ]
4777 : 0 : call init_matlu(natom,nspinor,nsppol,lpawu(:),level_shift(:))
4778 : 0 : call copy_matlu(energy_level%matlu(:),level_shift(:),natom)
4779 : :
4780 [ # # ]: 0 : shift(:) = cmplx(shift_mu,zero,kind=dp)
4781 : 0 : call shift_matlu(level_shift(:),natom,shift(:),signe=1)
4782 : :
4783 : 0 : call trace_matlu(level_shift(:),natom,itau=0,trace=weiss%trace_moments_log_loc(1))
4784 [ # # ]: 0 : do i=2,green%nmoments-1
4785 : 0 : call trace_matlu(weiss%moments(i)%matlu(:),natom,itau=0,trace=weiss%trace_moments_log_loc(i))
4786 : : end do ! i
4787 : 0 : call prod_matlu(level_shift(:),level_shift(:),matlu(:,1),natom)
4788 : 0 : call trace_matlu(matlu(:,1),natom,itau=0,trace=trace)
4789 : 0 : weiss%trace_moments_log_loc(2) = weiss%trace_moments_log_loc(2) + trace*half
4790 : 0 : call trace_prod_matlu(level_shift(:),weiss%moments(2)%matlu(:),natom,trace_loc(:),trace_tot=trace)
4791 : 0 : weiss%trace_moments_log_loc(3) = weiss%trace_moments_log_loc(3) + trace
4792 : 0 : call trace_prod_matlu(level_shift(:),matlu(:,1),natom,trace_loc(:),trace_tot=trace)
4793 : 0 : weiss%trace_moments_log_loc(3) = weiss%trace_moments_log_loc(3) + trace*third
4794 : 0 : call trace_prod_matlu(level_shift(:),weiss%moments(3)%matlu(:),natom,trace_loc(:),trace_tot=trace)
4795 : 0 : weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace
4796 : 0 : call trace_prod_matlu(weiss%moments(2)%matlu(:),weiss%moments(2)%matlu(:),natom,trace_loc(:),trace_tot=trace)
4797 : 0 : weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace*half
4798 : 0 : call trace_prod_matlu(weiss%moments(2)%matlu(:),matlu(:,1),natom,trace_loc(:),trace_tot=trace)
4799 : 0 : weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace
4800 : 0 : call trace_prod_matlu(matlu(:,1),matlu(:,1),natom,trace_loc(:),trace_tot=trace)
4801 : 0 : weiss%trace_moments_log_loc(4) = weiss%trace_moments_log_loc(4) + trace*quarter
4802 : :
4803 : 0 : call trace_matlu(green%moments(2)%matlu(:),natom,itau=0,trace=green%trace_moments_log_loc(1))
4804 : :
4805 : 0 : call destroy_matlu(level_shift(:),natom)
4806 [ # # # # : 0 : ABI_FREE(level_shift)
# # # # ]
4807 [ # # ]: 0 : ABI_FREE(shift)
4808 : :
4809 : : end if ! optlog
4810 : :
4811 : 0 : call prod_matlu(green%moments(2)%matlu(:),green%moments(2)%matlu(:),matlu(:,1),natom) ! matlu=m0m0
4812 : :
4813 : 0 : call add_matlu(green%moments(3)%matlu(:),matlu(:,1),matlu(:,2),natom,-1) ! matlu2=m1
4814 : :
4815 [ # # ]: 0 : if (optlog > 0) then
4816 : 0 : call trace_matlu(matlu(:,2),natom,itau=0,trace=green%trace_moments_log_loc(2))
4817 : 0 : call trace_matlu(matlu(:,1),natom,itau=0,trace=trace)
4818 : 0 : green%trace_moments_log_loc(2) = green%trace_moments_log_loc(2) + half*trace
4819 : : end if ! optlog
4820 : :
4821 [ # # ]: 0 : if (option == 0) then
4822 : 0 : call add_matlu(matlu(:,2),self%moments(2)%matlu(:),weiss%moments(2)%matlu(:),natom,-1)
4823 [ # # ]: 0 : else if (option == 1) then
4824 : 0 : call add_matlu(matlu(:,2),weiss%moments(2)%matlu(:),self%moments(2)%matlu(:),natom,-1)
4825 : : end if ! option
4826 : :
4827 : 0 : call prod_matlu(green%moments(2)%matlu(:),matlu(:,1),matlu(:,3),natom) ! matlu3=m0m0m0
4828 : 0 : call add_matlu(green%moments(4)%matlu(:),matlu(:,3),matlu(:,1),natom,-1) ! matlu=green%moments(4)-m0m0m0
4829 : :
4830 [ # # ]: 0 : if (optlog > 0) then
4831 : 0 : call trace_matlu(matlu(:,3),natom,itau=0,trace=trace)
4832 : 0 : green%trace_moments_log_loc(3) = trace * third
4833 : : end if ! optlog
4834 : :
4835 : 0 : call prod_matlu(green%moments(2)%matlu(:),matlu(:,2),matlu(:,4),natom) ! matlu4=m0m1
4836 : 0 : call prod_matlu(matlu(:,2),green%moments(2)%matlu(:),matlu(:,5),natom) ! matlu5=m1m0
4837 : :
4838 : 0 : call add_matlu(matlu(:,4),matlu(:,5),matlu(:,6),natom,1) ! matlu6=m0m1+m1m0
4839 : :
4840 [ # # ]: 0 : if (optlog > 0) then
4841 : 0 : call trace_matlu(matlu(:,4),natom,itau=0,trace=trace)
4842 : 0 : green%trace_moments_log_loc(3) = trace + green%trace_moments_log_loc(3)
4843 : : end if ! optlog
4844 : :
4845 : 0 : call add_matlu(matlu(:,1),matlu(:,6),matlu(:,5),natom,-1) ! matlu5=m2
4846 : :
4847 [ # # ]: 0 : if (optlog > 0) then
4848 : 0 : call trace_matlu(matlu(:,5),natom,itau=0,trace=trace)
4849 : 0 : green%trace_moments_log_loc(3) = trace + green%trace_moments_log_loc(3)
4850 : : end if ! optlog
4851 : :
4852 [ # # ]: 0 : if (option == 0) then
4853 : 0 : call add_matlu(matlu(:,5),self%moments(3)%matlu(:),weiss%moments(3)%matlu(:),natom,-1)
4854 [ # # ]: 0 : else if (option == 1) then
4855 : 0 : call add_matlu(matlu(:,5),weiss%moments(3)%matlu(:),self%moments(3)%matlu(:),natom,-1)
4856 : : end if ! option
4857 : :
4858 : 0 : call prod_matlu(green%moments(2)%matlu(:),matlu(:,3),matlu(:,1),natom) ! matlu=m0m0m0m0
4859 : 0 : call prod_matlu(matlu(:,6),green%moments(2)%matlu(:),matlu(:,3),natom) ! matlu3 = m0m1m0+m1m0m0
4860 : 0 : call prod_matlu(green%moments(2)%matlu(:),matlu(:,4),matlu(:,6),natom) ! matlu6 = m0m0m1
4861 : 0 : call add_matlu(matlu(:,3),matlu(:,6),matlu(:,4),natom,1) ! matlu4 = m0m1m0+m1m0m0+m0m0m1
4862 : :
4863 [ # # ]: 0 : if (optlog > 0) then
4864 : 0 : call trace_matlu(matlu(:,4),natom,itau=0,trace=trace)
4865 : 0 : green%trace_moments_log_loc(4) = trace * third
4866 : 0 : call trace_matlu(matlu(:,1),natom,itau=0,trace=trace)
4867 : 0 : green%trace_moments_log_loc(4) = green%trace_moments_log_loc(4) + trace*quarter
4868 : : end if ! optlog
4869 : :
4870 : 0 : call add_matlu(matlu(:,1),matlu(:,4),matlu(:,3),natom,1) ! matlu3 = m0m1m0+m1m0m0+m0m0m1+m0m0m0m0
4871 : :
4872 : 0 : call prod_matlu(green%moments(2)%matlu(:),matlu(:,5),matlu(:,1),natom) ! matlu=m0m2
4873 : 0 : call prod_matlu(matlu(:,5),green%moments(2)%matlu(:),matlu(:,4),natom) ! matlu4=m2m0
4874 : 0 : call add_matlu(matlu(:,1),matlu(:,4),matlu(:,5),natom,1) ! matlu5=m0m2+m2m0
4875 : 0 : call prod_matlu(matlu(:,2),matlu(:,2),matlu(:,1),natom) ! matlu=m1m1
4876 : 0 : call add_matlu(matlu(:,1),matlu(:,5),matlu(:,2),natom,1) ! matlu2=m1m1+m0m2+m2m0
4877 : :
4878 [ # # ]: 0 : if (optlog > 0) then
4879 : 0 : call trace_matlu(matlu(:,2),natom,itau=0,trace=trace)
4880 : 0 : green%trace_moments_log_loc(4) = green%trace_moments_log_loc(4) + trace*half
4881 : : end if ! optlog
4882 : :
4883 : 0 : call add_matlu(green%moments(5)%matlu(:),matlu(:,2),matlu(:,1),natom,-1)
4884 : 0 : call add_matlu(matlu(:,1),matlu(:,3),matlu(:,2),natom,-1) ! matlu2=m3
4885 : :
4886 [ # # ]: 0 : if (optlog > 0) then
4887 : 0 : call trace_matlu(matlu(:,2),natom,itau=0,trace=trace)
4888 : 0 : green%trace_moments_log_loc(4) = green%trace_moments_log_loc(4) + trace
4889 : : end if ! optlog
4890 : :
4891 [ # # ]: 0 : if (option == 0) then
4892 : 0 : call add_matlu(matlu(:,2),self%moments(4)%matlu(:),weiss%moments(4)%matlu(:),natom,-1)
4893 [ # # ]: 0 : else if (option == 1) then
4894 : 0 : call add_matlu(matlu(:,2),weiss%moments(4)%matlu(:),self%moments(4)%matlu(:),natom,-1)
4895 : : end if ! option
4896 : :
4897 [ # # ]: 0 : do i=1,6
4898 : 0 : call destroy_matlu(matlu(:,i),natom)
4899 : : end do
4900 : :
4901 [ # # ]: 0 : ABI_FREE(lpawu)
4902 [ # # # # : 0 : ABI_FREE(matlu)
# # # # ]
4903 [ # # ]: 0 : ABI_FREE(trace_loc)
4904 : :
4905 : 0 : end subroutine compute_moments_loc
4906 : : !!***
4907 : :
4908 : : !!****f* m_green/occup_fd
4909 : : !! NAME
4910 : : !! occup_fd
4911 : : !!
4912 : : !! FUNCTION
4913 : : !! Computes the Fermi-Dirac occupation
4914 : : !!
4915 : : !! INPUTS
4916 : : !! eig = eigenvalues
4917 : : !! fermie = Fermi level
4918 : : !! temp = temperature
4919 : : !!
4920 : : !! OUTPUT
4921 : : !!
4922 : : !!
4923 : : !! SOURCE
4924 : :
4925 : 9852 : function occup_fd(eig,fermie,temp)
4926 : :
4927 : : !Arguments ------------------------------------
4928 : : !type
4929 : : ! Integrate analytic tail 1/(iw-mu)
4930 : : real(dp), intent(in) :: eig,fermie,temp
4931 : : real(dp) :: occup_fd
4932 : : !Local variables-------------------------------
4933 : : ! *********************************************************************
4934 : :
4935 [ + + ]: 9852 : if ((eig-fermie) > zero) then
4936 : 5067 : occup_fd = exp(-(eig-fermie)/temp) / (one+exp(-(eig-fermie)/temp))
4937 : : else
4938 : 4785 : occup_fd = one / (one+exp((eig-fermie)/temp))
4939 : : end if ! eig-fermie>0
4940 : :
4941 : 9852 : end function occup_fd
4942 : :
4943 [ # # # # : 0 : END MODULE m_green
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
4944 : : !!***
|