Branch data Line data Source code
1 : : !!****m* ABINIT/m_gwls_GenerateEpsilon
2 : : !! NAME
3 : : !! m_gwls_GenerateEpsilon
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 : :
23 : : module m_gwls_GenerateEpsilon
24 : : !----------------------------------------------------------------------------------------------------
25 : : ! This module contains routines to compute and store the dielectric matrix, which plays a
26 : : ! central role in the self energy computations. In particular, global arrays are used to store
27 : : ! the static dielectric matrix.
28 : : !----------------------------------------------------------------------------------------------------
29 : : ! local modules
30 : : use m_gwls_utility
31 : : use m_gwls_wf
32 : : use m_gwls_hamiltonian
33 : : use m_gwls_lineqsolver
34 : : use m_gwls_TimingLog
35 : : use m_gwls_polarisability
36 : : use m_gwls_model_polarisability
37 : : use m_gwls_GWlanczos
38 : : ! Abinit modules
39 : : use m_abicore
40 : : use defs_basis
41 : : use m_dtset
42 : :
43 : : use m_io_tools, only : get_unit
44 : :
45 : : implicit none
46 : : save
47 : : private
48 : : !!***
49 : :
50 : : ! Global arrays
51 : :
52 : : real(dp), public, allocatable :: epsilon_eigenvalues_0(:) ! eigenvalues of the static dielectric matrix
53 : :
54 : : complex(dp), public, allocatable :: epsilon_inverse_0(:,:) ! eps^{-1}-1 in diagonal basis
55 : :
56 : : integer, public :: kmax, nseeds, lmax
57 : : integer, public :: first_seed
58 : : !!***
59 : :
60 : : public :: driver_generate_dielectric_matrix
61 : : public :: GeneratePrintDielectricEigenvalues
62 : : public :: Driver_GeneratePrintDielectricEigenvalues
63 : : !!***
64 : :
65 : : contains
66 : :
67 : : !!****f* m_gwls_GenerateEpsilon/driver_generate_dielectric_matrix
68 : : !! NAME
69 : : !! driver_generate_dielectric_matrix
70 : : !!
71 : : !! FUNCTION
72 : : !! .
73 : : !!
74 : : !! INPUTS
75 : : !!
76 : : !! OUTPUT
77 : : !!
78 : : !! SOURCE
79 : :
80 : 13 : subroutine driver_generate_dielectric_matrix(epsilon_matrix_function,nseeds,kmax,&
81 : 13 : epsilon_eigenvalues,Lbasis,debug)
82 : : !----------------------------------------------------------------------
83 : : ! This routine computes the Lanczos approximate representation of the
84 : : ! implicit dielectic operator and then diagonalizes the banded
85 : : ! Lanczos matrix.
86 : : !----------------------------------------------------------------------
87 : : interface
88 : : subroutine epsilon_matrix_function(v_out,v_in,l)
89 : : use defs_basis
90 : :
91 : : integer, intent(in) :: l
92 : : complex(dp), intent(out) :: v_out(l)
93 : : complex(dp), intent(in) :: v_in(l)
94 : :
95 : : end subroutine epsilon_matrix_function
96 : : end interface
97 : :
98 : : integer, intent(in) :: nseeds, kmax
99 : : logical, intent(in) :: debug
100 : :
101 : : real (dp), intent(out) :: epsilon_eigenvalues(nseeds*kmax)
102 : : complex(dp), intent(out) :: Lbasis(npw_k,nseeds*kmax) ! array containing the Lanczos basis
103 : :
104 : :
105 : : ! local variables
106 : :
107 : 13 : complex(dp), allocatable :: seeds(:,:)
108 : 13 : complex(dp),allocatable :: alpha(:,:,:)
109 : 13 : complex(dp),allocatable :: beta (:,:,:)
110 : :
111 : : integer :: mpi_communicator
112 : :
113 : : ! *************************************************************************
114 : :
115 : :
116 : : ! The epsilon operator will act in LA mode.
117 : 13 : mpi_communicator = mpi_enreg%comm_bandfft
118 : :
119 : :
120 : : !Create seeds
121 [ - + + - : 52 : ABI_MALLOC(seeds,(npw_k,nseeds))
- + + - +
- + - - +
- + ]
122 : 13 : call get_seeds(first_seed, nseeds, seeds)
123 : :
124 : : ! compute the Lanczos basis
125 [ - + + - : 65 : ABI_MALLOC(alpha,(nseeds,nseeds,kmax))
- + + - -
+ + - + -
+ - - + -
+ ]
126 [ - + + - : 52 : ABI_MALLOC(beta ,(nseeds,nseeds,kmax))
- + + - -
+ + - - +
- + ]
127 : :
128 : : call block_lanczos_algorithm(mpi_communicator,epsilon_matrix_function,kmax,nseeds,npw_k, &
129 : 13 : seeds,alpha,beta,Lbasis)
130 : :
131 : : ! Diagonalize the epsilon matrix, which is banded
132 : 13 : call diagonalize_lanczos_banded(kmax,nseeds,npw_k,alpha,beta,Lbasis,epsilon_eigenvalues,debug)
133 : :
134 [ - + ]: 13 : if (debug) then
135 : 0 : call ritz_analysis_general(mpi_communicator, epsilon_matrix_function,nseeds*kmax,npw_k,Lbasis,epsilon_eigenvalues)
136 : : end if
137 : :
138 [ - + ]: 13 : ABI_FREE(seeds)
139 [ - + ]: 13 : ABI_FREE(alpha)
140 [ - + ]: 13 : ABI_FREE(beta)
141 : :
142 : 13 : end subroutine driver_generate_dielectric_matrix
143 : : !!***
144 : :
145 : : !!****f* m_gwls_GenerateEpsilon/GeneratePrintDielectricEigenvalues
146 : : !! NAME
147 : : !! GeneratePrintDielectricEigenvalues
148 : : !!
149 : : !! FUNCTION
150 : : !! .
151 : : !!
152 : : !! INPUTS
153 : : !!
154 : : !! OUTPUT
155 : : !!
156 : : !! SOURCE
157 : :
158 [ - + - + : 2 : subroutine GeneratePrintDielectricEigenvalues(epsilon_matrix_function,nseeds,kmax,output_filename,Lbasis,alpha,beta)
- + ]
159 : : !----------------------------------------------------------------------
160 : : ! This routine computes the Lanczos approximate representation of the
161 : : ! implicit dielectic operator and then diagonalizes the banded
162 : : ! Lanczos matrix.
163 : : !----------------------------------------------------------------------
164 : : interface
165 : : subroutine epsilon_matrix_function(v_out,v_in,l)
166 : : use defs_basis
167 : :
168 : : integer, intent(in) :: l
169 : : complex(dp), intent(out) :: v_out(l)
170 : : complex(dp), intent(in) :: v_in(l)
171 : :
172 : : end subroutine epsilon_matrix_function
173 : : end interface
174 : :
175 : : integer, intent(in) :: nseeds, kmax
176 : :
177 : : character(*), intent(in) :: output_filename
178 : :
179 : :
180 : : complex(dp), intent(out) :: Lbasis(:,:)
181 : : complex(dp), intent(out) :: alpha(:,:,:)
182 : : complex(dp), intent(out) :: beta (:,:,:)
183 : :
184 : :
185 : : ! local variables
186 : :
187 : :
188 : 2 : complex(dp),allocatable :: seeds(:,:)
189 : 2 : complex(dp),allocatable :: Lbasis_diag(:,:)
190 : :
191 : :
192 : 2 : real(dp), allocatable :: psik(:,:)
193 : 2 : real(dp), allocatable :: psir(:,:,:,:)
194 : :
195 : 2 : real(dp), allocatable :: epsilon_eigenvalues(:)
196 : :
197 : :
198 : : integer :: mpi_communicator
199 : : integer :: io_unit
200 : : integer :: lmax
201 : : integer :: l
202 : : integer :: ir1, ir2, ir3
203 : : integer :: n1, n2, n3
204 : :
205 : : real(dp) :: R, G
206 : : real(dp) :: sigma_R, sigma_G
207 : : real(dp) :: x, y, z
208 : :
209 : 2 : real(dp),allocatable :: G_array(:)
210 : 2 : real(dp),allocatable :: R_array(:,:,:)
211 : :
212 : : logical :: debug
213 : :
214 : : ! *************************************************************************
215 : :
216 : :
217 : 2 : debug = .false.
218 : 2 : lmax = kmax*nseeds
219 : 2 : mpi_communicator = mpi_enreg%comm_bandfft
220 : : !Create seeds
221 [ - + + - : 8 : ABI_MALLOC(seeds,(npw_k,nseeds))
- + + - +
- + - - +
- + ]
222 : 2 : call get_seeds(first_seed, nseeds, seeds)
223 : :
224 : : ! compute the Lanczos basis
225 [ - + + - : 8 : ABI_MALLOC(Lbasis_diag,(npw_k,lmax))
- + + - +
- + - - +
- + ]
226 [ - + + - : 6 : ABI_MALLOC(epsilon_eigenvalues,(lmax))
+ - + - -
+ - + ]
227 : :
228 [ - + + - : 6 : ABI_MALLOC(psik,(2,npw_k))
+ - + - -
+ - + ]
229 [ - + + - : 10 : ABI_MALLOC(psir,(2,n4,n5,n6))
- + + - -
+ + - + -
+ - - + -
+ ]
230 [ - + + - : 6 : ABI_MALLOC(G_array,(npw_k))
+ - + - -
+ - + ]
231 [ - + + - : 10 : ABI_MALLOC(R_array,(n4,n5,n6))
- + + - -
+ + - + -
+ - - + -
+ ]
232 : :
233 [ + + + + : 39710 : psir = zero
+ + + + ]
234 [ + + + + : 13718 : R_array = zero
+ + ]
235 : :
236 : 2 : n1 = n4-1
237 : 2 : n2 = n5-1
238 : 2 : n3 = n6
239 : :
240 : : ! Generate the Lanczos basis and banded eigenvalue representation
241 [ - + - - : 2 : call block_lanczos_algorithm(mpi_communicator, epsilon_matrix_function,kmax,nseeds,npw_k, seeds,alpha,beta,Lbasis)
- + - - -
+ - - - +
- - - - -
- - + - -
- - - - -
+ - - -
- ]
242 : :
243 [ + - + - : 4132 : Lbasis_diag = Lbasis
- + - - +
+ + + ]
244 : :
245 : : ! Diagonalize the epsilon matrix, which is banded
246 [ - + - - : 2 : call diagonalize_lanczos_banded(kmax,nseeds,npw_k,alpha,beta,Lbasis_diag,epsilon_eigenvalues,debug)
- - - - -
- - + - -
- - - - -
- - + -
+ ]
247 : :
248 : 2 : call ritz_analysis_general(mpi_communicator, epsilon_matrix_function,lmax,npw_k,Lbasis_diag,epsilon_eigenvalues)
249 : :
250 : 2 : io_unit = get_unit()
251 : 2 : open(file=output_filename,status=files_status_new,unit=io_unit)
252 : 2 : write(io_unit,10) '#----------------------------------------------------------------------------'
253 : 2 : write(io_unit,10) '# '
254 : 2 : write(io_unit,10) '# Partial eigenvalues '
255 : 2 : write(io_unit,10) '# ========================================== '
256 : 2 : write(io_unit,10) '# '
257 : 2 : write(io_unit,10) '# Tabulate the eigenvalues of the dielectic matrix, as well as some '
258 : 2 : write(io_unit,10) '# information regarding the eigenstates. '
259 : 2 : write(io_unit,10) '# '
260 : 2 : write(io_unit,10) '# '
261 : 2 : write(io_unit,10) '# definitions: '
262 : 2 : write(io_unit,10) '# l index of the eigenvalue '
263 : 2 : write(io_unit,10) '# eig eigenvalue '
264 : 2 : write(io_unit,10) '# '
265 : 2 : write(io_unit,10) '# '
266 : 2 : write(io_unit,10) '# (the following vectors are expressed in crystal units) '
267 : 2 : write(io_unit,10) '# '
268 : 2 : write(io_unit,10) '# R = < l | |r| | l > '
269 : 2 : write(io_unit,10) '# sigma_R = sqrt{< l | (|r|-R)^2 | l > } '
270 : 2 : write(io_unit,10) '# '
271 : 2 : write(io_unit,10) '# G = < l | |G| | l > '
272 : 2 : write(io_unit,10) '# sigma_G = sqrt{< l | (|G|-G)^2 | l > } '
273 : 2 : write(io_unit,10) '# '
274 : 2 : write(io_unit,10) '# '
275 : 2 : write(io_unit,10) '# l eig r sigma_r G sigma_G '
276 : 2 : write(io_unit,10) '#----------------------------------------------------------------------------'
277 : 2 : flush(io_unit)
278 : :
279 : :
280 [ + + ]: 516 : G_array(:) = kg_k(1,:)**2+ kg_k(2,:)**2+ kg_k(3,:)**2
281 : :
282 [ + + ]: 516 : G_array(:) = sqrt(G_array(:))
283 : :
284 [ + + + + : 13718 : R_array = zero
+ + ]
285 : :
286 [ + + ]: 38 : do ir3=1,n3
287 : :
288 [ + + ]: 36 : if (ir3 <= n3/2 ) then
289 : 18 : z = (one*ir3)/(one*n3)
290 : : else
291 : 18 : z = (one*ir3)/(one*n3)-one
292 : : end if
293 : :
294 [ + + ]: 686 : do ir2=1,n2
295 : :
296 [ + + ]: 648 : if (ir2 <= n2/2 ) then
297 : 324 : y = (one*ir2)/(one*n2)
298 : : else
299 : 324 : y = (one*ir2)/(one*n2)-one
300 : : end if
301 : :
302 [ + + ]: 12348 : do ir1=1,n1
303 : :
304 [ + + ]: 11664 : if (ir1 <= n1/2 ) then
305 : 5832 : x = (one*ir1)/(one*n1)
306 : : else
307 : 5832 : x = (one*ir1)/(one*n1)-one
308 : : end if
309 : :
310 : :
311 : 12312 : R_array(ir1,ir2,ir3) = sqrt(x**2+y**2+z**2)
312 : : end do
313 : : end do
314 : : end do
315 : :
316 : :
317 : :
318 [ + + ]: 18 : do l=1, lmax
319 : :
320 [ + + ]: 4128 : psik(1,:) = dble (Lbasis_diag(:,l))
321 [ + + ]: 4128 : psik(2,:) = dimag(Lbasis_diag(:,l))
322 : :
323 : 16 : call g_to_r(psir ,psik)
324 : :
325 : :
326 [ + + ]: 4128 : G = sum(G_array(:)*(psik(1,:)**2+psik(2,:)**2))
327 [ + + + + : 109744 : R = sum(R_array(:,:,:)*(psir(1,:,:,:)**2+psir(2,:,:,:)**2) )*ucvol/nfft
+ + ]
328 : :
329 [ + + ]: 4128 : sigma_G = sqrt(sum((G_array(:) -G)**2*(psik(1,:)**2 +psik(2,:)**2)))
330 [ + + + + : 109744 : sigma_R = sqrt(sum((R_array(:,:,:)-R)**2*(psir(1,:,:,:)**2+psir(2,:,:,:)**2))*ucvol/nfft)
+ + ]
331 : :
332 : :
333 : :
334 : 18 : write(io_unit,20) l, epsilon_eigenvalues(l), R,sigma_R, G,sigma_G
335 : :
336 : : end do
337 : :
338 : 2 : close(io_unit)
339 : :
340 [ - + ]: 2 : ABI_FREE(seeds)
341 [ - + ]: 2 : ABI_FREE(Lbasis_diag)
342 [ - + ]: 2 : ABI_FREE(psik)
343 [ - + ]: 2 : ABI_FREE(psir)
344 [ - + ]: 2 : ABI_FREE(G_array)
345 [ - + ]: 2 : ABI_FREE(R_array)
346 : :
347 [ - + ]: 2 : ABI_FREE(epsilon_eigenvalues)
348 : :
349 : :
350 : : 10 format(A)
351 : : 20 format(I5,ES24.16,4F12.8)
352 : :
353 : 2 : end subroutine GeneratePrintDielectricEigenvalues
354 : : !!***
355 : :
356 : : !!****f* m_gwls_GenerateEpsilon/Driver_GeneratePrintDielectricEigenvalues
357 : : !! NAME
358 : : !! Driver_GeneratePrintDielectricEigenvalues
359 : : !!
360 : : !! FUNCTION
361 : : !! .
362 : : !!
363 : : !! INPUTS
364 : : !!
365 : : !! OUTPUT
366 : : !!
367 : : !! SOURCE
368 : :
369 : 1 : subroutine Driver_GeneratePrintDielectricEigenvalues(dtset)
370 : : !----------------------------------------------------------------------
371 : : ! Compute the eigenvalues of the various dielectric operators
372 : : !----------------------------------------------------------------------
373 : : type(dataset_type),intent(in) :: dtset
374 : :
375 : : integer :: kmax_exact, kmax_model, kmax
376 : : real(dp) :: second_model_parameter
377 : :
378 : :
379 : : integer :: lm, k, lmax, l1, l2
380 : : integer :: io_unit
381 : : integer :: io_unit2
382 : :
383 : : real(dp) :: time1, time2, time
384 : : ! local variables
385 : : character(128) :: output_filename
386 : : character(256) :: timing_string
387 : :
388 : :
389 : : complex(dp), allocatable :: Lbasis_exact(:,:)
390 : : complex(dp), allocatable :: Lbasis_model(:,:)
391 : 1 : complex(dp), allocatable :: sub_Lbasis_exact(:,:)
392 : 1 : complex(dp), allocatable :: sub_Lbasis_model(:,:)
393 : 1 : complex(dp), allocatable :: dummy(:,:)
394 : 1 : complex(dp), allocatable :: dummy2(:,:)
395 : 1 : complex(dp), allocatable :: dummy3(:,:)
396 : : complex(dp), allocatable :: alpha_exact(:,:,:)
397 : : complex(dp), allocatable :: beta_exact (:,:,:)
398 : : complex(dp), allocatable :: alpha_model(:,:,:)
399 : : complex(dp), allocatable :: beta_model (:,:,:)
400 : :
401 : 1 : real(dp), allocatable :: eig_exact(:)
402 : 1 : real(dp), allocatable :: eig_model(:)
403 : :
404 : 1 : complex(dp), allocatable :: model_epsilon_matrix(:,:)
405 : 1 : complex(dp), allocatable :: vector(:)
406 : :
407 : : real(dp) :: tr_eps_1, tr_eps_2, tr_eps_3
408 : :
409 : :
410 : : integer :: lwork, lrwork, liwork, info
411 : 1 : complex(dp), allocatable :: work(:)
412 : 1 : real(dp) , allocatable :: rwork(:)
413 : 1 : integer , allocatable :: iwork(:)
414 : :
415 : : integer :: debug_unit
416 : : character(50) :: debug_filename
417 : : ! *************************************************************************
418 : :
419 : 1 : kmax_exact = dtset%gwls_stern_kmax
420 : 1 : kmax_model = dtset%gwls_kmax_complement
421 : :
422 : : !second_model_parameter = dtset%gwls_second_model_parameter
423 : 1 : second_model_parameter = zero
424 : :
425 : :
426 : : ! global stuff
427 : 1 : nseeds = dtset%gwls_nseeds
428 : 1 : first_seed = dtset%gwls_first_seed
429 : 1 : e = dtset%gwls_band_index
430 : :
431 : :
432 : :
433 [ - + + - : 4 : ABI_MALLOC(Lbasis_exact,(npw_k,kmax_exact*nseeds))
- + + - +
- + - - +
- + ]
434 [ - + + - : 4 : ABI_MALLOC(Lbasis_model,(npw_k,kmax_model*nseeds))
- + + - +
- + - - +
- + ]
435 : :
436 [ - + + - : 5 : ABI_MALLOC(alpha_exact, (nseeds,nseeds,kmax_exact))
- + + - -
+ + - + -
+ - - + -
+ ]
437 [ - + + - : 4 : ABI_MALLOC(beta_exact , (nseeds,nseeds,kmax_exact))
- + + - -
+ + - - +
- + ]
438 [ - + + - : 5 : ABI_MALLOC(alpha_model, (nseeds,nseeds,kmax_model))
- + + - -
+ + - + -
+ - - + -
+ ]
439 [ - + + - : 4 : ABI_MALLOC(beta_model , (nseeds,nseeds,kmax_model))
- + + - -
+ + - - +
- + ]
440 : :
441 : :
442 : : ! set omega=0 for exact dielectric operator
443 : 1 : call set_dielectric_function_frequency([zero,zero])
444 : :
445 : :
446 : :
447 : 1 : call cpu_time(time1)
448 : 1 : output_filename = 'EIGENVALUES_EXACT.dat'
449 : : call GeneratePrintDielectricEigenvalues(matrix_function_epsilon_k, nseeds, kmax_exact, &
450 : 1 : output_filename, Lbasis_exact, alpha_exact, beta_exact)
451 : :
452 : :
453 : :
454 : 1 : call cpu_time(time2)
455 : 1 : time = time2-time1
456 : 1 : write(timing_string,'(A)') "Time to compute the EXACT Static Dielectric Matrix : "
457 : 1 : call write_timing_log(timing_string,time)
458 : :
459 : :
460 : :
461 : 1 : call cpu_time(time1)
462 : 1 : call setup_Pk_model(zero,second_model_parameter)
463 : 1 : output_filename = 'EIGENVALUES_MODEL.dat'
464 : : call GeneratePrintDielectricEigenvalues(matrix_function_epsilon_model_operator, nseeds, kmax_model, &
465 : 1 : &output_filename, Lbasis_model, alpha_model, beta_model)
466 : 1 : call cpu_time(time2)
467 : 1 : time = time2-time1
468 : 1 : write(timing_string,'(A)') "Time to compute the MODEL Static Dielectric Matrix : "
469 : 1 : call write_timing_log(timing_string,time)
470 : :
471 : :
472 : 1 : call cpu_time(time1)
473 : 1 : if (kmax_exact <= kmax_model) then
474 : : kmax = kmax_exact
475 : : else
476 : : kmax = kmax_model
477 : : end if
478 : 1 : lmax = nseeds*kmax
479 : :
480 : : ! Build model operator matrix elements in the exact basis
481 [ - + + - : 4 : ABI_MALLOC(model_epsilon_matrix, (lmax,lmax))
- + + - +
- + - - +
- + ]
482 [ - + + - : 3 : ABI_MALLOC(vector, (npw_k))
+ - + - -
+ - + ]
483 : :
484 [ + + + + ]: 73 : model_epsilon_matrix = cmplx_0
485 : :
486 [ + + ]: 9 : do l2 =1 , lmax
487 : 8 : call matrix_function_epsilon_model_operator(vector ,Lbasis_exact(:,l2),npw_k)
488 : :
489 : :
490 [ + + ]: 73 : do l1 =1, lmax
491 : :
492 : 72 : model_epsilon_matrix(l1, l2) = complex_vector_product(Lbasis_exact(:,l1),vector,npw_k)
493 : :
494 : : end do
495 : :
496 : :
497 : : end do
498 : :
499 [ - + ]: 1 : ABI_FREE(vector)
500 : :
501 : 1 : call cpu_time(time2)
502 : 1 : time = time2-time1
503 : 1 : write(timing_string,'(A)') "Compute MODEL matrix elements in EXACT basis : "
504 : 1 : call write_timing_log(timing_string,time)
505 : :
506 : :
507 : :
508 : :
509 : : ! Compare the traces
510 : :
511 : :
512 : 1 : io_unit = get_unit()
513 : 1 : open(file='DIELECTRIC_TRACE.dat',status=files_status_new,unit=io_unit)
514 : 1 : write(io_unit,10) '#----------------------------------------------------------------------------'
515 : 1 : write(io_unit,10) '# '
516 : 1 : write(io_unit,10) '# Partial traces '
517 : 1 : write(io_unit,10) '# ========================================== '
518 : 1 : write(io_unit,10) '# '
519 : 1 : write(io_unit,10) '# Tabulate the trace of various operators, as function of the number '
520 : 1 : write(io_unit,10) '# of lanczos steps performed. '
521 : 1 : write(io_unit,10) '# '
522 : 1 : write(io_unit,10) '# '
523 : 1 : write(io_unit,10) '# NOTES: '
524 : 1 : write(io_unit,10) '# Tr[1-eps^{-1}] is evaluated in the Lanczos basis of eps '
525 : 1 : write(io_unit,10) '# Tr[1-eps_m^{-1}] is evaluated in the Lanczos basis of eps_m '
526 : 1 : write(io_unit,10) '# Tr[eps_m^{-1}-eps^{-1}] is evaluated in the Lanczos basis of eps '
527 : 1 : write(io_unit,10) '# '
528 : 1 : write(io_unit,10) '# '
529 : 1 : write(io_unit,10) '# k Tr[1-eps^{-1}] Tr[1-eps_m^{-1}] Tr[eps_m^{-1}-eps^{-1}]'
530 : 1 : write(io_unit,10) '#----------------------------------------------------------------------------'
531 : 1 : flush(io_unit)
532 : :
533 : :
534 : 1 : io_unit2 = get_unit()
535 : 1 : open(file='RPA_ENERGY.dat',status=files_status_new,unit=io_unit2)
536 : 1 : write(io_unit2,10) '#----------------------------------------------------------------------------'
537 : 1 : write(io_unit2,10) '# '
538 : 1 : write(io_unit2,10) '# RPA TOTAL ENERGY '
539 : 1 : write(io_unit2,10) '# ========================================== '
540 : 1 : write(io_unit2,10) '# '
541 : 1 : write(io_unit2,10) '# It can be shown that the correlation energy, within the RPA, is given '
542 : 1 : write(io_unit2,10) '# by: '
543 : 1 : write(io_unit2,10) '# E_c = int_0^{infty} dw/(2pi) Tr[ ln(eps{iw)}+1-eps(iw)] '
544 : 1 : write(io_unit2,10) '# '
545 : 1 : write(io_unit2,10) '# As a gauge of what can be expected as far as convergence is concerned, '
546 : 1 : write(io_unit2,10) '# the following will be printed. '
547 : 1 : write(io_unit2,10) '# '
548 : 1 : write(io_unit2,10) '# I_1 = Tr[ ln(eps) + 1 - eps ] '
549 : 1 : write(io_unit2,10) '# I_2 = Tr[ ln(eps_m) + 1 - eps_m ] '
550 : 1 : write(io_unit2,10) '# I_3 = Tr[ ln(eps^{-1}_m . eps ) + eps_m - eps ] '
551 : 1 : write(io_unit2,10) '# '
552 : 1 : write(io_unit2,10) '# '
553 : 1 : write(io_unit2,10) '# '
554 : 1 : write(io_unit2,10) '# k I_1 I_2 I_3 '
555 : 1 : write(io_unit2,10) '#----------------------------------------------------------------------------'
556 : 1 : flush(io_unit2)
557 : :
558 : :
559 : : ! Iterate every 10 values of k max, or else the linear algebra gets too expensive...
560 [ - + ]: 1 : do k = 4, kmax, 4
561 : :
562 [ - + + - : 8 : ABI_MALLOC(sub_Lbasis_exact,(npw_k,k*nseeds))
- + + - +
- + - - +
- + ]
563 [ - + + - : 6 : ABI_MALLOC(sub_Lbasis_model,(npw_k,k*nseeds))
- + + - -
+ - + ]
564 : :
565 : :
566 [ - + + - : 6 : ABI_MALLOC(eig_exact,(k*nseeds))
+ - + - -
+ - + ]
567 [ - + + - : 4 : ABI_MALLOC(eig_model,(k*nseeds))
- + - + ]
568 [ - + + - : 8 : ABI_MALLOC(dummy,(k*nseeds,k*nseeds))
- + + - +
- + - - +
- + ]
569 [ - + + - : 6 : ABI_MALLOC(dummy2,(k*nseeds,k*nseeds))
- + + - -
+ - + ]
570 : :
571 [ + + + + ]: 3098 : sub_Lbasis_exact(:,:) = Lbasis_exact(:,1:k*nseeds)
572 [ + + + + ]: 3098 : sub_Lbasis_model(:,:) = Lbasis_model(:,1:k*nseeds)
573 : :
574 : : ! Diagonalize the epsilon matrix, which is banded
575 : 2 : call diagonalize_lanczos_banded(k,nseeds,npw_k,alpha_exact(:,:,1:k),beta_exact(:,:,1:k),sub_Lbasis_exact,eig_exact,.false.)
576 : 2 : call diagonalize_lanczos_banded(k,nseeds,npw_k,alpha_model(:,:,1:k),beta_model(:,:,1:k),sub_Lbasis_model,eig_model,.false.)
577 : :
578 [ + + ]: 14 : tr_eps_1 = sum(one-one/eig_exact(:))
579 [ + + ]: 14 : tr_eps_2 = sum(one-one/eig_model(:))
580 : :
581 [ + + ]: 14 : tr_eps_3 = -sum(one/eig_exact(:))
582 : :
583 [ + + + + ]: 94 : dummy(:,:) = model_epsilon_matrix(1:k*nseeds, 1:k*nseeds)
584 : :
585 : 2 : call driver_invert_positive_definite_hermitian_matrix(dummy,k*nseeds)
586 : :
587 [ + + ]: 14 : do lm = 1, k*nseeds
588 : :
589 : 14 : tr_eps_3 = tr_eps_3 + dble(dummy(lm,lm))
590 : : end do
591 : :
592 : :
593 : 2 : write(io_unit,20) k, tr_eps_1, tr_eps_2, tr_eps_3
594 : 2 : flush(io_unit)
595 : :
596 : :
597 : :
598 [ + + ]: 14 : tr_eps_1 = sum(log(eig_exact(:))+one-eig_exact(:))
599 [ + + ]: 14 : tr_eps_2 = sum(log(eig_model(:))+one-eig_model(:))
600 : :
601 [ + + + + ]: 94 : dummy2(:,:) = zero
602 : 2 : tr_eps_3 = zero
603 [ + + ]: 14 : do lm = 1, k*nseeds
604 : 12 : dummy2(lm,lm) = eig_exact(lm)
605 : 14 : tr_eps_3 = tr_eps_3 + dble(model_epsilon_matrix(lm,lm)) - dble(eig_exact(lm))
606 : : end do
607 : :
608 [ - + + - : 8 : ABI_MALLOC(dummy3,(k*nseeds,k*nseeds))
- + + - +
- + - - +
- + ]
609 : : call ZGEMM( 'N', & ! Hermitian conjugate the first array
610 : : 'N', & ! Leave second array as is
611 : : k*nseeds, & ! the number of rows of the matrix op( A )
612 : : k*nseeds, & ! the number of columns of the matrix op( B )
613 : : k*nseeds, & ! the number of columns of the matrix op( A ) == rows of matrix op( B )
614 : : cmplx_1, & ! alpha constant
615 : : dummy2, & ! matrix A
616 : : k*nseeds, & ! LDA
617 : : dummy, & ! matrix B
618 : : k*nseeds, & ! LDB
619 : : cmplx_0, & ! beta constant
620 : : dummy3, & ! matrix C
621 : 2 : k*nseeds) ! LDC
622 : :
623 [ + + + + ]: 94 : dummy2(:,:) = dummy3(:,:)
624 [ - + ]: 2 : ABI_FREE(dummy3)
625 : :
626 : : ! find eigenvalues
627 : : !call heevd(dummy2, eig_exact)
628 : :
629 : 2 : lwork = k*nseeds+1
630 : 2 : lrwork = k*nseeds
631 : 2 : liwork = 1
632 : :
633 [ - + + - : 6 : ABI_MALLOC(work,(lwork))
+ - + - -
+ - + ]
634 [ - + + - : 6 : ABI_MALLOC(rwork,(lrwork))
+ - + - -
+ - + ]
635 [ - + ]: 2 : ABI_MALLOC(iwork,(liwork))
636 : :
637 : 2 : call zheevd('N', 'U',k*nseeds, dummy2, k*nseeds, eig_exact, work, lwork, rwork, lrwork, iwork, liwork, info)
638 [ - + ]: 2 : if ( info /= 0) then
639 : 0 : debug_unit = get_unit()
640 : 0 : write(debug_filename,'(A,I4.4,A)') 'LAPACK_DEBUG_PROC=',mpi_enreg%me,'.log'
641 : :
642 : 0 : open(debug_unit,file=trim(debug_filename),status='unknown')
643 : :
644 : 0 : write(debug_unit,'(A)') '*************************************************************************************'
645 : 0 : write(debug_unit,'(A,I4,A)') '* ERROR: info = ',info,' in ZHEEVD(1), gwls_GenerateEpsilon'
646 : 0 : write(debug_unit,'(A)') '*************************************************************************************'
647 : :
648 : 0 : close(debug_unit)
649 : :
650 : : end if
651 : :
652 : :
653 : :
654 : :
655 : :
656 [ + + ]: 14 : tr_eps_3 = tr_eps_3 + sum(log(eig_exact))
657 : :
658 : 2 : write(io_unit2,20) k, tr_eps_1, tr_eps_2, tr_eps_3
659 : 2 : flush(io_unit2)
660 : :
661 : :
662 : :
663 [ - + ]: 2 : ABI_FREE(work)
664 [ - + ]: 2 : ABI_FREE(rwork)
665 [ - + ]: 2 : ABI_FREE(iwork)
666 : :
667 : :
668 : :
669 [ - + ]: 2 : ABI_FREE(sub_Lbasis_exact)
670 [ - + ]: 2 : ABI_FREE(sub_Lbasis_model)
671 : :
672 [ - + ]: 2 : ABI_FREE(eig_exact)
673 [ - + ]: 2 : ABI_FREE(eig_model)
674 [ - + ]: 2 : ABI_FREE(dummy)
675 [ - + + + ]: 2 : ABI_FREE(dummy2)
676 : : end do
677 : :
678 : 1 : close(io_unit)
679 : 1 : close(io_unit2)
680 : :
681 : 1 : call cpu_time(time2)
682 : 1 : time = time2-time1
683 : 1 : write(timing_string,'(A)') "Time to compute the TRACES of the Dielectric Matrices: "
684 : 1 : call write_timing_log(timing_string,time)
685 : :
686 [ - + ]: 1 : ABI_FREE(Lbasis_exact)
687 [ - + ]: 1 : ABI_FREE(Lbasis_model)
688 [ - + ]: 1 : ABI_FREE(alpha_exact)
689 [ - + ]: 1 : ABI_FREE(beta_exact )
690 [ - + ]: 1 : ABI_FREE(alpha_model)
691 [ - + ]: 1 : ABI_FREE(beta_model )
692 [ - + ]: 1 : ABI_FREE(model_epsilon_matrix)
693 : :
694 : :
695 : :
696 : : 10 format(A)
697 : : 20 format(I5,3ES24.16)
698 : :
699 : 1 : end subroutine Driver_GeneratePrintDielectricEigenvalues
700 : : !!***
701 : :
702 : : end module m_gwls_GenerateEpsilon
703 : : !!***
|