28#include "./base/base_uses.f90"
34 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'bse_iterative'
55 B_iaQ_bse_local, homo, virtual, bse_spin_config, unit_nr, &
56 Eigenval, para_env, mp2_env)
58 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: b_bar_ijq_bse_local, b_abq_bse_local, &
59 b_bar_iaq_bse_local, b_iaq_bse_local
60 INTEGER :: homo, virtual, bse_spin_config, unit_nr
61 REAL(kind=
dp),
DIMENSION(:) :: eigenval
65 CHARACTER(LEN=*),
PARAMETER :: routinen =
'do_subspace_iterations'
67 CHARACTER(LEN=10) :: bse_davidson_abort_cond_string, &
69 INTEGER :: bse_davidson_abort_cond, davidson_converged, fac_max_z_space, handle, i_iter, &
70 j_print, local_ri_size, num_add_start_z_space, num_davidson_iter, num_en_unconverged, &
71 num_exact_en_unconverged, num_exc_en, num_max_z_space, num_new_t, num_res_unconverged, &
72 num_z_vectors, num_z_vectors_init
73 LOGICAL :: bse_full_diag_debug
74 REAL(kind=
dp) :: eps_exc_en, eps_res, max_en_diff, &
75 max_res_norm, z_space_energy_cutoff
76 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: en_diffs, en_diffs_exact, full_exc_spectrum, &
77 res_norms, subspace_full_eigenval, subspace_new_eigenval, subspace_prev_eigenval
78 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: az_reshaped, m_ia_tmp, m_ji_tmp, ri_vector, &
79 subspace_new_eigenvec, subspace_residuals_reshaped, z_vectors_reshaped
80 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: az, bz, subspace_add_dir, &
81 subspace_ritzvec, w_vectors, z_vectors
83 CALL timeset(routinen, handle)
87 bse_full_diag_debug = .true.
88 num_en_unconverged = -1
89 num_res_unconverged = -1
90 num_exact_en_unconverged = -1
92 bse_davidson_abort_cond = mp2_env%bse%davidson_abort_cond
93 num_exc_en = mp2_env%bse%num_exc_en
94 num_add_start_z_space = mp2_env%bse%num_add_start_z_space
95 fac_max_z_space = mp2_env%bse%fac_max_z_space
96 num_new_t = mp2_env%bse%num_new_t
97 num_davidson_iter = mp2_env%bse%num_davidson_iter
98 eps_res = mp2_env%bse%eps_res
99 eps_exc_en = mp2_env%bse%eps_exc_en
100 z_space_energy_cutoff = mp2_env%bse%z_space_energy_cutoff
102 num_z_vectors_init = num_exc_en + num_add_start_z_space
104 IF (unit_nr > 0)
THEN
105 WRITE (unit_nr, *)
"bse_spin_config", bse_spin_config
106 WRITE (unit_nr, *)
"num_exc_en", num_exc_en
107 WRITE (unit_nr, *)
"num_add_start_z_space", num_add_start_z_space
108 WRITE (unit_nr, *)
"num_Z_vectors_init", num_z_vectors_init
109 WRITE (unit_nr, *)
"fac_max_z_space", fac_max_z_space
110 WRITE (unit_nr, *)
"num_new_t", num_new_t
111 WRITE (unit_nr, *)
"eps_res", eps_res
112 WRITE (unit_nr, *)
"num_davidson_iter", num_davidson_iter
113 WRITE (unit_nr, *)
"eps_exc_en", eps_exc_en
114 WRITE (unit_nr, *)
"bse_davidson_abort_cond", bse_davidson_abort_cond
115 WRITE (unit_nr, *)
"z_space_energy_cutoff", z_space_energy_cutoff
116 WRITE (unit_nr, *)
"Printing B_bar_iaQ_bse_local of shape", shape(b_bar_iaq_bse_local)
119 local_ri_size =
SIZE(b_iaq_bse_local, 3)
121 num_z_vectors = num_z_vectors_init
122 num_max_z_space = num_z_vectors_init*fac_max_z_space
125 IF (num_new_t > num_z_vectors_init)
THEN
126 num_new_t = num_z_vectors_init
127 IF (unit_nr > 0)
THEN
128 CALL cp_warn(__location__,
"Number of added directions has to be smaller/equals than "// &
129 "initial dimension. Corrected num_new_t accordingly.")
132 IF (unit_nr > 0)
THEN
133 WRITE (unit_nr, *)
"Between BSE correction Warnings"
136 IF (2*num_z_vectors_init > homo*virtual)
THEN
137 CALL cp_abort(__location__,
"Initial dimension was too large and could not be corrected. "// &
138 "Choose another num_exc_en and num_add_start_z_space or adapt your basis set.")
140 IF (num_max_z_space .GE. homo*virtual)
THEN
141 fac_max_z_space = homo*virtual/num_z_vectors_init
142 num_max_z_space = num_z_vectors_init*fac_max_z_space
144 IF (fac_max_z_space == 0)
THEN
145 CALL cp_abort(__location__,
"Maximal dimension was too large and could not be corrected. "// &
146 "Choose another fac_max_z_space and num_Z_vectors_init or adapt your basis set.")
148 IF (unit_nr > 0)
THEN
149 CALL cp_warn(__location__,
"Maximal dimension of Z space has to be smaller than homo*virtual. "// &
150 "Corrected fac_max_z_space accordingly.")
155 DO i_iter = 1, num_davidson_iter
156 IF (unit_nr > 0)
THEN
157 WRITE (unit_nr, *)
"Allocating Z_vec,AZ,BZ with dimensions (homo,virt,num_Z)", homo, virtual, num_z_vectors
158 WRITE (unit_nr, *)
'ProcNr', para_env%mepos,
'you really enter here for i_iter', i_iter
160 ALLOCATE (z_vectors(homo, virtual, num_z_vectors))
165 IF (i_iter == 1)
THEN
166 CALL initial_guess_z_vectors(z_vectors, eigenval, num_z_vectors, homo, virtual)
167 ALLOCATE (subspace_prev_eigenval(num_exc_en))
168 subspace_prev_eigenval = 0.0_dp
170 z_vectors(:, :, :) = w_vectors(:, :, :)
171 DEALLOCATE (w_vectors)
173 IF (unit_nr > 0)
THEN
174 WRITE (unit_nr, *)
'ProcNr', para_env%mepos,
"Allocated/rewritten Z arrays"
177 CALL create_bse_work_arrays(az, z_vectors_reshaped, az_reshaped, bz, m_ia_tmp, m_ji_tmp, &
178 ri_vector, subspace_new_eigenval, subspace_full_eigenval, subspace_new_eigenvec, &
179 subspace_residuals_reshaped, subspace_ritzvec, subspace_add_dir, w_vectors, &
180 homo, virtual, num_z_vectors, local_ri_size, num_new_t)
181 IF (unit_nr > 0)
THEN
182 WRITE (unit_nr, *)
'ProcNr', para_env%mepos,
"Allocated Work arrays"
185 CALL compute_az(az, z_vectors, b_iaq_bse_local, b_bar_ijq_bse_local, b_abq_bse_local, &
186 m_ia_tmp, ri_vector, eigenval, homo, virtual, num_z_vectors, local_ri_size, &
187 para_env, bse_spin_config, z_space_energy_cutoff, i_iter, bse_full_diag_debug, &
188 full_exc_spectrum, unit_nr)
195 IF (unit_nr > 0)
THEN
196 WRITE (unit_nr, *)
'ProcNr', para_env%mepos,
"Computed AZ"
200 az_reshaped(:, :) = reshape(az, (/homo*virtual, num_z_vectors/))
201 z_vectors_reshaped(:, :) = reshape(z_vectors, (/homo*virtual, num_z_vectors/))
204 CALL compute_diagonalize_zaz(az_reshaped, z_vectors_reshaped, num_z_vectors, subspace_new_eigenval, &
205 subspace_new_eigenvec, num_new_t, subspace_full_eigenval, para_env, unit_nr)
206 IF (unit_nr > 0)
THEN
207 WRITE (unit_nr, *)
"Eigenval (eV) in iter=", i_iter,
" is:", subspace_new_eigenval(:6)*
evolt
211 CALL check_en_convergence(subspace_full_eigenval, subspace_prev_eigenval, eps_exc_en, num_en_unconverged, &
212 num_exc_en, max_en_diff, en_diffs)
213 IF (unit_nr > 0)
THEN
214 WRITE (unit_nr, *)
"Largest change of desired exc ens =", max_en_diff
217 CALL compute_residuals(az_reshaped, z_vectors_reshaped, subspace_new_eigenval, subspace_new_eigenvec, &
218 subspace_residuals_reshaped, homo, virtual, num_new_t, num_z_vectors, subspace_ritzvec)
221 CALL check_res_convergence(subspace_residuals_reshaped, num_new_t, eps_res, num_res_unconverged, &
222 i_iter, max_res_norm, unit_nr, res_norms)
224 davidson_converged = -1
225 IF (num_res_unconverged == 0 .AND. bse_davidson_abort_cond /= 0)
THEN
226 davidson_converged = 1
227 success_abort_string =
"RESIDUALS"
228 ELSE IF (num_en_unconverged == 0 .AND. (bse_davidson_abort_cond /= 1))
THEN
229 davidson_converged = 1
230 success_abort_string =
"ENERGIES"
231 ELSE IF (i_iter == num_davidson_iter)
THEN
232 davidson_converged = -100
233 success_abort_string =
"-----"
235 davidson_converged = -1
238 IF (bse_davidson_abort_cond == 0)
THEN
239 bse_davidson_abort_cond_string =
"ENERGY"
240 ELSE IF (bse_davidson_abort_cond == 1)
THEN
241 bse_davidson_abort_cond_string =
"RESIDUAL"
243 bse_davidson_abort_cond_string =
"EITHER"
246 IF (davidson_converged == 1)
THEN
247 CALL postprocess_bse(subspace_full_eigenval, num_new_t, eps_res, num_res_unconverged, &
248 bse_spin_config, unit_nr, num_exc_en, num_z_vectors_init, &
249 num_davidson_iter, i_iter, num_z_vectors, num_max_z_space, max_res_norm, &
250 max_en_diff, num_en_unconverged, bse_davidson_abort_cond_string, &
251 eps_exc_en, success_abort_string, z_space_energy_cutoff)
254 DEALLOCATE (az, bz, &
255 z_vectors, m_ia_tmp, m_ji_tmp, ri_vector, subspace_prev_eigenval, &
256 subspace_new_eigenval, subspace_new_eigenvec, subspace_residuals_reshaped, &
257 subspace_add_dir, az_reshaped, z_vectors_reshaped, subspace_ritzvec, subspace_full_eigenval)
260 ELSE IF (davidson_converged < -1)
THEN
261 CALL print_davidson_parameter(i_iter, num_davidson_iter, num_z_vectors, num_res_unconverged, max_res_norm, &
262 eps_res, num_en_unconverged, max_en_diff, eps_exc_en, num_exc_en, &
263 num_z_vectors_init, num_max_z_space, num_new_t, unit_nr, &
264 success_abort_string, bse_davidson_abort_cond_string, z_space_energy_cutoff)
266 CALL cp_abort(__location__,
"BSE/TDA-Davidson did not converge using "// &
267 bse_davidson_abort_cond_string//
" threshold condition!")
271 CALL compute_new_directions(homo, virtual, subspace_residuals_reshaped, subspace_new_eigenval, eigenval, &
272 num_new_t, subspace_add_dir)
275 IF (bse_full_diag_debug)
THEN
276 ALLOCATE (en_diffs_exact(num_exc_en))
277 num_exact_en_unconverged = 0
278 DO j_print = 1, num_exc_en
279 en_diffs_exact(j_print) = abs(subspace_full_eigenval(j_print) - full_exc_spectrum(j_print))
280 IF (en_diffs_exact(j_print) > eps_exc_en) num_exact_en_unconverged = num_exact_en_unconverged + 1
285 CALL check_z_space_dimension(w_vectors, z_vectors, subspace_add_dir, subspace_ritzvec, &
286 num_z_vectors, num_new_t, num_max_z_space, homo, virtual, i_iter, unit_nr)
289 subspace_prev_eigenval(:) = subspace_full_eigenval(:num_exc_en)
292 z_vectors, m_ia_tmp, m_ji_tmp, ri_vector, &
293 subspace_new_eigenval, subspace_new_eigenvec, subspace_residuals_reshaped, &
294 subspace_add_dir, az_reshaped, z_vectors_reshaped, subspace_ritzvec, subspace_full_eigenval, &
297 IF (bse_full_diag_debug)
THEN
298 DEALLOCATE (en_diffs_exact)
302 CALL orthonormalize_w(w_vectors, num_z_vectors, homo, virtual)
306 CALL timestop(handle)
324 SUBROUTINE check_z_space_dimension(W_vectors, Z_vectors, Subspace_add_dir, Subspace_ritzvec, &
325 num_Z_vectors, num_new_t, num_max_z_space, homo, virtual, i_iter, unit_nr)
327 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: w_vectors, z_vectors, subspace_add_dir, &
329 INTEGER :: num_z_vectors, num_new_t, &
330 num_max_z_space, homo, virtual, &
333 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_Z_space_dimension'
337 CALL timeset(routinen, handle)
339 IF (num_z_vectors + num_new_t .LE. num_max_z_space)
THEN
340 w_vectors(:, :, :num_z_vectors) = z_vectors(:, :, :)
341 w_vectors(:, :, num_z_vectors + 1:) = subspace_add_dir
342 num_z_vectors = num_z_vectors + num_new_t
344 IF (unit_nr > 0)
THEN
345 WRITE (unit_nr, *)
"Resetting dimension in i_iter=", i_iter
347 DEALLOCATE (w_vectors)
348 ALLOCATE (w_vectors(homo, virtual, 2*num_new_t))
349 w_vectors(:, :, :num_new_t) = subspace_ritzvec(:, :, :)
350 w_vectors(:, :, num_new_t + 1:) = subspace_add_dir
351 num_z_vectors = 2*num_new_t
354 CALL timestop(handle)
380 SUBROUTINE create_bse_work_arrays(AZ, Z_vectors_reshaped, AZ_reshaped, BZ, M_ia_tmp, M_ji_tmp, &
381 RI_vector, Subspace_new_eigenval, Subspace_full_eigenval, Subspace_new_eigenvec, &
382 Subspace_residuals_reshaped, Subspace_ritzvec, Subspace_add_dir, W_vectors, &
383 homo, virtual, num_Z_vectors, local_RI_size, num_new_t)
385 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: az
386 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: z_vectors_reshaped, az_reshaped
387 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: bz
388 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: m_ia_tmp, m_ji_tmp, ri_vector
389 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: subspace_new_eigenval, &
390 subspace_full_eigenval
391 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: subspace_new_eigenvec, &
392 subspace_residuals_reshaped
393 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: subspace_ritzvec, subspace_add_dir, &
395 INTEGER :: homo, virtual, num_z_vectors, &
396 local_ri_size, num_new_t
398 CHARACTER(LEN=*),
PARAMETER :: routinen =
'create_bse_work_arrays'
402 CALL timeset(routinen, handle)
404 ALLOCATE (az(homo, virtual, num_z_vectors))
407 ALLOCATE (z_vectors_reshaped(homo*virtual, num_z_vectors))
408 z_vectors_reshaped = 0.0_dp
410 ALLOCATE (az_reshaped(homo*virtual, num_z_vectors))
413 ALLOCATE (bz(homo, virtual, num_z_vectors))
416 ALLOCATE (m_ia_tmp(homo, virtual))
419 ALLOCATE (m_ji_tmp(homo, homo))
422 ALLOCATE (ri_vector(local_ri_size, num_z_vectors))
425 ALLOCATE (subspace_new_eigenval(num_new_t))
426 subspace_new_eigenval = 0.0_dp
428 ALLOCATE (subspace_full_eigenval(num_z_vectors))
429 subspace_full_eigenval = 0.0_dp
431 ALLOCATE (subspace_new_eigenvec(num_z_vectors, num_new_t))
432 subspace_new_eigenvec = 0.0_dp
434 ALLOCATE (subspace_residuals_reshaped(homo*virtual, num_new_t))
435 subspace_residuals_reshaped = 0.0_dp
437 ALLOCATE (subspace_ritzvec(homo, virtual, num_new_t))
438 subspace_ritzvec = 0.0_dp
440 ALLOCATE (subspace_add_dir(homo, virtual, num_new_t))
441 subspace_add_dir = 0.0_dp
443 ALLOCATE (w_vectors(homo, virtual, num_z_vectors + num_new_t))
446 CALL timestop(handle)
472 SUBROUTINE postprocess_bse(Subspace_full_eigenval, num_new_t, eps_res, num_res_unconverged, &
473 bse_spin_config, unit_nr, num_exc_en, num_Z_vectors_init, &
474 num_davidson_iter, i_iter, num_Z_vectors, num_max_z_space, max_res_norm, &
475 max_en_diff, num_en_unconverged, bse_davidson_abort_cond_string, &
476 eps_exc_en, success_abort_string, z_space_energy_cutoff)
478 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: subspace_full_eigenval
480 REAL(kind=
dp) :: eps_res
481 INTEGER :: num_res_unconverged, bse_spin_config, unit_nr, num_exc_en, num_z_vectors_init, &
482 num_davidson_iter, i_iter, num_z_vectors, num_max_z_space
483 REAL(kind=
dp) :: max_res_norm, max_en_diff
484 INTEGER :: num_en_unconverged
485 CHARACTER(LEN=10) :: bse_davidson_abort_cond_string
486 REAL(kind=
dp) :: eps_exc_en
487 CHARACTER(LEN=10) :: success_abort_string
488 REAL(kind=
dp) :: z_space_energy_cutoff
490 CHARACTER(LEN=*),
PARAMETER :: routinen =
'postprocess_bse'
492 CHARACTER(LEN=10) :: multiplet
494 REAL(kind=
dp) :: alpha
496 CALL timeset(routinen, handle)
499 SELECT CASE (bse_spin_config)
502 multiplet =
"Singlet"
505 multiplet =
"Triplet"
508 IF (unit_nr > 0)
THEN
509 WRITE (unit_nr, *)
' '
510 WRITE (unit_nr,
'(T3,A)')
'******************************************************************************'
511 WRITE (unit_nr,
'(T3,A)')
'** **'
512 WRITE (unit_nr,
'(T3,A)')
'** BSE-TDA EXCITONIC ENERGIES **'
513 WRITE (unit_nr,
'(T3,A)')
'** **'
514 WRITE (unit_nr,
'(T3,A)')
'******************************************************************************'
515 WRITE (unit_nr,
'(T3,A)')
' '
516 WRITE (unit_nr,
'(T3,A)')
' '
517 WRITE (unit_nr,
'(T3,A)')
' The excitation energies are calculated by iteratively diagonalizing: '
518 WRITE (unit_nr,
'(T3,A)')
' '
519 WRITE (unit_nr,
'(T3,A)')
' A_iajb = (E_a-E_i) delta_ij delta_ab + alpha * v_iajb - W_ijab '
520 WRITE (unit_nr,
'(T3,A)')
' '
521 WRITE (unit_nr,
'(T3,A48,A7,A12,F3.1)') &
522 ' The spin-dependent factor for the requested ', multiplet,
" is alpha = ", alpha
523 WRITE (unit_nr,
'(T3,A)')
' '
524 WRITE (unit_nr,
'(T3,A16,T50,A22)') &
525 ' Excitonic level',
'Excitation energy (eV)'
528 WRITE (unit_nr,
'(T3,I16,T50,F22.3)') i, subspace_full_eigenval(i)*
evolt
531 WRITE (unit_nr,
'(T3,A)')
' '
534 CALL print_davidson_parameter(i_iter, num_davidson_iter, num_z_vectors, num_res_unconverged, max_res_norm, &
535 eps_res, num_en_unconverged, max_en_diff, eps_exc_en, num_exc_en, &
536 num_z_vectors_init, num_max_z_space, num_new_t, unit_nr, &
537 success_abort_string, bse_davidson_abort_cond_string, z_space_energy_cutoff)
540 IF (num_en_unconverged > 0)
THEN
541 WRITE (unit_nr,
'(T3,A)')
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
542 WRITE (unit_nr,
'(T3,A2,T79,A2)')
'!!',
"!!"
543 WRITE (unit_nr,
'(T3,A2,T8,A65,T79,A2)')
'!!',
"THERE ARE UNCONVERGED ENERGIES PRINTED OUT, SOMETHING WENT WRONG!",
"!!"
544 WRITE (unit_nr,
'(T3,A2,T79,A2)')
'!!',
"!!"
545 WRITE (unit_nr,
'(T3,A)')
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
549 CALL timestop(handle)
573 SUBROUTINE print_davidson_parameter(i_iter, num_davidson_iter, num_Z_vectors, num_res_unconverged, max_res_norm, &
574 eps_res, num_en_unconverged, max_en_diff, eps_exc_en, num_exc_en, &
575 num_Z_vectors_init, num_max_z_space, num_new_t, unit_nr, &
576 success_abort_string, bse_davidson_abort_cond_string, z_space_energy_cutoff)
578 INTEGER :: i_iter, num_davidson_iter, &
579 num_z_vectors, num_res_unconverged
580 REAL(kind=
dp) :: max_res_norm, eps_res
581 INTEGER :: num_en_unconverged
582 REAL(kind=
dp) :: max_en_diff, eps_exc_en
583 INTEGER :: num_exc_en, num_z_vectors_init, &
584 num_max_z_space, num_new_t, unit_nr
585 CHARACTER(LEN=10) :: success_abort_string, &
586 bse_davidson_abort_cond_string
587 REAL(kind=
dp) :: z_space_energy_cutoff
589 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_davidson_parameter'
593 CALL timeset(routinen, handle)
595 WRITE (unit_nr,
'(T3,A)')
'******************************************************************************'
596 WRITE (unit_nr,
'(T3,A2,T15,A49,T79,A2)') &
597 '**',
"Parameters of the BSE-Davidson solver:",
"**"
598 WRITE (unit_nr,
'(T3,A2,T79,A2)') &
600 WRITE (unit_nr,
'(T3,A2,T79,A2)') &
602 WRITE (unit_nr,
'(T3,A2,T10,A16,I5,A12,I5,A8,T79,A2)') &
603 '**',
"Converged after ", i_iter,
" of maximal ", num_davidson_iter,
" cycles,",
"**"
604 WRITE (unit_nr,
'(T3,A2,T20,A11,A9,A7,A8,A20,T79,A2)') &
605 '**',
"because of ", success_abort_string,
" using ", &
606 bse_davidson_abort_cond_string,
" threshold condition",
"**"
607 WRITE (unit_nr,
'(T3,A2,T79,A2)') &
609 WRITE (unit_nr,
'(T3,A2,T10,A32,T65,I11,T79,A2)') &
610 '**',
"The Z space has at the end dim. ", num_z_vectors,
"**"
611 WRITE (unit_nr,
'(T3,A2,T10,A45,T65,I11,T79,A2)') &
612 '**',
"Number of unconverged residuals in subspace: ", num_res_unconverged,
"**"
613 WRITE (unit_nr,
'(T3,A2,T10,A35,T65,E11.4,T79,A2)') &
614 '**',
"largest unconverged residual (eV): ", max_res_norm*
evolt,
"**"
615 WRITE (unit_nr,
'(T3,A2,T10,A45,T65,E11.4,T79,A2)') &
616 '**',
"threshold for convergence of residuals (eV): ", eps_res*
evolt,
"**"
617 WRITE (unit_nr,
'(T3,A2,T10,A45,T65,I11,T79,A2)') &
618 '**',
"Number of desired, but unconverged energies: ", num_en_unconverged,
"**"
619 WRITE (unit_nr,
'(T3,A2,T10,A44,T65,E11.4,T79,A2)') &
620 '**',
"largest unconverged energy difference (eV): ", max_en_diff*
evolt,
"**"
621 WRITE (unit_nr,
'(T3,A2,T10,A44,T65,E11.4,T79,A2)') &
622 '**',
"threshold for convergence of energies (eV): ", eps_exc_en*
evolt,
"**"
623 WRITE (unit_nr,
'(T3,A2,T10,A40,T65,I11,T79,A2)') &
624 '**',
"number of computed excitation energies: ", num_exc_en,
"**"
626 IF (z_space_energy_cutoff > 0)
THEN
627 WRITE (unit_nr,
'(T3,A2,T10,A37,T65,E11.4,T79,A2)') &
628 '**',
"cutoff for excitation energies (eV): ", z_space_energy_cutoff*
evolt,
"**"
631 WRITE (unit_nr,
'(T3,A2,T10,A36,T65,I11,T79,A2)') &
632 '**',
"number of Z space at the beginning: ", num_z_vectors_init,
"**"
633 WRITE (unit_nr,
'(T3,A2,T10,A30,T65,I11,T79,A2)') &
634 '**',
"maximal dimension of Z space: ", num_max_z_space,
"**"
635 WRITE (unit_nr,
'(T3,A2,T10,A31,T65,I11,T79,A2)') &
636 '**',
"added directions per iteration: ", num_new_t,
"**"
637 WRITE (unit_nr,
'(T3,A2,T79,A2)') &
639 WRITE (unit_nr,
'(T3,A2,T79,A2)') &
641 WRITE (unit_nr,
'(T3,A)')
'******************************************************************************'
642 WRITE (unit_nr,
'(T3,A)')
' '
644 CALL timestop(handle)
658 SUBROUTINE check_en_convergence(Subspace_full_eigenval, Subspace_prev_eigenval, eps_exc_en, num_en_unconverged, &
659 num_exc_en, max_en_diff, En_diffs)
661 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: subspace_full_eigenval, &
662 subspace_prev_eigenval
663 REAL(kind=
dp) :: eps_exc_en
664 INTEGER :: num_en_unconverged, num_exc_en
665 REAL(kind=
dp) :: max_en_diff
666 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: en_diffs
668 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_en_convergence'
670 INTEGER :: handle, mu_l
672 CALL timeset(routinen, handle)
674 num_en_unconverged = 0
675 ALLOCATE (en_diffs(num_exc_en))
676 DO mu_l = 1, num_exc_en
677 en_diffs(mu_l) = abs(subspace_full_eigenval(mu_l) - subspace_prev_eigenval(mu_l))
678 IF (en_diffs(mu_l) > eps_exc_en) num_en_unconverged = num_en_unconverged + 1
680 max_en_diff = maxval(en_diffs)
682 CALL timestop(handle)
697 SUBROUTINE check_res_convergence(Subspace_residuals_reshaped, num_new_t, eps_res, num_res_unconverged, &
698 i_iter, max_res_norm, unit_nr, Res_norms)
700 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: subspace_residuals_reshaped
702 REAL(kind=
dp) :: eps_res
703 INTEGER :: num_res_unconverged, i_iter
704 REAL(kind=
dp) :: max_res_norm
706 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: res_norms
708 CHARACTER(LEN=*),
PARAMETER :: routinen =
'check_res_convergence'
710 INTEGER :: handle, mu_l
712 CALL timeset(routinen, handle)
714 num_res_unconverged = 0
715 ALLOCATE (res_norms(num_new_t))
716 DO mu_l = 1, num_new_t
717 res_norms(mu_l) = norm2(subspace_residuals_reshaped(:, mu_l))
718 IF (res_norms(mu_l) > eps_res)
THEN
719 num_res_unconverged = num_res_unconverged + 1
720 IF (unit_nr > 0)
THEN
721 WRITE (unit_nr, *)
"Unconverged res in i_iter=", i_iter,
"is:", res_norms(mu_l)
725 max_res_norm = maxval(res_norms)
726 IF (unit_nr > 0)
THEN
727 WRITE (unit_nr, *)
"Maximal unconverged res (of ", num_res_unconverged, &
728 " unconverged res in this step) in i_iter=", i_iter,
"is:", max_res_norm
731 CALL timestop(handle)
742 SUBROUTINE orthonormalize_w(W_vectors, num_Z_vectors, homo, virtual)
744 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: w_vectors
745 INTEGER :: num_z_vectors, homo, virtual
747 CHARACTER(LEN=*),
PARAMETER :: routinen =
'orthonormalize_W'
749 INTEGER :: handle, info_dor, info_orth, lwork_dor, &
751 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: tau_w, work_w, work_w_dor
752 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: w_vectors_reshaped
754 CALL timeset(routinen, handle)
756 ALLOCATE (w_vectors_reshaped(homo*virtual, num_z_vectors))
757 w_vectors_reshaped(:, :) = reshape(w_vectors, (/homo*virtual, num_z_vectors/))
759 ALLOCATE (tau_w(min(homo*virtual, num_z_vectors)))
765 ALLOCATE (work_w_dor(1))
768 CALL dgeqrf(homo*virtual, num_z_vectors, w_vectors_reshaped, homo*virtual, tau_w, work_w, -1, info_orth)
769 lwork_w = int(work_w(1))
771 ALLOCATE (work_w(lwork_w))
773 CALL dgeqrf(homo*virtual, num_z_vectors, w_vectors_reshaped, homo*virtual, tau_w, work_w, lwork_w, info_orth)
774 IF (info_orth /= 0)
THEN
775 cpabort(
"QR Decomp Step 1 doesnt work")
777 CALL dorgqr(homo*virtual, num_z_vectors, min(homo*virtual, num_z_vectors), w_vectors_reshaped, homo*virtual, &
778 tau_w, work_w_dor, -1, info_dor)
779 lwork_dor = int(work_w_dor(1))
780 DEALLOCATE (work_w_dor)
781 ALLOCATE (work_w_dor(lwork_dor))
783 CALL dorgqr(homo*virtual, num_z_vectors, min(homo*virtual, num_z_vectors), w_vectors_reshaped, homo*virtual, &
784 tau_w, work_w_dor, lwork_dor, info_dor)
785 IF (info_orth /= 0)
THEN
786 cpabort(
"QR Decomp Step 2 doesnt work")
789 w_vectors(:, :, :) = reshape(w_vectors_reshaped, (/homo, virtual, num_z_vectors/))
791 DEALLOCATE (work_w, work_w_dor, tau_w, w_vectors_reshaped)
793 CALL timestop(handle)
807 SUBROUTINE compute_new_directions(homo, virtual, Subspace_residuals_reshaped, Subspace_new_eigenval, Eigenval, &
808 num_new_t, Subspace_add_dir)
810 INTEGER :: homo, virtual
811 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: subspace_residuals_reshaped
812 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: subspace_new_eigenval
813 REAL(kind=
dp),
DIMENSION(:) :: eigenval
815 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: subspace_add_dir
817 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_new_directions'
819 INTEGER :: a_virt, handle, i_occ, mu_subspace, &
821 REAL(kind=
dp) :: prec_scalar
822 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: subspace_add_dir_reshaped
824 CALL timeset(routinen, handle)
826 ALLOCATE (subspace_add_dir_reshaped(homo*virtual, num_new_t))
829 DO mu_subspace = 1, num_new_t
831 DO a_virt = 1, virtual
833 prec_scalar = -1/(subspace_new_eigenval(mu_subspace) - (eigenval(a_virt + homo) - eigenval(i_occ)))
834 IF (prec_scalar < 0)
THEN
835 prec_neg = prec_neg + 1
838 subspace_add_dir_reshaped((i_occ - 1)*virtual + a_virt, mu_subspace) = prec_scalar* &
839 subspace_residuals_reshaped((i_occ - 1)*virtual + a_virt, mu_subspace)
844 subspace_add_dir(:, :, :) = reshape(subspace_add_dir_reshaped, (/homo, virtual, num_new_t/))
846 DEALLOCATE (subspace_add_dir_reshaped)
847 CALL timestop(handle)
864 SUBROUTINE compute_residuals(AZ_reshaped, Z_vectors_reshaped, Subspace_new_eigenval, Subspace_new_eigenvec, &
865 Subspace_residuals_reshaped, homo, virtual, num_new_t, num_Z_vectors, Subspace_ritzvec)
867 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: az_reshaped, z_vectors_reshaped
868 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: subspace_new_eigenval
869 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: subspace_new_eigenvec, &
870 subspace_residuals_reshaped
871 INTEGER :: homo, virtual, num_new_t, num_z_vectors
872 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: subspace_ritzvec
874 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_residuals'
876 INTEGER :: handle, mu_subspace
877 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: subspace_res_a, subspace_res_ev
879 CALL timeset(routinen, handle)
881 ALLOCATE (subspace_res_ev(homo*virtual, num_new_t))
882 subspace_res_ev = 0.0_dp
884 ALLOCATE (subspace_res_a(homo*virtual, num_new_t))
885 subspace_res_a = 0.0_dp
888 DO mu_subspace = 1, num_new_t
890 CALL dgemm(
"N",
"N", homo*virtual, 1, num_z_vectors, 1.0_dp, z_vectors_reshaped, homo*virtual, &
891 subspace_new_eigenvec(:, mu_subspace), num_z_vectors, 0.0_dp, subspace_res_ev(:, mu_subspace), homo*virtual)
893 CALL dgemm(
"N",
"N", homo*virtual, 1, num_z_vectors, 1.0_dp, az_reshaped, homo*virtual, &
894 subspace_new_eigenvec(:, mu_subspace), num_z_vectors, 0.0_dp, subspace_res_a(:, mu_subspace), homo*virtual)
896 subspace_residuals_reshaped(:, mu_subspace) = subspace_new_eigenval(mu_subspace)*subspace_res_ev(:, mu_subspace) &
897 - subspace_res_a(:, mu_subspace)
900 subspace_ritzvec(:, :, :) = reshape(subspace_res_ev, (/homo, virtual, num_new_t/))
901 DEALLOCATE (subspace_res_ev, subspace_res_a)
903 CALL timestop(handle)
919 SUBROUTINE compute_diagonalize_zaz(AZ_reshaped, Z_vectors_reshaped, num_Z_vectors, Subspace_new_eigenval, &
920 Subspace_new_eigenvec, num_new_t, Subspace_full_eigenval, para_env, unit_nr)
922 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: az_reshaped, z_vectors_reshaped
923 INTEGER,
INTENT(in) :: num_z_vectors
924 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: subspace_new_eigenval
925 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: subspace_new_eigenvec
926 INTEGER,
INTENT(in) :: num_new_t
927 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: subspace_full_eigenval
929 INTEGER,
INTENT(in) :: unit_nr
931 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_diagonalize_ZAZ'
933 INTEGER :: handle, i_z_vector, j_z_vector, lwork, &
935 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
936 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: zaz
938 CALL timeset(routinen, handle)
940 ALLOCATE (zaz(num_z_vectors, num_z_vectors))
945 DO i_z_vector = 1, num_z_vectors
946 DO j_z_vector = 1, num_z_vectors
947 zaz(j_z_vector, i_z_vector) = dot_product(z_vectors_reshaped(:, j_z_vector), az_reshaped(:, i_z_vector))
950 IF (unit_nr > 0)
THEN
951 WRITE (unit_nr, *)
'ProcNr', para_env%mepos,
"Before Diag"
957 CALL dsyev(
"V",
"U", num_z_vectors, zaz, num_z_vectors, subspace_full_eigenval, work, -1, zaz_diag_info)
960 ALLOCATE (work(lwork))
963 CALL dsyev(
"V",
"U", num_z_vectors, zaz, num_z_vectors, subspace_full_eigenval, work, lwork, zaz_diag_info)
965 IF (zaz_diag_info /= 0)
THEN
966 cpabort(
"ZAZ could not be diagonalized successfully.")
969 IF (unit_nr > 0)
THEN
970 WRITE (unit_nr, *)
'ProcNr', para_env%mepos,
"After Diag"
973 subspace_new_eigenval(1:num_new_t) = subspace_full_eigenval(1:num_new_t)
974 subspace_new_eigenvec(:, 1:num_new_t) = zaz(:, 1:num_new_t)
978 CALL timestop(handle)
995 SUBROUTINE compute_bz(BZ, Z_vectors, B_iaQ_bse_local, B_bar_iaQ_bse_local, &
996 M_ji_tmp, homo, virtual, num_Z_vectors, local_RI_size, para_env)
998 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: bz, z_vectors, b_iaq_bse_local, &
1000 REAL(kind=
dp),
DIMENSION(:, :) :: m_ji_tmp
1001 INTEGER :: homo, virtual, num_z_vectors, &
1005 INTEGER :: i_z_vector, lll
1007 bz(:, :, :) = 0.0_dp
1012 DO i_z_vector = 1, num_z_vectors
1014 DO lll = 1, local_ri_size
1017 CALL dgemm(
"N",
"T", homo, homo, virtual, 1.0_dp, z_vectors(:, :, i_z_vector), homo, &
1018 b_iaq_bse_local(:, :, lll), homo, 0.0_dp, m_ji_tmp, homo)
1020 CALL dgemm(
"T",
"N", homo, virtual, homo, 1.0_dp, m_ji_tmp, homo, &
1021 b_bar_iaq_bse_local, homo, 1.0_dp, bz(:, :, i_z_vector), homo)
1028 CALL para_env%sum(bz)
1054 SUBROUTINE compute_az(AZ, Z_vectors, B_iaQ_bse_local, B_bar_ijQ_bse_local, B_abQ_bse_local, M_ia_tmp, &
1055 RI_vector, Eigenval, homo, virtual, num_Z_vectors, local_RI_size, &
1056 para_env, bse_spin_config, z_space_energy_cutoff, i_iter, bse_full_diag_debug, &
1057 Full_exc_spectrum, unit_nr)
1059 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: az, z_vectors, b_iaq_bse_local, &
1060 b_bar_ijq_bse_local, b_abq_bse_local
1061 REAL(kind=
dp),
DIMENSION(:, :) :: m_ia_tmp, ri_vector
1062 REAL(kind=
dp),
DIMENSION(:) :: eigenval
1063 INTEGER :: homo, virtual, num_z_vectors, &
1066 INTEGER :: bse_spin_config
1067 REAL(kind=
dp) :: z_space_energy_cutoff
1069 LOGICAL :: bse_full_diag_debug
1070 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: full_exc_spectrum
1073 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_AZ'
1075 INTEGER :: a, a_virt, b, diag_info, handle, i, &
1076 i_occ, i_z_vector, j, lll, lwork, m, n
1077 REAL(kind=
dp) :: eigen_diff
1078 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: work
1079 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: a_full_reshaped
1080 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :, :) :: a_full, v_iajb, w_ijab
1082 CALL timeset(routinen, handle)
1083 az(:, :, :) = 0.0_dp
1085 IF (i_iter == 1 .AND. bse_full_diag_debug)
THEN
1086 ALLOCATE (w_ijab(homo, homo, virtual, virtual))
1087 ALLOCATE (a_full(homo, virtual, homo, virtual))
1088 ALLOCATE (a_full_reshaped(homo*virtual, homo*virtual))
1089 ALLOCATE (full_exc_spectrum(homo*virtual))
1092 a_full_reshaped = 0.0_dp
1093 full_exc_spectrum = 0.0_dp
1096 CALL compute_v_ia_jb_part(az, z_vectors, b_iaq_bse_local, ri_vector, local_ri_size, &
1097 num_z_vectors, homo, virtual, bse_spin_config, v_iajb, bse_full_diag_debug, i_iter, &
1100 DO i_z_vector = 1, num_z_vectors
1102 DO lll = 1, local_ri_size
1105 CALL dgemm(
"N",
"N", homo, virtual, virtual, 1.0_dp, z_vectors(:, :, i_z_vector), homo, &
1106 b_abq_bse_local(:, :, lll), virtual, 0.0_dp, m_ia_tmp, homo)
1109 CALL dgemm(
"N",
"N", homo, virtual, homo, -1.0_dp, b_bar_ijq_bse_local(:, :, lll), homo, &
1110 m_ia_tmp, homo, 1.0_dp, az(:, :, i_z_vector), homo)
1115 IF (i_iter == 1 .AND. bse_full_diag_debug)
THEN
1118 DO lll = 1, local_ri_size
1123 w_ijab(i, j, a, b) = w_ijab(i, j, a, b) + b_bar_ijq_bse_local(i, j, lll)*b_abq_bse_local(a, b, lll)
1130 CALL para_env%sum(w_ijab)
1134 CALL para_env%sum(az)
1138 DO a_virt = 1, virtual
1140 eigen_diff = eigenval(a_virt + homo) - eigenval(i_occ)
1141 IF (unit_nr > 0 .AND. i_iter == 1)
THEN
1142 WRITE (unit_nr, *)
"Ediff at (i_occ,a_virt)=", i_occ, a_virt,
" is: ", eigen_diff
1145 az(i_occ, a_virt, :) = az(i_occ, a_virt, :) + z_vectors(i_occ, a_virt, :)*eigen_diff
1151 IF (z_space_energy_cutoff > 0)
THEN
1153 DO a_virt = 1, virtual
1155 IF (eigenval(a_virt + homo) > z_space_energy_cutoff .OR. -eigenval(i_occ) > z_space_energy_cutoff)
THEN
1156 az(i_occ, a_virt, :) = 0
1164 IF (i_iter == 1 .AND. bse_full_diag_debug)
THEN
1173 IF (a == b .AND. i == j)
THEN
1174 eigen_diff = eigenval(a + homo) - eigenval(i)
1178 a_full_reshaped(n, m) = eigen_diff + 2*v_iajb(i, a, j, b) - w_ijab(i, j, a, b)
1179 a_full(i, a, j, b) = eigen_diff + 2*v_iajb(i, a, j, b) - w_ijab(i, j, a, b)
1188 CALL dsyev(
"N",
"U", homo*virtual, a_full_reshaped, homo*virtual, full_exc_spectrum, work, -1, diag_info)
1189 lwork = int(work(1))
1191 ALLOCATE (work(lwork))
1194 CALL dsyev(
"N",
"U", homo*virtual, a_full_reshaped, homo*virtual, full_exc_spectrum, work, lwork, diag_info)
1198 DEALLOCATE (w_ijab, v_iajb, a_full, a_full_reshaped)
1201 CALL timestop(handle)
1221 SUBROUTINE compute_v_ia_jb_part(AZ, Z_vectors, B_iaQ_bse_local, RI_vector, local_RI_size, &
1222 num_Z_vectors, homo, virtual, bse_spin_config, v_iajb, bse_full_diag_debug, i_iter, &
1225 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT) :: az, z_vectors, b_iaq_bse_local
1226 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: ri_vector
1227 INTEGER,
INTENT(IN) :: local_ri_size, num_z_vectors, homo, &
1228 virtual, bse_spin_config
1229 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :, :) :: v_iajb
1230 LOGICAL :: bse_full_diag_debug
1231 INTEGER,
INTENT(IN) :: i_iter
1234 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_v_ia_jb_part'
1236 INTEGER :: a, a_virt, b, handle, i, i_occ, &
1238 REAL(kind=
dp) :: alpha
1242 CALL timeset(routinen, handle)
1245 SELECT CASE (bse_spin_config)
1255 DO lll = 1, local_ri_size
1256 DO i_z_vector = 1, num_z_vectors
1258 DO a_virt = 1, virtual
1260 ri_vector(lll, i_z_vector) = ri_vector(lll, i_z_vector) + &
1261 z_vectors(i_occ, a_virt, i_z_vector)* &
1262 b_iaq_bse_local(i_occ, a_virt, lll)
1270 DO lll = 1, local_ri_size
1271 DO i_z_vector = 1, num_z_vectors
1273 DO a_virt = 1, virtual
1275 az(i_occ, a_virt, i_z_vector) = az(i_occ, a_virt, i_z_vector) + &
1276 alpha*ri_vector(lll, i_z_vector)* &
1277 b_iaq_bse_local(i_occ, a_virt, lll)
1283 IF (i_iter == 1 .AND. bse_full_diag_debug)
THEN
1284 ALLOCATE (v_iajb(homo, virtual, homo, virtual))
1287 DO lll = 1, local_ri_size
1292 v_iajb(i, a, j, b) = v_iajb(i, a, j, b) + b_iaq_bse_local(i, a, lll)*b_iaq_bse_local(j, b, lll)
1299 CALL para_env%sum(v_iajb)
1302 CALL timestop(handle)
1314 SUBROUTINE initial_guess_z_vectors(Z_vectors, Eigenval, num_Z_vectors, homo, virtual)
1316 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(INOUT) :: z_vectors
1317 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: eigenval
1318 INTEGER,
INTENT(IN) :: num_z_vectors, homo, virtual
1320 CHARACTER(LEN=*),
PARAMETER :: routinen =
'initial_guess_Z_vectors'
1322 INTEGER :: a_virt, handle, i_occ, i_z_vector, &
1324 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigen_diff_ia
1326 CALL timeset(routinen, handle)
1328 ALLOCATE (eigen_diff_ia(homo, virtual))
1331 DO a_virt = 1, virtual
1332 eigen_diff_ia(i_occ, a_virt) = eigenval(a_virt + homo) - eigenval(i_occ)
1336 DO i_z_vector = 1, num_z_vectors
1338 min_loc = minloc(eigen_diff_ia)
1340 z_vectors(min_loc(1), min_loc(2), i_z_vector) = 1.0_dp
1342 eigen_diff_ia(min_loc(1), min_loc(2)) = 1.0e20_dp
1346 DEALLOCATE (eigen_diff_ia)
1348 CALL timestop(handle)
1370 fm_mat_S_bar_ia_bse, fm_mat_S_bar_ij_bse, &
1371 B_bar_ijQ_bse_local, B_abQ_bse_local, B_bar_iaQ_bse_local, &
1372 B_iaQ_bse_local, dimen_RI, homo, virtual, &
1373 gd_array, color_sub, para_env)
1375 TYPE(
cp_fm_type),
INTENT(IN) :: fm_mat_s_ab_bse, fm_mat_s, &
1376 fm_mat_s_bar_ia_bse, &
1378 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
1379 INTENT(OUT) :: b_bar_ijq_bse_local, b_abq_bse_local, &
1380 b_bar_iaq_bse_local, b_iaq_bse_local
1381 INTEGER,
INTENT(IN) :: dimen_ri, homo, virtual
1383 INTEGER,
INTENT(IN) :: color_sub
1386 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fill_local_3c_arrays'
1390 CALL timeset(routinen, handle)
1392 CALL allocate_and_fill_local_array(b_iaq_bse_local, fm_mat_s, gd_array, color_sub, homo, virtual, dimen_ri, para_env)
1394 CALL allocate_and_fill_local_array(b_bar_iaq_bse_local, fm_mat_s_bar_ia_bse, gd_array, color_sub, homo, virtual, &
1397 CALL allocate_and_fill_local_array(b_bar_ijq_bse_local, fm_mat_s_bar_ij_bse, gd_array, color_sub, homo, homo, &
1400 CALL allocate_and_fill_local_array(b_abq_bse_local, fm_mat_s_ab_bse, gd_array, color_sub, virtual, virtual, &
1403 CALL timestop(handle)
1418 SUBROUTINE allocate_and_fill_local_array(B_local, fm_mat_S, gd_array, &
1419 color_sub, small_size, big_size, dimen_RI, para_env)
1421 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
1422 INTENT(OUT) :: b_local
1425 INTEGER,
INTENT(IN) :: color_sub, small_size, big_size, dimen_ri
1428 CHARACTER(LEN=*),
PARAMETER :: routinen =
'allocate_and_fill_local_array'
1430 INTEGER :: combi_index, end_ri, handle, handle1, i_comm, i_entry, iib, imepos, jjb, &
1431 level_big_size, level_small_size, ncol_local, nrow_local, num_comm_cycles, ri_index, &
1433 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: entry_counter, mepos_from_ri_index, &
1434 num_entries_rec, num_entries_send
1435 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1436 REAL(kind=
dp) :: matrix_el
1438 DIMENSION(:) :: buffer_rec, buffer_send
1441 CALL timeset(routinen, handle)
1443 ALLOCATE (mepos_from_ri_index(dimen_ri))
1444 mepos_from_ri_index = 0
1446 DO imepos = 0, para_env%num_pe - 1
1448 CALL get_group_dist(gd_array, pos=imepos, starts=start_ri, ends=end_ri)
1450 mepos_from_ri_index(start_ri:end_ri) = imepos
1455 CALL get_group_dist(gd_array, color_sub, start_ri, end_ri, size_ri)
1457 ALLOCATE (b_local(small_size, big_size, 1:size_ri))
1459 ALLOCATE (num_entries_send(0:para_env%num_pe - 1))
1460 ALLOCATE (num_entries_rec(0:para_env%num_pe - 1))
1462 ALLOCATE (req_array(1:para_env%num_pe, 4))
1464 ALLOCATE (entry_counter(0:para_env%num_pe - 1))
1467 nrow_local=nrow_local, &
1468 ncol_local=ncol_local, &
1469 row_indices=row_indices, &
1470 col_indices=col_indices)
1472 num_comm_cycles = 10
1476 DO i_comm = 0, num_comm_cycles - 1
1478 num_entries_send = 0
1482 DO jjb = 1, nrow_local
1484 ri_index = row_indices(jjb)
1486 IF (
modulo(ri_index, num_comm_cycles) /= i_comm) cycle
1488 imepos = mepos_from_ri_index(ri_index)
1490 num_entries_send(imepos) = num_entries_send(imepos) + ncol_local
1494 CALL para_env%alltoall(num_entries_send, num_entries_rec, 1)
1496 ALLOCATE (buffer_rec(0:para_env%num_pe - 1))
1497 ALLOCATE (buffer_send(0:para_env%num_pe - 1))
1500 DO imepos = 0, para_env%num_pe - 1
1502 ALLOCATE (buffer_rec(imepos)%msg(num_entries_rec(imepos)))
1503 buffer_rec(imepos)%msg = 0.0_dp
1505 ALLOCATE (buffer_send(imepos)%msg(num_entries_send(imepos)))
1506 buffer_send(imepos)%msg = 0.0_dp
1508 ALLOCATE (buffer_rec(imepos)%indx(num_entries_rec(imepos), 3))
1509 buffer_rec(imepos)%indx = 0
1511 ALLOCATE (buffer_send(imepos)%indx(num_entries_send(imepos), 3))
1512 buffer_send(imepos)%indx = 0
1516 entry_counter(:) = 0
1519 DO jjb = 1, nrow_local
1521 ri_index = row_indices(jjb)
1523 IF (
modulo(ri_index, num_comm_cycles) /= i_comm) cycle
1525 imepos = mepos_from_ri_index(ri_index)
1527 DO iib = 1, ncol_local
1529 combi_index = col_indices(iib)
1530 level_small_size = max(1, combi_index - 1)/max(big_size, 2) + 1
1531 level_big_size = combi_index - (level_small_size - 1)*big_size
1533 entry_counter(imepos) = entry_counter(imepos) + 1
1535 buffer_send(imepos)%msg(entry_counter(imepos)) = fm_mat_s%local_data(jjb, iib)
1537 buffer_send(imepos)%indx(entry_counter(imepos), 1) = ri_index
1538 buffer_send(imepos)%indx(entry_counter(imepos), 2) = level_small_size
1539 buffer_send(imepos)%indx(entry_counter(imepos), 3) = level_big_size
1545 CALL timeset(
"BSE_comm_data", handle1)
1547 CALL communicate_buffer(para_env, num_entries_rec, num_entries_send, buffer_rec, buffer_send, req_array)
1549 CALL timestop(handle1)
1552 DO imepos = 0, para_env%num_pe - 1
1554 DO i_entry = 1, num_entries_rec(imepos)
1556 ri_index = buffer_rec(imepos)%indx(i_entry, 1) - start_ri + 1
1557 level_small_size = buffer_rec(imepos)%indx(i_entry, 2)
1558 level_big_size = buffer_rec(imepos)%indx(i_entry, 3)
1560 matrix_el = buffer_rec(imepos)%msg(i_entry)
1562 b_local(level_small_size, level_big_size, ri_index) = matrix_el
1568 DO imepos = 0, para_env%num_pe - 1
1569 DEALLOCATE (buffer_send(imepos)%msg)
1570 DEALLOCATE (buffer_send(imepos)%indx)
1571 DEALLOCATE (buffer_rec(imepos)%msg)
1572 DEALLOCATE (buffer_rec(imepos)%indx)
1575 DEALLOCATE (buffer_rec, buffer_send)
1579 DEALLOCATE (num_entries_send, num_entries_rec)
1581 DEALLOCATE (mepos_from_ri_index)
1583 DEALLOCATE (entry_counter, req_array)
1585 CALL timestop(handle)
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Iterative routines for GW + Bethe-Salpeter for computing electronic excitations.
subroutine, public do_subspace_iterations(b_bar_ijq_bse_local, b_abq_bse_local, b_bar_iaq_bse_local, b_iaq_bse_local, homo, virtual, bse_spin_config, unit_nr, eigenval, para_env, mp2_env)
...
subroutine, public fill_local_3c_arrays(fm_mat_s_ab_bse, fm_mat_s, fm_mat_s_bar_ia_bse, fm_mat_s_bar_ij_bse, b_bar_ijq_bse_local, b_abq_bse_local, b_bar_iaq_bse_local, b_iaq_bse_local, dimen_ri, homo, virtual, gd_array, color_sub, para_env)
...
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
Types to describe group distributions.
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
Types needed for MP2 calculations.
Definition of physical constants:
real(kind=dp), parameter, public evolt
Auxiliary routines necessary to redistribute an fm_matrix from a given blacs_env to another.
subroutine, public communicate_buffer(para_env, num_entries_rec, num_entries_send, buffer_rec, buffer_send, req_array, do_indx, do_msg)
...
stores all the informations relevant to an mpi environment