(git:f2099e5)
Loading...
Searching...
No Matches
rt_bse_ri_rs.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief RT-BSE RI-RS kernels: SEX and Hartree evaluated by collocation on grid points r_l.
10!> Once-built grid objects:
11!> φ_µ(r_l) [grid×AO], Z_lP [grid×RI],
12!> V^aux_PQ = [M^-1 V^tr M^-1]_PQ [RI×RI], W^0_ll' = sum_PQ Z_lP (V + W^c(ω=0))_PQ Z_l'Q.
13!> Per-call kernels, collocation X = φ_µ(r_l) (AO domain, written φ_lµ below):
14!> SEX: ρ^grid_ll' = sum_µν φ_lµ Δρ_µν φ_l'ν ;
15!> Σ_µν = pref * sum_ll' φ_lµ [ρ^grid ∘ W^0]_ll' φ_l'ν
16!> Hartree: n_l = sum_µν φ_lµ Δρ_µν φ_lν ;
17!> v_l = sum_PQl' Z_lP V^aux_PQ Z_l'Q n_l' (applied factorized, stage 2) ;
18!> V^H_µν = sum_l φ_lµ v_l φ_lν (diagonal-only, no grid×grid)
19!> Independent of which GW variant produced bs_env%fm_W_MIC_freq_zero.
20!> \author Maximilian Graml (05.26)
21! **************************************************************************************************
24 USE cp_cfm_types, ONLY: cp_cfm_create,&
29 USE cp_dbcsr_api, ONLY: &
38 USE cp_fm_types, ONLY: cp_fm_create,&
45 USE gw_ri_rs_non_periodic, ONLY: atomic_basis_at_grid_point,&
51 USE kinds, ONLY: dp
52 USE machine, ONLY: m_walltime
55 USE physcon, ONLY: angstrom
58#include "../base/base_uses.f90"
59
60 IMPLICIT NONE
61
62 PRIVATE
63
64 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rt_bse_ri_rs'
65
66 PUBLIC :: rt_bse_ri_rs_ensure_grid, &
75
76CONTAINS
77
78! **************************************************************************************************
79!> \brief Make sure the AO collocation φ_µ(r_l) (mat_phi_mu_l) and the RI fit coefficients
80!> Z_lP (mat_Z_lP) are populated in memory.
81!> If GW was run with RI-RS the grid is already built; otherwise build it here so the
82!> AO-RI GW + RI-RS RT-BSE combination is possible.
83!> \param bs_env ...
84!> \param qs_env ...
85! **************************************************************************************************
86 SUBROUTINE rt_bse_ri_rs_ensure_grid(bs_env, qs_env)
87
88 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
89 TYPE(qs_environment_type), POINTER :: qs_env
90
91 CHARACTER(LEN=*), PARAMETER :: routinen = 'rt_bse_ri_rs_ensure_grid'
92
93 INTEGER :: handle
94 REAL(kind=dp) :: t1
95
96 CALL timeset(routinen, handle)
97
98 IF (bs_env%ri_rs%grid_built) THEN
99 CALL timestop(handle)
100 RETURN
101 END IF
102
103 t1 = m_walltime()
104
105 CALL setup_ri_rs_grid(bs_env, bs_env%ri_rs%grid_points)
106 ! Per-atom AO/RI screening radii required by the screened grid-fill and d_lP routines; the
107 ! GW RI-RS driver populates these, but the standalone RT-BSE grid build must do so itself.
108 IF (.NOT. ALLOCATED(bs_env%ri_rs%radius_ao_per_atom)) THEN
109 CALL precompute_ri_rs_radii(bs_env)
110 END IF
111 CALL atomic_basis_at_grid_point(bs_env, bs_env%ri_rs%grid_points, &
112 bs_env%ri_rs%mat_phi_mu_l)
113 CALL compute_z_lp(qs_env, bs_env, bs_env%ri_rs%grid_points, &
114 bs_env%ri_rs%mat_phi_mu_l, bs_env%ri_rs%mat_Z_lP)
115
116 bs_env%ri_rs%grid_built = .true.
117
118 IF (bs_env%unit_nr > 0) THEN
119 WRITE (bs_env%unit_nr, '(T2,A,T58,A,F7.1,A)') &
120 'Built RI-RS grid for RT-BSE (no GW_RI_RS used),', ' Execution time', &
121 m_walltime() - t1, ' s'
122 WRITE (bs_env%unit_nr, '(A)') ' '
123 END IF
124
125 CALL timestop(handle)
126
127 END SUBROUTINE rt_bse_ri_rs_ensure_grid
128
129! **************************************************************************************************
130!> \brief Build V^aux_PQ = [M^-1 V^tr M^-1]_PQ (truncated Coulomb in the RI basis, M^-1-sandwiched
131!> to match the W^MIC convention). The grid Coulomb V_ll' = sum_PQ Z_lP V^aux_PQ Z_l'Q is
132!> never materialized -- the Hartree stage applies it factorized:
133!> v_l = sum_PQl' Z_lP V^aux_PQ Z_l'Q n_l'
134!> Needed by RT-BSE RI-RS Hartree.
135!> \param bs_env ...
136!> \param qs_env ...
137! **************************************************************************************************
138 SUBROUTINE rt_bse_ri_rs_ensure_v_grid(bs_env, qs_env)
139
140 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
141 TYPE(qs_environment_type), POINTER :: qs_env
142
143 CHARACTER(LEN=*), PARAMETER :: routinen = 'rt_bse_ri_rs_ensure_V_grid'
144
145 INTEGER :: handle
146 INTEGER, DIMENSION(:), POINTER :: blk_aux, dist_row_aux
147 REAL(kind=dp) :: t1
148 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_vtr_gamma
149 TYPE(dbcsr_distribution_type) :: dist_aux_aux
150
151 CALL timeset(routinen, handle)
152
153 IF (bs_env%ri_rs%V_grid_built) THEN
154 CALL timestop(handle)
155 RETURN
156 END IF
157
158 CALL rt_bse_ri_rs_ensure_grid(bs_env, qs_env)
159 t1 = m_walltime()
160
161 CALL setup_square_topology(bs_env%ri_rs%mat_Z_lP, 'COL', dist_aux_aux, blk_aux, dist_row_aux)
162
163 CALL ri_2c_integral_mat(qs_env, fm_vtr_gamma, bs_env%fm_RI_RI%matrix_struct, bs_env%n_RI, &
164 bs_env%trunc_coulomb)
165 ! Apply M^-1 sandwich to match the W^MIC convention; same scale as W^c when both used.
166 ! M^-1(k=0) V^tr M^-1(k=0) -> fm_Vtr_Gamma
167 CALL fm_contract_aba(bs_env%fm_Minv_Gamma, fm_vtr_gamma(:, 1))
168
169 ! Store the M^-1-sandwiched RI-basis Coulomb; the grid kernel Z V Z^T is applied factorized.
170 CALL dbcsr_create(bs_env%ri_rs%mat_V_aux_rtbse, "V_aux_rtbse", dist_aux_aux, &
171 dbcsr_type_no_symmetry, blk_aux, blk_aux)
172 CALL copy_fm_to_dbcsr(fm_vtr_gamma(1, 1), bs_env%ri_rs%mat_V_aux_rtbse, &
173 keep_sparsity=.false.)
174
175 bs_env%ri_rs%V_grid_built = .true.
176
177 IF (bs_env%unit_nr > 0) THEN
178 WRITE (bs_env%unit_nr, '(T2,A,T57,A,F7.1,A)') &
179 'Precomputed RT-BSE RI-RS V_aux kernel,', ' Execution time', &
180 m_walltime() - t1, ' s'
181 WRITE (bs_env%unit_nr, '(A)') ' '
182 END IF
183
184 CALL release_dbcsr_topology_and_matrices(dist=dist_aux_aux, mapped_dist=dist_row_aux)
185 CALL cp_fm_release(fm_vtr_gamma)
186
187 CALL timestop(handle)
188
189 END SUBROUTINE rt_bse_ri_rs_ensure_v_grid
190
191! **************************************************************************************************
192!> \brief Build W^0_ll' = sum_PQ Z_lP (V + W^c(ω=0))_PQ Z_l'Q (statically screened W on the grid).
193!> Needed by RT-BSE RI-RS SEX/COH. Reuses bs_env%fm_W_MIC_freq_zero which must already
194!> contain M^-1 W^c(ω=0) M^-1 (built by either GW path under the BSE rtp_method gate).
195!> W^0 enters only through the Hadamard ρ^grid ∘ W^0 -- its elements are needed, so it is
196!> the one persistent grid×grid object of the kernel layer.
197!> RTBSE%CUTOFF_RADIUS_W0 > 0 keeps only block pairs whose grid centroids lie within that
198!> radius; the per-step ρ^grid inherits the pattern, so both grid×grid objects shrink.
199!> \param bs_env ...
200!> \param qs_env ...
201! **************************************************************************************************
202 SUBROUTINE rt_bse_ri_rs_ensure_w0_grid(bs_env, qs_env)
203
204 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
205 TYPE(qs_environment_type), POINTER :: qs_env
206
207 CHARACTER(LEN=*), PARAMETER :: routinen = 'rt_bse_ri_rs_ensure_W0_grid'
208
209 INTEGER :: handle
210 INTEGER, DIMENSION(:), POINTER :: blk_aux, blk_grid, dist_col_grid, &
211 dist_row_aux
212 LOGICAL :: use_cutoff_w0
213 REAL(kind=dp) :: fnorm_w0, occ_w0, t1
214 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_vtr_gamma
215 TYPE(dbcsr_distribution_type) :: dist_aux_aux, dist_grid_grid
216 TYPE(dbcsr_type) :: matrix_v_aux, matrix_w_aux
217
218 CALL timeset(routinen, handle)
219
220 IF (bs_env%ri_rs%W0_grid_built) THEN
221 CALL timestop(handle)
222 RETURN
223 END IF
224
225 ! W(w=0) is built by the GW step only under its RTBSE rtp_method gate; reaching this consumer
226 ! without it means gate and consumer disagree. Abort rather than read a never-created cp_fm.
227 IF (.NOT. ASSOCIATED(bs_env%fm_W_MIC_freq_zero%matrix_struct)) THEN
228 CALL cp_abort(__location__, &
229 "RT-BSE RI-RS kernel needs the screened interaction W(w=0), which the GW "// &
230 "step did not build. Select the RT-BSE propagator with '&RTBSE' or "// &
231 "'&RTBSE RTBSE', not '&RTBSE TDDFT'.")
232 END IF
233
234 CALL rt_bse_ri_rs_ensure_grid(bs_env, qs_env)
235 t1 = m_walltime()
236
237 CALL setup_square_topology(bs_env%ri_rs%mat_phi_mu_l, 'ROW', dist_grid_grid, blk_grid, &
238 dist_col_grid)
239 CALL setup_square_topology(bs_env%ri_rs%mat_Z_lP, 'COL', dist_aux_aux, blk_aux, dist_row_aux)
240
241 CALL ri_2c_integral_mat(qs_env, fm_vtr_gamma, bs_env%fm_RI_RI%matrix_struct, bs_env%n_RI, &
242 bs_env%trunc_coulomb)
243 ! M^-1(k=0) V^tr M^-1(k=0) -> fm_Vtr_Gamma
244 CALL fm_contract_aba(bs_env%fm_Minv_Gamma, fm_vtr_gamma(:, 1))
245
246 CALL dbcsr_create(matrix_v_aux, "V_aux_rtbse_W0", dist_aux_aux, dbcsr_type_no_symmetry, &
247 blk_aux, blk_aux)
248 CALL copy_fm_to_dbcsr(fm_vtr_gamma(1, 1), matrix_v_aux, keep_sparsity=.false.)
249
250 CALL dbcsr_create(matrix_w_aux, "W_aux_rtbse", dist_aux_aux, dbcsr_type_no_symmetry, &
251 blk_aux, blk_aux)
252 CALL copy_fm_to_dbcsr(bs_env%fm_W_MIC_freq_zero, matrix_w_aux, keep_sparsity=.false.)
253 CALL dbcsr_add(matrix_w_aux, matrix_v_aux, 1.0_dp, 1.0_dp)
254
255 CALL dbcsr_create(bs_env%ri_rs%mat_W0_grid_rtbse, "W0_grid_rtbse", dist_grid_grid, &
256 dbcsr_type_no_symmetry, blk_grid, blk_grid)
257
258 ! CUTOFF_RADIUS_W0: pre-seed only the in-radius block pairs, then let retain_sparsity confine
259 ! the contraction to them. Gate on the value, never on ALLOCATED alone -- .AND. does not
260 ! short-circuit in Fortran.
261 use_cutoff_w0 = bs_env%ri_rs%cutoff_radius_w0 > 0.0_dp
262
263 ! chunk_centroids is built only by the non-periodic RI-RS GW driver, so on a periodic cell
264 ! the cut would silently fall through to the exact path while the log reports it as active.
265 IF (use_cutoff_w0 .AND. .NOT. ALLOCATED(bs_env%ri_rs%chunk_centroids)) THEN
266 CALL cp_abort(__location__, &
267 "RTBSE%CUTOFF_RADIUS_W0 needs the per-grid-block centroids, which only the "// &
268 "non-periodic RI-RS GW driver builds; this cell is periodic. Use '&CELL "// &
269 "PERIODIC NONE', or drop CUTOFF_RADIUS_W0 to propagate with the exact W0.")
270 END IF
271
272 IF (use_cutoff_w0) THEN
273 CALL reserve_blocks_within_radius(bs_env%ri_rs%mat_W0_grid_rtbse, &
274 bs_env%ri_rs%chunk_centroids, &
275 bs_env%ri_rs%cutoff_radius_w0)
276 ! TODO: eps_filter is INERT here -- DBCSR skips multrec_filtering whenever
277 ! keep_sparsity is set (dbcsr_mm_multrec.F: "IF (use_eps .AND. .NOT. keep_sparsity)").
278 ! So a radius wider than the cell equals the uncut build only while eps_filter prunes
279 ! nothing on W0, which holds for every system measured so far but is not guaranteed.
280 CALL dbcsr_contract_aba("N", "T", bs_env%ri_rs%mat_Z_lP, matrix_w_aux, &
281 bs_env%ri_rs%mat_W0_grid_rtbse, bs_env%eps_filter, &
282 retain_sparsity=.true.)
283 ELSE
284 CALL dbcsr_contract_aba("N", "T", bs_env%ri_rs%mat_Z_lP, matrix_w_aux, &
285 bs_env%ri_rs%mat_W0_grid_rtbse, bs_env%eps_filter)
286 END IF
287
288 bs_env%ri_rs%W0_grid_built = .true.
289
290 ! Occupancy is a storage statistic with no magnitude, so pair it with the retained Frobenius
291 ! weight -- the two together are the x-axis of a CUTOFF_RADIUS_W0 convergence scan. Both
292 ! reduce over all ranks; occupancy saturates at 1.000 and says nothing about magnitude.
293 occ_w0 = dbcsr_get_occupation(bs_env%ri_rs%mat_W0_grid_rtbse)
294 fnorm_w0 = dbcsr_frobenius_norm(bs_env%ri_rs%mat_W0_grid_rtbse)
295
296 IF (bs_env%unit_nr > 0) THEN
297 WRITE (bs_env%unit_nr, '(T2,A,T67,F14.4)') &
298 'W0CUT| Cutoff radius, negative = off [angstrom]', bs_env%ri_rs%cutoff_radius_w0*angstrom
299 WRITE (bs_env%unit_nr, '(T2,A,T67,F14.6)') 'W0CUT| Retained block fraction', occ_w0
300 WRITE (bs_env%unit_nr, '(T2,A,T59,ES22.8)') 'W0CUT| Retained Frobenius norm', fnorm_w0
301 WRITE (bs_env%unit_nr, '(T2,A,T57,A,F7.1,A)') &
302 'Precomputed RT-BSE RI-RS W0_grid kernel,', ' Execution time', &
303 m_walltime() - t1, ' s'
304 WRITE (bs_env%unit_nr, '(A)') ' '
305 END IF
306
307 CALL release_dbcsr_topology_and_matrices(dist=dist_grid_grid, mapped_dist=dist_col_grid)
308 CALL release_dbcsr_topology_and_matrices(dist=dist_aux_aux, mapped_dist=dist_row_aux, &
309 m1=matrix_v_aux, m2=matrix_w_aux)
310 CALL cp_fm_release(fm_vtr_gamma)
311
312 CALL timestop(handle)
313
314 END SUBROUTINE rt_bse_ri_rs_ensure_w0_grid
315
316! **************************************************************************************************
317!> \brief AO-domain SEX: Σ_µν = pref * sum_ll' φ_lµ [ρ^grid ∘ W^0]_ll' φ_l'ν,
318!> ρ^grid_ll' = sum_µν φ_lµ Δρ_µν φ_l'ν.
319!> The grid×grid ρ^grid is intrinsic to SEX -- the Hadamard needs W^0's elements, so no
320!> factorized application exists (unlike the Hartree V_ll'). Real input, real output;
321!> used for COH (input S^-1) and the init reference (ρ^0); dynamic Δρ goes through the
322!> complex variant. Mirrors the AO-RI get_sigma(rtbse_env, sigma_fm, prefactor, rho_fm) API.
323!> \param bs_env ...
324!> \param sigma_AO_fm result, AO x AO
325!> \param prefactor scaling applied to the final result
326!> \param rho_AO_fm input density-like matrix, AO x AO
327!> \param grid_diag_accum ...
328! **************************************************************************************************
329 SUBROUTINE compute_sigma_ri_rs(bs_env, sigma_AO_fm, prefactor, rho_AO_fm, &
330 grid_diag_accum)
331
332 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
333 TYPE(cp_fm_type), INTENT(INOUT) :: sigma_ao_fm
334 REAL(kind=dp), INTENT(IN) :: prefactor
335 TYPE(cp_fm_type), INTENT(IN) :: rho_ao_fm
336 REAL(kind=dp), INTENT(INOUT), OPTIONAL :: grid_diag_accum(:)
337
338 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_sigma_ri_rs'
339
340 INTEGER :: handle, n_grid
341 INTEGER, DIMENSION(:), POINTER :: blk_ao, dist_row_ao
342 REAL(kind=dp), ALLOCATABLE :: diag_local(:)
343 TYPE(dbcsr_distribution_type) :: dist_ao_ao
344 TYPE(dbcsr_type) :: matrix_rho_ao, matrix_rho_grid, &
345 matrix_sigma_ao
346
347 CALL timeset(routinen, handle)
348
349 cpassert(bs_env%ri_rs%W0_grid_built)
350
351 ! Only the AO×AO topology is built here; ρ^grid takes its grid×grid one from W^0's template.
352 CALL setup_square_topology(bs_env%ri_rs%mat_phi_mu_l, 'COL', dist_ao_ao, blk_ao, dist_row_ao)
353
354 CALL dbcsr_create(matrix_rho_ao, "rho_AO_ri_rs", dist_ao_ao, dbcsr_type_no_symmetry, &
355 blk_ao, blk_ao)
356 CALL copy_fm_to_dbcsr(rho_ao_fm, matrix_rho_ao, keep_sparsity=.false.)
357
358 ! The projection below is shared with the Hartree, so this cuts SEX and Hartree alike.
359 IF (bs_env%ri_rs%eps_filter_rho >= 0.0_dp) THEN
360 CALL dbcsr_filter(matrix_rho_ao, bs_env%ri_rs%eps_filter_rho)
361 END IF
362
363 ! ρ^grid_ll' = sum_µν φ_lµ Δρ_µν φ_l'ν (the SEX-intrinsic grid×grid transient),
364 ! built directly into W^0's block pattern. Exact: the Hadamard below zeroes every block
365 ! without a W^0 partner anyway, so restricting the multiply drops only computed zeros.
366 ! No eps_filter on the SEX projections either -- a Δρ-dependent block drop breaks kernel
367 ! self-adjointness (L non-Hermitian); W^0's pattern is symmetric and Δρ-independent.
368 ! TODO: seeds the pattern by copying W0's values and discarding them every RK4 substep --
369 ! unquantified overhead, paid even when no cut is set. Cache the zeroed pattern instead.
370 CALL dbcsr_create(matrix_rho_grid, template=bs_env%ri_rs%mat_W0_grid_rtbse)
371 CALL dbcsr_copy(matrix_rho_grid, bs_env%ri_rs%mat_W0_grid_rtbse)
372 CALL dbcsr_set(matrix_rho_grid, 0.0_dp)
373 CALL dbcsr_contract_aba("N", "T", bs_env%ri_rs%mat_phi_mu_l, matrix_rho_ao, &
374 matrix_rho_grid, 0.0_dp, retain_sparsity=.true.)
375
376 ! Harvest n_l = diag(ρ^grid) BEFORE the in-place Hadamard destroys it; the Hartree reuses it
377 ! (compute_hartree_ri_rs_from_diag) instead of rebuilding φρφ^T. Bare accumulate (caller
378 ! pre-zeroes): the cross-spin Hartree density is the spin SUM of these, and spin_degeneracy is
379 ! applied to the V_H OUTPUT (post-filter, bit-identical) -- never to the diagonal, which would
380 ! shift the stage-3 eps_filter cut (coarse-filter sensitivity).
381 IF (PRESENT(grid_diag_accum)) THEN
382 n_grid = SIZE(grid_diag_accum)
383 ALLOCATE (diag_local(n_grid))
384 diag_local = 0.0_dp
385 CALL dbcsr_get_diag(matrix_rho_grid, diag_local)
386 CALL bs_env%para_env%sum(diag_local)
387 grid_diag_accum(:) = grid_diag_accum(:) + diag_local(:)
388 DEALLOCATE (diag_local)
389 END IF
390
391 ! ρ^grid_ll' <- ρ^grid_ll' * W^0_ll' (in place; blocks without a W^0 partner zeroed)
392 CALL hadamard_product_inplace(matrix_rho_grid, bs_env%ri_rs%mat_W0_grid_rtbse, &
393 1.0_dp)
394
395 ! Σ_µν = sum_ll' φ_lµ [ρ^grid ∘ W^0]_ll' φ_l'ν
396 CALL dbcsr_create(matrix_sigma_ao, template=matrix_rho_ao)
397 ! Unfiltered for self-adjointness (see the forward projection above; PERF note there).
398 CALL dbcsr_contract_aba("T", "N", bs_env%ri_rs%mat_phi_mu_l, matrix_rho_grid, &
399 matrix_sigma_ao, 0.0_dp)
400
401 CALL dbcsr_scale(matrix_sigma_ao, prefactor)
402 CALL copy_dbcsr_to_fm(matrix_sigma_ao, sigma_ao_fm)
403
404 CALL release_dbcsr_topology_and_matrices(dist=dist_ao_ao, mapped_dist=dist_row_ao, &
405 m1=matrix_rho_ao, m2=matrix_sigma_ao)
406 CALL release_dbcsr_topology_and_matrices(m1=matrix_rho_grid)
407
408 CALL timestop(handle)
409
410 END SUBROUTINE compute_sigma_ri_rs
411
412! **************************************************************************************************
413!> \brief Complex-input AO SEX via Re/Im split: the kernel is real, so complex linearity holds as
414!> Σ[Δρ] = Σ[Re Δρ] + i Σ[Im Δρ]. Required for non-Hermitian Δρ inputs
415!> (TDA OV-only / ABBA OV+VO).
416!> \param bs_env ...
417!> \param sigma_AO_cfm result, AO x AO (complex)
418!> \param prefactor scaling applied to the final result
419!> \param rho_AO_cfm input AO x AO complex matrix
420!> \param grid_diag_re_accum optional: accumulate diag(φ.Re(ρ).φ^T) (bare; for the Hartree reuse)
421!> \param grid_diag_im_accum optional: accumulate diag(φ.Im(ρ).φ^T) (bare; for the Hartree reuse)
422! **************************************************************************************************
423 SUBROUTINE compute_sigma_ri_rs_complex(bs_env, sigma_AO_cfm, prefactor, rho_AO_cfm, &
424 grid_diag_re_accum, grid_diag_im_accum)
425
426 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
427 TYPE(cp_cfm_type), INTENT(INOUT) :: sigma_ao_cfm
428 REAL(kind=dp), INTENT(IN) :: prefactor
429 TYPE(cp_cfm_type), INTENT(IN) :: rho_ao_cfm
430 REAL(kind=dp), INTENT(INOUT), OPTIONAL :: grid_diag_re_accum(:), &
431 grid_diag_im_accum(:)
432
433 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_sigma_ri_rs_complex'
434
435 INTEGER :: handle
436 TYPE(cp_cfm_type) :: cfm_real_part
437 TYPE(cp_fm_type) :: fm_rho, fm_sigma
438
439 CALL timeset(routinen, handle)
440
441 CALL cp_fm_create(fm_rho, bs_env%fm_s_Gamma%matrix_struct)
442 CALL cp_fm_create(fm_sigma, bs_env%fm_s_Gamma%matrix_struct)
443 CALL cp_cfm_create(cfm_real_part, bs_env%fm_s_Gamma%matrix_struct)
444
445 ! Re/Im each harvest into their own accumulator; absent optionals propagate as absent.
446 CALL cp_cfm_to_fm(msource=rho_ao_cfm, mtargetr=fm_rho)
447 CALL compute_sigma_ri_rs(bs_env, fm_sigma, prefactor, fm_rho, &
448 grid_diag_accum=grid_diag_re_accum)
449 CALL cp_fm_to_cfm(msourcer=fm_sigma, mtarget=cfm_real_part)
450
451 CALL cp_cfm_to_fm(msource=rho_ao_cfm, mtargeti=fm_rho)
452 CALL compute_sigma_ri_rs(bs_env, fm_sigma, prefactor, fm_rho, &
453 grid_diag_accum=grid_diag_im_accum)
454 CALL cp_fm_to_cfm(msourcei=fm_sigma, mtarget=sigma_ao_cfm)
455
456 CALL cp_cfm_scale_and_add(cmplx(1.0_dp, 0.0_dp, kind=dp), sigma_ao_cfm, &
457 cmplx(1.0_dp, 0.0_dp, kind=dp), cfm_real_part)
458
459 CALL cp_fm_release(fm_rho)
460 CALL cp_fm_release(fm_sigma)
461 CALL cp_cfm_release(cfm_real_part)
462
463 CALL timestop(handle)
464
465 END SUBROUTINE compute_sigma_ri_rs_complex
466
467! **************************************************************************************************
468!> \brief AO-domain Hartree via RI-RS:
469!> n_l = sum_µν φ_lµ Δρ_µν φ_lν = (φ ρ φ^T)_ll (diagonal of materialized grid×grid) ;
470!> v_l = sum_PQl' Z_lP V^aux_PQ Z_l'Q n_l' (factorized, stage 2) ;
471!> V^H_µν = sum_l φ_lµ v_l φ_lν (diagonal-only row-scale, stage 3)
472!> Real input, real output; complex inputs go through compute_hartree_ri_rs_complex.
473!> \param bs_env ...
474!> \param rho_AO_fm input AO x AO density matrix
475!> \param V_H_AO_fm output AO x AO Hartree potential
476! **************************************************************************************************
477 SUBROUTINE compute_hartree_ri_rs(bs_env, rho_AO_fm, V_H_AO_fm)
478
479 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
480 TYPE(cp_fm_type), INTENT(IN) :: rho_ao_fm
481 TYPE(cp_fm_type), INTENT(INOUT) :: v_h_ao_fm
482
483 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_hartree_ri_rs'
484
485 INTEGER :: handle, n_grid
486 INTEGER, DIMENSION(:), POINTER :: blk_ao, blk_grid, dist_col_grid, &
487 dist_row_ao
488 REAL(kind=dp), ALLOCATABLE :: n_vec(:)
489 TYPE(dbcsr_distribution_type) :: dist_ao_ao, dist_grid_grid
490 TYPE(dbcsr_type) :: matrix_rho_ao, matrix_rho_grid
491
492 CALL timeset(routinen, handle)
493
494 cpassert(bs_env%ri_rs%V_grid_built)
495
496 CALL setup_square_topology(bs_env%ri_rs%mat_phi_mu_l, 'COL', dist_ao_ao, blk_ao, dist_row_ao)
497 CALL setup_square_topology(bs_env%ri_rs%mat_phi_mu_l, 'ROW', dist_grid_grid, blk_grid, &
498 dist_col_grid)
499
500 CALL dbcsr_create(matrix_rho_ao, "rho_AO_hartree", dist_ao_ao, dbcsr_type_no_symmetry, &
501 blk_ao, blk_ao)
502 CALL copy_fm_to_dbcsr(rho_ao_fm, matrix_rho_ao, keep_sparsity=.false.)
503
504 n_grid = sum(blk_grid)
505 ALLOCATE (n_vec(n_grid))
506
507 ! stage 1: n_l = (φ ρ φ^T)_ll. A grid×AO row-dot (iterate φρ, look up φ) silently drops
508 ! off-rank pairs at ≥2 ranks — φ is sparse and the product is not co-located with φ — so
509 ! materialize φρφ^T and take its diagonal, co-location-safe like the SEX grid kernel.
510 CALL dbcsr_create(matrix_rho_grid, "rho_grid_hartree", dist_grid_grid, &
511 dbcsr_type_no_symmetry, blk_grid, blk_grid)
512 ! No eps_filter: a Δρ-dependent diagonal-block drop zeroes n_l inconsistently between OV
513 ! pairs and breaks Hartree self-adjointness (L non-Hermitian).
514 ! PERF(rirs-selfadjoint): this full grid×grid is built only for its diagonal n_l; a
515 ! diagonal-only build would avoid it. NOT YET APPLIED, needs a perf test.
516 CALL dbcsr_contract_aba("N", "T", bs_env%ri_rs%mat_phi_mu_l, matrix_rho_ao, &
517 matrix_rho_grid, 0.0_dp)
518 n_vec = 0.0_dp
519 CALL dbcsr_get_diag(matrix_rho_grid, n_vec)
520 CALL bs_env%para_env%sum(n_vec)
521 CALL release_dbcsr_topology_and_matrices(dist=dist_grid_grid, mapped_dist=dist_col_grid, &
522 m1=matrix_rho_grid)
523 CALL release_dbcsr_topology_and_matrices(dist=dist_ao_ao, mapped_dist=dist_row_ao, &
524 m1=matrix_rho_ao)
525
526 ! stages 2-3: factorized Coulomb v = Z V^aux Z^T n, then V^H = φ^T diag(v) φ.
527 CALL hartree_potential_from_diag_ri_rs(bs_env, n_vec, v_h_ao_fm)
528
529 DEALLOCATE (n_vec)
530
531 CALL timestop(handle)
532
533 END SUBROUTINE compute_hartree_ri_rs
534
535! **************************************************************************************************
536!> \brief Hartree stages 2-3 from a precomputed grid density n_l (skips the stage-1 φρφ^T build):
537!> v_l = sum_PQl' Z_lP V^aux_PQ Z_l'Q n_l' (factorized Coulomb) ;
538!> V^H_µν = sum_l φ_lµ v_l φ_lν (Φ_lν = v_l φ_lν rowscale, then V^H = φ^T Φ).
539!> n_l is harvested as diag(φρφ^T) inside compute_sigma_ri_rs (the SEX grid kernel), so the
540!> Hartree never rebuilds the grid×grid product. Real in/out.
541!> \param bs_env ...
542!> \param n_vec grid density n_l (length n_grid, replicated)
543!> \param V_H_AO_fm output AO x AO Hartree potential
544! **************************************************************************************************
545 SUBROUTINE hartree_potential_from_diag_ri_rs(bs_env, n_vec, V_H_AO_fm)
546
547 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
548 REAL(kind=dp), INTENT(IN) :: n_vec(:)
549 TYPE(cp_fm_type), INTENT(INOUT) :: v_h_ao_fm
550
551 CHARACTER(LEN=*), PARAMETER :: routinen = 'hartree_potential_from_diag_ri_rs'
552
553 INTEGER :: handle
554 INTEGER, DIMENSION(:), POINTER :: blk_ao, dist_row_ao
555 REAL(kind=dp), ALLOCATABLE :: u_ri(:), v_vec(:), w_ri(:)
556 TYPE(dbcsr_distribution_type) :: dist_ao_ao
557 TYPE(dbcsr_type) :: matrix_phi, matrix_v_h_ao
558
559 CALL timeset(routinen, handle)
560
561 cpassert(bs_env%ri_rs%V_grid_built)
562
563 CALL setup_square_topology(bs_env%ri_rs%mat_phi_mu_l, 'COL', dist_ao_ao, blk_ao, dist_row_ao)
564 ALLOCATE (v_vec(SIZE(n_vec)))
565
566 ! stage 2: v_l = sum_PQl' Z_lP V^aux_PQ Z_l'Q n_l' (factorized; helper zeroes each output)
567 ALLOCATE (w_ri(bs_env%n_RI), u_ri(bs_env%n_RI))
568 ! w_Q = sum_l Z_lQ n_l
569 CALL dbcsr_matvec_replicated(bs_env%ri_rs%mat_Z_lP, n_vec, w_ri, bs_env%para_env, &
570 transposed=.true.)
571 ! u_P = sum_Q V^aux_PQ w_Q
572 CALL dbcsr_matvec_replicated(bs_env%ri_rs%mat_V_aux_rtbse, w_ri, u_ri, bs_env%para_env)
573 ! v_l = sum_P Z_lP u_P
574 CALL dbcsr_matvec_replicated(bs_env%ri_rs%mat_Z_lP, u_ri, v_vec, bs_env%para_env)
575 DEALLOCATE (w_ri, u_ri)
576
577 ! stage 3: V^H_µν = sum_l φ_lµ v_l φ_lν (Φ_lν = v_l φ_lν rowscale, then V^H = φ^T Φ)
578 CALL dbcsr_create(matrix_phi, template=bs_env%ri_rs%mat_phi_mu_l)
579 CALL dbcsr_copy(matrix_phi, bs_env%ri_rs%mat_phi_mu_l)
580 CALL dbcsr_scale_rows_replicated(matrix_phi, v_vec)
581
582 CALL dbcsr_create(matrix_v_h_ao, "V_H_AO_hartree", dist_ao_ao, dbcsr_type_no_symmetry, &
583 blk_ao, blk_ao)
584 ! No eps_filter: a Δρ-dependent block drop breaks Hartree kernel self-adjointness.
585 CALL dbcsr_multiply("T", "N", 1.0_dp, bs_env%ri_rs%mat_phi_mu_l, matrix_phi, &
586 0.0_dp, matrix_v_h_ao, filter_eps=0.0_dp)
587 CALL dbcsr_release(matrix_phi)
588
589 CALL copy_dbcsr_to_fm(matrix_v_h_ao, v_h_ao_fm)
590
591 DEALLOCATE (v_vec)
592
593 CALL release_dbcsr_topology_and_matrices(dist=dist_ao_ao, mapped_dist=dist_row_ao, &
594 m1=matrix_v_h_ao)
595
596 CALL timestop(handle)
597
599
600! **************************************************************************************************
601!> \brief Complex Hartree from precomputed grid diagonals: V^H = V^H[n_re] + i V^H[n_im], each via
602!> hartree_potential_from_diag_ri_rs (stages 2-3 only). n_re/n_im are the spin-summed grid
603!> densities harvested in the SEX kernel; this is the cross-spin / TDA complex consumer that
604!> replaces compute_hartree_ri_rs_complex when SEX already built the grid. n_im optional: when
605!> absent the result is purely real (matches the Re-only real-input Hartree).
606!> \param bs_env ...
607!> \param n_re grid density Re part (length n_grid, replicated)
608!> \param V_H_AO_cfm output AO x AO complex Hartree potential
609!> \param n_im optional grid density Im part (length n_grid, replicated)
610! **************************************************************************************************
611 SUBROUTINE compute_hartree_ri_rs_from_diag(bs_env, n_re, V_H_AO_cfm, n_im)
612
613 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
614 REAL(kind=dp), INTENT(IN) :: n_re(:)
615 TYPE(cp_cfm_type), INTENT(INOUT) :: v_h_ao_cfm
616 REAL(kind=dp), INTENT(IN), OPTIONAL :: n_im(:)
617
618 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_hartree_ri_rs_from_diag'
619
620 INTEGER :: handle
621 TYPE(cp_cfm_type) :: cfm_real_part
622 TYPE(cp_fm_type) :: fm_v
623
624 CALL timeset(routinen, handle)
625
626 CALL cp_fm_create(fm_v, bs_env%fm_s_Gamma%matrix_struct)
627
628 CALL hartree_potential_from_diag_ri_rs(bs_env, n_re, fm_v)
629 IF (PRESENT(n_im)) THEN
630 CALL cp_cfm_create(cfm_real_part, bs_env%fm_s_Gamma%matrix_struct)
631 CALL cp_fm_to_cfm(msourcer=fm_v, mtarget=cfm_real_part)
632 CALL hartree_potential_from_diag_ri_rs(bs_env, n_im, fm_v)
633 CALL cp_fm_to_cfm(msourcei=fm_v, mtarget=v_h_ao_cfm)
634 CALL cp_cfm_scale_and_add(cmplx(1.0_dp, 0.0_dp, kind=dp), v_h_ao_cfm, &
635 cmplx(1.0_dp, 0.0_dp, kind=dp), cfm_real_part)
636 CALL cp_cfm_release(cfm_real_part)
637 ELSE
638 CALL cp_fm_to_cfm(msourcer=fm_v, mtarget=v_h_ao_cfm)
639 END IF
640
641 CALL cp_fm_release(fm_v)
642
643 CALL timestop(handle)
644
646
647! **************************************************************************************************
648!> \brief Complex-input Hartree potential via RI-RS. Re/Im split: feed each part to the real
649!> compute_hartree_ri_rs and reassemble. Real-input Hartree on a non-Hermitian input
650!> would silently drop Im and break Hermitian conjugacy of OV+VO contributions in TDA.
651!> \param bs_env ...
652!> \param rho_AO_cfm input AO x AO complex density-like matrix
653!> \param V_H_AO_cfm output AO x AO complex Hartree potential
654! **************************************************************************************************
655 SUBROUTINE compute_hartree_ri_rs_complex(bs_env, rho_AO_cfm, V_H_AO_cfm)
656
657 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
658 TYPE(cp_cfm_type), INTENT(IN) :: rho_ao_cfm
659 TYPE(cp_cfm_type), INTENT(INOUT) :: v_h_ao_cfm
660
661 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_hartree_ri_rs_complex'
662
663 INTEGER :: handle
664 TYPE(cp_cfm_type) :: cfm_real_part
665 TYPE(cp_fm_type) :: fm_rho, fm_v
666
667 CALL timeset(routinen, handle)
668
669 CALL cp_fm_create(fm_rho, bs_env%fm_s_Gamma%matrix_struct)
670 CALL cp_fm_create(fm_v, bs_env%fm_s_Gamma%matrix_struct)
671 CALL cp_cfm_create(cfm_real_part, bs_env%fm_s_Gamma%matrix_struct)
672
673 CALL cp_cfm_to_fm(msource=rho_ao_cfm, mtargetr=fm_rho)
674 CALL compute_hartree_ri_rs(bs_env, fm_rho, fm_v)
675 CALL cp_fm_to_cfm(msourcer=fm_v, mtarget=cfm_real_part)
676
677 CALL cp_cfm_to_fm(msource=rho_ao_cfm, mtargeti=fm_rho)
678 CALL compute_hartree_ri_rs(bs_env, fm_rho, fm_v)
679 CALL cp_fm_to_cfm(msourcei=fm_v, mtarget=v_h_ao_cfm)
680
681 CALL cp_cfm_scale_and_add(cmplx(1.0_dp, 0.0_dp, kind=dp), v_h_ao_cfm, &
682 cmplx(1.0_dp, 0.0_dp, kind=dp), cfm_real_part)
683
684 CALL cp_fm_release(fm_rho)
685 CALL cp_fm_release(fm_v)
686 CALL cp_cfm_release(cfm_real_part)
687
688 CALL timestop(handle)
689
690 END SUBROUTINE compute_hartree_ri_rs_complex
691
692! **************************************************************************************************
693!> \brief Scale each row of a dbcsr matrix by a replicated full-length vector:
694!> block(ir,ic) <- vec(global_row(ir)) * block(ir,ic). Value mutation only.
695!> \param matrix ...
696!> \param vec full-length replicated row-scaling vector
697! **************************************************************************************************
698 SUBROUTINE dbcsr_scale_rows_replicated(matrix, vec)
699
700 TYPE(dbcsr_type), INTENT(INOUT) :: matrix
701 REAL(kind=dp), INTENT(IN) :: vec(:)
702
703 INTEGER :: col_blk, ic, ir, nblkrows_total, &
704 row_blk, row_off
705 INTEGER, ALLOCATABLE :: row_offset(:)
706 INTEGER, DIMENSION(:), POINTER :: row_blk_size
707 REAL(kind=dp), DIMENSION(:, :), POINTER :: blk
708 TYPE(dbcsr_iterator_type) :: iter
709
710 CALL dbcsr_get_info(matrix, nblkrows_total=nblkrows_total, row_blk_size=row_blk_size)
711 ALLOCATE (row_offset(nblkrows_total + 1))
712 row_offset(1) = 0
713 DO ir = 1, nblkrows_total
714 row_offset(ir + 1) = row_offset(ir) + row_blk_size(ir)
715 END DO
716
717 CALL dbcsr_iterator_start(iter, matrix)
718 DO WHILE (dbcsr_iterator_blocks_left(iter))
719 CALL dbcsr_iterator_next_block(iter, row_blk, col_blk, blk)
720 row_off = row_offset(row_blk)
721 DO ic = 1, SIZE(blk, 2)
722 DO ir = 1, SIZE(blk, 1)
723 blk(ir, ic) = vec(row_off + ir)*blk(ir, ic)
724 END DO
725 END DO
726 END DO
727 CALL dbcsr_iterator_stop(iter)
728
729 DEALLOCATE (row_offset)
730
731 END SUBROUTINE dbcsr_scale_rows_replicated
732
733! **************************************************************************************************
734!> \brief Replicated matvec: vec_out = matrix * vec_in (or matrix^T * vec_in if transposed) for a
735!> possibly rectangular distributed dbcsr matrix and replicated full-length vectors.
736!> Iterates over local blocks and reduces.
737!> \param matrix distributed dbcsr matrix (may be rectangular)
738!> \param vec_in full input vector, replicated on all ranks (column length, or row length if transposed)
739!> \param vec_out full output vector, replicated on all ranks (zeroed on entry; sum-reduced on exit)
740!> \param para_env ...
741!> \param transposed if .TRUE. compute vec_out = matrix^T * vec_in
742! **************************************************************************************************
743 SUBROUTINE dbcsr_matvec_replicated(matrix, vec_in, vec_out, para_env, transposed)
744
745 TYPE(dbcsr_type), INTENT(INOUT) :: matrix
746 REAL(kind=dp), INTENT(IN) :: vec_in(:)
747 REAL(kind=dp), INTENT(INOUT) :: vec_out(:)
748 TYPE(mp_para_env_type), POINTER :: para_env
749 LOGICAL, INTENT(IN), OPTIONAL :: transposed
750
751 INTEGER :: col_blk, col_off, ic, ir, &
752 nblkcols_total, nblkrows_total, &
753 row_blk, row_off
754 INTEGER, ALLOCATABLE :: col_offset(:), row_offset(:)
755 INTEGER, DIMENSION(:), POINTER :: col_blk_size, row_blk_size
756 LOGICAL :: my_trans
757 REAL(kind=dp), DIMENSION(:, :), POINTER :: block
758 TYPE(dbcsr_iterator_type) :: iter
759
760 my_trans = .false.
761 IF (PRESENT(transposed)) my_trans = transposed
762
763 CALL dbcsr_get_info(matrix, nblkrows_total=nblkrows_total, &
764 nblkcols_total=nblkcols_total, &
765 row_blk_size=row_blk_size, col_blk_size=col_blk_size)
766
767 ALLOCATE (row_offset(nblkrows_total + 1), col_offset(nblkcols_total + 1))
768 row_offset(1) = 0
769 DO ir = 1, nblkrows_total
770 row_offset(ir + 1) = row_offset(ir) + row_blk_size(ir)
771 END DO
772 col_offset(1) = 0
773 DO ic = 1, nblkcols_total
774 col_offset(ic + 1) = col_offset(ic) + col_blk_size(ic)
775 END DO
776
777 vec_out(:) = 0.0_dp
778
779 CALL dbcsr_iterator_start(iter, matrix)
780 DO WHILE (dbcsr_iterator_blocks_left(iter))
781 CALL dbcsr_iterator_next_block(iter, row_blk, col_blk, block)
782 row_off = row_offset(row_blk)
783 col_off = col_offset(col_blk)
784 IF (my_trans) THEN
785 DO ic = 1, SIZE(block, 2)
786 DO ir = 1, SIZE(block, 1)
787 vec_out(col_off + ic) = vec_out(col_off + ic) + &
788 block(ir, ic)*vec_in(row_off + ir)
789 END DO
790 END DO
791 ELSE
792 DO ic = 1, SIZE(block, 2)
793 DO ir = 1, SIZE(block, 1)
794 vec_out(row_off + ir) = vec_out(row_off + ir) + &
795 block(ir, ic)*vec_in(col_off + ic)
796 END DO
797 END DO
798 END IF
799 END DO
800 CALL dbcsr_iterator_stop(iter)
801
802 DEALLOCATE (row_offset, col_offset)
803
804 CALL para_env%sum(vec_out)
805
806 END SUBROUTINE dbcsr_matvec_replicated
807
808END MODULE rt_bse_ri_rs
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b).
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_filter(matrix, eps)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_get_diag(matrix, diag)
Copies the diagonal elements from the given matrix into the given array.
real(dp) function, public dbcsr_frobenius_norm(matrix)
Compute the frobenius norm of a dbcsr matrix.
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
Computes the RI-RS fitting matrix Z_lP.
subroutine, public compute_z_lp(qs_env, bs_env, ri_rs_grid_points, mat_phi_mu_l, mat_z_lp)
Computes Z_lP for (1) a tabulated RI basis set or (2) an on-the-fly generated RI basis set.
Main setup file for RI-RS grids {r_l}.
subroutine, public setup_ri_rs_grid(bs_env, grid_points)
Get RI-RS grid points {r_l}, either by on-the-fly optimization or reading pretabulated atomic grids.
GW using RI-RS Approximation for molecules.
subroutine, public setup_square_topology(matrix_template, dim_type, square_dist, blk_sizes, mapped_dist)
DBCSR Topology Generation.
subroutine, public release_dbcsr_topology_and_matrices(dist, mapped_dist, m1, m2, m3, m4)
DBCSR matrices deallocation.
GW using RI-RS Approximation for molecules.
subroutine, public reserve_blocks_within_radius(matrix, centers, radius)
Pre-seeds a square blocked DBCSR matrix with zero blocks only for block pairs whose centers lie withi...
Common setup operations used by the periodic and non-periodic GW RI-RS implementations.
subroutine, public precompute_ri_rs_radii(bs_env)
Compute per-atom AO and RI basis radii from the most diffuse Gaussian primitive in the AO ("ORB") and...
Common DBCSR matrix operations used by GW modules.
subroutine, public hadamard_product_inplace(matrix_a, matrix_b, factor)
Form A = factor * (A element-wise B) without changing A's block structure.
subroutine, public dbcsr_contract_aba(trans_a_left, trans_a_right, matrix_a, matrix_b, matrix_c, eps_filter, retain_sparsity)
Computes C=A B A^T or C=A^T B A for DBCSR matrices.
Full-matrix operations not provided by the CP2K FM packages.
Definition gw_utils_fm.F:13
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:141
Interface to the message passing library MPI.
Framework for 2c-integrals for RI.
Definition mp2_ri_2c.F:14
subroutine, public ri_2c_integral_mat(qs_env, fm_matrix_minv_l_gamma, fm_matrix_l_struct, dimen_ri, ri_metric, put_mat_ks_env, regularization_ri)
...
Definition mp2_ri_2c.F:578
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
RT-BSE RI-RS kernels: SEX and Hartree evaluated by collocation on grid points r_l....
subroutine, public compute_hartree_ri_rs_complex(bs_env, rho_ao_cfm, v_h_ao_cfm)
Complex-input Hartree potential via RI-RS. Re/Im split: feed each part to the real compute_hartree_ri...
subroutine, public rt_bse_ri_rs_ensure_w0_grid(bs_env, qs_env)
Build W^0_ll' = sum_PQ Z_lP (V + W^c(ω=0))_PQ Z_l'Q (statically screened W on the grid)....
subroutine, public hartree_potential_from_diag_ri_rs(bs_env, n_vec, v_h_ao_fm)
Hartree stages 2-3 from a precomputed grid density n_l (skips the stage-1 φρφ^T build): v_l = sum_PQl...
subroutine, public compute_sigma_ri_rs_complex(bs_env, sigma_ao_cfm, prefactor, rho_ao_cfm, grid_diag_re_accum, grid_diag_im_accum)
Complex-input AO SEX via Re/Im split: the kernel is real, so complex linearity holds as Σ[Δρ] = Σ[Re ...
subroutine, public rt_bse_ri_rs_ensure_grid(bs_env, qs_env)
Make sure the AO collocation φ_µ(r_l) (mat_phi_mu_l) and the RI fit coefficients Z_lP (mat_Z_lP) are ...
subroutine, public compute_sigma_ri_rs(bs_env, sigma_ao_fm, prefactor, rho_ao_fm, grid_diag_accum)
AO-domain SEX: Σ_µν = pref * sum_ll' φ_lµ [ρ^grid ∘ W^0]_ll' φ_l'ν, ρ^grid_ll' = sum_µν φ_lµ Δρ_µν φ_...
subroutine, public compute_hartree_ri_rs(bs_env, rho_ao_fm, v_h_ao_fm)
AO-domain Hartree via RI-RS: n_l = sum_µν φ_lµ Δρ_µν φ_lν = (φ ρ φ^T)_ll (diagonal of materialized gr...
subroutine, public compute_hartree_ri_rs_from_diag(bs_env, n_re, v_h_ao_cfm, n_im)
Complex Hartree from precomputed grid diagonals: V^H = V^H[n_re] + i V^H[n_im], each via hartree_pote...
subroutine, public rt_bse_ri_rs_ensure_v_grid(bs_env, qs_env)
Build V^aux_PQ = [M^-1 V^tr M^-1]_PQ (truncated Coulomb in the RI basis, M^-1-sandwiched to match the...
Represent a complex full matrix.
represent a full matrix
stores all the informations relevant to an mpi environment