Line data Source code
1 : !!****m* ABINIT/m_self
2 : !! NAME
3 : !! m_self
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_self
26 :
27 : use defs_basis
28 : use m_errors
29 : use m_abicore
30 :
31 : use m_datafordmft, only : compute_levels
32 : use m_fstrings, only : int2char4
33 : use m_hu, only : hu_type
34 : use m_io_tools, only : get_unit
35 : use m_matlu, only : add_matlu,copy_matlu,destroy_matlu,diag_matlu,fac_matlu, &
36 : & init_matlu,matlu_type,print_matlu,rotate_matlu,xmpi_matlu,zero_matlu
37 : use m_oper, only : destroy_oper,gather_oper,init_oper,oper_type,print_oper
38 : use m_paw_dmft, only : mpi_distrib_dmft_type,paw_dmft_type
39 : use m_paw_exactDC, only : compute_exactDC
40 : use m_pawtab, only : pawtab_type
41 : use m_xmpi, only : xmpi_bcast,xmpi_sum
42 :
43 : #ifdef HAVE_GPU_MARKERS
44 : use m_nvtx_data
45 : #endif
46 :
47 : implicit none
48 :
49 : private
50 :
51 : public :: alloc_self
52 : public :: initialize_self
53 : public :: destroy_self
54 : public :: print_self
55 : public :: rw_self
56 : public :: dc_self
57 : public :: new_self
58 : !public :: make_qmcshift_self
59 : public :: selfreal2imag_self
60 :
61 : !!***
62 :
63 : !!****t* m_self/self_type
64 : !! NAME
65 : !! self_type
66 : !!
67 : !! FUNCTION
68 : !! This structured datatype contains the necessary data
69 : !!
70 : !! SOURCE
71 :
72 : type, public :: self_type ! for each atom
73 :
74 : integer :: dmft_nwli
75 : ! Linear index of the last imaginary frequency
76 :
77 : integer :: dmft_nwlo
78 : ! Number of imaginary frequencies
79 :
80 : integer :: has_moments
81 : ! =1 if the high-frequency moments are computed
82 :
83 : integer :: iself_cv
84 : ! Integer for convergence of self-energy
85 :
86 : integer :: nmoments
87 : ! Number of high-frequency moments which will be computed
88 :
89 : integer :: nw
90 : ! Number of frequencies (equal to dmft_nwlo only if w_type="imag")
91 :
92 : character(len=4) :: w_type
93 : ! Type of frequencies used ("real" or "imag")
94 :
95 : !real(dp), allocatable :: qmc_shift(:)
96 : ! value of frequencies
97 :
98 : !real(dp), allocatable :: qmc_xmu(:)
99 : ! value of frequencies
100 :
101 : type(oper_type) :: hdc
102 : ! Operator for double counting
103 :
104 : type(oper_type), allocatable :: moments(:)
105 : ! High-frequency moments
106 :
107 : type(oper_type), allocatable :: oper(:)
108 : ! Operator for self-energy, for each frequency
109 :
110 : real(dp), ABI_CONTIGUOUS pointer :: omega(:) => null()
111 : ! Value of frequencies
112 :
113 : type(mpi_distrib_dmft_type), pointer :: distrib => null()
114 : ! Datastructure for MPI parallelization
115 :
116 : end type self_type
117 : !!***
118 :
119 : !----------------------------------------------------------------------
120 :
121 :
122 : CONTAINS !========================================================================================
123 : !!***
124 :
125 : !!****f* m_self/alloc_self
126 : !! NAME
127 : !! alloc_self
128 : !!
129 : !! FUNCTION
130 : !! Allocate variables used in type self_type.
131 : !!
132 : !! INPUTS
133 : !! self <type(self_type)>= variables related to self-energy
134 : !! paw_dmft <type(paw_dmft_type)> = variables related to self-consistent DFT+DMFT calculations.
135 : !! opt_oper = 1 Allocate only quantities in the KS basis.
136 : !! 2 Allocate only quantities in the local basis.
137 : !! 3 Allocate quantities in both the KS and local basis.
138 : !! wtype = "real" Self energy will be computed for real frequencies
139 : !! = "imag" (default) Self energy will be computed for imaginary frequencies
140 : !! opt_moments = 1 to allocate the high-frequency moments
141 : !!
142 : !! OUTPUTS
143 : !! self <type(self_type)>= variables related to self-energy
144 : !!
145 : !! SOURCE
146 :
147 211 : subroutine alloc_self(self,paw_dmft,opt_oper,wtype,opt_moments)
148 :
149 : !Arguments ------------------------------------
150 : type(self_type), intent(inout) :: self
151 : type(paw_dmft_type), target, intent(in) :: paw_dmft
152 : integer, optional, intent(in) :: opt_moments,opt_oper
153 : character(len=4), optional :: wtype
154 : !Local variables ------------------------------------
155 : integer :: i,ifreq,mkmem,optmoments,optoper,shift
156 : !************************************************************************
157 :
158 211 : optoper = 2
159 211 : self%w_type = "imag"
160 211 : self%nmoments = 0
161 211 : optmoments = 0
162 :
163 211 : if (present(opt_oper)) optoper = opt_oper
164 211 : if (present(wtype)) self%w_type = wtype
165 211 : if (present(opt_moments)) optmoments = opt_moments
166 :
167 211 : self%has_moments = optmoments
168 :
169 211 : if (self%w_type == "imag") then
170 207 : self%nw = paw_dmft%dmft_nwlo
171 207 : self%omega => paw_dmft%omega_lo(:)
172 207 : self%distrib => paw_dmft%distrib
173 4 : else if (self%w_type == "real") then
174 4 : self%nw = size(paw_dmft%omega_r(:))
175 4 : self%omega => paw_dmft%omega_r(:)
176 4 : self%distrib => paw_dmft%distrib_r
177 : end if ! w_type
178 :
179 211 : self%dmft_nwlo = paw_dmft%dmft_nwlo
180 211 : self%dmft_nwli = paw_dmft%dmft_nwli
181 211 : self%iself_cv = 0
182 :
183 211 : call init_oper(paw_dmft,self%hdc,opt_ksloc=optoper)
184 :
185 68311 : ABI_MALLOC(self%oper,(self%nw))
186 67889 : do ifreq=1,self%nw
187 67889 : call init_oper(paw_dmft,self%oper(ifreq),opt_ksloc=optoper)
188 : end do ! ifreq
189 :
190 211 : if (optmoments == 1) then
191 0 : self%nmoments = 4
192 0 : shift = self%distrib%shiftk
193 0 : mkmem = self%distrib%nkpt_mem(self%distrib%me_kpt+1)
194 0 : ABI_MALLOC(self%moments,(self%nmoments))
195 0 : call init_oper(paw_dmft,self%moments(1),nkpt=mkmem,shiftk=shift,opt_ksloc=2)
196 0 : do i=2,self%nmoments
197 0 : call init_oper(paw_dmft,self%moments(i),nkpt=mkmem,shiftk=shift,opt_ksloc=3)
198 : end do ! i
199 : end if ! optmoments
200 :
201 : !if (paw_dmft%dmft_solv == 4) then
202 : ! ABI_MALLOC(self%qmc_shift,(paw_dmft%natom))
203 : ! ABI_MALLOC(self%qmc_xmu,(paw_dmft%natom))
204 : ! self%qmc_shift(:) = zero
205 : ! self%qmc_xmu(:) = zero
206 : !end if ! dmft_solv=4
207 :
208 211 : end subroutine alloc_self
209 : !!***
210 :
211 : !!****f* m_self/initialize_self
212 : !! NAME
213 : !! initialize_self
214 : !!
215 : !! FUNCTION
216 : !! Initialize self-energy.
217 : !!
218 : !! INPUTS
219 : !! self <type(self_type)>= variables related to self-energy
220 : !! paw_dmft <type(paw_dmft_type)> = variables related to self-consistent DFT+DMFT calculations.
221 : !! wtype = "real" Self energy will be computed for real frequencies
222 : !! = "imag" (default) Self energy will be computed for imaginary frequencies
223 : !! opt_moments = 1 to compute the high frequency moments
224 : !!
225 : !! OUTPUTS
226 : !! self <type(self_type)>= variables related to self-energy
227 : !!
228 : !!
229 : !! SOURCE
230 :
231 211 : subroutine initialize_self(self,paw_dmft,wtype,opt_moments)
232 :
233 : !Arguments ------------------------------------
234 : type(self_type), intent(inout) :: self
235 : type(paw_dmft_type), intent(in) :: paw_dmft
236 : character(len=4), optional, intent(in) :: wtype
237 : integer, optional, intent(in) :: opt_moments
238 : !Local variables ------------------------------------
239 : ! character(len=500) :: message
240 : integer :: optmoments
241 : character(len=4) :: wtype2
242 : !************************************************************************
243 :
244 211 : optmoments = 0
245 211 : wtype2 = "imag"
246 211 : if (present(wtype)) wtype2 = wtype
247 211 : if (present(opt_moments)) optmoments = opt_moments
248 :
249 211 : call alloc_self(self,paw_dmft,opt_oper=2,wtype=wtype2,opt_moments=optmoments) ! opt_oper=1 is not useful and not implemented
250 : ! if(paw_dmft%dmft_rslf==1.and.opt_read==1) then
251 : ! call rw_self(cryst_struc,self,mpi_enreg,paw_dmft,pawtab,pawprtvol=2,opt_rw=1)
252 : ! endif
253 : ! write(message,'(a,a)') ch10," Self-energy for large frequency is"
254 : ! call wrtout(std_out,message,'COLL')
255 : ! call print_matlu(self%oper(paw_dmft%dmft_nwlo)%matlu, &
256 : !& paw_dmft%natom,3)
257 :
258 211 : end subroutine initialize_self
259 : !!***
260 :
261 : !!****f* m_self/destroy_self
262 : !! NAME
263 : !! destroy_self
264 : !!
265 : !! FUNCTION
266 : !! Deallocate self
267 : !!
268 : !! INPUTS
269 : !! self <type(self_type)>= variables related to self-energy
270 : !!
271 : !! OUTPUT
272 : !!
273 : !! SOURCE
274 :
275 211 : subroutine destroy_self(self)
276 :
277 : !Arguments ------------------------------------
278 : type(self_type), intent(inout) :: self
279 : !Local variables-------------------------------
280 : integer :: i,ifreq
281 : ! *********************************************************************
282 :
283 211 : if (allocated(self%oper)) then
284 67889 : do ifreq=1,self%nw
285 67889 : call destroy_oper(self%oper(ifreq))
286 : end do
287 67889 : ABI_FREE(self%oper)
288 : end if
289 :
290 211 : call destroy_oper(self%hdc)
291 :
292 211 : if (allocated(self%moments)) then
293 0 : do i=1,self%nmoments
294 0 : call destroy_oper(self%moments(i))
295 : end do ! i
296 0 : ABI_FREE(self%moments)
297 : end if
298 : !if (allocated(self%qmc_shift)) ABI_FREE(self%qmc_shift)
299 : !if (allocated(self%qmc_xmu)) ABI_FREE(self%qmc_xmu)
300 211 : self%distrib => null()
301 211 : self%omega => null()
302 :
303 211 : end subroutine destroy_self
304 : !!***
305 :
306 : !!****f* m_self/print_self
307 : !! NAME
308 : !! print_self
309 : !!
310 : !! FUNCTION
311 : !! Print self-energy
312 : !!
313 : !! INPUTS
314 : !! self <type(self_type)>= variables related to self-energy
315 : !! prtdc = print double counting if equal to "print_dc"
316 : !! paw_dmft <type(paw_dmft_type)> = variables related to self-consistent DFT+DMFT calculations.
317 : !! prtopt = integer which specifies the amount of printing in the subroutine called
318 : !!
319 : !! OUTPUT
320 : !! self <type(self_type)>= variables related to self-energy
321 : !!
322 : !! SOURCE
323 :
324 339 : subroutine print_self(self,prtdc,paw_dmft,prtopt)
325 :
326 : !Arguments ------------------------------------
327 : type(paw_dmft_type), intent(in) :: paw_dmft
328 : type(self_type), intent(in) :: self
329 : character(len=*), intent(in) :: prtdc
330 : integer, intent(in) :: prtopt
331 : !Local variables-------------------------------
332 : character(len=500) :: message
333 : ! *********************************************************************
334 :
335 339 : write(message,'(2a)') ch10," == The self-energy for smallest frequency is == "
336 339 : call wrtout(std_out,message,'COLL')
337 339 : call print_oper(self%oper(1),1,paw_dmft,prtopt)
338 : ! write(message,'(2a)') ch10," == The self-energy for small (3) frequency is == "
339 : ! call wrtout(std_out,message,'COLL')
340 : ! call print_oper(self%oper(3),1,paw_dmft,prtopt)
341 339 : write(message,'(2a)') ch10," == The self-energy for largest frequency is == "
342 339 : call wrtout(std_out,message,'COLL')
343 339 : call print_oper(self%oper(self%nw),1,paw_dmft,prtopt)
344 339 : if (prtdc == "print_dc") then
345 339 : write(message,'(2a)') ch10," == The double counting potential is == "
346 339 : call wrtout(std_out,message,'COLL')
347 339 : call print_matlu(self%hdc%matlu(:),paw_dmft%natom,prtopt)
348 : end if ! prtdc
349 :
350 339 : end subroutine print_self
351 : !!***
352 :
353 : !!****f* m_self/dc_self
354 : !! NAME
355 : !! dc_self
356 : !!
357 : !! FUNCTION
358 : !! Computes the double counting
359 : !!
360 : !! INPUTS
361 : !! charge_loc : local charge for each polarization and each atom
362 : !! hu <type(hu_type)>= U interaction
363 : !! paw_dmft <type(paw_dmft_type)> = variables related to self-consistent DFT+DMFT calculations.
364 : !! pawtab <type(pawtab_type)>=paw tabulated starting data
365 : !! occ_matlu : local occupation matrix
366 : !!
367 : !! OUTPUT
368 : !! hdc : double counting
369 : !!
370 : !! SOURCE
371 :
372 199 : subroutine dc_self(charge_loc,hdc,hu,paw_dmft,pawtab,occ_matlu)
373 :
374 : !Arguments ------------------------------------
375 : !type
376 : !type(crystal_t),intent(in) :: cryst_struc
377 : type(paw_dmft_type), intent(inout) :: paw_dmft
378 : type(matlu_type), intent(inout) :: hdc(paw_dmft%natom)
379 : real(dp), intent(in) :: charge_loc(paw_dmft%nsppol+1,paw_dmft%natom)
380 : type(hu_type), intent(in) :: hu(paw_dmft%ntypat)
381 : type(pawtab_type), intent(inout) :: pawtab(paw_dmft%ntypat)
382 : type(matlu_type), intent(in) :: occ_matlu(paw_dmft%natom)
383 : !type(hu_type),intent(inout) :: hu(cryst_struc%ntypat)
384 : !integer, intent(in) :: dmft_dc
385 : !Local variables-------------------------------
386 : integer :: dmft_dc,iatom,iatomc,ierr,im,ispinor,isppol
387 : integer :: itypat,lpawu,natom,ndim,nspinor,nsppol
388 : real(dp) :: dc,jpawu,ntot,upawu
389 : logical :: amf,fll,nmdc
390 : character(len=500) :: message
391 199 : complex(dp), allocatable :: occ(:,:),vdc(:,:)
392 : ! *********************************************************************
393 :
394 199 : dmft_dc = paw_dmft%dmft_dc
395 199 : natom = paw_dmft%natom
396 199 : nspinor = paw_dmft%nspinor
397 199 : nsppol = paw_dmft%nsppol
398 :
399 199 : amf = (dmft_dc == 2 .or. dmft_dc == 6) ! AMF double counting
400 199 : fll = (dmft_dc == 1 .or. dmft_dc == 4 .or. dmft_dc == 5) ! FLL double counting
401 199 : nmdc = (nspinor == 2 .or. (dmft_dc >= 5 .and. dmft_dc <= 8)) ! non-magnetic double counting
402 :
403 199 : if ((.not. fll) .and. (.not. amf) .and. dmft_dc /= 7 .and. dmft_dc /= 8) &
404 0 : & ABI_ERROR("not implemented")
405 199 : if (amf .and. (nspinor == 2)) then
406 0 : write(message,'(a,i4,i4,2x,e20.10)') " AMF Double counting is under test for SOC"
407 0 : ABI_WARNING(message)
408 : end if
409 :
410 199 : if (dmft_dc == 8) then
411 0 : paw_dmft%edc(:) = zero
412 0 : paw_dmft%edcdc(:) = zero
413 0 : call zero_matlu(hdc(:),natom)
414 : end if
415 :
416 : iatomc = -1
417 :
418 890 : do iatom=1,natom
419 691 : lpawu = paw_dmft%lpawu(iatom)
420 691 : if (lpawu == -1) cycle
421 235 : iatomc = iatomc + 1
422 10896 : hdc(iatom)%mat(:,:,:) = czero
423 235 : ntot = charge_loc(nsppol+1,iatom)
424 235 : ndim = 2*lpawu + 1
425 235 : itypat = paw_dmft%typat(iatom)
426 235 : upawu = hu(itypat)%upawu
427 235 : jpawu = merge(zero,hu(itypat)%jpawu,dmft_dc==4)
428 :
429 434 : if (dmft_dc == 8) then
430 0 : if (mod(iatomc,paw_dmft%nproc) /= paw_dmft%myproc) cycle
431 0 : ABI_MALLOC(occ,(ndim,ndim))
432 0 : ABI_MALLOC(vdc,(ndim,ndim))
433 0 : occ(:,:) = czero
434 0 : do isppol=1,nsppol
435 0 : do ispinor=1,nspinor
436 0 : occ(:,:) = occ(:,:) + occ_matlu(iatom)%mat(1+(ispinor-1)*ndim:ispinor*ndim,1+(ispinor-1)*ndim:ispinor*ndim,isppol)
437 : end do ! ispinor
438 : end do ! isppol
439 0 : if (nsppol == 1 .and. nspinor == 1) occ(:,:) = occ(:,:) * two
440 : call compute_exactDC(lpawu,pawtab(itypat),paw_dmft%radgrid(itypat),occ(:,:), &
441 0 : & vdc(:,:),paw_dmft%edc(iatom),paw_dmft%edcdc(iatom),paw_dmft%ixc)
442 0 : do isppol=1,nsppol
443 0 : do ispinor=1,nspinor
444 0 : hdc(iatom)%mat(1+(ispinor-1)*ndim:ispinor*ndim,1+(ispinor-1)*ndim:ispinor*ndim,isppol) = vdc(:,:)
445 : end do ! ispinor
446 : end do ! isppol
447 0 : ABI_FREE(occ)
448 0 : ABI_FREE(vdc)
449 : else
450 235 : if (nmdc) then ! Non-magnetic DC
451 29 : if (fll) dc = upawu*(ntot-half) - half*jpawu*(ntot-one)
452 29 : if (amf) dc = upawu*ntot*half + (upawu-jpawu)*ntot*half*dble(2*lpawu)/dble(2*lpawu+1)
453 29 : if (dmft_dc == 7) dc = upawu*(dble(paw_dmft%dmft_nominal(iatom))-half) - &
454 0 : & half*jpawu*(dble(paw_dmft%dmft_nominal(iatom))-one)
455 : end if ! nmdc
456 235 : ndim = nspinor * ndim
457 594 : do isppol=1,nsppol
458 359 : if (.not. nmdc) then ! Magnetic DC
459 304 : if (fll) dc = upawu*(ntot-half) - jpawu*(charge_loc(isppol,iatom)-half)
460 304 : if (amf) dc = upawu*charge_loc(min(3-isppol,nsppol),iatom) + &
461 0 : & (upawu-jpawu)*charge_loc(isppol,iatom)*dble(2*lpawu)/dble(2*lpawu+1)
462 : end if ! not nmdc
463 2728 : do im=1,ndim
464 2037 : hdc(iatom)%mat(im,im,isppol) = dc
465 : end do ! im
466 : end do ! isppol
467 : end if ! dc=8
468 : end do ! iatom
469 :
470 199 : if (dmft_dc == 8) then
471 0 : call xmpi_sum(paw_dmft%edc(:),paw_dmft%spacecomm,ierr)
472 0 : call xmpi_sum(paw_dmft%edcdc(:),paw_dmft%spacecomm,ierr)
473 0 : call xmpi_matlu(hdc(:),natom,paw_dmft%spacecomm)
474 : end if ! dmft_dc=8
475 :
476 199 : end subroutine dc_self
477 : !!***
478 :
479 : !!****f* m_self/rw_self
480 : !! NAME
481 : !! rw_self
482 : !!
483 : !! FUNCTION
484 : !! Read/write self-energy on file.
485 : !!
486 : !! INPUTS
487 : !! self <type(self_type)>= variables related to self-energy
488 : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
489 : !! prtopt = flag for printing
490 : !! opt_rw = 0 (default) Set self-energy either to double counting or 0 depending on dmft_rslf
491 : !! 1 Read Self-Energy.
492 : !! 2 Write Self-Energy.
493 : !! 3 Impose Self-Energy.
494 : !! istep_iter = iteration step
495 : !! opt_char = char to add at the end of the filename
496 : !! opt_imagonly = only reads the imaginary part (useful when reading from Maxent)
497 : !! opt_selflimit = 0th order moment of the self-energy (useful when reading from Maxent)
498 : !! opt_hdc = double counting (useful when reading from Maxent)
499 : !! opt_stop = stop when encountering errors
500 : !! opt_maxent = if > 0, read/write Maxent files
501 : !!
502 : !! OUTPUT
503 : !!
504 : !! SOURCE
505 :
506 406 : subroutine rw_self(self,paw_dmft,prtopt,opt_rw,istep_iter,opt_char,opt_imagonly,&
507 406 : & opt_selflimit,opt_hdc,opt_stop,opt_maxent)
508 :
509 : !Arguments ------------------------------------
510 : !type
511 : type(self_type), intent(inout) :: self
512 : type(paw_dmft_type), intent(inout) :: paw_dmft
513 : integer, intent(in) :: prtopt
514 : integer, optional, intent(in) :: istep_iter,opt_imagonly,opt_maxent,opt_rw,opt_stop
515 : character(len=4), optional, intent(in) :: opt_char
516 : type(matlu_type), optional, intent(inout) :: opt_selflimit(paw_dmft%natom)
517 : type(matlu_type), optional, intent(in) :: opt_hdc(paw_dmft%natom)
518 : !local variables-------------------------------
519 : integer :: i,iall,iatom,iatu,icount,ier,iexist2,iexit,iflavor,ifreq,im,im1,ioerr
520 : integer :: ispinor,ispinor1,isppol,istep,istep_imp,istepiter,iter,iter_imp,lpawu,master
521 : integer :: myproc,natom,natom_read,ncount,ndim,ndim_read,nrecl,nspinor,nspinor_read
522 : integer :: nsppol,nsppol_read,nw_read,optmaxent,optrw,readimagonly,spacecomm,unitrot
523 : real(dp) :: fermie_read,x_r,x_i,xtemp
524 : logical :: lexist,lexist_rot,nondiaglevels,prtself
525 : character(len=30000) :: message ! Big buffer to avoid buffer overflow.
526 : character(len=fnlen) :: stringfile,tmpfil,tmpfil2,tmpfilrot,tmpmatrot
527 : character(len=1) :: tag_is
528 : character(len=3) :: self_iter
529 : character(len=4) :: chtemp
530 : character(len=5) :: tag_freq
531 : character(len=10) :: tag_at,tag_iflavor
532 : character(len=13) :: tag
533 : character(len=50) :: string_format
534 406 : type(oper_type) :: energy_level
535 406 : integer, allocatable :: unitselffunc_arr(:),unitselffunc_arr2(:),unitselfrot(:,:,:,:)
536 406 : real(dp), allocatable :: s_i(:,:),s_r(:,:) !,fermie_read2(:)
537 406 : complex(dp), allocatable :: buffer(:)
538 406 : type(matlu_type), allocatable :: eigvectmatlu(:),level_diag(:),selfmomrot(:,:)
539 406 : type(oper_type), allocatable :: selfrotmatlu(:)
540 : ! *********************************************************************
541 :
542 : ABI_NVTX_START_RANGE(NVTX_DMFT_RW_SELF)
543 406 : natom = paw_dmft%natom
544 406 : nspinor = paw_dmft%nspinor
545 406 : nsppol = paw_dmft%nsppol
546 : !mbandc = paw_dmft%mbandc
547 : !nkpt = paw_dmft%nkpt
548 :
549 : ! Initialise spaceComm, myproc, and nproc
550 406 : istep = 0
551 406 : iter = 0
552 406 : istep_imp = 0
553 406 : istepiter = 0
554 406 : iter_imp = 0
555 406 : optmaxent = 0
556 406 : optrw = 0
557 406 : prtself = (paw_dmft%dmft_prtself == 1)
558 406 : readimagonly = 0
559 :
560 406 : if (present(opt_rw)) optrw = opt_rw
561 406 : if (present(opt_maxent)) optmaxent = opt_maxent
562 :
563 406 : if (present(opt_imagonly)) then
564 4 : if (opt_imagonly == 1 .and. paw_dmft%dmft_solv >= 5) then
565 4 : readimagonly = opt_imagonly
566 4 : write(message,*)
567 4 : write(message,'(a,4x,2a)') ch10,"About to read imaginary part of Self energy"
568 4 : call wrtout(std_out,message,'COLL')
569 : else
570 0 : write(message,'(4x,2a)') "About to read both real and imaginary part of Self energy"
571 0 : call wrtout(std_out,message,'COLL')
572 : end if ! opt_imagonly
573 : end if ! present(opt_imagonly)
574 :
575 406 : if (present(istep_iter)) istepiter = istep_iter
576 :
577 406 : if (paw_dmft%use_fixed_self > 0) then
578 0 : istep = istepiter / 1000
579 0 : iter = istepiter - (istepiter/1000)*1000
580 0 : istep_imp = paw_dmft%use_fixed_self / 1000
581 0 : iter_imp = paw_dmft%use_fixed_self - (paw_dmft%use_fixed_self/1000)*1000
582 : end if !use_fixed_self
583 :
584 406 : if (paw_dmft%dmft_rslf <= 0 .and. optrw == 1) optrw = 0
585 :
586 406 : iexist2 = 1
587 406 : iexit = 0
588 406 : ioerr = 0
589 406 : lexist = .true.
590 406 : master = 0
591 406 : myproc = paw_dmft%myproc
592 406 : spacecomm = paw_dmft%spacecomm
593 : !nproc = paw_dmft%nproc
594 :
595 : ! write(std_out,*) "myproc,master",myproc,master
596 : !if(prtopt>200) then
597 : !endif
598 :
599 : ! - For the Tentative rotation of the self-energy file (begin init)
600 406 : if (optmaxent > 0) then
601 110 : if (optrw == 2) then
602 106 : write(message,'(a,2x,a)') ch10," == About to print self-energy for MAXENT code in basis that diagonalizes the atomic levels"
603 4 : else if (optrw == 1) then
604 4 : write(message,'(a,2x,a)') ch10," == About to read self-energy from MAXENT code"
605 : end if
606 110 : call wrtout(std_out,message,'COLL')
607 :
608 704 : ABI_MALLOC(eigvectmatlu,(natom))
609 110 : call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),eigvectmatlu(:))
610 : end if ! optmaxent > 0
611 : ! - For the Tentative rotation of the self-energy file (end init)
612 :
613 : ! - For the Tentative rotation of the self-energy file (begin diag)
614 406 : if (optrw == 2 .and. optmaxent > 0) then
615 636 : ABI_MALLOC(unitselfrot,(2*paw_dmft%maxlpawu+1,nspinor,nsppol,natom)) ! 7 is the max ndim possible
616 688 : ABI_MALLOC(level_diag,(natom))
617 23407 : ABI_MALLOC(selfrotmatlu,(self%nw))
618 106 : call init_oper(paw_dmft,energy_level,opt_ksloc=2)
619 106 : call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),level_diag(:))
620 106 : call compute_levels(energy_level,self%hdc,paw_dmft,nondiag=nondiaglevels)
621 106 : write(tag,'(f13.5)') paw_dmft%fermie
622 106 : if (self%nw >= 2) then
623 106 : write(message,'(a,2x,2a)') ch10," == Print non Diagonalized Self Energy for Fermi Level= ",adjustl(tag)
624 106 : call wrtout(std_out,message,'COLL')
625 106 : call print_matlu(self%oper(2)%matlu(:),natom,1,compl=1,opt_exp=1)
626 : end if
627 106 : call diag_matlu(energy_level%matlu(:),level_diag(:),natom,prtopt,eigvectmatlu(:),test=paw_dmft%dmft_solv)
628 106 : write(message,'(a,2x,2a)') ch10," == Print Diagonalized levels for Fermi Level= ",adjustl(tag)
629 106 : call wrtout(std_out,message,'COLL')
630 106 : call print_matlu(level_diag(:),natom,1,compl=1,opt_exp=1)
631 : ! Rotate self
632 23195 : do ifreq=1,self%nw
633 23089 : call init_oper(paw_dmft,selfrotmatlu(ifreq),opt_ksloc=2)
634 23089 : if (self%distrib%procf(ifreq) /= myproc) cycle
635 8032 : call copy_matlu(self%oper(ifreq)%matlu(:),selfrotmatlu(ifreq)%matlu(:),natom)
636 23195 : call rotate_matlu(selfrotmatlu(ifreq)%matlu(:),eigvectmatlu(:),natom,1)
637 : end do ! ifreq
638 106 : call gather_oper(selfrotmatlu(:),self%distrib,paw_dmft,2,master=master)
639 106 : if (self%has_moments == 1) then
640 0 : ABI_MALLOC(selfmomrot,(natom,self%nmoments))
641 0 : do i=1,self%nmoments
642 0 : call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),selfmomrot(:,i))
643 0 : call copy_matlu(self%moments(i)%matlu(:),selfmomrot(:,i),natom)
644 0 : call rotate_matlu(selfmomrot(:,i),eigvectmatlu(:),natom,1)
645 : end do ! i
646 : end if
647 530 : do ifreq=1,min(3,self%nw)
648 318 : write(tag_freq,'(i5)') ifreq
649 424 : if (ifreq < 3 .and. myproc == master) then ! very important to call print_matlu only on master node
650 98 : write(message,'(a,2x,2a)') ch10," == Print non Rotated Self Energy for frequency ",adjustl(tag_freq)
651 98 : call wrtout(std_out,message,'COLL')
652 98 : call print_matlu(self%oper(ifreq)%matlu(:),natom,1,compl=1)
653 98 : write(message,'(a,2x,2a)') ch10," == Print Rotated Self Energy for frequency ",adjustl(tag_freq)
654 98 : call wrtout(std_out,message,'COLL')
655 98 : call print_matlu(selfrotmatlu(ifreq)%matlu(:),natom,1,compl=1)
656 220 : else if (ifreq == 3) then
657 106 : write(message,'(a,2x,a,i4)') ch10," (Other frequencies not printed)"
658 106 : call wrtout(std_out,message,'COLL')
659 : end if ! ifreq<3
660 : end do ! ifreq
661 : end if ! optrw=2 and optmaxent>0
662 : ! Create file for rotation
663 406 : if (optmaxent > 0 .and. myproc == master .and. (optrw == 1 .or. optrw == 2)) then
664 208 : do iatom=1,natom
665 158 : lpawu = paw_dmft%lpawu(iatom)
666 158 : if (lpawu == -1) cycle
667 62 : call int2char4(iatom,tag_at)
668 62 : ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
669 62 : if (optrw == 2) then
670 61 : tmpmatrot = trim(paw_dmft%filapp)//'_UnitaryMatrix_iatom'//trim(tag_at)
671 : else if (optrw == 1) then
672 1 : tmpmatrot = trim(paw_dmft%filnamei)//'_UnitaryMatrix_iatom'//trim(tag_at)
673 1 : inquire(file=trim(tmpmatrot),exist=lexist_rot)
674 1 : if (.not. lexist_rot) ABI_ERROR("File "//trim(tmpmatrot)//" does not exist !")
675 : end if ! optrw
676 62 : unitrot = 3189 + iatom
677 : #ifdef FC_NAG
678 : open(unit=unitrot,file=trim(tmpmatrot),status='unknown',form='formatted',recl=ABI_RECL)
679 : #else
680 62 : open(unit=unitrot,file=trim(tmpmatrot),status='unknown',form='formatted')
681 : #endif
682 62 : write(std_out,'(2a)') " Open file ",trim(tmpmatrot)
683 62 : rewind(unitrot)
684 62 : ndim = (2*lpawu+1) * nspinor
685 165 : do isppol=1,nsppol
686 674 : do im=1,ndim
687 3433 : do im1=1,ndim
688 3330 : if (optrw == 2) then
689 2796 : write(message,*) dble(eigvectmatlu(iatom)%mat(im,im1,isppol)),aimag(eigvectmatlu(iatom)%mat(im,im1,isppol))
690 2796 : call wrtout(unitrot,message,'COLL')
691 : else if (optrw == 1) then
692 25 : read(unitrot,*) x_r,x_i
693 25 : eigvectmatlu(iatom)%mat(im,im1,isppol) = cmplx(x_r,x_i,kind=dp)
694 : end if ! optrw
695 : end do ! im1
696 : end do ! im
697 : end do ! isppol
698 208 : close(unitrot)
699 : end do ! iatom
700 :
701 50 : if (optrw == 1) then
702 1 : write(message,'(2a)') ch10," == Print non-rotated high-frequency limit of the self-energy"
703 1 : call wrtout(std_out,message,'COLL')
704 1 : call print_matlu(opt_selflimit(:),natom,1,compl=1)
705 1 : call rotate_matlu(opt_selflimit(:),eigvectmatlu(:),natom,1)
706 1 : write(message,'(2a)') ch10," == Print rotated high-frequency limit of the self-energy"
707 1 : call wrtout(std_out,message,'COLL')
708 1 : call print_matlu(opt_selflimit(:),natom,1,compl=1)
709 : end if ! optrw=1
710 :
711 : end if ! optmaxent > 0
712 : ! - For the Tentative rotation of the self-energy file (end diag)
713 :
714 406 : if ((optrw == 2 .or. optrw == 1) .and. myproc == master) then
715 390 : ABI_MALLOC(unitselffunc_arr,(natom*nsppol))
716 130 : if (optrw == 2) then
717 182 : ABI_MALLOC(unitselffunc_arr2,(natom*nsppol))
718 91 : if (paw_dmft%idmftloop < 10) then
719 89 : write(self_iter,'("00",i1)') paw_dmft%idmftloop
720 2 : else if (paw_dmft%idmftloop >= 10 .and. paw_dmft%idmftloop < 100) then
721 2 : write(self_iter,'("0",i2)') paw_dmft%idmftloop
722 0 : else if (paw_dmft%idmftloop >= 100 .and. paw_dmft%idmftloop < 1000) then
723 0 : write(self_iter,'(i3)') paw_dmft%idmftloop
724 : else
725 0 : self_iter="xxx"
726 : end if ! idmftloop
727 : end if ! optrw=2
728 130 : iall = 0
729 532 : do iatom=1,natom
730 402 : lpawu = paw_dmft%lpawu(iatom)
731 402 : if (lpawu == -1) cycle
732 150 : ndim = 2*lpawu + 1
733 600 : ABI_MALLOC(s_r,(ndim*nspinor,ndim*nspinor))
734 450 : ABI_MALLOC(s_i,(ndim*nspinor,ndim*nspinor))
735 : ! write(std_out,*) "print_self",ndim
736 150 : call int2char4(iatom,tag_at)
737 150 : ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
738 390 : do isppol=1,nsppol
739 240 : write(tag_is,'(i1)') isppol
740 : ! do ispinor=1,nspinor
741 240 : iall = iall + 1
742 : ! write(tag_is2,'(i1)')ispinor
743 :
744 : ! ===========================
745 : ! == Create name for file
746 : ! ===========================
747 :
748 240 : if (self%w_type == "real") then
749 1 : tmpfil = trim(merge(paw_dmft%filnamei,paw_dmft%filapp,optrw==1))//'_Self_ra-omega_iatom'//trim(tag_at)//'_isppol'//tag_is
750 : else
751 239 : if (present(opt_char)) then
752 0 : tmpfil = trim(paw_dmft%filapp)//'Self_ra-omega_iatom'//trim(tag_at)//'_isppol'//tag_is//opt_char
753 : else
754 239 : stringfile = "_iatom" // trim(tag_at) // '_isppol' // tag_is
755 239 : if (optrw == 1 .and. paw_dmft%idmftloop == 0) then
756 32 : tmpfil = trim(paw_dmft%filselfin) // stringfile
757 32 : iexist2 = paw_dmft%ireadself
758 : else
759 207 : tmpfil = trim(paw_dmft%filapp) // '_Self-omega' // stringfile
760 : end if
761 : end if ! opt_char
762 : end if ! w_type
763 240 : if (optrw == 2) tmpfil2 = trim(tmpfil)//"_"//self_iter
764 :
765 240 : if (optrw == 1 .and. iexist2 == 1) then
766 30 : write(message,'(3a)') ch10," == Read self-energy and Fermi Level from file ",trim(tmpfil)
767 30 : call wrtout(std_out,message,'COLL')
768 210 : else if (optrw == 2) then
769 179 : write(message,'(3a)') ch10," == Write self-energy and Fermi Level on file ",trim(tmpfil)
770 179 : call wrtout(std_out,message,'COLL')
771 : end if
772 : !unitselffunc_arr(iall)=300+iall-1
773 240 : unitselffunc_arr(iall) = get_unit()
774 240 : ABI_CHECK(unitselffunc_arr(iall) > 0, "Cannot find free IO unit!")
775 :
776 : !- For the Tentative rotation of the self-energy file (create file)
777 240 : if (optrw == 2 .and. optmaxent > 0) then
778 102 : iflavor = 0
779 206 : do ispinor=1,nspinor
780 710 : do im=1,ndim
781 504 : iflavor = iflavor + 1
782 504 : call int2char4(iflavor,tag_iflavor)
783 504 : unitselfrot(im,ispinor,isppol,iatom) = 3000 + iflavor
784 : !ABI_CHECK(unitselfrot(im,ispinor,isppol,iatom) > 0, "Cannot find free IO unit for unitselfrot!")
785 : tmpfilrot = trim(paw_dmft%filapp)//'_Selfmxent'//&
786 504 : & trim(tag_at)//'_is'//tag_is//'_iflav'//trim(tag_iflavor)
787 504 : write(std_out,*) "Create file ",trim(tmpfilrot)," unit ",unitselfrot(im,ispinor,isppol,iatom)," for flavor",iflavor
788 : #ifdef FC_NAG
789 : open(unit=unitselfrot(im,ispinor,isppol,iatom),file=trim(tmpfilrot),status='unknown',form='formatted',recl=ABI_RECL)
790 : #else
791 504 : open(unit=unitselfrot(im,ispinor,isppol,iatom),file=trim(tmpfilrot),status='unknown',form='formatted')
792 : #endif
793 504 : rewind(unitselfrot(im,ispinor,isppol,iatom))
794 504 : write(unitselfrot(im,ispinor,isppol,iatom),'(3a)') "# Diagonal component of the self-energy, in the basis that diagonalizes the electronic levels.", &
795 1112 : & ch10,"# Frequency (Ha) Real part Imaginary part"
796 :
797 : end do ! im
798 : end do ! ispinor
799 : end if ! optrw=2 and optmaxent>0
800 : !- For the Tentative rotation of the self-energy file (create file)
801 :
802 : ! write(std_out,*) "1"
803 :
804 : ! ===========================
805 : ! == Read: check that the file exists
806 : ! ===========================
807 240 : if (optrw == 1) then
808 : ! write(std_out,*) "3"
809 61 : inquire(file=trim(tmpfil),exist=lexist,recl=nrecl)
810 61 : if (.not. lexist .and. (paw_dmft%ireadself == 1 .or. paw_dmft%idmftloop > 0)) then
811 : ! write(std_out,*) "4"
812 0 : iexist2 = 0
813 0 : write(message,'(4x,a,i5,3a)') "File number",unitselffunc_arr(iall),&
814 0 : & " called ",trim(tmpfil)," does not exist"
815 : ! write(std_out,*) lexist,nrecl
816 0 : call wrtout(std_out,message,'COLL')
817 : end if ! not lexist
818 : end if ! optrw=1
819 : !write(std_out,*) "2"
820 :
821 : ! ===========================
822 : ! == Open file
823 : ! ===========================
824 240 : if (optrw == 2 .or. (optrw == 1 .and. iexist2 == 1)) then
825 : !write(std_out,*) "5"
826 : #ifdef FC_NAG
827 : open(unit=unitselffunc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted',recl=ABI_RECL)
828 : #else
829 209 : open(unit=unitselffunc_arr(iall),file=trim(tmpfil),status='unknown',form='formatted')
830 : #endif
831 209 : rewind(unitselffunc_arr(iall))
832 :
833 209 : if (optrw == 2 .and. prtself) then
834 0 : unitselffunc_arr2(iall) = get_unit()
835 0 : ABI_CHECK(unitselffunc_arr2(iall) > 0,"Cannot find free IO unit!")
836 : #ifdef FC_NAG
837 : open(unit=unitselffunc_arr2(iall),file=trim(tmpfil2),status="unknown",form="formatted",recl=ABI_RECL)
838 : #else
839 0 : open(unit=unitselffunc_arr2(iall),file=trim(tmpfil2),status="unknown",form="formatted")
840 : #endif
841 0 : rewind(unitselffunc_arr2(iall))
842 : end if ! optrw=2
843 :
844 : !write(std_out,*) "61",nrecl
845 209 : if (prtopt >= 3) then
846 2 : write(message,'(3a,i4)') ' Opened file : ',trim(tmpfil),' on unit ',unitselffunc_arr(iall)
847 2 : call wrtout(std_out,message,'COLL')
848 : end if ! prtopt>=3
849 : end if
850 : !write(std_out,*) "6",nrecl
851 :
852 : ! ===========================
853 : ! == Check Header
854 : ! ===========================
855 :
856 240 : if (optrw == 2) then
857 :
858 179 : write(message,'(11a,4i5,i6,2x,e25.17e3)') "# DFT+DMFT self-energy for each frequency",ch10, &
859 179 : & "# Columns are ordered this way:",ch10, &
860 179 : & "# Frequency (Ha) ((((Re(Sigma(im,im1,ispinor,ispinor1)) ", &
861 179 : & "Im(Sigma(im,im1,ispinor,ispinor1)),im=1,2*l+1),im1=1,2*l+1),", &
862 179 : & "ispinor=1,nspinor),ispinor1=1,nspinor) where the leftmost index varies first", &
863 179 : & ch10,"# natom,nsppol,nspinor,ndim,nw,fermilevel",ch10,&
864 358 : & "####",natom,nsppol,nspinor,ndim,self%nw,paw_dmft%fermie
865 179 : call wrtout(unitselffunc_arr(iall),message,'COLL')
866 179 : if (prtself) then
867 0 : call wrtout(unitselffunc_arr2(iall),message,'COLL')
868 : end if
869 61 : else if (optrw == 1 .and. iexist2 == 1 .and. readimagonly == 0) then
870 29 : read(unitselffunc_arr(iall),*)
871 29 : read(unitselffunc_arr(iall),*)
872 29 : read(unitselffunc_arr(iall),*)
873 29 : read(unitselffunc_arr(iall),*)
874 : read(unitselffunc_arr(iall),*,iostat=ioerr) &
875 29 : & chtemp,natom_read,nsppol_read,nspinor_read,ndim_read,nw_read,fermie_read
876 : !if(ioerr<0) then
877 : ! write(std_out,*)" HEADER IOERR"
878 : ! write(std_out,'(a4,2x,31(e15.8,2x))') chtemp,natom_read,nsppol_read,nspinor_read,ndim_read,nw_read,fermie_read
879 : !endif
880 29 : if (ioerr == 0) then
881 29 : write(message,'(a,3x,3a,i12,2a,i11,2a,i10,2a,i13,2a,i15,2a,e25.8)') ch10,"Data in Self Energy file corresponds to",&
882 29 : & ch10," natom",natom_read,&
883 29 : & ch10," nsppol",nsppol_read,&
884 29 : & ch10," nspinor",nspinor_read,&
885 29 : & ch10," ndim",ndim_read, &
886 29 : & ch10," nw",nw_read, &
887 58 : & ch10," Fermi level",fermie_read
888 29 : call wrtout(std_out,message,'COLL')
889 : if ((natom /= natom_read) .or. (nsppol_read /= nsppol) .or. &
890 29 : & (nspinor /= nspinor_read) .or. (nw_read /= self%nw)) then
891 0 : write(message,'(a,3x,3a,i12,2a,i11,2a,i10,2a,i13,2a,i15,2a,e25.8)') ch10,"Data required is ",&
892 0 : & ch10," natom",natom,&
893 0 : & ch10," nsppol",nsppol,&
894 0 : & ch10," nspinor",nspinor,&
895 0 : & ch10," ndim",ndim, &
896 0 : & ch10," nw",self%nw, &
897 0 : & ch10," Fermi level",paw_dmft%fermie
898 0 : call wrtout(std_out,message,'COLL')
899 0 : message = "Dimensions in self-energy file are not correct"
900 0 : if (present(opt_stop)) then
901 0 : ABI_ERROR(message)
902 : else
903 0 : ABI_WARNING(message)
904 : end if
905 0 : iexist2 = 2
906 : end if
907 : else
908 0 : ABI_WARNING("Self-energy file is empty")
909 : end if ! ioerr
910 : end if ! optrw
911 : !write(std_out,*) "7"
912 :
913 : ! ===========================
914 : ! == Write/Read self in the file
915 : ! ===========================
916 :
917 : !rewind(111)
918 46808 : do ifreq=1,self%nw
919 46808 : if (optrw == 2) then
920 : ! write(std_out,'(a,2x,31(e15.8,2x))') &
921 : !& "SETEST",self%omega(ifreq),&
922 : !& (self%oper(ifreq)%matlu(iatom)%mat(im,im,isppol,ispinor,ispinor)&
923 : !& ,im=1,ndim)
924 : ! write(std_out,*) self%omega(ifreq),&
925 : !& ((self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor)&
926 : !& ,im=1,ndim),im1=1,ndim)
927 : ! write(message,'(2x,393(e25.17,2x))') self%omega(ifreq),&
928 : !& ((((self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
929 : !& ,im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
930 :
931 : !MGNAG Runtime Error: wrtout_cpp.f90, line 896: Buffer overflow on output
932 : !Is it possible to rewrite the code below to avoid such a long message
933 : !What about Netcdf binary files ?
934 28956 : string_format = merge('(2x,393(e25.17e3,2x))','(2x,393(e18.10e3,2x))',nspinor==1)
935 28956 : write(message,string_format) self%omega(ifreq),&
936 746272 : & ((((dble(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
937 892640 : & aimag(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
938 1009664 : & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
939 28956 : call wrtout(unitselffunc_arr(iall),message,'COLL')
940 28956 : if (prtself) then
941 0 : call wrtout(unitselffunc_arr2(iall),message,'COLL')
942 : end if
943 :
944 : !- For the Tentative rotation of the self-energy file (begin rot)
945 : !----------------------------------------------------------------
946 28956 : if (optmaxent > 0) then
947 : !iflavor = 0
948 30024 : do ispinor=1,nspinor
949 103728 : do im=1,ndim
950 : !iflavor = iflavor + 1
951 : ! if(ifreq<5) then
952 : ! write(std_out,*) "Write in file unit",unitselfrot(iatom,isppol,ispinor,im),"for flavor",iflavor
953 : ! endif
954 73704 : write(message,'(2x,393(es24.16e3,2x))') self%omega(ifreq),&
955 73704 : & dble(selfrotmatlu(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)),&
956 147408 : & aimag(selfrotmatlu(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol))
957 : ! write(6,'(2x,393(e18.10,2x))') self%omega(ifreq),&
958 : !& real(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor)),&
959 : !& aimag(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor))
960 : ! if(iflavor==1) then
961 : ! write(1024,*) iatom,isppol,ispinor,im,unitselfrot(iatom,isppol,ispinor,im)
962 : ! write(1024,'(2x,393(e18.10,2x))') self%omega(ifreq),&
963 : ! & real(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor)),&
964 : ! & aimag(selfrotmatlu(iatom)%mat(im,im,isppol,ispinor,ispinor))
965 : ! endif
966 88816 : call wrtout(unitselfrot(im,ispinor,isppol,iatom),message,'COLL')
967 : end do ! im
968 : end do ! ispinor
969 : end if ! optrw=2 and optmaxent>0
970 : !- For the Tentative rotation of the self-energy file (end rot)
971 :
972 : ! write(std_out,*) unitselffunc_arr(iall)
973 17612 : else if (optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 0) then
974 : !write(std_out,*) "8"
975 : ! read(unitselffunc_arr(iall),'(2x,31(e15.8,2x))',iostat=ioerr) &
976 : !& xtemp,(s_r(im),s_i(im),im=1,ndim)
977 : !if (readimagonly == 0) then
978 3462 : read(unitselffunc_arr(iall),*,iostat=ioerr) xtemp,&
979 88928 : & ((((s_r(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim),s_i(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim), &
980 102776 : & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
981 : ! if(ioerr<0) then
982 : ! write(std_out,*)" SELF IOERR<"
983 : ! else if(ioerr>0) then
984 : ! write(std_out,*)" SELF IOERR>"
985 : ! write(std_out,'(a4,2x,31(e15.8,2x))') xtemp,(s_r(im),s_i(im),im=1,ndim)
986 : ! endif
987 92390 : self%oper(ifreq)%matlu(iatom)%mat(:,:,isppol) = cmplx(s_r(:,:),s_i(:,:),kind=dp)
988 : end if ! optrw
989 : end do ! ifreq
990 :
991 : !- For the Tentative rotation of the self-energy file (begin close file)
992 240 : if (optrw == 2 .and. optmaxent > 0) then
993 206 : do ispinor=1,nspinor
994 710 : do im=1,ndim
995 504 : if (self%has_moments == 1) then
996 0 : do i=1,self%nmoments
997 0 : write(tag_is,'(i1)') i
998 0 : write(message,'(a,2x,2(es24.16e3,2x))') "#moments_"//tag_is, &
999 0 : & dble(selfmomrot(iatom,i)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)), &
1000 0 : & aimag(selfmomrot(iatom,i)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol))
1001 0 : call wrtout(unitselfrot(im,ispinor,isppol,iatom),message,'COLL')
1002 : end do ! i
1003 : end if ! nmoments
1004 504 : close(unitselfrot(im,ispinor,isppol,iatom))
1005 608 : write(std_out,*) "Close file unit",unitselfrot(im,ispinor,isppol,iatom)
1006 : end do ! im
1007 : end do ! ispinor
1008 : end if ! optrw=2 and optmaxent>0
1009 :
1010 : !- For the Tentative rotation of the self-energy file (end close file)
1011 :
1012 240 : if (optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 1) then
1013 :
1014 : ! Read self energy from Maxent (imag part) on the real axis
1015 : !----------------------------------------------------------
1016 3001 : do ifreq=1,self%nw
1017 96001 : self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = czero
1018 : end do ! ifreq
1019 2 : do ispinor=1,nspinor
1020 7 : do im=1,ndim
1021 15006 : do ifreq=1,self%nw
1022 15000 : read(unitselffunc_arr(iall),*,iostat=ioerr) xtemp,s_i(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim)
1023 : ! minus sign because - Im Sigma is the output of OmegaMaxent
1024 : self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol) &
1025 15005 : & = cmplx(zero,-half*s_i(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim),kind=dp)
1026 : end do ! ifreq
1027 : end do ! im
1028 : end do ! ispinor
1029 :
1030 1 : write(message,'(4x,2a)') " Read only diagonal self energy from Maxent"
1031 1 : call wrtout(std_out,message,'COLL')
1032 : !write(6,*) "opt_hdc",opt_hdc(1)%mat(1,1,1,1,1)
1033 :
1034 : end if ! optrw=1
1035 :
1036 : ! ===========================
1037 : ! == Write/Read hdc in the file
1038 : ! ===========================
1039 240 : if (optrw == 2) then
1040 : ! write(std_out,'(a,2x,31(e15.8,2x))') &
1041 : !& "SETEST #dc ",(self%hdc%matlu(iatom)%mat(im,im,isppol,ispinor,ispinor),im=1,ndim)
1042 : write(message,'(a,2x,500(e25.17e3,2x))') &
1043 5891 : & "#dc ",((((self%hdc%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol),&
1044 6440 : & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
1045 179 : call wrtout(unitselffunc_arr(iall),message,'COLL')
1046 179 : if (prtself) then
1047 0 : call wrtout(unitselffunc_arr2(iall),message,'COLL')
1048 : end if
1049 179 : if (self%has_moments == 1) then
1050 0 : do i=1,self%nmoments
1051 0 : write(tag_is,'(i1)') i
1052 0 : write(message,'(a,2x,500(e25.17e3,2x))') "#moments_"//trim(tag_is),&
1053 0 : & ((self%moments(i)%matlu(iatom)%mat(im,im1,isppol),im=1,nspinor*ndim),im1=1,nspinor*ndim)
1054 0 : call wrtout(unitselffunc_arr(iall),message,'COLL')
1055 0 : if (prtself) then
1056 0 : call wrtout(unitselffunc_arr2(iall),message,'COLL')
1057 : end if
1058 : end do ! i
1059 : end if ! moments
1060 61 : else if (optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 0) then
1061 : !write(std_out,*) "8"
1062 : read(unitselffunc_arr(iall),*,iostat=ioerr) &
1063 775 : & chtemp,((((s_r(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim),s_i(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim),&
1064 862 : & im=1,ndim),im1=1,ndim),ispinor=1,nspinor),ispinor1=1,nspinor)
1065 : !if(ioerr<0) then
1066 : ! write(std_out,*)" HDC IOERR<",ioerr
1067 : !else if(ioerr>0) then
1068 : ! write(std_out,*)" HDC IOERR>",ioerr
1069 : !endif
1070 775 : self%hdc%matlu(iatom)%mat(:,:,isppol) = cmplx(s_r(:,:),s_i(:,:),kind=dp)
1071 :
1072 29 : if (self%has_moments == 1) then
1073 0 : do i=1,self%nmoments
1074 : read(unitselffunc_arr(iall),*,iostat=ioerr) &
1075 0 : & chtemp,((s_r(im,im1),s_i(im,im1),im=1,nspinor*ndim),im1=1,nspinor*ndim)
1076 0 : self%moments(i)%matlu(iatom)%mat(:,:,isppol) = cmplx(s_r(:,:),s_i(:,:),kind=dp)
1077 : end do ! i
1078 : end if ! moments
1079 : !write(6,*) "read selfhdc",self%hdc%matlu(1)%mat(1,1,1,1,1)
1080 32 : else if (readimagonly == 1 .and. (.not. present(opt_hdc))) then
1081 0 : self%hdc%matlu(iatom)%mat(:,:,isppol) = czero
1082 : !else
1083 : ! write(std_out,*) " self%hdc fixed in kramerskronig_self"
1084 : end if ! optrw
1085 240 : close(unitselffunc_arr(iall))
1086 390 : if (optrw == 2 .and. prtself) close(unitselffunc_arr2(iall))
1087 : ! enddo ! ispinor
1088 : end do ! isppol
1089 150 : ABI_FREE(s_r)
1090 532 : ABI_FREE(s_i)
1091 : end do ! iatom
1092 :
1093 130 : ABI_FREE(unitselffunc_arr)
1094 130 : ABI_SFREE(unitselffunc_arr2)
1095 : end if ! optrw==1 or 2 and myproc==master
1096 :
1097 : ! ===========================
1098 : ! == Error messages
1099 : ! ===========================
1100 289 : if (optrw == 1) then
1101 : ! call xmpi_barrier(spacecomm)
1102 : !write(std_out,*) ncount,maxval(pawtab(:)%lpawu)*2+1
1103 90 : call xmpi_bcast(iexist2,master,spacecomm,ier)
1104 90 : call xmpi_bcast(ioerr,master,spacecomm,ier)
1105 90 : if (iexist2 == 0 .or. ioerr /= 0) then
1106 32 : message = "Self-energy file does not exist or is incomplete"
1107 32 : if (readimagonly == 1 .or. present(opt_stop)) then
1108 0 : if (readimagonly == 1) message = "Self-energy file does not exist or is incomplete: check the number of self-energy data in file"
1109 0 : ABI_ERROR(message)
1110 32 : else if (paw_dmft%ireadself == 1 .or. paw_dmft%idmftloop > 0) then
1111 0 : ABI_WARNING(message)
1112 : end if ! readimagonly=1 or present(opt_stop)
1113 32 : if (iexist2 == 0 .and. (paw_dmft%ireadself == 1 .or. paw_dmft%idmftloop > 0)) then
1114 0 : write(message,'(4x,2a)') "File does not exist"
1115 0 : call wrtout(std_out,message,'COLL')
1116 : end if ! iexist2=0
1117 32 : if (ioerr < 0) then
1118 0 : write(message,'(4x,2a)') "End of file reached"
1119 0 : call wrtout(std_out,message,'COLL')
1120 : end if ! ioerr<0
1121 32 : if (ioerr > 0) then
1122 0 : write(message,'(4x,2a)') "Error during read statement"
1123 0 : call wrtout(std_out,message,'COLL')
1124 : end if ! ioerr>0
1125 : !if (paw_dmft%dmft_solv /= 4) then
1126 32 : write(message,'(4x,2a,5i5,2x,e14.7)') "-> Set Self-Energy Equal to double counting term"
1127 : !else if (paw_dmft%dmft_solv == 4) then
1128 : ! write(message,'(4x,a,a,5i5,2x,e14.7)') "-> Put Self-Energy Equal to dc term - shift"
1129 : ! call wrtout(std_out,message,'COLL')
1130 : ! write(message,'(4x,a,a,5i5,2x,e14.7)') " No self energy is given, change dmft_rslf"
1131 : ! ABI_ERROR(message)
1132 : !end if
1133 32 : call wrtout(std_out,message,'COLL')
1134 17513 : do ifreq=1,self%nw
1135 : ! write(std_out,*) "before",self%oper(1)%matlu(1)%mat(1,1,1,1,1)
1136 : ! write(std_out,*) "before",self%hdc%matlu(1)%mat(1,1,1,1,1)
1137 17481 : call copy_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),natom)
1138 17513 : if (nspinor == 1 .and. nsppol == 2 .and. paw_dmft%dmft_dc >= 5) then
1139 32162 : do iatom=1,natom
1140 16081 : lpawu = paw_dmft%lpawu(iatom)
1141 16081 : if (lpawu == -1) cycle
1142 16081 : ndim = 2*lpawu + 1
1143 112567 : do im=1,ndim
1144 : self%oper(ifreq)%matlu(iatom)%mat(im,im,1) = self%oper(ifreq)%matlu(iatom)%mat(im,im,2) + &
1145 96486 : & paw_dmft%dmft_shiftself(iatom)
1146 : end do ! im
1147 : end do ! iatom
1148 : end if ! nspinor=1 and nsppol=2
1149 : ! write(std_out,*) "after",self%oper(1)%matlu(1)%mat(1,1,1,1,1)
1150 : ! write(std_out,*) "before",self%hdc%matlu(1)%mat(1,1,1,1,1)
1151 : !if (paw_dmft%dmft_solv == 4) then
1152 : ! if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
1153 : ! call shift_matlu(self%oper(ifreq)%matlu(:),natom,cmplx(self%qmc_shift(:),zero,kind=dp),1)
1154 : ! if(ifreq==1) write(std_out,*) "self after dc and shift",self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
1155 : ! if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
1156 : !end if ! dmft_solv=4
1157 : end do ! ifreq
1158 32 : if (self%has_moments == 1) then
1159 0 : call copy_matlu(self%oper(1)%matlu(:),self%moments(1)%matlu(:),natom)
1160 : end if
1161 : else ! test read successfull
1162 : ! call xmpi_barrier(spacecomm)
1163 : !! lignes 924-928 semblent inutiles puisque la valeur de paw_dmft%fermie creee
1164 : !! en ligne 927 est ecrasee en ligne 992. BA+jmb
1165 : !! ABI_MALLOC(fermie_read2,(1))
1166 : !! fermie_read2(1)=fermie_read
1167 : !! call xmpi_sum(fermie_read2,spacecomm ,ier)
1168 : !! paw_dmft%fermie=fermie_read2(1)
1169 : !! ABI_FREE(fermie_read2)
1170 : !ncount = natom * nsppol * (nspinor**2) * (self%nw+1) *(maxval(paw_dmft%lpawu(:))*2+1)**2
1171 58 : ncount = 0
1172 279 : do iatom=1,natom
1173 221 : lpawu = paw_dmft%lpawu(iatom)
1174 221 : if (lpawu == -1) cycle
1175 59 : ndim = 2*lpawu + 1
1176 279 : ncount = ncount + ndim**2
1177 : end do ! iatom
1178 58 : ncount = ncount * (nspinor**2) * (self%nw+self%nmoments+1) * nsppol
1179 :
1180 : ! ===========================
1181 : ! bcast to other proc
1182 : ! ===========================
1183 174 : ABI_MALLOC(buffer,(ncount))
1184 : !! BA+jmb
1185 : !fermie_read2 = zero
1186 : !write(std_out,*) self%nw
1187 58 : if (myproc == master) then
1188 :
1189 : ! == Send read data to all process
1190 22 : if (readimagonly == 0) paw_dmft%fermie = fermie_read
1191 22 : icount = 0
1192 : ! Self energy-----------
1193 6020 : do ifreq=1,self%nw
1194 17058 : do iatom=1,natom
1195 11038 : lpawu = paw_dmft%lpawu(iatom)
1196 11038 : if (lpawu == -1) cycle
1197 6030 : ndim = (2*lpawu+1) * nspinor
1198 18490 : do isppol=1,nsppol
1199 47694 : do im1=1,ndim
1200 178928 : buffer(icount+1:icount+ndim) = self%oper(ifreq)%matlu(iatom)%mat(:,im1,isppol)
1201 36656 : icount = icount + ndim
1202 : !if (icount > ncount) then
1203 : ! write(message,'(2a,2i5)') ch10,"Error buffer",icount,ncount
1204 : ! iexit = 1
1205 : ! ABI_ERROR(message)
1206 : !end if ! icount > ncount
1207 : end do ! im1
1208 : end do ! isppol
1209 : end do ! iatom
1210 : end do ! ifreq
1211 : ! Double counting-------
1212 99 : do iatom=1,natom
1213 77 : lpawu = paw_dmft%lpawu(iatom)
1214 77 : if (lpawu == -1) cycle
1215 23 : ndim = (2*lpawu+1) * nspinor
1216 75 : do isppol=1,nsppol
1217 237 : do im1=1,ndim
1218 776 : buffer(icount+1:icount+ndim) = self%hdc%matlu(iatom)%mat(:,im1,isppol)
1219 160 : icount = icount + ndim
1220 : !if (icount > ncount) then
1221 : ! write(message,'(2a,2i5)') ch10,"Error buffer",icount,ncount
1222 : ! iexit = 1
1223 : ! ABI_ERROR(message)
1224 : !end if ! icount > ncount
1225 : end do ! im1
1226 : end do ! isppol
1227 : end do ! iatom
1228 22 : if (self%has_moments == 1) then
1229 0 : do i=1,self%nmoments
1230 0 : do iatom=1,natom
1231 0 : lpawu = paw_dmft%lpawu(iatom)
1232 0 : if (lpawu == -1) cycle
1233 0 : ndim = (2*lpawu+1) * nspinor
1234 0 : do isppol=1,nsppol
1235 0 : do im1=1,ndim
1236 0 : buffer(icount+1:icount+ndim) = self%moments(i)%matlu(iatom)%mat(:,im1,isppol)
1237 0 : icount = icount + ndim
1238 : end do ! im1
1239 : end do ! isppol
1240 : end do ! iatom
1241 : end do ! i
1242 : end if ! moments
1243 : end if ! proc=master
1244 58 : call xmpi_bcast(buffer(:),master,spacecomm,ier)
1245 : ! call xmpi_sum(iexit,spacecomm ,ier)
1246 : !!JB call xmpi_barrier(spacecomm)
1247 : !call xmpi_sum(buffer,spacecomm,ier)
1248 : !!JB call xmpi_barrier(spacecomm)
1249 :
1250 : ! bcast fermi level
1251 : !call xmpi_sum(fermie_read2,spacecomm,ier)
1252 58 : if (readimagonly == 0) then
1253 54 : call xmpi_bcast(paw_dmft%fermie,master,spacecomm,ier)
1254 : end if
1255 :
1256 58 : if (ier /= 0) then
1257 0 : message = "error in xmpi_sum in rw_self"
1258 0 : ABI_ERROR(message)
1259 : end if
1260 : !paw_dmft%fermie = fermie_read2(1)
1261 : ! write(std_out,*) "Fermi level",paw_dmft%fermie
1262 58 : icount = 0
1263 : ! Self ---------------
1264 21770 : do ifreq=1,self%nw
1265 59322 : do iatom=1,natom
1266 37552 : lpawu = paw_dmft%lpawu(iatom)
1267 37552 : if (lpawu == -1) cycle
1268 21744 : ndim = (2*lpawu+1) * nspinor
1269 65632 : do isppol=1,nsppol
1270 163632 : do im1=1,ndim
1271 608768 : self%oper(ifreq)%matlu(iatom)%mat(:,im1,isppol) = buffer(icount+1:icount+ndim)
1272 126080 : icount = icount + ndim
1273 : !write(6,*)'self procs', ifreq, self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)
1274 : end do ! im1
1275 : end do ! isppol
1276 : end do ! iatom
1277 : end do ! ifreq
1278 : ! hdc ---------------
1279 279 : do iatom=1,natom
1280 221 : lpawu = paw_dmft%lpawu(iatom)
1281 221 : if (lpawu == -1) cycle
1282 59 : ndim = (2*lpawu+1) * nspinor
1283 183 : do isppol=1,nsppol
1284 549 : do im1=1,ndim
1285 1448 : self%hdc%matlu(iatom)%mat(:,im1,isppol) = buffer(icount+1:icount+ndim)
1286 328 : icount = icount + ndim
1287 : end do ! im1
1288 : end do ! isppol
1289 : end do ! iatom
1290 58 : if (self%has_moments == 1) then
1291 0 : do i=1,self%nmoments
1292 0 : do iatom=1,natom
1293 0 : lpawu = paw_dmft%lpawu(iatom)
1294 0 : if (lpawu == -1) cycle
1295 0 : ndim = (2*lpawu+1) * nspinor
1296 0 : do isppol=1,nsppol
1297 0 : do im1=1,ndim
1298 0 : self%moments(i)%matlu(iatom)%mat(:,im1,isppol) = buffer(icount+1:icount+ndim)
1299 0 : icount = icount + ndim
1300 : end do ! im1
1301 : end do ! isppol
1302 : end do ! iatom
1303 : end do ! i
1304 : end if ! moments
1305 : !ABI_FREE(fermie_read2)
1306 58 : ABI_FREE(buffer)
1307 : end if ! test read successful
1308 : end if ! optrw==1
1309 :
1310 406 : if (optmaxent > 0 .and. optrw == 1 .and. iexist2 == 1 .and. ioerr == 0 .and. readimagonly == 1) then
1311 :
1312 4 : write(message,'(4x,2a)') " Rotate Back self-energy in the cubic basis"
1313 4 : call wrtout(std_out,message,'COLL')
1314 :
1315 : ! Kramers Kronig
1316 : !-----------------------------
1317 :
1318 4 : call kramerskronig_self(self,opt_selflimit(:),opt_hdc(:),paw_dmft,paw_dmft%filapp)
1319 :
1320 4 : call xmpi_matlu(eigvectmatlu(:),natom,spacecomm,master=master,option=2)
1321 :
1322 4 : call copy_matlu(opt_hdc(:),self%hdc%matlu(:),natom)
1323 :
1324 : ! Rotate back self
1325 : !-----------------------------
1326 :
1327 12004 : do ifreq=1,self%nw
1328 12000 : if (ifreq < 20) then
1329 76 : write(tag_freq,'(i5)') ifreq
1330 76 : write(message,'(a,2x,2a)') ch10," == Print Rotated Self Energy on real axis for frequency ",adjustl(tag_freq)
1331 76 : call wrtout(std_out,message,'COLL')
1332 76 : call print_matlu(self%oper(ifreq)%matlu(:),natom,1,compl=1)
1333 : end if ! ifreq<20
1334 12000 : if (self%distrib%procf(ifreq) /= myproc) cycle
1335 12004 : call rotate_matlu(self%oper(ifreq)%matlu(:),eigvectmatlu(:),natom,-1)
1336 : end do ! ifreq
1337 4 : call gather_oper(self%oper(:),self%distrib,paw_dmft,opt_ksloc=2)
1338 80 : do ifreq=1,min(19,self%nw)
1339 76 : write(tag_freq,'(i5)') ifreq
1340 76 : write(message,'(a,2x,2a)') ch10," == Print Self Energy rotated back in cubic basis on real axis for frequency ",adjustl(tag_freq)
1341 76 : call wrtout(std_out,message,'COLL')
1342 80 : call print_matlu(self%oper(ifreq)%matlu(:),natom,1,compl=1)
1343 : end do ! ifreq
1344 : end if ! rotate back self-energy
1345 :
1346 : ! call xmpi_barrier(spacecomm)
1347 : !write(std_out,*) "9"
1348 : ! - For the Tentative rotation of the self-energy file (begin destroy)
1349 406 : if (optmaxent > 0) then
1350 :
1351 110 : if (optrw == 2) then
1352 106 : call destroy_oper(energy_level)
1353 106 : call destroy_matlu(level_diag(:),natom)
1354 106 : if (self%has_moments == 1) then
1355 0 : do i=1,self%nmoments
1356 0 : call destroy_matlu(selfmomrot(:,i),natom)
1357 : end do
1358 0 : ABI_FREE(selfmomrot)
1359 : end if
1360 23195 : do ifreq=1,self%nw
1361 23195 : call destroy_oper(selfrotmatlu(ifreq))
1362 : end do ! ifreq
1363 476 : ABI_FREE(level_diag)
1364 23195 : ABI_FREE(selfrotmatlu)
1365 106 : ABI_FREE(unitselfrot) ! 7 is the max ndim possible
1366 : end if ! optrw=2
1367 :
1368 110 : call destroy_matlu(eigvectmatlu(:),natom)
1369 484 : ABI_FREE(eigvectmatlu)
1370 : end if ! optmaxent > 0
1371 : ! - For the Tentative rotation of the self-energy file (end destroy)
1372 :
1373 :
1374 : ! call flush_unit(std_out)
1375 : ! ABI_ERROR("Aboring now")
1376 406 : if (optrw == 0) then
1377 11 : if (paw_dmft%dmft_rslf == 0) then
1378 : !if (paw_dmft%dmft_solv /= 4) then
1379 11 : write(message,'(4x,a)') "-> Set Self-Energy Equal to double counting term"
1380 : !else if (paw_dmft%dmft_solv == 4) then
1381 : ! write(message,'(4x,a,a,5i5,2x,e14.7)') "-> Put Self-Energy Equal to dc term - shift"
1382 : !end if ! dmft_solv=4
1383 0 : else if (paw_dmft%dmft_rslf == -1) then
1384 0 : write(message,'(4x,a)') "-> Set Self-Energy Equal to zero"
1385 : end if ! dmft_rslf=0
1386 11 : call wrtout(std_out,message,'COLL')
1387 415 : do ifreq=1,self%nw
1388 415 : if (paw_dmft%dmft_rslf == 0) then
1389 404 : call copy_matlu(self%hdc%matlu(:),self%oper(ifreq)%matlu(:),natom)
1390 : ! if(ifreq==1) write(std_out,*) "self after dc",self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
1391 : !if (paw_dmft%dmft_solv == 4) then
1392 : ! if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
1393 : ! call shift_matlu(self%oper(ifreq)%matlu(:),natom,cmplx(self%qmc_shift(:),zero,kind=dp),1)
1394 : ! if(ifreq==1) write(std_out,*) "self after dc and shift",self%oper(ifreq)%matlu(1)%mat(1,1,1,1,1)
1395 : ! if(ifreq==1) write(std_out,*) "shift",self%qmc_shift(1)
1396 : !end if ! dmft_solv=4
1397 0 : else if (paw_dmft%dmft_rslf == -1) then
1398 0 : call zero_matlu(self%oper(ifreq)%matlu(:),natom)
1399 : end if ! dmft_rslf
1400 : end do ! ifreq
1401 11 : if (paw_dmft%dmft_rslf == 0 .and. self%has_moments == 1) then
1402 0 : call copy_matlu(self%hdc%matlu(:),self%moments(1)%matlu(:),natom)
1403 : end if
1404 : end if ! optrw=0
1405 :
1406 : ! write(std_out,*) "optrw,use_fixed_self,istep,iter,istep_imp,iter_imp"
1407 : ! write(std_out,*) optrw,paw_dmft%use_fixed_self,istep,iter,istep_imp,iter_imp
1408 406 : if ((optrw == 1 .or. optrw == 3) .and. paw_dmft%use_fixed_self > 0 .and. istep <= istep_imp .and. iter <= iter_imp) then
1409 0 : write(message,'(4x,a)') "-> Set Self-Energy Equal to imposed self-energy"
1410 0 : call wrtout(std_out,message,'COLL')
1411 0 : do ifreq=1,self%nw
1412 0 : iatu = 0
1413 0 : do iatom=1,natom
1414 0 : lpawu = paw_dmft%lpawu(iatom)
1415 0 : if (lpawu == -1) cycle
1416 0 : self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = czero
1417 0 : iatu = iatu + 1
1418 0 : ndim = 2*lpawu + 1
1419 0 : do isppol=1,nsppol
1420 0 : do ispinor=1,nspinor
1421 0 : do im=1,ndim
1422 0 : if (nspinor == 1) then
1423 0 : self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol) = paw_dmft%fixed_self(im,im,isppol,iatu)
1424 : ! write(std_out,*) paw_dmft%fixed_self(im,im,isppol,iatu)
1425 : else
1426 0 : self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol) = paw_dmft%fixed_self(im,im,ispinor,iatu)
1427 : ! write(message,'(a,i4,i4,2x,e20.10)') " Fixed self not implemented for nspinor==2"
1428 : ! call wrtout(std_out, message,'COLL')
1429 : ! ABI_ERROR("Aboring now")
1430 : end if ! nspinor
1431 : end do ! im
1432 : end do ! ispinor
1433 : end do ! isppol
1434 : end do ! iatom
1435 : end do ! ifreq
1436 0 : if (self%has_moments == 1) then
1437 0 : call copy_matlu(self%oper(1)%matlu(:),self%moments(1)%matlu(:),natom)
1438 0 : do i=2,self%nmoments
1439 0 : call zero_matlu(self%moments(i)%matlu(:),natom)
1440 : end do ! i
1441 : end if
1442 :
1443 : end if ! use_fixed_self
1444 : ABI_NVTX_END_RANGE()
1445 :
1446 406 : end subroutine rw_self
1447 : !!***
1448 :
1449 : !!****f* m_self/new_self
1450 : !! NAME
1451 : !! new_self
1452 : !!
1453 : !! FUNCTION
1454 : !!
1455 : !! Mix Old and New self_energy with the mixing coefficient dmft_mxsf
1456 : !!
1457 : !! INPUTS
1458 : !! self <type(self_type)>= variables related to self-energy
1459 : !! self_new <type(self_type)>= variables related to the new self-energy
1460 : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
1461 : !!
1462 : !! OUTPUT
1463 : !! self <type(self_type)>= variables related to mixed self-energy
1464 : !!
1465 : !! SOURCE
1466 :
1467 106 : subroutine new_self(self,self_new,paw_dmft)
1468 :
1469 : !Arguments ------------------------------------
1470 : !type
1471 : ! type(crystal_t),intent(in) :: cryst_struc
1472 : type(self_type), intent(inout) :: self
1473 : type(self_type), intent(in) :: self_new
1474 : type(paw_dmft_type), intent(in) :: paw_dmft
1475 : !Local variables-------------------------------
1476 : integer :: i,iatom,icount,ifreq,im,im1,isppol,lpawu,natom,ndim,nspinor,nsppol
1477 : real(dp) :: alpha,diff_self,sum_self
1478 : character(len=500) :: message
1479 : ! *********************************************************************
1480 :
1481 106 : alpha = paw_dmft%dmft_mxsf
1482 106 : natom = paw_dmft%natom
1483 106 : nspinor = paw_dmft%nspinor
1484 106 : nsppol = paw_dmft%nsppol
1485 :
1486 23195 : do ifreq=1,self%nw
1487 67068 : do iatom=1,natom
1488 43873 : lpawu = paw_dmft%lpawu(iatom)
1489 43873 : if (lpawu == -1) cycle
1490 : self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = (one-alpha)*self%oper(ifreq)%matlu(iatom)%mat(:,:,:) + &
1491 1355756 : & alpha*self_new%oper(ifreq)%matlu(iatom)%mat(:,:,:)
1492 : ! warning: self_new is the recent self-energy, which is mixed with self
1493 : ! to give self= mixed self energy. self_new is deallocated just after.
1494 : end do ! iatom
1495 : end do ! ifreq
1496 :
1497 106 : diff_self = zero
1498 106 : sum_self = zero
1499 106 : icount = 0
1500 :
1501 476 : do iatom=1,natom
1502 370 : lpawu = paw_dmft%lpawu(iatom)
1503 370 : if (lpawu == -1) cycle
1504 130 : ndim = nspinor * (2*lpawu+1)
1505 130 : icount = icount + nsppol*ndim
1506 440 : do isppol=1,nsppol
1507 1540 : do im1=1,ndim
1508 6180 : do im=1,ndim
1509 5010 : diff_self = diff_self + abs(self%hdc%matlu(iatom)%mat(im,im1,isppol)-self_new%hdc%matlu(iatom)%mat(im,im1,isppol))
1510 5010 : sum_self = sum_self + abs(self%hdc%matlu(iatom)%mat(im,im1,isppol))
1511 : self%hdc%matlu(iatom)%mat(im,im1,isppol) = (one-alpha)*self%hdc%matlu(iatom)%mat(im,im1,isppol) + &
1512 5976 : & alpha*self_new%hdc%matlu(iatom)%mat(im,im1,isppol)
1513 : end do ! im
1514 : end do ! im1
1515 : end do ! isppol
1516 : end do ! iatom
1517 :
1518 106 : if (self%has_moments == 1) then
1519 0 : do i=1,self%nmoments
1520 0 : do iatom=1,natom
1521 0 : lpawu = paw_dmft%lpawu(iatom)
1522 0 : if (lpawu == -1) cycle
1523 : self%moments(i)%matlu(iatom)%mat(:,:,:) = (one-alpha)*self%moments(i)%matlu(iatom)%mat(:,:,:) + &
1524 0 : & alpha*self_new%moments(i)%matlu(iatom)%mat(:,:,:)
1525 : end do ! iatom
1526 : end do ! i
1527 : end if ! moments
1528 :
1529 : !if(opt_mix==1) then
1530 : !endif
1531 :
1532 106 : diff_self = diff_self / dble(icount)
1533 :
1534 106 : write(message,'(8x,a,e12.5)') "DMFT Loop: Precision on self-energy is",diff_self
1535 106 : call wrtout(std_out,message,'COLL')
1536 106 : if (diff_self < paw_dmft%dmft_fermi_prec .and. sum_self > tol6 .and. paw_dmft%idmftloop >= 2) then
1537 0 : write(message,'(a,8x,a,e9.2,a,8x,a)') ch10, "Change of self =<", paw_dmft%dmft_fermi_prec,&
1538 0 : & ch10,"DMFT Loop: Self Energy is converged"
1539 0 : call wrtout(std_out,message,'COLL')
1540 0 : self%iself_cv = 1
1541 : else
1542 106 : write(message,'(a,8x,a)') ch10,"DMFT Loop: Self Energy is not converged"
1543 106 : call wrtout(std_out,message,'COLL')
1544 106 : self%iself_cv = 0
1545 : end if ! diff_self
1546 :
1547 106 : end subroutine new_self
1548 : !!***
1549 :
1550 : !!****f* m_self/make_qmcshift_self
1551 : !! NAME
1552 : !! make_qmcshift_hu
1553 : !!
1554 : !! FUNCTION
1555 : !!
1556 : !! INPUTS
1557 : !! hu <type(hu_type)> = U interaction
1558 : !! paw_dmft <type(paw_dmft_type)> = paw+dmft related data
1559 : !!
1560 : !! OUTPUT
1561 : !! self%qmc_shift in self <type(self_type)> = Self-energy
1562 : !!
1563 : !! SOURCE
1564 :
1565 : !subroutine make_qmcshift_self(cryst_struc,hu,self,apply)
1566 :
1567 : !Arguments ------------------------------------
1568 : !type
1569 : ! type(crystal_t),intent(in) :: cryst_struc
1570 : ! type(hu_type),intent(in) :: hu(cryst_struc%ntypat)
1571 : ! type(self_type),intent(inout) :: self
1572 : ! logical, optional :: apply
1573 :
1574 : !Local variables-------------------------------
1575 : ! integer :: im,iatom,ifreq,itypat,lpawu,tndim
1576 : ! real(dp) :: hu_shift2
1577 : ! character(len=500) :: message
1578 : ! *********************************************************************
1579 :
1580 : ! do iatom = 1 , cryst_struc%natom
1581 : ! lpawu=self%hdc%matlu(iatom)%lpawu
1582 : ! tndim=2*lpawu+1
1583 : ! itypat=cryst_struc%typat(iatom)
1584 : ! if(lpawu/=-1) then
1585 : ! self%qmc_shift(iatom) = zero
1586 : ! do im =1, 2*tndim-1
1587 : !! write(std_out,*)"make before",self%qmc_shift(iatom)
1588 : ! self%qmc_shift(iatom) = self%qmc_shift(iatom) + hu(itypat)%uqmc(im)
1589 : !! write(std_out,*)"make after",self%qmc_shift(iatom)
1590 : ! enddo
1591 : ! self%qmc_shift(iatom) = self%qmc_shift(iatom) / two
1592 : ! hu_shift2 = hu(itypat)%uqmc(1)
1593 : !
1594 : ! do im = 2*tndim, 2*tndim + 2*tndim -3
1595 : ! hu_shift2 = hu_shift2 + hu(itypat)%uqmc(im)
1596 : ! enddo
1597 :
1598 : ! hu_shift2 = hu_shift2 / two
1599 : ! write(message,'(2a,i4)') ch10,' -------> For Correlated atom',iatom
1600 : ! call wrtout(std_out, message,'COLL')
1601 :
1602 : ! if(abs(self%qmc_shift(iatom)-hu_shift2)>tol6) then
1603 : ! write(message,'(2a,2f16.7)') " Shift for QMC is not correctly"&
1604 : !& ," computed",self%qmc_shift(iatom),hu_shift2
1605 : ! ABI_ERROR(message)
1606 : ! endif ! shifts not equals
1607 : !
1608 : ! write(message,'(4x,a,f16.7)') &
1609 : !& " Shift for QMC (used to compute G(w)) is (in Ha) :",&
1610 : !& self%qmc_shift(iatom)
1611 : ! call wrtout(std_out, message,'COLL')
1612 :
1613 : ! self%qmc_xmu(iatom)=-self%qmc_shift(iatom)
1614 : ! self%qmc_xmu(iatom)=zero
1615 : ! write(message,'(4x,a,f16.7)') &
1616 : !& "Artificial Shift used in QMC AND to compute G is (in Ha) :",self%qmc_xmu(iatom)
1617 : ! ABI_WARNING(message)
1618 :
1619 : ! endif ! lpawu/=1
1620 : ! enddo ! natom
1621 :
1622 : ! if(present(apply)) then
1623 : ! if (apply) then
1624 : ! write(message,'(5x,a,f16.7,a)') " Shifts applied to self"
1625 : ! call wrtout(std_out, message,'COLL')
1626 : ! do ifreq=1,self%nw
1627 : ! call shift_matlu(self%oper(ifreq)%matlu,cryst_struc%natom,cmplx(self%qmc_shift,0.d0,kind=dp),1)
1628 : ! call shift_matlu(self%oper(ifreq)%matlu,cryst_struc%natom,cmplx(self%qmc_xmu,0.d0,kind=dp),1)
1629 : ! enddo
1630 : ! endif
1631 : ! endif
1632 :
1633 :
1634 : !end subroutine make_qmcshift_self
1635 : !!***
1636 :
1637 : !!****f* m_self/kramerskronig_self
1638 : !! NAME
1639 : !! kramerskronig_self
1640 : !!
1641 : !! FUNCTION
1642 : !! Compute the real part of the self-energy using Kramers-Kronig formula.
1643 : !!
1644 : !! INPUTS
1645 : !! self <type(self_type)>= variables related to self-energy
1646 : !! selflimit = 0th order moment of the self-energy for each atom
1647 : !! selfhdc = double counting
1648 : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
1649 : !! filapp = name of the file
1650 : !!
1651 : !! OUTPUT
1652 : !!
1653 : !! SOURCE
1654 :
1655 4 : subroutine kramerskronig_self(self,selflimit,selfhdc,paw_dmft,filapp)
1656 :
1657 : !Arguments ------------------------------------
1658 : type(self_type), intent(inout) :: self
1659 : type(matlu_type), intent(in) :: selfhdc(self%hdc%natom),selflimit(self%hdc%natom)
1660 : type(paw_dmft_type), intent(in) :: paw_dmft
1661 : character(len=fnlen), intent(in) :: filapp
1662 : !Local variables-------------------------------
1663 : integer :: iatom,ifreq,im,im1,ispinor,ispinor1,isppol,jfreq
1664 : integer :: lpawu,myproc,natom,ndim,nspinor,nsppol,unt
1665 : character(len=2) :: tag_im,tag_im1
1666 : character(len=4) :: tag_at
1667 : character(len=50) :: tag_is
1668 : character(len=500) :: message
1669 : ! *********************************************************************
1670 :
1671 : !delta = 0.0000000
1672 :
1673 4 : myproc = paw_dmft%myproc
1674 4 : natom = self%hdc%natom
1675 4 : nspinor = self%hdc%nspinor
1676 4 : nsppol = self%hdc%nsppol
1677 :
1678 : !ABI_MALLOC(selftemp_imag,(self%nw))
1679 :
1680 4 : write(message,'(2a,i4)') ch10,' ------ High-frequency limit of the Self-Energy'
1681 4 : call wrtout(std_out,message,'COLL')
1682 :
1683 4 : call print_matlu(selflimit(:),natom,3)
1684 :
1685 : !print norms
1686 4 : write(message,'(2a,i4)') ch10,' ------ Double counting'
1687 4 : call wrtout(std_out,message,'COLL')
1688 :
1689 4 : call print_matlu(selfhdc(:),natom,3)
1690 :
1691 : ! Compute limit of Real Part and put in double counting energy.
1692 : ! call copy_matlu(selfhdc,self%hdc%matlu,natom)
1693 : !!write(6,*) "selfhdc kramerskronig",selfhdc(1)%mat(1,1,1,1,1)
1694 : !write(6,*) "selfr%hdc kramerskronig",self%hdc%matlu(1)%mat(1,1,1,1,1)
1695 :
1696 12004 : do ifreq=1,self%nw
1697 12000 : if (self%distrib%procf(ifreq) /= myproc) cycle
1698 9000000 : do jfreq=1,self%nw-1
1699 8997000 : if (jfreq == ifreq) cycle
1700 17991002 : do iatom=1,natom
1701 8994001 : lpawu = selfhdc(iatom)%lpawu
1702 8994001 : if (lpawu == -1) cycle
1703 : self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = self%oper(ifreq)%matlu(iatom)%mat(:,:,:) - &
1704 : & cmplx(aimag(self%oper(jfreq)%matlu(iatom)%mat(:,:,:)) / (self%omega(ifreq)-self%omega(jfreq)) &
1705 296805032 : & * (self%omega(jfreq+1)-self%omega(jfreq)),zero,kind=dp)
1706 : end do ! iatom
1707 : end do ! jfreq
1708 6004 : do iatom=1,natom
1709 3000 : lpawu = selfhdc(iatom)%lpawu
1710 3000 : if (lpawu == -1) cycle
1711 : self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = cmplx(dble(self%oper(ifreq)%matlu(iatom)%mat(:,:,:))/pi,&
1712 108000 : & aimag(self%oper(ifreq)%matlu(iatom)%mat(:,:,:)),kind=dp) + selflimit(iatom)%mat(:,:,:)
1713 : ! write(6,*) "TWO FACTOR IS PUT BECAUSE OF MAXENT CODE ??"
1714 : !self%oper(ifreq)%matlu(iatom)%mat(:,:,:) = self%oper(ifreq)%matlu(iatom)%mat(:,:,:) * half
1715 : ! & aimag(self%oper(ifreq)%matlu(iatom)%mat(:,:,:)),kind=dp) * half
1716 : end do ! iatom
1717 : end do ! ifreq
1718 :
1719 4 : call gather_oper(self%oper(:),self%distrib,paw_dmft,opt_ksloc=2)
1720 :
1721 4 : if (myproc == 0) then
1722 :
1723 1 : unt = get_unit()
1724 1 : open(unit=unt,file=trim(filapp)//"_DFTDMFT_Self_realaxis.dat",status='unknown',form='formatted')
1725 1 : rewind(unt)
1726 1 : write(unt,'(4a)') "# Self-energy on the real axis, with the real part computed using Kramers-Kronig relations.",ch10, &
1727 2 : "# Real Frequency (Ha.) Real part Imaginary part",ch10
1728 1 : tag_is = ""
1729 2 : do iatom=1,natom
1730 1 : lpawu = selfhdc(iatom)%lpawu
1731 1 : if (lpawu == -1) cycle
1732 1 : write(tag_at,'(i4)') iatom
1733 1 : ndim = 2*lpawu + 1
1734 3 : do isppol=1,nsppol
1735 1 : if (nsppol == 2) tag_is = trim(adjustl(" for spin " // merge("up ","down",isppol==1))) // "and"
1736 3 : do ispinor=1,nspinor
1737 3 : do ispinor1=1,nspinor
1738 7 : do im=1,ndim
1739 5 : write(tag_im,'(i2)') im + (ispinor-1)*ndim
1740 31 : do im1=1,ndim
1741 25 : write(tag_im1,'(i2)') im1 + (ispinor1-1)*ndim
1742 25 : write(unt,'(9a)') "## Sigma_{",trim(adjustl(tag_im)),",",trim(adjustl(tag_im1)),"}",trim(adjustl(tag_is))," for atom ",trim(adjustl(tag_at)),ch10
1743 75025 : do ifreq=1,self%nw
1744 75000 : write(unt,'(2x,393(es24.16e3,2x))') self%omega(ifreq),&
1745 75000 : & dble(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)), &
1746 150025 : & aimag(self%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol))
1747 : end do ! ifreq
1748 30 : write(unt,*)
1749 : end do ! im1
1750 : end do ! im
1751 : end do ! ispinor1
1752 : end do ! ispinor
1753 : end do ! isppol
1754 : end do ! iatom
1755 :
1756 1 : close(unt)
1757 :
1758 : end if ! master node
1759 :
1760 : !do iatom=1,natom
1761 : ! lpawu = self%oper(1)%matlu(iatom)%lpawu
1762 : ! if (lpawu == -1) cycle
1763 : ! ndim = 2*lpawu + 1
1764 : ! do isppol=1,nsppol
1765 : ! do ispinor=1,nspinor
1766 : ! do ispinor1=1,nspinor
1767 : ! do im=1,ndim
1768 : ! do im1=1,ndim
1769 : !write(6,*)
1770 : !"realpart",real(selflimit(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
1771 : ! do ifreq=1,self%nw
1772 : ! selftemp_re(ifreq)=zero
1773 : ! selftemp_imag(ifreq)=aimag(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
1774 : ! do jfreq=1,self%nw-1
1775 : ! if(jfreq==ifreq) cycle
1776 : ! selftemp_re(ifreq)=selftemp_re(ifreq) - &
1777 : ! &
1778 : ! aimag(self%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)) &
1779 : ! & *(self%omega(ifreq)-self%omega(jfreq)) &
1780 : ! & /((self%omega(ifreq)-self%omega(jfreq))**2+delta**2)&
1781 : ! & *(self%omega(jfreq+1)-self%omega(jfreq))
1782 : ! selftemp_re(ifreq)=selftemp_re(ifreq) - &
1783 : !&
1784 : !aimag(self%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)) &
1785 : !& /(self%omega(ifreq)-self%omega(jfreq)) *
1786 : !(self%omega(jfreq+1)-self%omega(jfreq))
1787 : ! enddo
1788 : ! selftemp_re(ifreq)=selftemp_re(ifreq)/pi
1789 : !write(671,*)
1790 : !self%omega(ifreq),selftemp_re(ifreq),selftemp_imag(ifreq)
1791 : ! enddo
1792 : ! TEST*************************
1793 : ! do ifreq=1,self%nw
1794 : ! selftemp_imag(ifreq)=zero
1795 : ! do jfreq=1,self%nw-1
1796 : ! if(jfreq==ifreq) cycle
1797 : !! selftemp_re(ifreq)=selftemp_re(ifreq) - &
1798 : !! &
1799 : !aimag(self%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)) &
1800 : !! & *(self%omega(ifreq)-self%omega(jfreq)) &
1801 : !! & /((self%omega(ifreq)-self%omega(jfreq))**2+delta**2)&
1802 : !! & *(self%omega(jfreq+1)-self%omega(jfreq))
1803 : ! selftemp_imag(ifreq)=selftemp_imag(ifreq) + &
1804 : ! & selftemp_re(jfreq) &
1805 : ! & /(self%omega(ifreq)-self%omega(jfreq)) *
1806 : ! (self%omega(jfreq+1)-self%omega(jfreq))
1807 : ! enddo
1808 : ! selftemp_imag(ifreq)=selftemp_imag(ifreq)/pi
1809 : ! write(672,*)
1810 : ! self%omega(ifreq),selftemp_re(ifreq),selftemp_imag(ifreq)
1811 : ! enddo
1812 : ! TEST*************************
1813 : ! write(6,*) "TWO FACTOR IS PUT BECAUSE OF MAXENT CODE ??"
1814 : ! do ifreq=1,self%nw
1815 : ! write(68,*)
1816 : ! self%omega(ifreq),selftemp_re(ifreq),selftemp_imag(ifreq)
1817 : ! selftemp_re(ifreq)=selftemp_re(ifreq)+ &
1818 : !& real(selflimit(iatom)%mat(im,im1,isppol,ispinor,ispinor1)- &
1819 : !& selfhdc(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
1820 : ! self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
1821 : ! &
1822 : ! =cmplx(selftemp_re(ifreq),selftemp_imag(ifreq),kind=dp)/two
1823 : !& =cmplx(0.d0,selftemp_imag(ifreq),kind=dp)/two
1824 : ! & =cmplx(selftemp_re(ifreq),0.d0,kind=dp)/two
1825 : ! self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
1826 : !& =cmplx(selftemp_re(ifreq),0.d0,kind=dp)/two
1827 : !& =cmplx(0.d0,0.d0,kind=dp)/two
1828 : ! The factor two is here to compensate for the factor two in OmegaMaxent..
1829 : ! & =cmplx(selftemp_re(ifreq),0.0,kind=dp)
1830 : ! write(67,*)
1831 : ! self%omega(ifreq),real(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))&
1832 : ! ,aimag(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
1833 : ! enddo
1834 : ! write(67,*)
1835 : !write(68,*)
1836 : !!!!!!!!!! Z renormalization
1837 : ! i0=389
1838 : ! slope=(selftemp_re(i0+1)-selftemp_re(i0))/&
1839 : ! (self%omega(i0+1)-self%omega(i0))
1840 : ! y0= selftemp_re(i0)
1841 : ! do ifreq=1,self%nw
1842 : ! selftemp_re(ifreq)=slope * (self%omega(ifreq)-self%omega(i0))
1843 : ! + y0
1844 : ! selftemp_imag(ifreq)=zero
1845 : ! self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)&
1846 : ! &
1847 : ! =cmplx(selftemp_re(ifreq),selftemp_imag(ifreq),kind=dp)/two
1848 : ! write(6777,*)
1849 : ! self%omega(ifreq),real(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)),aimag(self%oper(ifreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
1850 : ! enddo
1851 : !!!!!!!!!!
1852 : ! enddo
1853 : ! enddo
1854 : ! enddo
1855 : ! enddo
1856 : ! enddo ! isppol
1857 : ! end do ! iatom
1858 :
1859 4 : end subroutine kramerskronig_self
1860 : !!***
1861 :
1862 : !!****f* m_self/selfreal2imag_self
1863 : !! NAME
1864 : !! selfreal2imag_self
1865 : !!
1866 : !! FUNCTION
1867 : !! Print self on imaginary axis from real axis
1868 : !!
1869 : !! INPUTS
1870 : !! selfr = self on real axis
1871 : !! self = self on imaginary axis
1872 : !! filapp = name of the filename
1873 : !! paw_dmft <type(paw_dmft_type)>= paw+dmft related data
1874 : !!
1875 : !! OUTPUT
1876 : !! self%qmc_shift in self <type(self_type)> = Self-energy
1877 : !!
1878 : !! SOURCE
1879 :
1880 4 : subroutine selfreal2imag_self(selfr,self,filapp,paw_dmft)
1881 :
1882 : !Arguments ------------------------------------
1883 : !type
1884 : type(self_type), intent(in) :: selfr,self
1885 : character(len=fnlen), intent(in) :: filapp
1886 : type(paw_dmft_type), intent(in) :: paw_dmft
1887 : !Local variables-------------------------------
1888 : integer :: iatom,ifreq,im,im1,ispinor,ispinor1,isppol,jfreq
1889 : integer :: lpawu,myproc,natom,ndim,nspinor,nsppol,unt
1890 : logical :: triqs
1891 : complex(dp) :: omega
1892 : !real(dp) :: delta
1893 4 : type(self_type) :: selftempmatsub
1894 : character(len=2) :: tag_im,tag_im1
1895 : character(len=4) :: tag_at
1896 : character(len=50) :: tag_is
1897 4 : type(matlu_type), allocatable :: matlu_tmp(:)
1898 : ! *********************************************************************
1899 :
1900 : !delta=0.0000000
1901 4 : call initialize_self(selftempmatsub,paw_dmft)
1902 :
1903 4 : myproc = paw_dmft%myproc
1904 4 : natom = self%hdc%natom
1905 4 : nspinor = self%hdc%nspinor
1906 4 : nsppol = self%hdc%nsppol
1907 : ! Compute limit of Real Part and put in double counting energy.
1908 : ! call copy_matlu(selfhdc,self%hdc%matlu,natom)
1909 : !write(6,*) "self3",aimag(selfr%oper(489)%matlu(1)%mat(1,1,1,1,1))
1910 :
1911 4 : triqs = (paw_dmft%dmft_solv == 6 .or. paw_dmft%dmft_solv == 7)
1912 :
1913 4 : if (triqs) then
1914 0 : ABI_MALLOC(matlu_tmp,(natom))
1915 0 : call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),matlu_tmp(:))
1916 : end if ! triqs
1917 :
1918 4996 : do ifreq=1,self%nw
1919 4992 : if (self%distrib%procf(ifreq) /= myproc) cycle
1920 1248 : omega = cmplx(zero,self%omega(ifreq),kind=dp)
1921 3744000 : do jfreq=1,selfr%nw-1
1922 7486752 : do iatom=1,natom
1923 3742752 : lpawu = paw_dmft%lpawu(iatom)
1924 3742752 : if (lpawu == -1) cycle
1925 : selftempmatsub%oper(ifreq)%matlu(iatom)%mat(:,:,:) = selftempmatsub%oper(ifreq)%matlu(iatom)%mat(:,:,:) - &
1926 : & aimag(selfr%oper(jfreq)%matlu(iatom)%mat(:,:,:)) / &
1927 123510816 : & (omega-selfr%omega(jfreq)) * (selfr%omega(jfreq+1)-selfr%omega(jfreq))
1928 : end do ! iatom
1929 : end do ! jfreq
1930 1248 : call fac_matlu(selftempmatsub%oper(ifreq)%matlu(:),natom,cone/pi)
1931 1252 : if (triqs) then ! add the missing high-frequency moment when using TRIQS
1932 0 : call add_matlu(selftempmatsub%oper(ifreq)%matlu(:),self%moments(1)%matlu(:),matlu_tmp(:),natom,1)
1933 0 : call copy_matlu(matlu_tmp(:),selftempmatsub%oper(ifreq)%matlu(:),natom)
1934 : end if ! triqs
1935 : end do ! ifreq
1936 :
1937 4 : if (triqs) then
1938 0 : call destroy_matlu(matlu_tmp(:),natom)
1939 0 : ABI_FREE(matlu_tmp)
1940 : end if ! triqs
1941 :
1942 4 : call gather_oper(selftempmatsub%oper(:),self%distrib,paw_dmft,opt_ksloc=2)
1943 :
1944 4 : if (myproc == 0) then
1945 1 : unt = get_unit()
1946 1 : open(unit=unt,file=trim(filapp)//"_DFTDMFT_Self_backtransform.dat",status='unknown',form='formatted')
1947 1 : write(unt,'(6a)') "# Hilbert transform of the analytically continued self-energy. To be compared with the actual",ch10, &
1948 2 : & "# self-energy on the imaginary axis in the cubic basis.",ch10,"# Matsubara Frequency (Ha.) Real part Imaginary part",ch10
1949 1 : tag_is = ""
1950 2 : do iatom=1,natom
1951 1 : lpawu = self%hdc%matlu(iatom)%lpawu
1952 1 : if (lpawu == -1) cycle
1953 1 : write(tag_at,'(i4)') iatom
1954 1 : ndim = 2*lpawu + 1
1955 3 : do isppol=1,nsppol
1956 1 : if (nsppol == 2) tag_is = trim(adjustl(" for spin " // merge("up ","down",isppol==1))) // "and"
1957 3 : do ispinor=1,nspinor
1958 3 : do ispinor1=1,nspinor
1959 7 : do im=1,ndim
1960 5 : write(tag_im,'(i2)') im + (ispinor-1)*ndim
1961 31 : do im1=1,ndim
1962 25 : write(tag_im1,'(i2)') im1 + (ispinor1-1)*ndim
1963 : !do jfreq=1,selfr%nw-1
1964 : ! write(6700,*) selfr%omega(jfreq),aimag(selfr%oper(jfreq)%matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))
1965 : !enddo
1966 : ! write(6700,*)
1967 25 : write(unt,'(9a)') "## Sigma_{",trim(adjustl(tag_im)),",",trim(adjustl(tag_im1)),"}",trim(adjustl(tag_is))," for atom ",trim(adjustl(tag_at)),ch10
1968 31225 : do ifreq=1,self%nw
1969 31200 : write(unt,'(2x,393(es24.16e3,2x))') self%omega(ifreq),&
1970 31200 : & dble(selftempmatsub%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
1971 62425 : & aimag(selftempmatsub%oper(ifreq)%matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol))
1972 : end do ! ifreq
1973 30 : write(unt,*)
1974 : end do ! im1
1975 : end do ! im
1976 : end do ! ispinor1
1977 : end do ! ispinor
1978 : end do ! isppol
1979 : end do ! iatom
1980 1 : close(unt)
1981 : end if ! master node
1982 :
1983 4 : call destroy_self(selftempmatsub)
1984 :
1985 4 : end subroutine selfreal2imag_self
1986 : !!***
1987 :
1988 0 : END MODULE m_self
1989 : !!***
|