Branch data Line data Source code
1 : : !!****m* ABINIT/m_gwls_ComputeCorrelationEnergy
2 : : !! NAME
3 : : !! m_gwls_ComputeCorrelationEnergy
4 : : !!
5 : : !! FUNCTION
6 : : !! .
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2009-2026 ABINIT group (JLJ, BR, MC)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : module m_gwls_ComputeCorrelationEnergy
23 : :
24 : : ! local modules
25 : : use m_gwls_utility
26 : : use m_gwls_wf
27 : : use m_gwls_hamiltonian
28 : : use m_gwls_lineqsolver
29 : : use m_gwls_polarisability
30 : : use m_gwls_model_polarisability
31 : : use m_gwls_DielectricArray
32 : : use m_gwls_ComputePoles
33 : : use m_gwls_Projected_AT
34 : : use m_gwls_Projected_BT
35 : : use m_gwls_GWlanczos
36 : : use m_gwls_GenerateEpsilon
37 : : use m_gwls_GWanalyticPart
38 : : use m_gwls_TimingLog
39 : : use m_gwls_LanczosBasis
40 : :
41 : : ! abinit modules
42 : : use defs_basis
43 : : use defs_wvltypes
44 : : use m_abicore
45 : : use m_xmpi
46 : : use m_pawang
47 : : use m_errors
48 : : use m_dtset
49 : :
50 : : use m_time, only : timab
51 : : use m_io_tools, only : get_unit, open_file
52 : :
53 : :
54 : : implicit none
55 : : save
56 : : private
57 : : !!***
58 : :
59 : : !!***
60 : : public :: compute_correlations_shift_lanczos
61 : : public :: compute_correlations_no_model_shift_lanczos
62 : : !!***
63 : : contains
64 : :
65 : : !!****f* m_gwls_ComputeCorrelationEnergy/compute_correlations_shift_lanczos
66 : : !! NAME
67 : : !! compute_correlations_shift_lanczos
68 : : !!
69 : : !! FUNCTION
70 : : !! .
71 : : !!
72 : : !! INPUTS
73 : : !!
74 : : !! OUTPUT
75 : : !!
76 : : !! SOURCE
77 : :
78 : 6 : subroutine compute_correlations_shift_lanczos(dtset, Sigma_x,Vxc_energy,debug)
79 : : !----------------------------------------------------------------------------------------------------
80 : : !
81 : : !
82 : : ! This function computes the correlation energy Sigma_c(w) for the state we wish to correct.
83 : : ! The shift lanczos algorithm is used.
84 : : !
85 : : !----------------------------------------------------------------------------------------------------
86 : :
87 : : type(dataset_type),intent(in) :: dtset
88 : :
89 : : real(dp),intent(in) :: Sigma_x,Vxc_energy
90 : : logical, intent(in) :: debug
91 : :
92 : :
93 : : !Local variables
94 : :
95 : : integer :: n_ext_freq
96 : :
97 : : integer :: npt_gauss
98 : : integer :: print_debug
99 : :
100 : :
101 : : integer :: kmax_poles
102 : : integer :: kmax_model
103 : : integer :: lmax_model
104 : :
105 : :
106 : : integer :: kmax_analytic
107 : : integer :: kmax_numeric
108 : :
109 : : real(dp) :: omega_static
110 : :
111 : : real(dp) :: lorentzian
112 : : integer :: iw_ext
113 : : integer :: iw
114 : :
115 : 6 : real(dp) , allocatable :: psie_k(:,:)
116 : :
117 : :
118 : 6 : real(dp), allocatable :: epsilon_eigenvalues_0(:)
119 : 6 : real(dp), allocatable :: epsilon_model_eigenvalues_0(:)
120 : :
121 : :
122 : 6 : complex(dp), allocatable :: AT_Lanczos(:,:)
123 : 6 : complex(dp), allocatable :: AT_model_Lanczos(:,:)
124 : :
125 : :
126 : : ! To use lanczos instead of sqmr
127 : 6 : complex(dp), allocatable :: Lbasis_diagonalize_dielectric_terms(:,:)
128 : 6 : complex(dp), allocatable :: hermitian_static_eps_m1_minus_eps_model_m1(:,:)
129 : 6 : real(dp), allocatable :: eigenvalues_static_eps_m1_minus_eps_model_m1(:)
130 : 6 : real(dp), allocatable :: eigenvalues_static_eps_model_m1_minus_one(:)
131 : 6 : complex(dp), allocatable :: work(:)
132 : 6 : real(dp), allocatable :: rwork(:)
133 : : integer :: lwork
134 : : integer :: info
135 : : integer :: l
136 : :
137 : :
138 : : integer :: debug_unit
139 : : character(50) :: debug_filename
140 : :
141 : : real(dp) :: time1, time2, time
142 : : real(dp) :: total_time1,total_time2,total_time
143 : : real(dp) :: setup_time1, setup_time2, setup_time
144 : : real(dp) :: freq_time1, freq_time2, freq_time
145 : :
146 : : integer :: nfrequencies
147 : 6 : real(dp),allocatable :: list_projection_frequencies(:)
148 : :
149 : 6 : complex(dp), allocatable :: array_integrand_exact_sector(:,:)
150 : 6 : complex(dp), allocatable :: array_integrand_model_sector(:,:)
151 : 6 : complex(dp), allocatable :: tmp_dielectric_array(:,:,:)
152 : :
153 : : real(dp) :: external_omega
154 : :
155 : : character(256) :: timing_string
156 : :
157 : : integer :: recy_line_size
158 : : character(128) :: recy_name
159 : : logical :: local_tmp_exist
160 : : logical :: use_model
161 : :
162 : : ! Energy contributions
163 : :
164 : : real(dp) :: pole_energy
165 : :
166 : : real(dp) :: sigma_A_Lanczos
167 : : real(dp) :: sigma_A_model_Lanczos
168 : : real(dp) :: sigma_B_Lanczos
169 : : real(dp) :: sigma_B_model_Lanczos
170 : :
171 : : real(dp) :: correlations
172 : : real(dp) :: renormalized_energy
173 : :
174 : : real(dp) :: second_model_parameter
175 : :
176 : : real(dp):: tsec(2)
177 : : integer :: GWLS_TIMAB, OPTION_TIMAB
178 : : character(500) :: msg
179 : :
180 : : ! *************************************************************************
181 : :
182 : : !--------------------------------------------------------------------------------
183 : : !
184 : : ! Set up variables and allocate arrays
185 : : !
186 : : !--------------------------------------------------------------------------------
187 : :
188 : 6 : call cpu_time(total_time1)
189 : : !Variable allocation and initialization
190 : 6 : model_number = dtset%gwls_diel_model
191 : 6 : model_parameter = dtset%gwls_model_parameter
192 : 6 : npt_gauss = dtset%gwls_npt_gauss_quad
193 : 6 : print_debug = dtset%gwls_print_debug
194 : :
195 : 6 : first_seed = dtset%gwls_first_seed
196 : 6 : e = dtset%gwls_band_index
197 : :
198 : :
199 : : !second_model_parameter = dtset%gwls_second_model_parameter
200 : 6 : second_model_parameter = zero
201 : :
202 : :
203 : :
204 : : ! set variables from gwls_GenerateEpsilon module
205 : 6 : kmax = dtset%gwls_stern_kmax
206 : 6 : nseeds = dtset%gwls_nseeds
207 : :
208 : 6 : kmax_model = dtset%gwls_kmax_complement
209 : 6 : kmax_poles = dtset%gwls_kmax_poles
210 : 6 : kmax_analytic = dtset%gwls_kmax_analytic
211 : 6 : kmax_numeric = dtset%gwls_kmax_numeric
212 : :
213 : 6 : n_ext_freq = dtset%gw_customnfreqsp
214 : :
215 : 6 : use_model = .True.
216 : :
217 : 6 : call cpu_time(setup_time1)
218 : :
219 : : !--------------------------------------------------------------------------------
220 : : !
221 : : ! Extract the frequencies at which the integrand will be evaluated
222 : : ! add the value zero in the set.
223 : : !
224 : : !--------------------------------------------------------------------------------
225 : :
226 : 6 : call generate_frequencies_and_weights(npt_gauss)
227 : :
228 : : !--------------------------------------------------------------------------------
229 : : !
230 : : !
231 : : ! Compute the static bases for the exact and model
232 : : ! dielectric operator
233 : : !
234 : : !
235 : : !--------------------------------------------------------------------------------
236 : :
237 : 6 : omega_static = zero
238 : : ! define dimensions
239 : 6 : lmax = nseeds*kmax
240 : 6 : lmax_model = nseeds*kmax_model
241 : :
242 : : ! Allocate arrays which will contain basis
243 : 6 : call setup_Lanczos_basis(lmax,lmax_model)
244 : :
245 : : ! allocate eigenvalues array
246 [ - + + - : 18 : ABI_MALLOC(epsilon_eigenvalues_0, (lmax))
+ - + - -
+ - + ]
247 [ - + + - : 18 : ABI_MALLOC(epsilon_model_eigenvalues_0, (lmax_model))
+ - + - -
+ - + ]
248 : :
249 : : ! set omega=0 for exact dielectric operator
250 [ + + ]: 18 : call set_dielectric_function_frequency([0.0_dp,omega_static])
251 : :
252 : : ! and make note that the Sternheimer solutions must be kept (for use in the projected Sternheimer section).
253 [ + + ]: 6 : if(dtset%gwls_recycle == 1) then
254 [ - + + - : 20 : ABI_MALLOC(Sternheimer_solutions_zero,(2,npw_k,lmax,nbandv))
- + + - -
+ + - + -
+ - - + -
+ - + ]
255 [ + + + + : 24820 : Sternheimer_solutions_zero = zero
+ + + + ]
256 : 4 : write_solution = .true.
257 : : end if
258 [ + + ]: 6 : if(dtset%gwls_recycle == 2) then
259 : 2 : write(recy_name,'(A,I0.4,A)') "Recycling_",mpi_enreg%me,".dat"
260 : :
261 : 2 : inquire(iolength=recy_line_size) cg(:,1:npw_k)
262 : :
263 : 2 : inquire(file='local_tmp', exist=local_tmp_exist)
264 [ - + ]: 2 : if(local_tmp_exist) recy_name = 'local_tmp/' // recy_name(1:118)
265 : :
266 [ - + ]: 2 : if (open_file(file=recy_name,iomsg=msg,newunit=recy_unit,access='direct',form='unformatted',&
267 : : & status='replace',recl=recy_line_size)/=0) then
268 : 0 : ABI_ERROR(msg)
269 : : end if
270 : :
271 : 2 : write_solution = .true.
272 : : end if
273 : :
274 : 6 : call cpu_time(time1)
275 : : ! Compute the Lanczos basis using Block Lanczos; store
276 : : ! basis in Lbasis_lanczos
277 : 6 : GWLS_TIMAB = 1504
278 : 6 : OPTION_TIMAB = 1
279 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
280 : :
281 : : call driver_generate_dielectric_matrix( matrix_function_epsilon_k, &
282 : : nseeds, kmax, &
283 : : epsilon_eigenvalues_0, &
284 : 6 : Lbasis_lanczos, debug)
285 : 6 : OPTION_TIMAB = 2
286 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
287 : :
288 : 6 : call cpu_time(time2)
289 : 6 : time = time2-time1
290 : :
291 : 6 : write(timing_string,'(A)') "Time to compute the EXACT Static Dielectric Matrix : "
292 : 6 : call write_timing_log(timing_string,time)
293 : :
294 : :
295 : 6 : call output_epsilon_eigenvalues(lmax,epsilon_eigenvalues_0,1)
296 : :
297 : :
298 : : ! The Sternheimer solutions at $\omega = 0$ have been stored.
299 : 6 : write_solution = .false.
300 : :
301 : :
302 : : ! Prepare the model dielectric operator
303 : 6 : call setup_Pk_model(omega_static,second_model_parameter)
304 : :
305 : 6 : call cpu_time(time1)
306 : : ! Compute the Lanczos basis of the model operator using Block Lanczos; store
307 : : ! basis in Lbasis_model_lanczos
308 : 6 : GWLS_TIMAB = 1505
309 : 6 : OPTION_TIMAB = 1
310 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
311 : :
312 : : call driver_generate_dielectric_matrix(matrix_function_epsilon_model_operator, &
313 : : nseeds, kmax_model, &
314 : : epsilon_model_eigenvalues_0, &
315 : 6 : Lbasis_model_lanczos, debug)
316 : 6 : OPTION_TIMAB = 2
317 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
318 : :
319 : 6 : call cpu_time(time2)
320 : 6 : time = time2-time1
321 : :
322 : 6 : write(timing_string,'(A)') "Time to compute the MODEL Static Dielectric Matrix : "
323 : 6 : call write_timing_log(timing_string,time)
324 : :
325 : :
326 : 6 : call output_epsilon_eigenvalues(lmax_model,epsilon_model_eigenvalues_0,2)
327 : :
328 : :
329 [ - + + - : 12 : ABI_MALLOC(eigenvalues_static_eps_model_m1_minus_one, (lmax_model))
- + - + ]
330 : :
331 [ + + ]: 54 : do l = 1, lmax_model
332 : 54 : eigenvalues_static_eps_model_m1_minus_one(l) = one/epsilon_model_eigenvalues_0(l)-one
333 : : end do
334 : :
335 : :
336 : :
337 : : !--------------------------------------------------------------------------------
338 : : !
339 : : !
340 : : ! Prepare and compute the projection of the dielectric Sternheimer equations
341 : : !
342 : : !
343 : : !--------------------------------------------------------------------------------
344 : :
345 : : ! Setup various arrays necessary for the Sternheimer projection scheme
346 : 6 : nfrequencies = dtset%gwls_n_proj_freq
347 [ + - - - : 18 : ABI_MALLOC(list_projection_frequencies,(nfrequencies))
+ - - + -
+ - + ]
348 : :
349 [ + - - + : 12 : list_projection_frequencies = dtset%gwls_list_proj_freq
- - - - -
+ ]
350 : :
351 : 6 : call cpu_time(time1)
352 : 6 : GWLS_TIMAB = 1507
353 : 6 : OPTION_TIMAB = 1
354 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
355 : :
356 : : !call setup_projected_Sternheimer_epsilon(lmax, npt_gauss, second_model_parameter, &
357 : : ! list_projection_frequencies,nfrequencies,debug)
358 : :
359 : :
360 : : call ProjectedSternheimerEpsilon(lmax, npt_gauss, second_model_parameter, &
361 : : list_projection_frequencies,nfrequencies,&
362 : 6 : epsilon_eigenvalues_0,debug,use_model)
363 : :
364 : :
365 : :
366 : :
367 : : ! The Sternheimer solutions at $\omega = 0$ have been used to make the basis for the projected Sternheimer equations.
368 [ + + ]: 6 : if(dtset%gwls_recycle == 1) then
369 [ - + ]: 4 : ABI_FREE(Sternheimer_solutions_zero)
370 : : end if
371 [ + + ]: 6 : if(dtset%gwls_recycle == 2) then
372 : 2 : close(recy_unit,status='delete')
373 : : end if
374 : :
375 : 6 : OPTION_TIMAB = 2
376 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
377 : :
378 : :
379 : 6 : call cpu_time(time2)
380 : 6 : time = time2-time1
381 : 6 : write(timing_string,'(A)') "Time to setup and compute the projected Sternheimer epsilon : "
382 : 6 : call write_timing_log(timing_string,time)
383 : :
384 : :
385 : 6 : call cpu_time(time1)
386 : :
387 : 6 : GWLS_TIMAB = 1508
388 : 6 : OPTION_TIMAB = 1
389 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
390 : :
391 : 6 : call compute_eps_m1_minus_eps_model_m1(lmax, npt_gauss)
392 : :
393 : 6 : OPTION_TIMAB = 2
394 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
395 : :
396 : 6 : call cpu_time(time2)
397 : 6 : time = time2-time1
398 : 6 : write(timing_string,'(A)') "Time to compute eps^{-1}-eps_model^{-1} : "
399 : 6 : call write_timing_log(timing_string,time)
400 : :
401 : :
402 : : !--------------------------------------------------------------------------------
403 : : !
404 : : !
405 : : ! Compute the model dielectric array
406 : : !
407 : : !
408 : : !--------------------------------------------------------------------------------
409 : :
410 : 6 : call cpu_time(time1)
411 : :
412 : 6 : GWLS_TIMAB = 1509
413 : 6 : OPTION_TIMAB = 1
414 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
415 : :
416 : 6 : call compute_eps_model_m1_minus_one(lmax_model, npt_gauss, second_model_parameter, epsilon_model_eigenvalues_0)
417 : :
418 : 6 : OPTION_TIMAB = 2
419 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
420 [ - + ]: 6 : ABI_FREE(epsilon_model_eigenvalues_0)
421 : :
422 : :
423 : 6 : call cpu_time(time2)
424 : 6 : time = time2-time1
425 : 6 : write(timing_string,'(A)') "Time to compute eps_model^{-1}-1 : "
426 : 6 : call write_timing_log(timing_string,time)
427 : :
428 : :
429 : : !--------------------------------------------------------------------------------
430 : : !
431 : : !
432 : : ! We no longer need the Lanczos basis in its current form!
433 : : ! Modify the basis so that it now contains (V^1/2.L)^*.psie
434 : : !
435 : : !
436 : : !--------------------------------------------------------------------------------
437 : :
438 : 6 : call cpu_time(time1)
439 [ - + + - : 18 : ABI_MALLOC(psie_k, (2,npw_k))
+ - + - -
+ - + ]
440 : :
441 : 6 : GWLS_TIMAB = 1510
442 : 6 : OPTION_TIMAB = 1
443 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
444 : :
445 : :
446 [ + - + - : 2325 : psie_k = cg(:,(e-1)*npw_k+1:e*npw_k)
- + - - +
+ + + ]
447 : :
448 : 6 : call modify_Lbasis_Coulomb(psie_k, lmax, lmax_model)
449 : :
450 [ - + ]: 6 : ABI_FREE(psie_k)
451 : :
452 : 6 : OPTION_TIMAB = 2
453 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
454 : :
455 : :
456 : 6 : call cpu_time(time2)
457 : 6 : time = time2-time1
458 : 6 : write(timing_string,'(A)') "Time to modify the Lanczos basis : "
459 : 6 : call write_timing_log(timing_string,time)
460 : :
461 : : !--------------------------------------------------------------------------------
462 : : !
463 : : !
464 : : !
465 : : ! Diagonalize the static array eps^{-1} - eps^{-1}_model in order to
466 : : ! be able to apply diagonal shift Lanczos.
467 : : !
468 : : !--------------------------------------------------------------------------------
469 : :
470 : 6 : call cpu_time(time1)
471 : : ! diagonalize the static eps^{-1} - eps^{-1}_model array, so as the use the diagonal Lanczos procedure
472 : : ! for the analytical term
473 : 6 : GWLS_TIMAB = 1511
474 : 6 : OPTION_TIMAB = 1
475 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
476 : :
477 [ - + + - : 24 : ABI_MALLOC(Lbasis_diagonalize_dielectric_terms, (npw_k,lmax))
- + + - +
- + - - +
- + ]
478 [ - + + - : 24 : ABI_MALLOC(hermitian_static_eps_m1_minus_eps_model_m1, (lmax,lmax))
- + + - +
- + - - +
- + ]
479 : :
480 [ - + + - : 18 : ABI_MALLOC(eigenvalues_static_eps_m1_minus_eps_model_m1, (lmax))
+ - + - -
+ - + ]
481 : :
482 [ + - - + : 18 : ABI_MALLOC(rwork, (3*lmax-2))
+ - + - +
- - + -
+ ]
483 : :
484 : :
485 [ + + + + ]: 438 : hermitian_static_eps_m1_minus_eps_model_m1(:,:) = eps_m1_minus_eps_model_m1(:,:,1)
486 : :
487 : :
488 : :
489 : : ! WORK QUERRY
490 : 6 : lwork = -1
491 [ - + ]: 6 : ABI_MALLOC(work, (1))
492 : : call ZHEEV( 'V', & ! Compute eigenvectors and eigenvalues
493 : : 'U', & ! use Upper triangular part
494 : : lmax, & ! order of matrix
495 : : hermitian_static_eps_m1_minus_eps_model_m1, & ! initial matrix on input; eigenvectors on output
496 : : lmax, & ! LDA
497 : : eigenvalues_static_eps_m1_minus_eps_model_m1,& ! eigenvalues
498 : 6 : work, lwork, rwork, info ) ! work stuff
499 : :
500 [ - + ]: 6 : if ( info /= 0) then
501 : 0 : debug_unit = get_unit()
502 : 0 : write(debug_filename,'(A,I4.4,A)') 'LAPACK_DEBUG_PROC=',mpi_enreg%me,'.log'
503 : :
504 : 0 : open(debug_unit,file=trim(debug_filename),status='unknown')
505 : :
506 : 0 : write(debug_unit,'(A)') '*********************************************************************************************'
507 : 0 : write(debug_unit,'(A,I4,A)') '* ERROR: info = ',info,' in ZHEEV (1), gwls_ComputeCorrelationEnergy'
508 : 0 : write(debug_unit,'(A)') '*********************************************************************************************'
509 : :
510 : 0 : close(debug_unit)
511 : :
512 : : end if
513 : :
514 : : ! COMPUTATION
515 : 6 : lwork = nint(dble(work(1)))
516 : 6 : ABI_FREE(work)
517 [ - + + - : 18 : ABI_MALLOC(work, (lwork))
+ - + - -
+ - + ]
518 : : call ZHEEV( 'V', & ! Compute eigenvectors and eigenvalues
519 : : 'U', & ! use Upper triangular part
520 : : lmax, & ! order of matrix
521 : : hermitian_static_eps_m1_minus_eps_model_m1, & ! initial matrix on input; eigenvectors on output
522 : : lmax, & ! LDA
523 : : eigenvalues_static_eps_m1_minus_eps_model_m1,& ! eigenvalues
524 : 6 : work, lwork, rwork, info ) ! work stuff
525 : :
526 [ - + ]: 6 : if ( info /= 0) then
527 : 0 : debug_unit = get_unit()
528 : 0 : write(debug_filename,'(A,I4.4,A)') 'LAPACK_DEBUG_PROC=',mpi_enreg%me,'.log'
529 : :
530 : 0 : open(debug_unit,file=trim(debug_filename),status='unknown')
531 : :
532 : 0 : write(debug_unit,'(A)') '*********************************************************************************************'
533 : 0 : write(debug_unit,'(A,I4,A)') '* ERROR: info = ',info,' in ZHEEV (2), gwls_ComputeCorrelationEnergy'
534 : 0 : write(debug_unit,'(A)') '*********************************************************************************************'
535 : :
536 : 0 : close(debug_unit)
537 : :
538 : : end if
539 : :
540 : :
541 : :
542 [ - + ]: 6 : ABI_FREE(work)
543 [ - + ]: 6 : ABI_FREE(rwork)
544 : :
545 : : !--------------------------------------------------------------------------------
546 : : !
547 : : ! update basis: L' = L . Q
548 : : !
549 : : !
550 : : ! CAREFUL!!! We must multiply by conjg(hermitian_static_eps_m1_minus_eps_model_m1),
551 : : ! which is the COMPLEX CONJUGATE of the eigenvectors of the matrix
552 : : ! eps^{-1}-eps_m^{-1}, because we have MODIFIED the basis Lbasis_lanczos
553 : : ! to contain the complex conjugate of the eigenvectors of eps.
554 : : ! This is somewhat subtle, but forgetting to do this leads to small errors
555 : : ! in the results...
556 : : !--------------------------------------------------------------------------------
557 [ + + + + ]: 438 : hermitian_static_eps_m1_minus_eps_model_m1 = conjg(hermitian_static_eps_m1_minus_eps_model_m1)
558 : :
559 : : call ZGEMM('N','N',npw_k,lmax,lmax,cmplx_1,Lbasis_lanczos,npw_k, &
560 : : hermitian_static_eps_m1_minus_eps_model_m1, &
561 : 6 : lmax,cmplx_0,Lbasis_diagonalize_dielectric_terms,npw_k)
562 : :
563 : :
564 : 6 : OPTION_TIMAB = 2
565 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
566 : :
567 : :
568 : 6 : call cpu_time(time2)
569 : 6 : time = time2-time1
570 : 6 : write(timing_string,'(A)') "Time to diagonalize eps^{-1}(0)-eps^{-1}(0)_model : "
571 : 6 : call write_timing_log(timing_string,time)
572 : :
573 [ - + ]: 6 : ABI_FREE(hermitian_static_eps_m1_minus_eps_model_m1)
574 : :
575 : :
576 : 6 : call cpu_time(setup_time2)
577 : 6 : setup_time = setup_time2 - setup_time1
578 : :
579 : 6 : write(timing_string,'(A)') " TOTAL DIELECTRIC SETUP TIME : "
580 : 6 : call write_timing_log(timing_string,setup_time)
581 : :
582 : : !--------------------------------------------------------------------------------
583 : : !
584 : : ! Compute the Analytic energy using Shift Lanczos
585 : : !
586 : : !--------------------------------------------------------------------------------
587 : :
588 : 6 : call cpu_time(time1)
589 : :
590 : 6 : GWLS_TIMAB = 1512
591 : 6 : OPTION_TIMAB = 1
592 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
593 : :
594 : :
595 [ - + + - : 24 : ABI_MALLOC(AT_Lanczos,(n_ext_freq,lmax))
- + + - +
- + - - +
- + ]
596 : : call compute_AT_shift_Lanczos(n_ext_freq,dtset%gw_freqsp, model_parameter, lmax, Lbasis_diagonalize_dielectric_terms,&
597 : 6 : & kmax_analytic, AT_Lanczos)
598 : :
599 : 6 : OPTION_TIMAB = 2
600 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
601 : :
602 : :
603 [ - + ]: 6 : ABI_FREE(Lbasis_diagonalize_dielectric_terms)
604 : :
605 : 6 : call cpu_time(time2)
606 : 6 : time = time2 - time1
607 : :
608 : 6 : write(timing_string,'(A)') "Time to compute analytical term by SHIFT LANCZOS : "
609 : 6 : call write_timing_log(timing_string,time)
610 : :
611 : :
612 : 6 : call cpu_time(time1)
613 : :
614 : 6 : GWLS_TIMAB = 1513
615 : 6 : OPTION_TIMAB = 1
616 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
617 : :
618 [ - + + - : 24 : ABI_MALLOC(AT_model_Lanczos,(n_ext_freq,lmax_model))
- + + - +
- + - - +
- + ]
619 : : call compute_AT_shift_Lanczos(n_ext_freq,dtset%gw_freqsp, model_parameter, lmax_model, &
620 : 6 : Lbasis_model_lanczos, kmax_analytic, AT_model_Lanczos)
621 : :
622 : 6 : OPTION_TIMAB = 2
623 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
624 : :
625 : 6 : call cpu_time(time2)
626 : 6 : time = time2 - time1
627 : :
628 : 6 : write(timing_string,'(A)') "Time to compute analytical MODEL by SHIFT LANCZOS : "
629 : 6 : call write_timing_log(timing_string,time)
630 : :
631 : :
632 : : !--------------------------------------------------------------------------------
633 : : !
634 : : ! Compute the Numeric energy using Shift Lanczos
635 : : !
636 : : !--------------------------------------------------------------------------------
637 : :
638 : 6 : call cpu_time(time1)
639 : :
640 [ + - - + : 24 : ABI_MALLOC(array_integrand_exact_sector,(npt_gauss+1,n_ext_freq))
+ - - + +
- + - + -
- + - + ]
641 : :
642 [ - + + - : 30 : ABI_MALLOC( tmp_dielectric_array, (lmax,lmax,npt_gauss+1))
- + + - -
+ + - + -
+ - - + -
+ ]
643 : :
644 [ + + ]: 72 : do iw = 1, npt_gauss + 1
645 : :
646 : 66 : lorentzian = model_parameter**2/(list_omega(iw)**2+model_parameter**2)
647 [ + + + + ]: 4824 : tmp_dielectric_array(:,:,iw) = eps_m1_minus_eps_model_m1(:,:,iw)-lorentzian*eps_m1_minus_eps_model_m1(:,:,1)
648 : :
649 : : end do
650 : 6 : GWLS_TIMAB = 1514
651 : 6 : OPTION_TIMAB = 1
652 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
653 : :
654 : : call compute_projected_BT_shift_Lanczos(n_ext_freq, dtset%gw_freqsp, lmax, Lbasis_lanczos, &
655 : 6 : kmax_numeric, npt_gauss, tmp_dielectric_array, array_integrand_exact_sector )
656 : :
657 : 6 : OPTION_TIMAB = 2
658 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
659 : :
660 [ - + ]: 6 : ABI_FREE( tmp_dielectric_array)
661 : 6 : call cpu_time(time2)
662 : 6 : time = time2 - time1
663 : 6 : write(timing_string,'(A)') "Time to compute numerical term by SHIFT LANCZOS : "
664 : 6 : call write_timing_log(timing_string,time)
665 : :
666 : :
667 : :
668 : 6 : call cpu_time(time1)
669 : :
670 [ - + + - : 18 : ABI_MALLOC(array_integrand_model_sector,(npt_gauss+1,n_ext_freq))
- + + - -
+ - + ]
671 : :
672 : : !ABI_MALLOC( tmp_dielectric_array, (lmax_model,lmax_model,npt_gauss+1))
673 [ - + + - : 30 : ABI_MALLOC( tmp_dielectric_array, (lmax_model,blocksize_epsilon,npt_gauss+1))
- + + - -
+ + - + -
+ - - + -
+ ]
674 : :
675 : :
676 [ + + ]: 72 : do iw = 1, npt_gauss + 1
677 : :
678 : 66 : lorentzian = model_parameter**2/(list_omega(iw)**2+model_parameter**2)
679 : : !tmp_dielectric_array(:,:,iw) = eps_model_m1_minus_one(:,:,iw)-lorentzian*eps_model_m1_minus_one(:,:,1)
680 [ + + + + ]: 2448 : tmp_dielectric_array(:,:,iw) = eps_model_m1_minus_one_DISTR(:,:,iw)-lorentzian*eps_model_m1_minus_one_DISTR(:,:,1)
681 : :
682 : : end do
683 : :
684 : 6 : GWLS_TIMAB = 1515
685 : 6 : OPTION_TIMAB = 1
686 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
687 : :
688 : : !call compute_projected_BT_shift_Lanczos(n_ext_freq , dtset%gw_freqsp, lmax_model, Lbasis_model_lanczos, &
689 : : ! kmax_numeric, npt_gauss, tmp_dielectric_array, array_integrand_model_sector )
690 : :
691 : :
692 : : call compute_projected_BT_shift_Lanczos_DISTRIBUTED(n_ext_freq, dtset%gw_freqsp, lmax_model, blocksize_epsilon, &
693 : : model_lanczos_vector_belongs_to_this_node, model_lanczos_vector_index, &
694 : : Lbasis_model_lanczos, kmax_numeric, npt_gauss, tmp_dielectric_array, &
695 : 6 : array_integrand_model_sector )
696 : :
697 : 6 : OPTION_TIMAB = 2
698 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
699 : :
700 [ - + ]: 6 : ABI_FREE(tmp_dielectric_array)
701 : 6 : call cpu_time(time2)
702 : 6 : time = time2 - time1
703 : 6 : write(timing_string,'(A)') "Time to compute numerical model SHIFT LANCZOS : "
704 : 6 : call write_timing_log(timing_string,time)
705 : :
706 : :
707 : : !--------------------------------------------------------------------------------
708 : : !
709 : : ! set up arrays for poles
710 : : !
711 : : !--------------------------------------------------------------------------------
712 : :
713 : :
714 : :
715 : : !call generate_degeneracy_table_for_poles(debug) ! so we can compute Poles contributions
716 : 6 : call generate_degeneracy_table_for_poles(.true.) ! so we can compute Poles contributions
717 : :
718 : : !--------------------------------------------------------------------------------
719 : : !
720 : : ! Print contributions to sigma_A_Lanczos to a file
721 : : !
722 : : !--------------------------------------------------------------------------------
723 : 6 : call output_Sigma_A_by_eigenvalues(n_ext_freq,lmax,dtset%gw_freqsp,AT_Lanczos,eigenvalues_static_eps_m1_minus_eps_model_m1,2)
724 : : call output_Sigma_A_by_eigenvalues(n_ext_freq,lmax_model,dtset%gw_freqsp,AT_model_Lanczos,&
725 : 6 : & eigenvalues_static_eps_model_m1_minus_one,3)
726 : :
727 : : !epsilon_eigenvalues_0
728 : :
729 [ - + ]: 6 : ABI_FREE(epsilon_eigenvalues_0)
730 : : !--------------------------------------------------------------------------------
731 : : !
732 : : ! Iterate on external frequencies
733 : : !
734 : : !--------------------------------------------------------------------------------
735 : :
736 : :
737 [ + + ]: 12 : do iw_ext = 1, dtset%gw_customnfreqsp
738 : :
739 : 6 : call cpu_time(freq_time1)
740 : 6 : external_omega = dtset%gw_freqsp(iw_ext)
741 : :
742 : 6 : write(timing_string,'(A)') "#"
743 : 6 : call write_text_block_in_Timing_log(timing_string)
744 : 6 : write(timing_string,'(A)') "#"
745 : 6 : call write_text_block_in_Timing_log(timing_string)
746 : 6 : write(timing_string,'(A,I4,A,F8.4,A)') "# Frequency # ",iw_ext," omega = ",external_omega," Ha"
747 : 6 : call write_text_block_in_Timing_log(timing_string)
748 : 6 : write(timing_string,'(A)') "#"
749 : 6 : call write_text_block_in_Timing_log(timing_string)
750 : 6 : write(timing_string,'(A)') "#"
751 : 6 : call write_text_block_in_Timing_log(timing_string)
752 : :
753 : :
754 : : !--------------------------------------------------------------------------------
755 : : !
756 : : ! compute the pole term
757 : : ! CAREFUL! The real valence states must still be allocated
758 : : ! for the dielectric operator to work properly
759 : : !
760 : : !--------------------------------------------------------------------------------
761 : :
762 : 6 : call cpu_time(time1)
763 : 6 : GWLS_TIMAB = 1516
764 : 6 : OPTION_TIMAB = 1
765 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
766 : :
767 : 6 : pole_energy = compute_Poles(external_omega,kmax_poles,debug)
768 : :
769 : 6 : OPTION_TIMAB = 2
770 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
771 : :
772 : 6 : call cpu_time(time2)
773 : :
774 : 6 : time = time2-time1
775 : 6 : write(timing_string,'(A)') "Time to compute the Poles contribution : "
776 : 6 : call write_timing_log(timing_string,time)
777 : :
778 : :
779 : :
780 : : !================================================================================
781 : : ! Compute the contributions from the analytic term
782 : : !================================================================================
783 : 6 : GWLS_TIMAB = 1517
784 : 6 : OPTION_TIMAB = 1
785 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
786 : :
787 : :
788 : 6 : call cpu_time(time1)
789 : :
790 [ + + ]: 54 : sigma_A_Lanczos = dble(sum(AT_Lanczos(iw_ext,:)*eigenvalues_static_eps_m1_minus_eps_model_m1(:)))
791 : :
792 : 6 : call cpu_time(time2)
793 : 6 : time = time2-time1
794 : 6 : write(timing_string,'(A)') "Time Tr[(eps^{-1}-eps_model^{-1}).AT] AFTER SHIFT : "
795 : 6 : call write_timing_log(timing_string,time)
796 : :
797 : :
798 : 6 : call cpu_time(time1)
799 : :
800 [ + + ]: 54 : sigma_A_model_Lanczos= dble(sum(AT_model_Lanczos(iw_ext,:)*eigenvalues_static_eps_model_m1_minus_one(:)))
801 : :
802 : 6 : call cpu_time(time2)
803 : 6 : time = time2-time1
804 : 6 : write(timing_string,'(A)') "Time for Tr[ (eps_model^{-1}-1) . AT ] AFTER SHIFT : "
805 : 6 : call write_timing_log(timing_string,time)
806 : :
807 : 6 : OPTION_TIMAB = 2
808 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
809 : : !--------------------------------------------------------------------------------
810 : : !
811 : : ! compute integrand
812 : : !
813 : : !--------------------------------------------------------------------------------
814 : 6 : GWLS_TIMAB = 1518
815 : 6 : OPTION_TIMAB = 1
816 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
817 : :
818 : : call compute_integrands_shift_lanczos(iw_ext, n_ext_freq, npt_gauss, array_integrand_exact_sector, &
819 : 6 : array_integrand_model_sector, sigma_B_Lanczos, sigma_B_model_Lanczos)
820 : :
821 : 6 : OPTION_TIMAB = 2
822 : 6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
823 : :
824 : : !--------------------------------------------------------------------------------
825 : : !
826 : : ! Output results
827 : : !
828 : : !--------------------------------------------------------------------------------
829 : :
830 : :
831 : : call output_results(iw_ext,npt_gauss, lmax,lmax_model, model_parameter, second_model_parameter, &
832 : : external_omega, Sigma_x,Vxc_energy,pole_energy, &
833 : 6 : sigma_A_Lanczos,sigma_A_model_Lanczos,sigma_B_Lanczos,sigma_B_model_Lanczos)
834 : :
835 : :
836 : 6 : call cpu_time(freq_time2)
837 : 6 : freq_time = freq_time2-freq_time1
838 : :
839 : 6 : write(timing_string,'(A)') " TOTAL FREQUENCY TIME : "
840 : 6 : call write_timing_log(timing_string,freq_time)
841 : :
842 : :
843 : :
844 : 6 : correlations = pole_energy+sigma_A_Lanczos+sigma_A_model_Lanczos+sigma_B_Lanczos+sigma_B_model_Lanczos
845 : :
846 : 6 : renormalized_energy = eig(e) + Sigma_x-Vxc_energy +correlations
847 : 6 : write(std_out,10) ' '
848 : 6 : write(std_out,14) ' For omega : ',external_omega ,' Ha = ',external_omega *Ha_eV,' eV'
849 : 6 : write(std_out,14) ' <psi_e | Sigma_c | psi_e>: ',correlations ,' Ha = ',correlations *Ha_eV,' eV'
850 : 6 : write(std_out,14) ' eps_e + <Sigma_xc - V_xc> : ',renormalized_energy,' Ha = ',renormalized_energy*Ha_eV,' eV'
851 : :
852 : 6 : write(ab_out,10) ' '
853 : 6 : write(ab_out,14) ' For omega : ',external_omega ,' Ha = ',external_omega *Ha_eV,' eV'
854 : 6 : write(ab_out,14) ' <psi_e | Sigma_c | psi_e>: ',correlations ,' Ha = ',correlations *Ha_eV,' eV'
855 : 18 : write(ab_out,14) ' eps_e + <Sigma_xc - V_xc> : ',renormalized_energy,' Ha = ',renormalized_energy*Ha_eV,' eV'
856 : :
857 : :
858 : : end do
859 : :
860 [ - + ]: 6 : ABI_FREE(AT_Lanczos)
861 [ - + ]: 6 : ABI_FREE(AT_model_Lanczos)
862 [ - + ]: 6 : ABI_FREE(array_integrand_exact_sector)
863 [ - + ]: 6 : ABI_FREE(array_integrand_model_sector)
864 [ - + ]: 6 : ABI_FREE(eigenvalues_static_eps_model_m1_minus_one)
865 [ - + ]: 6 : ABI_FREE(eigenvalues_static_eps_m1_minus_eps_model_m1)
866 : 6 : call clean_degeneracy_table_for_poles()
867 : 6 : call cleanup_Pk_model()
868 : 6 : call cleanup_Lanczos_basis()
869 : 6 : call cleanup_projected_Sternheimer_epsilon()
870 : :
871 : 6 : call cpu_time(total_time2)
872 : 6 : total_time = total_time2-total_time1
873 : 6 : write(timing_string,'(A)') " TOTAL TIME : "
874 : 6 : call write_timing_log(timing_string,total_time)
875 : :
876 : :
877 : : 10 format(A)
878 : : 14 format(A,ES24.16,A,F16.8,A)
879 : :
880 [ + - ]: 6 : end subroutine compute_correlations_shift_lanczos
881 : : !!***
882 : :
883 : : !!****f* m_gwls_ComputeCorrelationEnergy/compute_correlations_no_model_shift_lanczos
884 : : !! NAME
885 : : !! compute_correlations_no_model_shift_lanczos
886 : : !!
887 : : !! FUNCTION
888 : : !! .
889 : : !!
890 : : !! INPUTS
891 : : !!
892 : : !! OUTPUT
893 : : !!
894 : : !! SOURCE
895 : :
896 : 1 : subroutine compute_correlations_no_model_shift_lanczos(dtset, Sigma_x,Vxc_energy,debug)
897 : : !----------------------------------------------------------------------------------------------------
898 : : !
899 : : !
900 : : ! This function computes the correlation energy Sigma_c(w) for the state we wish to correct.
901 : : !
902 : : ! this subroutine does not rely on the use of a model dielectric operator. Thus
903 : : !
904 : : ! Sigma^A(w) = Tr[ (eps^{-1}(0)-1). A^T(w)]
905 : : ! Sigma^N(w) = int dw' Tr[{(eps^{-1}(w')-1)-f(w')(eps^{-1}(0)-1)}B^T(w';w)]
906 : : !
907 : : ! Shift lanczos is used for the resolvents.
908 : : !----------------------------------------------------------------------------------------------------
909 : :
910 : : type(dataset_type),intent(in) :: dtset
911 : :
912 : : real(dp),intent(in) :: Sigma_x, Vxc_energy
913 : : logical, intent(in) :: debug
914 : :
915 : :
916 : : !Local variables
917 : :
918 : : real(dp):: Sigma_x_Lanczos_projected
919 : : integer :: npt_gauss
920 : : integer :: print_debug
921 : :
922 : :
923 : : integer :: kmax_poles
924 : :
925 : : integer :: lmax_model
926 : :
927 : : integer :: kmax_analytic
928 : : integer :: kmax_numeric
929 : : integer :: n_ext_freq
930 : :
931 : :
932 : : real(dp) :: omega_static
933 : :
934 : : real(dp) :: lorentzian
935 : : integer :: iw_ext
936 : : integer :: iw
937 : :
938 : :
939 : :
940 : 1 : real(dp) , allocatable :: psie_k(:,:)
941 : :
942 : 1 : real(dp), allocatable :: epsilon_eigenvalues_0(:)
943 : :
944 : :
945 : 1 : complex(dp), allocatable :: AT_Lanczos(:,:)
946 : :
947 : :
948 : :
949 : : real(dp) :: time1, time2, time
950 : : real(dp) :: total_time1,total_time2,total_time
951 : : real(dp) :: setup_time1, setup_time2, setup_time
952 : : real(dp) :: freq_time1, freq_time2, freq_time
953 : :
954 : : integer :: nfrequencies
955 : 1 : real(dp),allocatable :: list_projection_frequencies(:)
956 : :
957 : :
958 : :
959 : 1 : complex(dp), allocatable :: array_integrand_exact_sector(:,:)
960 : 1 : complex(dp), allocatable :: array_integrand_model_sector(:,:)
961 : 1 : complex(dp), allocatable :: tmp_dielectric_array(:,:,:)
962 : :
963 : : real(dp) :: external_omega
964 : :
965 : : character(256) :: timing_string
966 : :
967 : : integer :: recy_line_size
968 : : character(128) :: recy_name
969 : : logical :: local_tmp_exist
970 : : character(500) :: msg
971 : :
972 : : ! Energy contributions
973 : :
974 : : real(dp) :: pole_energy
975 : :
976 : : real(dp) :: sigma_A_Lanczos
977 : : real(dp) :: sigma_A_model_Lanczos
978 : : real(dp) :: sigma_B_Lanczos
979 : : real(dp) :: sigma_B_model_Lanczos
980 : :
981 : : real(dp) :: correlations
982 : : real(dp) :: renormalized_energy
983 : :
984 : : logical :: use_model
985 : :
986 : : ! *************************************************************************
987 : :
988 : :
989 : : !--------------------------------------------------------------------------------
990 : : !
991 : : ! Set up variables and allocate arrays
992 : : !
993 : : !--------------------------------------------------------------------------------
994 : :
995 : : !Variable allocation and initialization
996 : 1 : model_number = dtset%gwls_diel_model
997 : 1 : model_parameter = dtset%gwls_model_parameter
998 : 1 : npt_gauss = dtset%gwls_npt_gauss_quad
999 : 1 : print_debug = dtset%gwls_print_debug
1000 : :
1001 : 1 : first_seed = dtset%gwls_first_seed
1002 : 1 : e = dtset%gwls_band_index
1003 : :
1004 : :
1005 : : ! set variables from gwls_GenerateEpsilon module
1006 : 1 : kmax = dtset%gwls_stern_kmax
1007 : 1 : nseeds = dtset%gwls_nseeds
1008 : :
1009 : 1 : kmax_poles = dtset%gwls_kmax_poles
1010 : :
1011 : : kmax_poles = dtset%gwls_kmax_poles
1012 : 1 : kmax_analytic = dtset%gwls_kmax_analytic
1013 : 1 : kmax_numeric = dtset%gwls_kmax_numeric
1014 : :
1015 : 1 : n_ext_freq = dtset%gw_customnfreqsp
1016 : :
1017 : :
1018 : 1 : use_model = .False.
1019 : :
1020 : :
1021 : 1 : call cpu_time(setup_time1)
1022 : : !--------------------------------------------------------------------------------
1023 : : !
1024 : : ! Extract the frequencies at which the integrand will be evaluated
1025 : : ! add the value zero in the set.
1026 : : !
1027 : : !--------------------------------------------------------------------------------
1028 : :
1029 : 1 : call generate_frequencies_and_weights(npt_gauss)
1030 : :
1031 : : !--------------------------------------------------------------------------------
1032 : : !
1033 : : !
1034 : : ! Compute the static bases for the exact dielectric operator
1035 : : !
1036 : : !
1037 : : !--------------------------------------------------------------------------------
1038 : :
1039 : :
1040 : 1 : omega_static = zero
1041 : : ! define dimensions
1042 : 1 : lmax = nseeds*kmax
1043 : :
1044 : : ! Allocate arrays which will contain basis
1045 : : ! the 0 indicates we will not use arrays for the model dielectric operator
1046 : 1 : call setup_Lanczos_basis(lmax,0)
1047 : :
1048 : : ! allocate eigenvalues array
1049 [ - + + - : 3 : ABI_MALLOC(epsilon_eigenvalues_0, (lmax))
+ - + - -
+ - + ]
1050 : :
1051 : : ! set omega=0 for exact dielectric operator
1052 [ + + ]: 3 : call set_dielectric_function_frequency([0.0_dp,omega_static])
1053 : :
1054 : : ! and make note that the Sternheimer solutions must be kept (for use in the projected Sternheimer section).
1055 [ - + ]: 1 : if(dtset%gwls_recycle == 1) then
1056 [ # # # # : 0 : ABI_MALLOC(Sternheimer_solutions_zero,(2,npw_k,lmax,nbandv))
# # # # #
# # # # #
# # # # #
# # # ]
1057 [ # # # # : 0 : Sternheimer_solutions_zero = zero
# # # # ]
1058 : 0 : write_solution = .true.
1059 : : end if
1060 [ + - ]: 1 : if(dtset%gwls_recycle == 2) then
1061 : 1 : write(recy_name,'(A,I0.4,A)') "Recycling_",mpi_enreg%me,".dat"
1062 : :
1063 : 1 : inquire(iolength=recy_line_size) cg(:,1:npw_k)
1064 : :
1065 : 1 : inquire(file='local_tmp', exist=local_tmp_exist)
1066 [ - + ]: 1 : if(local_tmp_exist) recy_name = 'local_tmp/' // recy_name(1:118)
1067 : :
1068 [ - + ]: 1 : if (open_file(file=recy_name,iomsg=msg,newunit=recy_unit,access='direct',form='unformatted',&
1069 : : & status='replace',recl=recy_line_size)/=0) then
1070 : 0 : ABI_ERROR(msg)
1071 : : end if
1072 : :
1073 : 1 : write_solution = .true.
1074 : : end if
1075 : :
1076 : :
1077 : 1 : call cpu_time(time1)
1078 : : ! Compute the Lanczos basis using Block Lanczos; store
1079 : : ! basis in Lbasis_lanczos
1080 : : call driver_generate_dielectric_matrix( matrix_function_epsilon_k, &
1081 : : nseeds, kmax, &
1082 : : epsilon_eigenvalues_0, &
1083 : 1 : Lbasis_lanczos, debug)
1084 : 1 : call cpu_time(time2)
1085 : 1 : time = time2-time1
1086 : :
1087 : 1 : write(timing_string,'(A)') "Time to compute the EXACT Static Dielectric Matrix : "
1088 : 1 : call write_timing_log(timing_string,time)
1089 : :
1090 : : ! The Sternheimer solutions at $\omega = 0$ have been stored.
1091 : 1 : write_solution = .false.
1092 : :
1093 : :
1094 : 1 : call output_epsilon_eigenvalues(lmax,epsilon_eigenvalues_0,1)
1095 : :
1096 : :
1097 : : ! compute the Exchange energy, when it is projected on the Lanczos basis
1098 : : ! CAREFUL! This must be done BEFORE we modify the lanczos basis
1099 : 1 : Sigma_x_Lanczos_projected = exchange(e, Lbasis_lanczos)
1100 : :
1101 : :
1102 : :
1103 : : !--------------------------------------------------------------------------------
1104 : : !
1105 : : !
1106 : : ! Prepare and compute the projection of the dielectric Sternheimer equations
1107 : : !
1108 : : !
1109 : : !--------------------------------------------------------------------------------
1110 : :
1111 : : ! Setup various arrays necessary for the Sternheimer projection scheme
1112 : 1 : nfrequencies = dtset%gwls_n_proj_freq
1113 [ + - - - : 3 : ABI_MALLOC(list_projection_frequencies,(nfrequencies))
+ - - + -
+ - + ]
1114 : :
1115 [ + - - + : 2 : list_projection_frequencies = dtset%gwls_list_proj_freq
- - - - -
+ ]
1116 : :
1117 : 1 : call cpu_time(time1)
1118 : : ! The explicit "false" as the last argument is for the optional
1119 : : ! variable "use_model"; we are not using a model here!
1120 : :
1121 : : !call setup_projected_Sternheimer_epsilon(lmax, npt_gauss, zero, &
1122 : : ! list_projection_frequencies,nfrequencies,debug,.false.)
1123 : :
1124 : :
1125 : : call ProjectedSternheimerEpsilon(lmax, npt_gauss, zero, &
1126 : : list_projection_frequencies,nfrequencies,&
1127 : 1 : epsilon_eigenvalues_0,debug,use_model)
1128 : :
1129 : :
1130 : :
1131 : : !call cpu_time(time2)
1132 : : !time = time2-time1
1133 : : !write(timing_string,'(A)') "Time to setup the projected Sternheimer epsilon : "
1134 : : !call write_timing_log(timing_string,time)
1135 : :
1136 : :
1137 : : ! The Sternheimer solutions at $\omega = 0$ have been used to make the basis for the projected Sternheimer equations.
1138 [ - + ]: 1 : if(dtset%gwls_recycle == 1) then
1139 [ # # ]: 0 : ABI_FREE(Sternheimer_solutions_zero)
1140 : : end if
1141 [ + - ]: 1 : if(dtset%gwls_recycle == 2) then
1142 : 1 : close(recy_unit,status='delete')
1143 : : end if
1144 : :
1145 : :
1146 : : !call cpu_time(time1)
1147 : : !call compute_projected_Sternheimer_epsilon(lmax, npt_gauss, epsilon_eigenvalues_0,debug)
1148 : :
1149 : :
1150 : :
1151 : 1 : call cpu_time(time2)
1152 : :
1153 : 1 : time = time2-time1
1154 : 1 : write(timing_string,'(A)') "Time to compute the projected Sternheimer epsilon : "
1155 : 1 : call write_timing_log(timing_string,time)
1156 : :
1157 : :
1158 : :
1159 : 1 : call cpu_time(time1)
1160 : 1 : call compute_eps_m1_minus_one(lmax, npt_gauss)
1161 : 1 : call cpu_time(time2)
1162 : 1 : time = time2-time1
1163 : 1 : write(timing_string,'(A)') "Time to compute eps^{-1}-I : "
1164 : 1 : call write_timing_log(timing_string,time)
1165 : :
1166 : :
1167 : : !--------------------------------------------------------------------------------
1168 : : !
1169 : : !
1170 : : ! We no longer need the Lanczos basis in its current form!
1171 : : ! Modify the basis so that it now contains (V^{1/2}.l)
1172 : : !
1173 : : !
1174 : : !--------------------------------------------------------------------------------
1175 : :
1176 : 1 : call cpu_time(time1)
1177 [ - + + - : 3 : ABI_MALLOC(psie_k, (2,npw_k))
+ - + - -
+ - + ]
1178 [ + - + - : 773 : psie_k = cg(:,(e-1)*npw_k+1:e*npw_k)
- + - - +
+ + + ]
1179 : :
1180 : 1 : lmax_model = 0
1181 : 1 : call modify_Lbasis_Coulomb(psie_k, lmax, lmax_model) ! lmax_model is set to zero, such that
1182 : : ! the model lanczos basis (which doesn't exist
1183 : : ! in this case) will not be modified
1184 : :
1185 [ - + ]: 1 : ABI_FREE(psie_k)
1186 : :
1187 : 1 : call cpu_time(time2)
1188 : 1 : time = time2-time1
1189 : 1 : write(timing_string,'(A)') "Time to modify the Lanczos basis : "
1190 : 1 : call write_timing_log(timing_string,time)
1191 : :
1192 : :
1193 : 1 : call cpu_time(setup_time2)
1194 : 1 : setup_time = setup_time2 - setup_time1
1195 : :
1196 : 1 : write(timing_string,'(A)') " TOTAL DIELECTRIC SETUP TIME : "
1197 : 1 : call write_timing_log(timing_string,setup_time)
1198 : :
1199 : : !--------------------------------------------------------------------------------
1200 : : !
1201 : : ! Compute the Analytic energy using Shift Lanczos
1202 : : !
1203 : : !--------------------------------------------------------------------------------
1204 : :
1205 : 1 : call cpu_time(time1)
1206 : :
1207 [ - + + - : 4 : ABI_MALLOC(AT_Lanczos,(n_ext_freq,lmax))
- + + - +
- + - - +
- + ]
1208 : : ! Note that the array eps^{-1}(0) - 1 is diagonal in the lanczos basis already! No need to diagonalize, so we can
1209 : : ! use Lbasis_lanczos directly...
1210 : 1 : call compute_AT_shift_Lanczos(n_ext_freq,dtset%gw_freqsp, model_parameter, lmax, Lbasis_lanczos, kmax_analytic, AT_Lanczos)
1211 : :
1212 : 1 : call cpu_time(time2)
1213 : 1 : time = time2 - time1
1214 : :
1215 : 1 : write(timing_string,'(A)') "Time to compute analytical term by SHIFT LANCZOS : "
1216 : 1 : call write_timing_log(timing_string,time)
1217 : :
1218 : :
1219 : : !--------------------------------------------------------------------------------
1220 : : !
1221 : : ! Compute the Numeric energy using Shift Lanczos
1222 : : !
1223 : : !--------------------------------------------------------------------------------
1224 : :
1225 : 1 : call cpu_time(time1)
1226 : :
1227 [ + - - + : 4 : ABI_MALLOC(array_integrand_exact_sector,(npt_gauss+1,n_ext_freq))
+ - - + +
- + - + -
- + - + ]
1228 [ - + + - : 3 : ABI_MALLOC(array_integrand_model_sector,(npt_gauss+1,n_ext_freq))
- + + - -
+ - + ]
1229 : :
1230 : :
1231 [ - + + - : 5 : ABI_MALLOC( tmp_dielectric_array, (lmax,lmax,npt_gauss+1))
- + + - -
+ + - + -
+ - - + +
- ]
1232 : :
1233 [ + + ]: 12 : do iw = 1, npt_gauss + 1
1234 : :
1235 : 11 : lorentzian = model_parameter**2/(list_omega(iw)**2+model_parameter**2)
1236 [ + + + + ]: 804 : tmp_dielectric_array(:,:,iw) = eps_m1_minus_eps_model_m1(:,:,iw)-lorentzian*eps_m1_minus_eps_model_m1(:,:,1)
1237 : :
1238 : : end do
1239 : :
1240 : : call compute_projected_BT_shift_Lanczos(n_ext_freq, dtset%gw_freqsp, lmax, Lbasis_lanczos, &
1241 : 1 : kmax_numeric, npt_gauss, tmp_dielectric_array, array_integrand_exact_sector )
1242 : :
1243 [ + + + + ]: 13 : array_integrand_model_sector = zero ! just a dummy array in this case
1244 : :
1245 [ - + ]: 1 : ABI_FREE( tmp_dielectric_array)
1246 : 1 : call cpu_time(time2)
1247 : 1 : time = time2 - time1
1248 : 1 : write(timing_string,'(A)') "Time to compute numerical term by SHIFT LANCZOS : "
1249 : 1 : call write_timing_log(timing_string,time)
1250 : :
1251 : :
1252 : :
1253 : : !--------------------------------------------------------------------------------
1254 : : !
1255 : : ! set up arrays for poles
1256 : : !
1257 : : !--------------------------------------------------------------------------------
1258 : :
1259 : : !call generate_degeneracy_table_for_poles(debug) ! so we can compute Poles contributions
1260 : 1 : call generate_degeneracy_table_for_poles(.true.) ! so we can compute Poles contributions
1261 : :
1262 : : !--------------------------------------------------------------------------------
1263 : : !
1264 : : ! Print contributions to sigma_A_Lanczos to a file
1265 : : !
1266 : : !--------------------------------------------------------------------------------
1267 [ + - + + ]: 9 : call output_Sigma_A_by_eigenvalues(n_ext_freq,lmax,dtset%gw_freqsp,AT_Lanczos,one/epsilon_eigenvalues_0-one,1)
1268 : :
1269 : :
1270 : : !--------------------------------------------------------------------------------
1271 : : !
1272 : : ! Iterate on external frequencies
1273 : : !
1274 : : !--------------------------------------------------------------------------------
1275 : :
1276 : :
1277 [ + + ]: 2 : do iw_ext = 1, dtset%gw_customnfreqsp
1278 : :
1279 : 1 : call cpu_time(freq_time1)
1280 : 1 : external_omega = dtset%gw_freqsp(iw_ext)
1281 : :
1282 : 1 : write(timing_string,'(A)') "#"
1283 : 1 : call write_text_block_in_Timing_log(timing_string)
1284 : 1 : write(timing_string,'(A)') "#"
1285 : 1 : call write_text_block_in_Timing_log(timing_string)
1286 : 1 : write(timing_string,'(A,I4,A,F8.4,A)') "# Frequency # ",iw_ext," omega = ",external_omega," Ha"
1287 : 1 : call write_text_block_in_Timing_log(timing_string)
1288 : 1 : write(timing_string,'(A)') "#"
1289 : 1 : call write_text_block_in_Timing_log(timing_string)
1290 : 1 : write(timing_string,'(A)') "#"
1291 : 1 : call write_text_block_in_Timing_log(timing_string)
1292 : :
1293 : :
1294 : : !--------------------------------------------------------------------------------
1295 : : !
1296 : : ! compute the pole term
1297 : : ! CAREFUL! The real valence states must still be allocated
1298 : : ! for the dielectric operator to work properly
1299 : : !
1300 : : !--------------------------------------------------------------------------------
1301 : :
1302 : 1 : call cpu_time(time1)
1303 : :
1304 : 1 : pole_energy = compute_Poles(external_omega,kmax_poles,debug)
1305 : :
1306 : 1 : call cpu_time(time2)
1307 : :
1308 : 1 : time = time2-time1
1309 : 1 : write(timing_string,'(A)') "Time to compute the Poles contribution : "
1310 : 1 : call write_timing_log(timing_string,time)
1311 : :
1312 : : !================================================================================
1313 : : ! Compute the contributions from the analytic term
1314 : : !================================================================================
1315 : :
1316 : 1 : call cpu_time(time1)
1317 : :
1318 : :
1319 [ + + ]: 9 : sigma_A_Lanczos = dble(sum(AT_Lanczos(iw_ext,:)*(one/epsilon_eigenvalues_0(:)-one)))
1320 : :
1321 [ - + ]: 1 : ABI_FREE(epsilon_eigenvalues_0)
1322 : :
1323 : 1 : call cpu_time(time2)
1324 : 1 : time = time2-time1
1325 : 1 : write(timing_string,'(A)') "Time for Tr[ (eps_model^{-1}-1) . AT ] AFTER SHIFT : "
1326 : 1 : call write_timing_log(timing_string,time)
1327 : :
1328 : : !--------------------------------------------------------------------------------
1329 : : !
1330 : : ! compute integrand
1331 : : !
1332 : : !--------------------------------------------------------------------------------
1333 : :
1334 : :
1335 : : call compute_integrands_shift_lanczos(iw_ext, n_ext_freq, npt_gauss, array_integrand_exact_sector, &
1336 : 1 : array_integrand_model_sector, sigma_B_Lanczos, sigma_B_model_Lanczos)
1337 : :
1338 : :
1339 : :
1340 : : !--------------------------------------------------------------------------------
1341 : : !
1342 : : ! Output results
1343 : : !
1344 : : !--------------------------------------------------------------------------------
1345 : :
1346 : : ! just dummy variables so we can use the output_results routine
1347 : 1 : sigma_A_model_Lanczos = zero
1348 : 1 : sigma_B_model_Lanczos = zero
1349 : : call output_results(iw_ext,npt_gauss, lmax, lmax_model, model_parameter, zero, &
1350 : : external_omega, Sigma_x,Vxc_energy,pole_energy, &
1351 : : sigma_A_Lanczos,sigma_A_model_Lanczos,sigma_B_Lanczos,sigma_B_model_Lanczos, &
1352 : 1 : Sigma_x_Lanczos_projected )
1353 : :
1354 : :
1355 : 1 : call cpu_time(freq_time2)
1356 : 1 : freq_time = freq_time2-freq_time1
1357 : :
1358 : 1 : write(timing_string,'(A)') " TOTAL FREQUENCY TIME : "
1359 : 1 : call write_timing_log(timing_string,freq_time)
1360 : :
1361 : :
1362 : :
1363 : 1 : correlations = pole_energy+sigma_A_Lanczos+sigma_B_Lanczos
1364 : :
1365 : 1 : renormalized_energy = eig(e) + Sigma_x-Vxc_energy +correlations
1366 : 1 : write(std_out,10) ' '
1367 : 1 : write(std_out,14) ' For omega : ',external_omega ,' Ha = ',external_omega *Ha_eV,' eV'
1368 : 1 : write(std_out,14) ' <psi_e | Sigma_c | psi_e> : ',correlations ,' Ha = ',correlations *Ha_eV,' eV'
1369 : 1 : write(std_out,14) ' eps_e + <Sigma_xc - V_xc> : ',renormalized_energy,' Ha = ',renormalized_energy*Ha_eV,' eV'
1370 : :
1371 : 1 : write(ab_out,10) ' '
1372 : 1 : write(ab_out,14) ' For omega : ',external_omega ,' Ha = ',external_omega *Ha_eV,' eV'
1373 : 1 : write(ab_out,14) ' <psi_e | Sigma_c | psi_e>: ',correlations ,' Ha = ',correlations *Ha_eV,' eV'
1374 : 3 : write(ab_out,14) ' eps_e + <Sigma_xc - V_xc> : ',renormalized_energy,' Ha = ',renormalized_energy*Ha_eV,' eV'
1375 : :
1376 : :
1377 : :
1378 : : end do
1379 : :
1380 [ - + ]: 1 : ABI_FREE(AT_Lanczos)
1381 [ - + ]: 1 : ABI_FREE(array_integrand_exact_sector)
1382 [ - + ]: 1 : ABI_FREE(array_integrand_model_sector)
1383 : 1 : call clean_degeneracy_table_for_poles()
1384 : 1 : call cleanup_Pk_model()
1385 : 1 : call cleanup_Lanczos_basis()
1386 : 1 : call cleanup_projected_Sternheimer_epsilon()
1387 : :
1388 : 1 : call cpu_time(total_time2)
1389 : 1 : total_time1 = zero
1390 : 1 : total_time = total_time2-total_time1
1391 : 1 : write(timing_string,'(A)') " TOTAL TIME : "
1392 : 1 : call write_timing_log(timing_string,total_time)
1393 : :
1394 : :
1395 : :
1396 : : 10 format(A)
1397 : : 14 format(A,ES24.16,A,F16.8,A)
1398 : :
1399 [ + - - + ]: 1 : end subroutine compute_correlations_no_model_shift_lanczos
1400 : : !!***
1401 : :
1402 : : !!****f* m_gwls_ComputeCorrelationEnergy/compute_integrands_shift_lanczos
1403 : : !! NAME
1404 : : !! compute_integrands_shift_lanczos
1405 : : !!
1406 : : !! FUNCTION
1407 : : !! .
1408 : : !!
1409 : : !! INPUTS
1410 : : !!
1411 : : !! OUTPUT
1412 : : !!
1413 : : !! SOURCE
1414 : :
1415 : 7 : subroutine compute_integrands_shift_lanczos(iw_ext,n_ext_freq,npt_gauss, array_integrand_exact_sector, &
1416 : 7 : array_integrand_model_sector, sigma_B_Lanczos, sigma_B_model_Lanczos)
1417 : : !----------------------------------------------------------------------------------------------------
1418 : : !
1419 : : ! This subroutine computes the integrands, assuming data was generated by shift lanczos.
1420 : : !----------------------------------------------------------------------------------------------------
1421 : :
1422 : : integer, intent(in) :: iw_ext, npt_gauss, n_ext_freq
1423 : :
1424 : : complex(dp), intent(in) :: array_integrand_exact_sector(npt_gauss+1,n_ext_freq)
1425 : : complex(dp), intent(in) :: array_integrand_model_sector(npt_gauss+1,n_ext_freq)
1426 : :
1427 : : real(dp), intent(out) :: sigma_B_Lanczos, sigma_B_model_Lanczos
1428 : :
1429 : : real(dp) :: integrand_Lanczos , integrand_model_Lanczos
1430 : : real(dp) :: omega_prime
1431 : :
1432 : : integer :: iw
1433 : : integer :: io_unit
1434 : : character(256) :: title_string
1435 : : character(256) :: timing_string
1436 : :
1437 : :
1438 : : real(dp) :: time1, time2, time
1439 : :
1440 : : ! *************************************************************************
1441 : :
1442 : :
1443 [ + + ]: 7 : if (mpi_enreg%me == 0) then
1444 : 4 : io_unit = get_unit()
1445 : :
1446 [ + - ]: 4 : if (iw_ext < 10) then
1447 : 4 : write(title_string,'(A,I1,A)') 'APPROXIMATE_INTEGRANDS_',iw_ext,'.dat'
1448 [ # # ]: 0 : else if (iw_ext < 100) then
1449 : 0 : write(title_string,'(A,I2,A)') 'APPROXIMATE_INTEGRANDS_',iw_ext,'.dat'
1450 : : else
1451 : 0 : write(title_string,'(A,I3,A)') 'APPROXIMATE_INTEGRANDS_',iw_ext,'.dat'
1452 : : end if
1453 : :
1454 : 4 : open(file=title_string,status=files_status_new,unit=io_unit)
1455 : 4 : write(io_unit,10) '#-----------------------------------------------------------------------------------------------'
1456 : 4 : write(io_unit,10) '#'
1457 : 4 : write(io_unit,10) '# Approximate Integrands as a function of frequency'
1458 : 4 : write(io_unit,10) '#'
1459 : 4 : write(io_unit,10) '# I1 = Tr[ (eps^{-1}(iw) - eps_model^{-1}(iw)) - '
1460 : 4 : write(io_unit,10) '# f(w)(eps^{-1}(0) - eps_model^{-1}(0)) BT(w) ]'
1461 : 4 : write(io_unit,10) '#'
1462 : 4 : write(io_unit,10) '# I2 = Tr[ (eps_model^{-1}(iw) - 1) - f(w)(eps_model^{-1}(0)-1) BT(w)]'
1463 : 4 : write(io_unit,10) '# '
1464 : 4 : write(io_unit,10) '# DIAG[I] will represent the contribution coming from taking only the diagonal elements of'
1465 : 4 : write(io_unit,10) '# the arrays in the trace.'
1466 : 4 : write(io_unit,10) '#'
1467 : 4 : write(io_unit,10) '# omega (Ha) I1 I2 gaussian weight'
1468 : 4 : write(io_unit,10) '#-----------------------------------------------------------------------------------------------'
1469 : 4 : flush(io_unit)
1470 : : end if
1471 : :
1472 : 7 : call cpu_time(time1)
1473 : :
1474 : 7 : sigma_B_Lanczos = zero
1475 : 7 : sigma_B_model_Lanczos = zero
1476 : :
1477 [ + + ]: 84 : do iw = 1,npt_gauss+1
1478 : :
1479 : 77 : omega_prime = list_omega(iw)
1480 : :
1481 : 77 : integrand_Lanczos = dble(array_integrand_exact_sector(iw,iw_ext))
1482 : 77 : integrand_model_Lanczos = dble(array_integrand_model_sector(iw,iw_ext))
1483 : :
1484 : 77 : sigma_B_Lanczos = sigma_B_Lanczos + integrand_Lanczos*list_weights(iw)
1485 : 77 : sigma_B_model_Lanczos = sigma_B_model_Lanczos + integrand_model_Lanczos*list_weights(iw)
1486 : :
1487 : :
1488 : :
1489 [ + + ]: 84 : if (mpi_enreg%me == 0) write(io_unit,8) omega_prime, integrand_Lanczos , integrand_model_Lanczos, list_weights(iw)
1490 : :
1491 : :
1492 : :
1493 : : end do
1494 : 7 : call cpu_time(time2)
1495 : :
1496 [ + + ]: 7 : if (mpi_enreg%me == 0) then
1497 : 4 : write(io_unit,10) ''
1498 : 4 : write(io_unit,14) '# Value of the I1 integral: ',sigma_B_Lanczos ,' Ha'
1499 : 4 : write(io_unit,14) '# Value of the I2 integral: ',sigma_B_model_Lanczos ,' Ha'
1500 : 4 : write(io_unit,10) ''
1501 : 4 : write(io_unit,10) ''
1502 : 4 : close(io_unit)
1503 : : end if
1504 : :
1505 : 7 : time = time2-time1
1506 : 7 : write(timing_string,'(A)') "Time compute the integrands and integrals : "
1507 : 7 : call write_timing_log(timing_string,time)
1508 : :
1509 : : 8 format(4ES24.16)
1510 : : 10 format(A)
1511 : : 14 format(A,ES24.16,A)
1512 : :
1513 : :
1514 : 7 : end subroutine compute_integrands_shift_lanczos
1515 : : !!***
1516 : :
1517 : : !!****f* m_gwls_ComputeCorrelationEnergy/output_results
1518 : : !! NAME
1519 : : !! output_results
1520 : : !!
1521 : : !! FUNCTION
1522 : : !! .
1523 : : !!
1524 : : !! INPUTS
1525 : : !!
1526 : : !! OUTPUT
1527 : : !!
1528 : : !! SOURCE
1529 : :
1530 : 7 : subroutine output_results(iw_ext,npt_gauss, lmax,lmax_model, model_parameter, second_model_parameter, external_omega, &
1531 : : Sigma_x,Vxc_energy,pole_energy,sigma_A_Lanczos,sigma_A_model_Lanczos,sigma_B_Lanczos,sigma_B_model_Lanczos,&
1532 : : Sigma_x_Lanczos_projected )
1533 : : !----------------------------------------------------------------------------------------------------
1534 : : !
1535 : : ! This subroutine computes the integrands
1536 : : !----------------------------------------------------------------------------------------------------
1537 : :
1538 : : integer, intent(in) :: iw_ext,lmax,lmax_model,npt_gauss
1539 : : real(dp), intent(in) :: model_parameter, second_model_parameter, external_omega
1540 : : real(dp), intent(in) :: Sigma_x,Vxc_energy,pole_energy,sigma_A_Lanczos
1541 : : real(dp), intent(in) :: sigma_A_model_Lanczos,sigma_B_Lanczos,sigma_B_model_Lanczos
1542 : :
1543 : : real(dp), optional, intent(in) :: Sigma_x_Lanczos_projected
1544 : :
1545 : : integer :: io_unit
1546 : :
1547 : : character(128) :: filename
1548 : :
1549 : : real(dp) :: Sigma_c
1550 : :
1551 : : ! *************************************************************************
1552 : :
1553 : :
1554 [ + + ]: 7 : if (mpi_enreg%me == 0) then
1555 : 4 : io_unit = get_unit()
1556 [ + - ]: 4 : if (iw_ext < 10) then
1557 : 4 : write(filename,'(A,I1,A)') 'ALL_ENERGY_',iw_ext,'.dat'
1558 [ # # ]: 0 : else if (iw_ext < 100) then
1559 : 0 : write(filename,'(A,I2,A)') 'ALL_ENERGY_',iw_ext,'.dat'
1560 : : else
1561 : 0 : write(filename,'(A,I3,A)') 'ALL_ENERGY_',iw_ext,'.dat'
1562 : : end if
1563 : :
1564 : :
1565 : 4 : open(file=filename,status=files_status_new,unit=io_unit)
1566 : 4 : write(io_unit,10) '#-----------------------------------------------------------------------------------------------'
1567 : 4 : write(io_unit,10) '#'
1568 : 4 : write(io_unit,10) '# This file contains the results of the Correlation energy calculation.'
1569 : 4 : write(io_unit,10) '# '
1570 : 4 : write(io_unit,10) '# Definitions:'
1571 : 4 : write(io_unit,10) '# '
1572 : 4 : write(io_unit,10) '# eps_e = Bare DFT energy of the state '
1573 : 4 : write(io_unit,10) '# '
1574 : 4 : write(io_unit,10) '# Sigma_A_1 = Tr[(eps^{-1}(0) - eps_model^{-1}(0)) AT(W) ] '
1575 : 4 : write(io_unit,10) '# '
1576 : 4 : write(io_unit,10) '# Sigma_A_2 = Tr[(eps_model^{-1}(0) - 1) AT(W) ] '
1577 : 4 : write(io_unit,10) '# '
1578 : 4 : write(io_unit,10) '# Sigma_B_1 = Int dw I1(w) '
1579 : 4 : write(io_unit,10) '# '
1580 : 4 : write(io_unit,10) '# Sigma_B_2 = Int dw I2(w) '
1581 : 4 : write(io_unit,10) '# '
1582 : 4 : write(io_unit,10) '# I1(w) = Tr[ (eps^{-1}(iw) - eps_model^{-1}(iw)) - '
1583 : 4 : write(io_unit,10) '# f(w)(eps^{-1}(0) - eps_model^{-1}(0)) BT(w,W) ]'
1584 : 4 : write(io_unit,10) '#'
1585 : 4 : write(io_unit,10) '# I2(w) = Tr[ (eps_model^{-1}(iw) - 1) - f(w)(eps_model^{-1}(0)-1) BT(w,W)]'
1586 : 4 : write(io_unit,10) '# '
1587 : 4 : write(io_unit,10) '# Parameters: '
1588 : 4 : write(io_unit,10) '# '
1589 : 4 : write(io_unit,25) '# lmax = ', lmax
1590 : 4 : write(io_unit,25) '# lmax_model = ', lmax_model
1591 : 4 : write(io_unit,25) '# npt_gauss = ', npt_gauss
1592 : 4 : write(io_unit,12) '# omega0 = ', model_parameter,' Ha'
1593 : 4 : write(io_unit,12) '# epsilon0 = ', second_model_parameter,' Ha'
1594 : 4 : write(io_unit,14) '# omega_ext (W) = ', external_omega,' Ha'
1595 : 4 : write(io_unit,10) '# '
1596 : 4 : write(io_unit,10) '# '
1597 : 4 : write(io_unit,10) '# NOTE: if lmax_model = 0, then eps_model = I, the identity. '
1598 : 4 : write(io_unit,10) '# '
1599 : 4 : write(io_unit,10) '# '
1600 : 4 : write(io_unit,10) '#-----------------------------------------------------------------------------------------------'
1601 : 4 : write(io_unit,10) ' '
1602 : 4 : write(io_unit,30) ' eps_e (Ha) : ', eig(e)
1603 : 4 : write(io_unit,10) ' '
1604 : 4 : write(io_unit,30) ' Sigma_x (Ha) : ', Sigma_x
1605 : :
1606 [ + + ]: 4 : if (present(Sigma_x_Lanczos_projected) ) then
1607 : 1 : write(io_unit,30) ' Sigma_x_PROJECTED (Ha) : ', Sigma_x_Lanczos_projected
1608 : : end if
1609 : :
1610 : :
1611 : :
1612 : 4 : write(io_unit,30) ' < V_xc >_e (Ha) : ', Vxc_energy
1613 : 4 : write(io_unit,10) ' '
1614 : 4 : write(io_unit,30) ' poles (Ha) : ', pole_energy
1615 : 4 : write(io_unit,30) ' Sigma_A_1 (Ha) : ', sigma_A_Lanczos
1616 : 4 : write(io_unit,30) ' Sigma_A_2 (Ha) : ', sigma_A_model_Lanczos
1617 : 4 : write(io_unit,30) ' Sigma_B_1 (Ha) : ', sigma_B_Lanczos
1618 : 4 : write(io_unit,30) ' Sigma_B_2 (Ha) : ', sigma_B_model_Lanczos
1619 : 4 : write(io_unit,10) ' '
1620 : :
1621 : 4 : Sigma_c = pole_energy+sigma_A_Lanczos+sigma_A_model_Lanczos+sigma_B_Lanczos+sigma_B_model_Lanczos
1622 : :
1623 : 4 : write(io_unit,30) ' Sigma_c (Ha) : ',Sigma_c
1624 : 4 : write(io_unit,10) ' '
1625 : 4 : write(io_unit,30) ' E_e (Ha) : ', eig(e)+Sigma_x-Vxc_energy+Sigma_c
1626 : :
1627 : :
1628 : 4 : close(io_unit)
1629 : : end if
1630 : :
1631 : :
1632 : :
1633 : : 10 format(A)
1634 : : 12 format(A,ES10.3,A)
1635 : : 14 format(A,ES24.16,A)
1636 : : 25 format(A,I5)
1637 : : 30 format(A,ES24.16)
1638 : :
1639 : 7 : end subroutine output_results
1640 : : !!***
1641 : :
1642 : : !!****f* m_gwls_ComputeCorrelationEnergy/output_epsilon_eigenvalues
1643 : : !! NAME
1644 : : !! output_epsilon_eigenvalues
1645 : : !!
1646 : : !! FUNCTION
1647 : : !! .
1648 : : !!
1649 : : !! INPUTS
1650 : : !!
1651 : : !! OUTPUT
1652 : : !!
1653 : : !! SOURCE
1654 : :
1655 : 13 : subroutine output_epsilon_eigenvalues(lmax,eigenvalues,which_case)
1656 : : !----------------------------------------------------------------------------------------------------
1657 : : ! This routine outputs the eigenvalues of the static dielectric matrix
1658 : : !
1659 : : ! There are two cases to consider:
1660 : : ! 1 ) the exact dielectric matrix
1661 : : ! 2 ) the model dielectric matrix
1662 : : !----------------------------------------------------------------------------------------------------
1663 : :
1664 : : integer, intent(in) :: lmax, which_case
1665 : : real(dp), intent(in) :: eigenvalues(lmax)
1666 : :
1667 : :
1668 : : integer :: io_unit
1669 : : character(128) :: filename
1670 : :
1671 : : integer :: l
1672 : :
1673 : : ! *************************************************************************
1674 : :
1675 [ + + ]: 13 : if (mpi_enreg%me == 0) then
1676 : 7 : io_unit = get_unit()
1677 : :
1678 [ + + ]: 7 : if (which_case == 1) then
1679 : 4 : write(filename,'(A)') "EPSILON_EIGENVALUES.dat"
1680 [ + - ]: 3 : else if (which_case == 2) then
1681 : 3 : write(filename,'(A)') "MODEL_EPSILON_EIGENVALUES.dat"
1682 : : end if
1683 : :
1684 : :
1685 : 7 : open(file=filename,status=files_status_new,unit=io_unit)
1686 : 7 : write(io_unit,10) '#-----------------------------------------------------------------------------------------------'
1687 : 7 : write(io_unit,10) '#'
1688 : 7 : write(io_unit,10) '# This file contains the computed eigenvalues of the static dielectric operator'
1689 : 7 : write(io_unit,10) '# either exact or model, as indicated by the name of this file.'
1690 : 7 : write(io_unit,10) '#'
1691 : 7 : write(io_unit,10) '# l epsilon_l '
1692 : 7 : write(io_unit,10) '#-----------------------------------------------------------------------------------------------'
1693 : :
1694 [ + + ]: 63 : do l = 1, lmax
1695 : :
1696 : 63 : write(io_unit,20) l, eigenvalues(l)
1697 : : end do
1698 : :
1699 : :
1700 : 7 : close(io_unit)
1701 : :
1702 : :
1703 : : end if
1704 : :
1705 : : 10 format(A)
1706 : : 20 format(I7,20X,ES24.16)
1707 : :
1708 : :
1709 : 13 : end subroutine output_epsilon_eigenvalues
1710 : : !!***
1711 : :
1712 : :
1713 : : !!****f* m_gwls_ComputeCorrelationEnergy/output_Sigma_A_by_eigenvalues
1714 : : !! NAME
1715 : : !! output_Sigma_A_by_eigenvalues
1716 : : !!
1717 : : !! FUNCTION
1718 : : !! .
1719 : : !!
1720 : : !! INPUTS
1721 : : !!
1722 : : !! OUTPUT
1723 : : !!
1724 : : !! SOURCE
1725 : :
1726 : 13 : subroutine output_Sigma_A_by_eigenvalues(n_ext_freq,lmax,external_frequencies,AT_Lanczos,eigenvalues_array,which_case)
1727 : : !----------------------------------------------------------------------------------------------------
1728 : : ! This routine outputs the eigenvalues of the static dielectric matrix, as well as the
1729 : : ! contributions to Sigma_A, decomposed by eigenvalues.
1730 : : !
1731 : : ! There are three cases to consider:
1732 : : ! 1 ) no model is being used; we are printing A
1733 : : ! 2 ) a model is being used; we are printing A1
1734 : : ! 2 ) a model is being used; we are printing A2
1735 : : !----------------------------------------------------------------------------------------------------
1736 : :
1737 : : integer, intent(in) :: n_ext_freq, lmax, which_case
1738 : : complex(dp), intent(in) :: AT_Lanczos(n_ext_freq,lmax)
1739 : : real(dp), intent(in) :: eigenvalues_array(lmax)
1740 : : real(dp), intent(in) :: external_frequencies(n_ext_freq)
1741 : :
1742 : : integer :: iw_ext, l
1743 : : real(dp) :: external_omega
1744 : :
1745 : :
1746 : : complex(dp) :: matrix, eig
1747 : :
1748 : : integer :: io_unit
1749 : : character(128) :: filename
1750 : :
1751 : : ! *************************************************************************
1752 : :
1753 : :
1754 [ + + ]: 13 : if (mpi_enreg%me == 0) then
1755 : 7 : io_unit = get_unit()
1756 : :
1757 : :
1758 [ + + ]: 14 : do iw_ext = 1, n_ext_freq
1759 : :
1760 [ + + ]: 7 : if (which_case == 1) then
1761 : 1 : write(filename,'(A,I0.4,A)') "SIGMA_A_BY_EIGENVALUES_",iw_ext,".dat"
1762 [ + + ]: 6 : else if (which_case == 2) then
1763 : 3 : write(filename,'(A,I0.4,A)') "SIGMA_A1_BY_EIGENVALUES_",iw_ext,".dat"
1764 [ + - ]: 3 : else if (which_case == 3) then
1765 : 3 : write(filename,'(A,I0.4,A)') "SIGMA_A2_BY_EIGENVALUES_",iw_ext,".dat"
1766 : : end if
1767 : :
1768 : :
1769 : 7 : external_omega = external_frequencies(iw_ext)
1770 : :
1771 : 7 : open(file=filename,status=files_status_new,unit=io_unit)
1772 : 7 : write(io_unit,10) '#-----------------------------------------------------------------------------------------------'
1773 : 7 : write(io_unit,10) '#'
1774 : 7 : write(io_unit,10) '# This file contains the contributions to Sigma_A, the analytical self-energy term,'
1775 : 7 : write(io_unit,10) '# as a function of the eigenvalue of the dielectric operator.'
1776 : 7 : write(io_unit,10) '#'
1777 : 7 : write(io_unit,10) '# Definitions:'
1778 : 7 : write(io_unit,10) '# '
1779 : 7 : write(io_unit,10) '# '
1780 : :
1781 [ + + ]: 7 : if (which_case == 1) then
1782 : 1 : write(io_unit,10) '# Sigma_A = Tr[(eps^{-1}(0) -I ) AT(W) ] '
1783 : 1 : write(io_unit,10) '# = sum_{l} ( 1/eps_l -1 ) < V_l | AT(W) | V_l > '
1784 [ + + ]: 6 : else if (which_case == 2) then
1785 : 3 : write(io_unit,10) '# Sigma_A1= Tr[(eps^{-1}(0) - eps_model^{-1}(0) ) A1T(W) ] '
1786 : 3 : write(io_unit,10) '# = sum_{l} ( LBDA_l ) < V_l | A1T(W) | V_l > '
1787 : 3 : write(io_unit,10) '# where LBDA_l are the eigenvalues of eps^{-1}(0)-eps_model^{-1}(0) '
1788 [ + - ]: 3 : else if (which_case == 3) then
1789 : 3 : write(io_unit,10) '# Sigma_A2= Tr[(eps_model^{-1}(0)- I ) A2T(W) ] '
1790 : 3 : write(io_unit,10) '# = sum_{l} (1/eps^{model}_l -1 ) < V_l | A2T(W) | V_l > '
1791 : : end if
1792 : :
1793 : :
1794 : 7 : write(io_unit,10) '# '
1795 : 7 : write(io_unit,10) '# '
1796 : 7 : write(io_unit,10) '# Parameters: '
1797 : 7 : write(io_unit,10) '# '
1798 : :
1799 [ + + ]: 7 : if (which_case == 1 .or. which_case == 2) then
1800 : 4 : write(io_unit,25) '# lmax = ', lmax
1801 [ + - ]: 3 : else if (which_case == 3) then
1802 : 3 : write(io_unit,25) '# lmax_model = ', lmax
1803 : : end if
1804 : :
1805 : 7 : write(io_unit,25) '# n_ext_freq = ', n_ext_freq
1806 : 7 : write(io_unit,25) '# iw_ext = ', iw_ext
1807 : 7 : write(io_unit,14) '# omega_ext (W) = ', external_omega,' Ha'
1808 : 7 : write(io_unit,10) '# '
1809 : 7 : write(io_unit,10) '# '
1810 [ + + ]: 7 : if (which_case == 1) then
1811 : : write(io_unit,10) '# (1/eps_l -1) < V_l | AT(W) | V_l > (Ha) ( 1/eps_l -1 ) '&
1812 : 1 : & //'< V_l | AT(W) | V_l > (Ha)'
1813 [ + + ]: 6 : else if (which_case == 2) then
1814 : : write(io_unit,10) '# LBDA_1 < V_l | A1T(W) | V_l > (Ha) LBDA_l '&
1815 : 3 : & //'< V_l | A1T(W) | V_l > (Ha)'
1816 [ + - ]: 3 : else if (which_case == 3) then
1817 : : write(io_unit,10) '# (1/eps_m_l -1) < V_l | A2T(W) | V_l > (Ha) ( 1/eps_m_l -1 ) '&
1818 : 3 : & //'< V_l | A2T(W) | V_l > (Ha)'
1819 : : end if
1820 : :
1821 : : write(io_unit,10) '# real imaginary real '&
1822 : 7 : & //'imaginary'
1823 : : write(io_unit,10) '#---------------------------------------------------------------------------------------------------------'&
1824 : 7 : & //'----------------'
1825 : :
1826 [ + + ]: 63 : do l = 1, lmax
1827 : :
1828 : 56 : matrix = AT_Lanczos(iw_ext,l)
1829 : 56 : eig = eigenvalues_array(l)
1830 : :
1831 : :
1832 : 63 : write(io_unit,20) real(eig), matrix, eig*matrix
1833 : : end do
1834 : :
1835 : :
1836 : 14 : close(io_unit)
1837 : :
1838 : : end do
1839 : :
1840 : : end if
1841 : :
1842 : : 10 format(A)
1843 : : 14 format(A,ES24.16,A)
1844 : : 20 format(ES24.16,2ES24.16,2X,2ES24.16)
1845 : : 25 format(A,I5)
1846 : :
1847 : :
1848 : :
1849 : 13 : end subroutine output_Sigma_A_by_eigenvalues
1850 : : !!***
1851 : :
1852 : :
1853 : : end module m_gwls_ComputeCorrelationEnergy
1854 : : !!***
|