(git:71c3ab0)
Loading...
Searching...
No Matches
gw_large_cell_gamma.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 Routines from paper [Graml2024]
10!> \par History
11!> 01.2026 Maximilian Graml: add more bounds to exploit sparsity in 3c integrals, fixes
12!> \author Jan Wilhelm
13!> \date 07.2023
14! **************************************************************************************************
17 USE bibliography, ONLY: graml2024,&
18 cite_reference
19 USE cell_types, ONLY: cell_type,&
20 get_cell,&
21 pbc
26 USE cp_cfm_diag, ONLY: cp_cfm_geeig
27 USE cp_cfm_types, ONLY: cp_cfm_create,&
34 USE cp_dbcsr_api, ONLY: &
43 USE cp_files, ONLY: close_file,&
46 USE cp_fm_diag, ONLY: cp_fm_power
47 USE cp_fm_types, ONLY: &
52 USE cp_output_handling, ONLY: cp_p_file,&
55 USE dbt_api, ONLY: dbt_clear,&
56 dbt_contract,&
57 dbt_copy,&
58 dbt_create,&
59 dbt_destroy,&
60 dbt_filter,&
61 dbt_type
69 USE kinds, ONLY: default_path_length,&
70 dp,&
71 int_8
73 USE kpoint_types, ONLY: kpoint_type
74 USE machine, ONLY: m_walltime
75 USE mathconstants, ONLY: twopi,&
76 z_one,&
77 z_zero
91#include "./base/base_uses.f90"
92
93 IMPLICIT NONE
94
95 PRIVATE
96
97 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gw_large_cell_gamma'
98
99 PUBLIC :: gw_calc_large_cell_gamma, &
105
106CONTAINS
107
108! **************************************************************************************************
109!> \brief Perform GW band structure calculation
110!> \param qs_env ...
111!> \param bs_env ...
112!> \par History
113!> * 07.2023 created [Jan Wilhelm]
114! **************************************************************************************************
115 SUBROUTINE gw_calc_large_cell_gamma(qs_env, bs_env)
116 TYPE(qs_environment_type), POINTER :: qs_env
117 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
118
119 CHARACTER(LEN=*), PARAMETER :: routinen = 'gw_calc_large_cell_Gamma'
120
121 INTEGER :: handle
122 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_sigma_x_gamma, fm_w_mic_time
123 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
124
125 CALL timeset(routinen, handle)
126
127 CALL cite_reference(graml2024)
128
129 ! G^occ_µλ(i|τ|,k=0) = sum_n^occ C_µn(k=0) e^(-|(ϵ_nk=0-ϵ_F)τ|) C_λn(k=0)
130 ! G^vir_µλ(i|τ|,k=0) = sum_n^vir C_µn(k=0) e^(-|(ϵ_nk=0-ϵ_F)τ|) C_λn(k=0)
131 ! χ_PQ(iτ,k=0) = sum_λν [sum_µ (µν|P) G^occ_µλ(i|τ|)] [sum_σ (σλ|Q) G^vir_σν(i|τ|)]
132 CALL get_mat_chi_gamma_tau(bs_env, qs_env, bs_env%mat_chi_Gamma_tau)
133
134 ! χ_PQ(iτ,k=0) -> χ_PQ(iω,k) -> ε_PQ(iω,k) -> W_PQ(iω,k) -> W^MIC_PQ(iτ) -> M^-1*W^MIC*M^-1
135 CALL get_w_mic(bs_env, qs_env, bs_env%mat_chi_Gamma_tau, fm_w_mic_time)
136
137 ! D_µν = sum_n^occ C_µn(k=0) C_νn(k=0), V^trunc_PQ = sum_cell_R <phi_P,0|V^trunc|phi_Q,R>
138 ! Σ^x_λσ(k=0) = sum_νQ [sum_P (νσ|P) V^trunc_PQ] [sum_µ (λµ|Q) D_µν)]
139 CALL get_sigma_x(bs_env, qs_env, fm_sigma_x_gamma)
140
141 ! Σ^c_λσ(iτ,k=0) = sum_νQ [sum_P (νσ|P) W^MIC_PQ(iτ)] [sum_µ (λµ|Q) G^occ_µν(i|τ|)], τ < 0
142 ! Σ^c_λσ(iτ,k=0) = sum_νQ [sum_P (νσ|P) W^MIC_PQ(iτ)] [sum_µ (λµ|Q) G^vir_µν(i|τ|)], τ > 0
143 CALL get_sigma_c(bs_env, qs_env, fm_w_mic_time, fm_sigma_c_gamma_time)
144
145 ! Σ^c_λσ(iτ,k=0) -> Σ^c_nn(ϵ,k); ϵ_nk^GW = ϵ_nk^DFT + Σ^c_nn(ϵ,k) + Σ^x_nn(k) - v^xc_nn(k)
146 CALL compute_qp_energies(bs_env, qs_env, fm_sigma_x_gamma, fm_sigma_c_gamma_time)
147
148 CALL de_init_bs_env(bs_env)
149
150 CALL timestop(handle)
151
152 END SUBROUTINE gw_calc_large_cell_gamma
153
154! **************************************************************************************************
155!> \brief ...
156!> \param bs_env ...
157!> \param qs_env ...
158!> \param mat_chi_Gamma_tau ...
159! **************************************************************************************************
160 SUBROUTINE get_mat_chi_gamma_tau(bs_env, qs_env, mat_chi_Gamma_tau)
161 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
162 TYPE(qs_environment_type), POINTER :: qs_env
163 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_gamma_tau
164
165 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_mat_chi_Gamma_tau'
166
167 INTEGER :: handle, i_intval_idx, i_t, inner_loop_atoms_interval_index, ispin, j_intval_idx
168 INTEGER(KIND=int_8) :: flop
169 INTEGER, DIMENSION(2) :: bounds_p, bounds_q, i_atoms, il_atoms, &
170 j_atoms
171 INTEGER, DIMENSION(2, 2) :: bounds_comb
172 LOGICAL :: dist_too_long_i, dist_too_long_j
173 REAL(kind=dp) :: t1, tau
174 TYPE(dbt_type) :: t_2c_gocc, t_2c_gvir, t_3c_for_gocc, &
175 t_3c_for_gvir, t_3c_x_gocc, &
176 t_3c_x_gocc_2, t_3c_x_gvir, &
177 t_3c_x_gvir_2
178
179 CALL timeset(routinen, handle)
180
181 DO i_t = 1, bs_env%num_time_freq_points
182
183 t1 = m_walltime()
184
185 IF (bs_env%read_chi(i_t)) THEN
186
187 CALL fm_read(bs_env%fm_RI_RI, bs_env, bs_env%chi_name, i_t)
188
189 CALL copy_fm_to_dbcsr(bs_env%fm_RI_RI, mat_chi_gamma_tau(i_t)%matrix, &
190 keep_sparsity=.false.)
191
192 IF (bs_env%unit_nr > 0) THEN
193 WRITE (bs_env%unit_nr, '(T2,A,I5,A,I3,A,F10.1,A)') &
194 χτ'Read (i,k=0) from file for time point ', i_t, ' /', &
195 bs_env%num_time_freq_points, &
196 ', Execution time', m_walltime() - t1, ' s'
197 END IF
198
199 cycle
200
201 END IF
202
203 IF (.NOT. bs_env%calc_chi(i_t)) cycle
204
205 CALL create_tensors_chi(t_2c_gocc, t_2c_gvir, t_3c_for_gocc, t_3c_for_gvir, &
206 t_3c_x_gocc, t_3c_x_gvir, t_3c_x_gocc_2, t_3c_x_gvir_2, bs_env)
207
208 ! 1. compute G^occ and G^vir
209 ! Background: G^σ(iτ) = G^occ,σ(iτ) * Θ(-τ) + G^vir,σ(iτ) * Θ(τ), σ ∈ {↑,↓}
210 ! G^occ,σ_µλ(i|τ|,k=0) = sum_n^occ C^σ_µn(k=0) e^(-|(ϵ^σ_nk=0-ϵ_F)τ|) C^σ_λn(k=0)
211 ! G^vir,σ_µλ(i|τ|,k=0) = sum_n^vir C^σ_µn(k=0) e^(-|(ϵ^σ_nk=0-ϵ_F)τ|) C^σ_λn(k=0)
212 tau = bs_env%imag_time_points(i_t)
213
214 DO ispin = 1, bs_env%n_spin
215 CALL g_occ_vir(bs_env, tau, bs_env%fm_Gocc, ispin, occ=.true., vir=.false.)
216 CALL g_occ_vir(bs_env, tau, bs_env%fm_Gvir, ispin, occ=.false., vir=.true.)
217
218 CALL fm_to_local_tensor(bs_env%fm_Gocc, bs_env%mat_ao_ao%matrix, &
219 bs_env%mat_ao_ao_tensor%matrix, t_2c_gocc, bs_env, &
220 bs_env%atoms_j_t_group)
221 CALL fm_to_local_tensor(bs_env%fm_Gvir, bs_env%mat_ao_ao%matrix, &
222 bs_env%mat_ao_ao_tensor%matrix, t_2c_gvir, bs_env, &
223 bs_env%atoms_i_t_group)
224
225 ! every group has its own range of i_atoms and j_atoms; only deal with a
226 ! limited number of i_atom-j_atom pairs simultaneously in a group to save memory
227 DO i_intval_idx = 1, bs_env%n_intervals_i
228 DO j_intval_idx = 1, bs_env%n_intervals_j
229 i_atoms = bs_env%i_atom_intervals(1:2, i_intval_idx)
230 j_atoms = bs_env%j_atom_intervals(1:2, j_intval_idx)
231
232 IF (bs_env%skip_chi(i_intval_idx, j_intval_idx)) THEN
233 ! Do that only after first timestep to avoid skips due to vanishing G
234 ! caused by gaps
235 IF (i_t == 2) THEN
236 bs_env%n_skip_chi = bs_env%n_skip_chi + 1
237 END IF
238 cycle
239 END IF
240
241 DO inner_loop_atoms_interval_index = 1, bs_env%n_intervals_inner_loop_atoms
242
243 il_atoms = bs_env%inner_loop_atom_intervals(1:2, inner_loop_atoms_interval_index)
244 ! Idea: Use sparsity in 3c integrals behind χ_PQ(iτ,k=0)
245 ! -> λ bounds from j_atoms -> sparse in IL_atoms through σ in
246 ! N_Qλν(iτ) = sum_σ (Qλ|σ) G^vir_νσ(i|τ|,k=0)
247 ! -> ν bounds from i_atoms -> sparse in IL_atoms through µ in
248 ! M_Pνλ(iτ) = sum_µ (Pν|µ) G^occ_λµ(i|τ|,k=0)
249 CALL check_dist(i_atoms, il_atoms, qs_env, bs_env, dist_too_long_i)
250 CALL check_dist(j_atoms, il_atoms, qs_env, bs_env, dist_too_long_j)
251 IF (.NOT. dist_too_long_i) THEN
252 ! 2. compute 3-center integrals (Pν|µ) ("|": truncated Coulomb operator)
253 CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_gocc, &
254 atoms_ao_1=i_atoms, atoms_ao_2=il_atoms)
255 ! 3. tensor operation M_Pνλ(iτ) = sum_µ (Pν|µ) G^occ_λµ(i|τ|,k=0)
256 CALL g_times_3c(t_3c_for_gocc, t_2c_gocc, t_3c_x_gocc, bs_env, &
257 j_atoms, i_atoms, il_atoms)
258 END IF
259 IF (.NOT. dist_too_long_j) THEN
260 ! 4. compute 3-center integrals (Qλ|σ) ("|": truncated Coulomb operator)
261 CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_gvir, &
262 atoms_ao_1=j_atoms, atoms_ao_2=il_atoms)
263 ! 5. tensor operation N_Qλν(iτ) = sum_σ (Qλ|σ) G^vir_νσ(i|τ|,k=0)
264 CALL g_times_3c(t_3c_for_gvir, t_2c_gvir, t_3c_x_gvir, bs_env, &
265 i_atoms, j_atoms, il_atoms)
266 END IF
267 END DO ! IL_atoms
268
269 ! 6. reorder tensors: M_Pνλ -> M_Pλν
270 CALL dbt_copy(t_3c_x_gocc, t_3c_x_gocc_2, move_data=.true., order=[1, 3, 2])
271 CALL dbt_copy(t_3c_x_gvir, t_3c_x_gvir_2, move_data=.true.)
272
273 ! 7. tensor operation χ_PQ(iτ,k=0) = sum_λν M_Pλν(iτ) N_Qλν(iτ),
274 ! Bounds:
275 ! "comb" (combined index)
276 ! -> λ bounds from j_atoms
277 ! -> ν bounds from i_atoms
278 ! P -> sparse in ν (see 3.)
279 ! Q -> sparse in λ (see 5.)
280 bounds_comb(1:2, 1) = [bs_env%i_ao_start_from_atom(j_atoms(1)), &
281 bs_env%i_ao_end_from_atom(j_atoms(2))]
282 bounds_comb(1:2, 2) = [bs_env%i_ao_start_from_atom(i_atoms(1)), &
283 bs_env%i_ao_end_from_atom(i_atoms(2))]
284
285 CALL get_bounds_from_atoms(bounds_p, i_atoms, [1, bs_env%n_atom], &
286 bs_env%min_RI_idx_from_AO_AO_atom, &
287 bs_env%max_RI_idx_from_AO_AO_atom)
288 CALL get_bounds_from_atoms(bounds_q, [1, bs_env%n_atom], j_atoms, &
289 bs_env%min_RI_idx_from_AO_AO_atom, &
290 bs_env%max_RI_idx_from_AO_AO_atom)
291
292 IF (bounds_q(1) > bounds_q(2) .OR. bounds_p(1) > bounds_p(2)) THEN
293 flop = 0_int_8
294 ELSE
295 CALL dbt_contract(alpha=bs_env%spin_degeneracy, &
296 tensor_1=t_3c_x_gocc_2, tensor_2=t_3c_x_gvir_2, &
297 beta=1.0_dp, tensor_3=bs_env%t_chi, &
298 contract_1=[2, 3], notcontract_1=[1], map_1=[1], &
299 contract_2=[2, 3], notcontract_2=[1], map_2=[2], &
300 bounds_1=bounds_comb, &
301 bounds_2=bounds_p, &
302 bounds_3=bounds_q, &
303 filter_eps=bs_env%eps_filter, move_data=.false., flop=flop, &
304 unit_nr=bs_env%unit_nr_contract, &
305 log_verbose=bs_env%print_contract_verbose)
306 END IF
307 IF (flop == 0_int_8) bs_env%skip_chi(i_intval_idx, j_intval_idx) = .true.
308
309 END DO ! j_atoms
310 END DO ! i_atoms
311 END DO ! ispin
312
313 ! 8. communicate data of χ_PQ(iτ,k=0) in tensor bs_env%t_chi (which local in the
314 ! subgroup) to the global dbcsr matrix mat_chi_Gamma_tau (which stores
315 ! χ_PQ(iτ,k=0) for all time points)
316 CALL local_dbt_to_global_mat(bs_env%t_chi, bs_env%mat_RI_RI_tensor%matrix, &
317 mat_chi_gamma_tau(i_t)%matrix, bs_env%para_env)
318
319 CALL write_matrix(mat_chi_gamma_tau(i_t)%matrix, i_t, bs_env%chi_name, &
320 bs_env%fm_RI_RI, qs_env)
321
322 CALL destroy_tensors_chi(t_2c_gocc, t_2c_gvir, t_3c_for_gocc, t_3c_for_gvir, &
323 t_3c_x_gocc, t_3c_x_gvir, t_3c_x_gocc_2, t_3c_x_gvir_2)
324
325 IF (bs_env%unit_nr > 0) THEN
326 WRITE (bs_env%unit_nr, '(T2,A,I13,A,I3,A,F10.1,A)') &
327 χτ'Computed (i,k=0) for time point', i_t, ' /', bs_env%num_time_freq_points, &
328 ', Execution time', m_walltime() - t1, ' s'
329 END IF
330
331 END DO ! i_t
332
333 IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
334
335 CALL timestop(handle)
336
337 END SUBROUTINE get_mat_chi_gamma_tau
338
339! **************************************************************************************************
340!> \brief ...
341!> \param fm ...
342!> \param bs_env ...
343!> \param mat_name ...
344!> \param idx ...
345! **************************************************************************************************
346 SUBROUTINE fm_read(fm, bs_env, mat_name, idx)
347 TYPE(cp_fm_type) :: fm
348 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
349 CHARACTER(LEN=*) :: mat_name
350 INTEGER :: idx
351
352 CHARACTER(LEN=*), PARAMETER :: routinen = 'fm_read'
353
354 CHARACTER(LEN=default_path_length) :: f_chi
355 INTEGER :: handle, unit_nr
356
357 CALL timeset(routinen, handle)
358
359 unit_nr = -1
360 IF (bs_env%para_env%is_source()) THEN
361
362 IF (idx < 10) THEN
363 WRITE (f_chi, '(3A,I1,A)') trim(bs_env%prefix), trim(mat_name), "_0", idx, ".matrix"
364 ELSE IF (idx < 100) THEN
365 WRITE (f_chi, '(3A,I2,A)') trim(bs_env%prefix), trim(mat_name), "_", idx, ".matrix"
366 ELSE
367 cpabort('Please implement more than 99 time/frequency points.')
368 END IF
369
370 CALL open_file(file_name=trim(f_chi), file_action="READ", file_form="UNFORMATTED", &
371 file_position="REWIND", file_status="OLD", unit_number=unit_nr)
372
373 END IF
374
375 CALL cp_fm_read_unformatted(fm, unit_nr)
376
377 IF (bs_env%para_env%is_source()) CALL close_file(unit_number=unit_nr)
378
379 CALL timestop(handle)
380
381 END SUBROUTINE fm_read
382
383! **************************************************************************************************
384!> \brief ...
385!> \param t_2c_Gocc ...
386!> \param t_2c_Gvir ...
387!> \param t_3c_for_Gocc ...
388!> \param t_3c_for_Gvir ...
389!> \param t_3c_x_Gocc ...
390!> \param t_3c_x_Gvir ...
391!> \param t_3c_x_Gocc_2 ...
392!> \param t_3c_x_Gvir_2 ...
393!> \param bs_env ...
394! **************************************************************************************************
395 SUBROUTINE create_tensors_chi(t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, t_3c_for_Gvir, &
396 t_3c_x_Gocc, t_3c_x_Gvir, t_3c_x_Gocc_2, t_3c_x_Gvir_2, bs_env)
397
398 TYPE(dbt_type) :: t_2c_gocc, t_2c_gvir, t_3c_for_gocc, &
399 t_3c_for_gvir, t_3c_x_gocc, &
400 t_3c_x_gvir, t_3c_x_gocc_2, &
401 t_3c_x_gvir_2
402 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
403
404 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_tensors_chi'
405
406 INTEGER :: handle
407
408 CALL timeset(routinen, handle)
409
410 CALL dbt_create(bs_env%t_G, t_2c_gocc, name="Gocc 2c (AO|AO)")
411 CALL dbt_create(bs_env%t_G, t_2c_gvir, name="Gvir 2c (AO|AO)")
412 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_for_gocc, name="Gocc 3c (RI AO|AO)")
413 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_for_gvir, name="Gvir 3c (RI AO|AO)")
414 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_gocc, name="xGocc 3c (RI AO|AO)")
415 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_gvir, name="xGvir 3c (RI AO|AO)")
416 CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_x_gocc_2, name="x2Gocc 3c (RI AO|AO)")
417 CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_x_gvir_2, name="x2Gvir 3c (RI AO|AO)")
418
419 CALL timestop(handle)
420
421 END SUBROUTINE create_tensors_chi
422
423! **************************************************************************************************
424!> \brief ...
425!> \param t_2c_Gocc ...
426!> \param t_2c_Gvir ...
427!> \param t_3c_for_Gocc ...
428!> \param t_3c_for_Gvir ...
429!> \param t_3c_x_Gocc ...
430!> \param t_3c_x_Gvir ...
431!> \param t_3c_x_Gocc_2 ...
432!> \param t_3c_x_Gvir_2 ...
433! **************************************************************************************************
434 SUBROUTINE destroy_tensors_chi(t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, t_3c_for_Gvir, &
435 t_3c_x_Gocc, t_3c_x_Gvir, t_3c_x_Gocc_2, t_3c_x_Gvir_2)
436 TYPE(dbt_type) :: t_2c_gocc, t_2c_gvir, t_3c_for_gocc, &
437 t_3c_for_gvir, t_3c_x_gocc, &
438 t_3c_x_gvir, t_3c_x_gocc_2, &
439 t_3c_x_gvir_2
440
441 CHARACTER(LEN=*), PARAMETER :: routinen = 'destroy_tensors_chi'
442
443 INTEGER :: handle
444
445 CALL timeset(routinen, handle)
446
447 CALL dbt_destroy(t_2c_gocc)
448 CALL dbt_destroy(t_2c_gvir)
449 CALL dbt_destroy(t_3c_for_gocc)
450 CALL dbt_destroy(t_3c_for_gvir)
451 CALL dbt_destroy(t_3c_x_gocc)
452 CALL dbt_destroy(t_3c_x_gvir)
453 CALL dbt_destroy(t_3c_x_gocc_2)
454 CALL dbt_destroy(t_3c_x_gvir_2)
455
456 CALL timestop(handle)
457
458 END SUBROUTINE destroy_tensors_chi
459
460! **************************************************************************************************
461!> \brief ...
462!> \param matrix ...
463!> \param matrix_index ...
464!> \param matrix_name ...
465!> \param fm ...
466!> \param qs_env ...
467! **************************************************************************************************
468 SUBROUTINE write_matrix(matrix, matrix_index, matrix_name, fm, qs_env)
469 TYPE(dbcsr_type) :: matrix
470 INTEGER :: matrix_index
471 CHARACTER(LEN=*) :: matrix_name
472 TYPE(cp_fm_type), INTENT(IN), POINTER :: fm
473 TYPE(qs_environment_type), POINTER :: qs_env
474
475 CHARACTER(LEN=*), PARAMETER :: routinen = 'write_matrix'
476
477 INTEGER :: handle
478
479 CALL timeset(routinen, handle)
480
481 CALL cp_fm_set_all(fm, 0.0_dp)
482
483 CALL copy_dbcsr_to_fm(matrix, fm)
484
485 CALL fm_write(fm, matrix_index, matrix_name, qs_env)
486
487 CALL timestop(handle)
488
489 END SUBROUTINE write_matrix
490
491! **************************************************************************************************
492!> \brief ...
493!> \param fm ...
494!> \param matrix_index ...
495!> \param matrix_name ...
496!> \param qs_env ...
497! **************************************************************************************************
498 SUBROUTINE fm_write(fm, matrix_index, matrix_name, qs_env)
499 TYPE(cp_fm_type) :: fm
500 INTEGER :: matrix_index
501 CHARACTER(LEN=*) :: matrix_name
502 TYPE(qs_environment_type), POINTER :: qs_env
503
504 CHARACTER(LEN=*), PARAMETER :: key = 'PROPERTIES%BANDSTRUCTURE%GW%PRINT%RESTART', &
505 routinen = 'fm_write'
506
507 CHARACTER(LEN=default_path_length) :: filename
508 INTEGER :: handle, unit_nr
509 TYPE(cp_logger_type), POINTER :: logger
510 TYPE(section_vals_type), POINTER :: input
511
512 CALL timeset(routinen, handle)
513
514 CALL get_qs_env(qs_env, input=input)
515
516 logger => cp_get_default_logger()
517
518 IF (btest(cp_print_key_should_output(logger%iter_info, input, key), cp_p_file)) THEN
519
520 IF (matrix_index < 10) THEN
521 WRITE (filename, '(3A,I1)') "RESTART_", matrix_name, "_0", matrix_index
522 ELSE IF (matrix_index < 100) THEN
523 WRITE (filename, '(3A,I2)') "RESTART_", matrix_name, "_", matrix_index
524 ELSE
525 cpabort('Please implement more than 99 time/frequency points.')
526 END IF
527
528 unit_nr = cp_print_key_unit_nr(logger, input, key, extension=".matrix", &
529 file_form="UNFORMATTED", middle_name=trim(filename), &
530 file_position="REWIND", file_action="WRITE")
531
532 CALL cp_fm_write_unformatted(fm, unit_nr)
533 IF (unit_nr > 0) THEN
534 CALL close_file(unit_nr)
535 END IF
536 END IF
537
538 CALL timestop(handle)
539
540 END SUBROUTINE fm_write
541
542! **************************************************************************************************
543!> \brief ...
544!> \param bs_env ...
545!> \param tau ...
546!> \param fm_G_Gamma ...
547!> \param ispin ...
548!> \param occ ...
549!> \param vir ...
550! **************************************************************************************************
551 SUBROUTINE g_occ_vir(bs_env, tau, fm_G_Gamma, ispin, occ, vir)
552 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
553 REAL(kind=dp) :: tau
554 TYPE(cp_fm_type) :: fm_g_gamma
555 INTEGER :: ispin
556 LOGICAL :: occ, vir
557
558 CHARACTER(LEN=*), PARAMETER :: routinen = 'G_occ_vir'
559
560 INTEGER :: handle, homo, i_row_local, j_col, &
561 j_col_local, n_mo, ncol_local, &
562 nrow_local
563 INTEGER, DIMENSION(:), POINTER :: col_indices
564 REAL(kind=dp) :: tau_e
565
566 CALL timeset(routinen, handle)
567
568 cpassert(occ .NEQV. vir)
569
570 CALL cp_fm_get_info(matrix=bs_env%fm_work_mo(1), &
571 nrow_local=nrow_local, &
572 ncol_local=ncol_local, &
573 col_indices=col_indices)
574
575 n_mo = bs_env%n_ao
576 homo = bs_env%n_occ(ispin)
577
578 CALL cp_fm_to_fm(bs_env%fm_mo_coeff_Gamma(ispin), bs_env%fm_work_mo(1))
579
580 DO i_row_local = 1, nrow_local
581 DO j_col_local = 1, ncol_local
582
583 j_col = col_indices(j_col_local)
584
585 tau_e = abs(tau*0.5_dp*(bs_env%eigenval_scf_Gamma(j_col, ispin) - bs_env%e_fermi(ispin)))
586
587 IF (tau_e < bs_env%stabilize_exp) THEN
588 bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local) = &
589 bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local)*exp(-tau_e)
590 ELSE
591 bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local) = 0.0_dp
592 END IF
593
594 IF ((occ .AND. j_col > homo) .OR. (vir .AND. j_col <= homo)) THEN
595 bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local) = 0.0_dp
596 END IF
597
598 END DO
599 END DO
600
601 CALL parallel_gemm(transa="N", transb="T", m=n_mo, n=n_mo, k=n_mo, alpha=1.0_dp, &
602 matrix_a=bs_env%fm_work_mo(1), matrix_b=bs_env%fm_work_mo(1), &
603 beta=0.0_dp, matrix_c=fm_g_gamma)
604
605 CALL timestop(handle)
606
607 END SUBROUTINE g_occ_vir
608
609! **************************************************************************************************
610!> \brief ...
611!> \param qs_env ...
612!> \param bs_env ...
613!> \param t_3c ...
614!> \param atoms_AO_1 ...
615!> \param atoms_AO_2 ...
616!> \param atoms_RI ...
617! **************************************************************************************************
618 SUBROUTINE compute_3c_integrals(qs_env, bs_env, t_3c, atoms_AO_1, atoms_AO_2, atoms_RI)
619 TYPE(qs_environment_type), POINTER :: qs_env
620 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
621 TYPE(dbt_type) :: t_3c
622 INTEGER, DIMENSION(2), OPTIONAL :: atoms_ao_1, atoms_ao_2, atoms_ri
623
624 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_3c_integrals'
625
626 INTEGER :: handle
627 TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_array
628
629 CALL timeset(routinen, handle)
630
631 ! free memory (not clear whether memory has been freed previously)
632 CALL dbt_clear(t_3c)
633
634 ALLOCATE (t_3c_array(1, 1))
635 CALL dbt_create(t_3c, t_3c_array(1, 1))
636
637 CALL build_3c_integrals(t_3c_array, &
638 bs_env%eps_filter, &
639 qs_env, &
640 bs_env%nl_3c, &
641 int_eps=bs_env%eps_filter, &
642 basis_i=bs_env%basis_set_RI, &
643 basis_j=bs_env%basis_set_AO, &
644 basis_k=bs_env%basis_set_AO, &
645 potential_parameter=bs_env%ri_metric, &
646 bounds_i=atoms_ri, &
647 bounds_j=atoms_ao_1, &
648 bounds_k=atoms_ao_2, &
649 desymmetrize=.false.)
650
651 CALL dbt_filter(t_3c_array(1, 1), bs_env%eps_filter)
652
653 CALL dbt_copy(t_3c_array(1, 1), t_3c, move_data=.true.)
654
655 CALL dbt_destroy(t_3c_array(1, 1))
656 DEALLOCATE (t_3c_array)
657
658 CALL timestop(handle)
659
660 END SUBROUTINE compute_3c_integrals
661
662! **************************************************************************************************
663!> \brief ...
664!> \param t_3c_for_G ...
665!> \param t_G ...
666!> \param t_M ...
667!> \param bs_env ...
668!> \param atoms_AO_1 ...
669!> \param atoms_AO_2 ...
670!> \param atoms_IL ...
671! **************************************************************************************************
672 SUBROUTINE g_times_3c(t_3c_for_G, t_G, t_M, bs_env, atoms_AO_1, atoms_AO_2, atoms_IL)
673 TYPE(dbt_type) :: t_3c_for_g, t_g, t_m
674 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
675 INTEGER, DIMENSION(2) :: atoms_ao_1, atoms_ao_2, atoms_il
676
677 CHARACTER(LEN=*), PARAMETER :: routinen = 'G_times_3c'
678
679 INTEGER :: handle
680 INTEGER(KIND=int_8) :: flop
681 INTEGER, DIMENSION(2) :: bounds_ao_1, bounds_il
682 INTEGER, DIMENSION(2, 2) :: bounds_comb
683
684 CALL timeset(routinen, handle)
685
686 ! Bounds reduce needed memory and therefore scaling behavior
687 ! Operations are of the form, e.g, M_Pνλ = sum_µ (Pν|µ) G_λµ
688 ! "comb" (combined index)
689 ! -> P sparse in ν and µ
690 ! -> λ bounds from j_atoms (via atoms_AO_1)
691 ! µ bounds from inner loop "IL" indices and sparse in P and ν
692 ! ν bounds from i_atoms (via atoms_AO_2) and sparse in P and µ
693
694 ! µ index
695 CALL get_bounds_from_atoms(bounds_il, [1, bs_env%n_atom], atoms_ao_2, &
696 bs_env%min_AO_idx_from_RI_AO_atom, &
697 bs_env%max_AO_idx_from_RI_AO_atom, &
698 atoms_3=atoms_il, &
699 indices_3_start=bs_env%i_ao_start_from_atom, &
700 indices_3_end=bs_env%i_ao_end_from_atom)
701
702 ! P index
703 CALL get_bounds_from_atoms(bounds_comb(:, 1), atoms_il, atoms_ao_2, &
704 bs_env%min_RI_idx_from_AO_AO_atom, &
705 bs_env%max_RI_idx_from_AO_AO_atom)
706
707 ! ν index
708 CALL get_bounds_from_atoms(bounds_comb(:, 2), [1, bs_env%n_atom], atoms_il, &
709 bs_env%min_AO_idx_from_RI_AO_atom, &
710 bs_env%max_AO_idx_from_RI_AO_atom, &
711 atoms_3=atoms_ao_2, &
712 indices_3_start=bs_env%i_ao_start_from_atom, &
713 indices_3_end=bs_env%i_ao_end_from_atom)
714
715 ! λ index
716 bounds_ao_1(1:2) = [bs_env%i_ao_start_from_atom(atoms_ao_1(1)), &
717 bs_env%i_ao_end_from_atom(atoms_ao_1(2))]
718
719 IF (bounds_il(1) > bounds_il(2) .OR. bounds_comb(1, 2) > bounds_comb(2, 2)) THEN
720 flop = 0_int_8
721 ELSE
722 CALL dbt_contract(alpha=1.0_dp, &
723 tensor_1=t_3c_for_g, &
724 tensor_2=t_g, &
725 beta=1.0_dp, &
726 tensor_3=t_m, &
727 contract_1=[3], notcontract_1=[1, 2], map_1=[1, 2], &
728 contract_2=[2], notcontract_2=[1], map_2=[3], &
729 bounds_1=bounds_il, &
730 bounds_2=bounds_comb, &
731 bounds_3=bounds_ao_1, &
732 flop=flop, &
733 filter_eps=bs_env%eps_filter, &
734 unit_nr=bs_env%unit_nr_contract, &
735 log_verbose=bs_env%print_contract_verbose)
736 END IF
737
738 CALL dbt_clear(t_3c_for_g)
739
740 CALL timestop(handle)
741
742 END SUBROUTINE g_times_3c
743
744! **************************************************************************************************
745!> \brief ...
746!> \param atoms_1 ...
747!> \param atoms_2 ...
748!> \param qs_env ...
749!> \param bs_env ...
750!> \param dist_too_long ...
751! **************************************************************************************************
752 SUBROUTINE check_dist(atoms_1, atoms_2, qs_env, bs_env, dist_too_long)
753 INTEGER, DIMENSION(2) :: atoms_1, atoms_2
754 TYPE(qs_environment_type), POINTER :: qs_env
755 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
756 LOGICAL :: dist_too_long
757
758 CHARACTER(LEN=*), PARAMETER :: routinen = 'check_dist'
759
760 INTEGER :: atom_1, atom_2, handle
761 REAL(dp) :: abs_rab, min_dist_ao_atoms
762 REAL(kind=dp), DIMENSION(3) :: rab
763 TYPE(cell_type), POINTER :: cell
764 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
765
766 CALL timeset(routinen, handle)
767
768 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
769
770 min_dist_ao_atoms = huge(1.0_dp)
771 DO atom_1 = atoms_1(1), atoms_1(2)
772 DO atom_2 = atoms_2(1), atoms_2(2)
773 rab = pbc(particle_set(atom_1)%r(1:3), particle_set(atom_2)%r(1:3), cell)
774
775 abs_rab = sqrt(rab(1)**2 + rab(2)**2 + rab(3)**2)
776
777 min_dist_ao_atoms = min(min_dist_ao_atoms, abs_rab)
778 END DO
779 END DO
780
781 dist_too_long = (min_dist_ao_atoms > bs_env%max_dist_AO_atoms)
782
783 CALL timestop(handle)
784
785 END SUBROUTINE check_dist
786
787! **************************************************************************************************
788!> \brief ...
789!> \param bs_env ...
790!> \param qs_env ...
791!> \param mat_chi_Gamma_tau ...
792!> \param fm_W_MIC_time ...
793! **************************************************************************************************
794 SUBROUTINE get_w_mic(bs_env, qs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
795 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
796 TYPE(qs_environment_type), POINTER :: qs_env
797 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_gamma_tau
798 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
799
800 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_W_MIC'
801
802 INTEGER :: handle
803
804 CALL timeset(routinen, handle)
805
806 IF (bs_env%all_W_exist) THEN
807 CALL read_w_mic_time(bs_env, mat_chi_gamma_tau, fm_w_mic_time)
808 ELSE
809 CALL compute_w_mic(bs_env, qs_env, mat_chi_gamma_tau, fm_w_mic_time)
810 END IF
811
812 CALL timestop(handle)
813
814 END SUBROUTINE get_w_mic
815
816! **************************************************************************************************
817!> \brief ...
818!> \param bs_env ...
819!> \param qs_env ...
820!> \param fm_V_kp ...
821!> \param ikp_batch ...
822! **************************************************************************************************
823 SUBROUTINE compute_v_k_by_lattice_sum(bs_env, qs_env, fm_V_kp, ikp_batch)
824 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
825 TYPE(qs_environment_type), POINTER :: qs_env
826 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_v_kp
827 INTEGER :: ikp_batch
828
829 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_V_k_by_lattice_sum'
830
831 INTEGER :: handle, ikp, ikp_end, ikp_start, &
832 nkp_chi_eps_w_batch, re_im
833 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
834 TYPE(cell_type), POINTER :: cell
835 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_v_kp
836 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
837 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
838
839 CALL timeset(routinen, handle)
840
841 nkp_chi_eps_w_batch = bs_env%nkp_chi_eps_W_batch
842
843 ikp_start = (ikp_batch - 1)*bs_env%nkp_chi_eps_W_batch + 1
844 ikp_end = min(ikp_batch*bs_env%nkp_chi_eps_W_batch, bs_env%kpoints_chi_eps_W%nkp)
845
846 NULLIFY (mat_v_kp)
847 ALLOCATE (mat_v_kp(ikp_start:ikp_end, 2))
848
849 DO re_im = 1, 2
850 DO ikp = ikp_start, ikp_end
851 NULLIFY (mat_v_kp(ikp, re_im)%matrix)
852 ALLOCATE (mat_v_kp(ikp, re_im)%matrix)
853 CALL dbcsr_create(mat_v_kp(ikp, re_im)%matrix, template=bs_env%mat_RI_RI%matrix)
854 CALL dbcsr_reserve_all_blocks(mat_v_kp(ikp, re_im)%matrix)
855 CALL dbcsr_set(mat_v_kp(ikp, re_im)%matrix, 0.0_dp)
856 END DO ! ikp
857 END DO ! re_im
858
859 CALL get_qs_env(qs_env=qs_env, &
860 particle_set=particle_set, &
861 cell=cell, &
862 qs_kind_set=qs_kind_set, &
863 atomic_kind_set=atomic_kind_set)
864
865 IF (ikp_end <= bs_env%nkp_chi_eps_W_orig) THEN
866
867 ! 1. 2c Coulomb integrals for the first "original" k-point grid
868 bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_orig
869
870 ELSE IF (ikp_start > bs_env%nkp_chi_eps_W_orig .AND. &
871 ikp_end <= bs_env%nkp_chi_eps_W_orig_plus_extra) THEN
872
873 ! 2. 2c Coulomb integrals for the second "extrapolation" k-point grid
874 bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_extra
875
876 ELSE
877
878 cpabort("Error with k-point parallelization.")
879
880 END IF
881
882 CALL build_2c_coulomb_matrix_kp(mat_v_kp, &
883 bs_env%kpoints_chi_eps_W, &
884 basis_type="RI_AUX", &
885 cell=cell, &
886 particle_set=particle_set, &
887 qs_kind_set=qs_kind_set, &
888 atomic_kind_set=atomic_kind_set, &
889 size_lattice_sum=bs_env%size_lattice_sum_V, &
890 operator_type=operator_coulomb, &
891 ikp_start=ikp_start, &
892 ikp_end=ikp_end)
893
894 bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_orig
895
896 ALLOCATE (fm_v_kp(ikp_start:ikp_end, 2))
897 DO re_im = 1, 2
898 DO ikp = ikp_start, ikp_end
899 CALL cp_fm_create(fm_v_kp(ikp, re_im), bs_env%fm_RI_RI%matrix_struct)
900 CALL copy_dbcsr_to_fm(mat_v_kp(ikp, re_im)%matrix, fm_v_kp(ikp, re_im))
901 CALL dbcsr_deallocate_matrix(mat_v_kp(ikp, re_im)%matrix)
902 END DO
903 END DO
904 DEALLOCATE (mat_v_kp)
905
906 CALL timestop(handle)
907
908 END SUBROUTINE compute_v_k_by_lattice_sum
909
910! **************************************************************************************************
911!> \brief ...
912!> \param bs_env ...
913!> \param qs_env ...
914!> \param fm_V_kp ...
915!> \param cfm_V_sqrt_ikp ...
916!> \param cfm_M_inv_V_sqrt_ikp ...
917!> \param ikp ...
918! **************************************************************************************************
919 SUBROUTINE compute_minvvsqrt_vsqrt(bs_env, qs_env, fm_V_kp, cfm_V_sqrt_ikp, &
920 cfm_M_inv_V_sqrt_ikp, ikp)
921 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
922 TYPE(qs_environment_type), POINTER :: qs_env
923 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_v_kp
924 TYPE(cp_cfm_type) :: cfm_v_sqrt_ikp, cfm_m_inv_v_sqrt_ikp
925 INTEGER :: ikp
926
927 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_MinvVsqrt_Vsqrt'
928
929 INTEGER :: handle, info, n_ri
930 TYPE(cp_cfm_type) :: cfm_m_inv_ikp, cfm_work
931 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_m_ikp
932
933 CALL timeset(routinen, handle)
934
935 n_ri = bs_env%n_RI
936
937 ! get here M(k) and write it to fm_M_ikp
938 CALL ri_2c_integral_mat(qs_env, fm_m_ikp, fm_v_kp(ikp, 1), &
939 n_ri, bs_env%ri_metric, do_kpoints=.true., &
940 kpoints=bs_env%kpoints_chi_eps_W, &
941 regularization_ri=bs_env%regularization_RI, ikp_ext=ikp, &
942 do_build_cell_index=(ikp == 1))
943
944 IF (ikp == 1) THEN
945 CALL cp_cfm_create(cfm_v_sqrt_ikp, fm_v_kp(ikp, 1)%matrix_struct)
946 CALL cp_cfm_create(cfm_m_inv_v_sqrt_ikp, fm_v_kp(ikp, 1)%matrix_struct)
947 END IF
948 CALL cp_cfm_create(cfm_m_inv_ikp, fm_v_kp(ikp, 1)%matrix_struct)
949
950 CALL cp_fm_to_cfm(fm_m_ikp(1, 1), fm_m_ikp(1, 2), cfm_m_inv_ikp)
951 CALL cp_fm_to_cfm(fm_v_kp(ikp, 1), fm_v_kp(ikp, 2), cfm_v_sqrt_ikp)
952
953 CALL cp_fm_release(fm_m_ikp)
954
955 CALL cp_cfm_create(cfm_work, fm_v_kp(ikp, 1)%matrix_struct)
956
957 ! M(k) -> M^-1(k)
958 CALL cp_cfm_to_cfm(cfm_m_inv_ikp, cfm_work)
959 CALL cp_cfm_cholesky_decompose(matrix=cfm_m_inv_ikp, n=n_ri, info_out=info)
960 IF (info == 0) THEN
961 ! successful Cholesky decomposition
962 CALL cp_cfm_cholesky_invert(cfm_m_inv_ikp)
963 ! symmetrize the result
964 CALL cp_cfm_uplo_to_full(cfm_m_inv_ikp)
965 ELSE
966 ! Cholesky decomposition not successful: use expensive diagonalization
967 CALL cp_cfm_power(cfm_work, threshold=bs_env%eps_eigval_mat_RI, exponent=-1.0_dp)
968 CALL cp_cfm_to_cfm(cfm_work, cfm_m_inv_ikp)
969 END IF
970
971 ! V(k) -> L(k) with L^H(k)*L(k) = V(k) [L(k) can be just considered to be V^0.5(k)]
972 CALL cp_cfm_to_cfm(cfm_v_sqrt_ikp, cfm_work)
973 CALL cp_cfm_cholesky_decompose(matrix=cfm_v_sqrt_ikp, n=n_ri, info_out=info)
974 IF (info == 0) THEN
975 ! successful Cholesky decomposition
976 CALL clean_lower_part(cfm_v_sqrt_ikp)
977 ELSE
978 ! Cholesky decomposition not successful: use expensive diagonalization
979 CALL cp_cfm_power(cfm_work, threshold=0.0_dp, exponent=0.5_dp)
980 CALL cp_cfm_to_cfm(cfm_work, cfm_v_sqrt_ikp)
981 END IF
982 CALL cp_cfm_release(cfm_work)
983
984 ! get M^-1(k)*V^0.5(k)
985 CALL parallel_gemm("N", "C", n_ri, n_ri, n_ri, z_one, cfm_m_inv_ikp, cfm_v_sqrt_ikp, &
986 z_zero, cfm_m_inv_v_sqrt_ikp)
987
988 CALL cp_cfm_release(cfm_m_inv_ikp)
989
990 CALL timestop(handle)
991
992 END SUBROUTINE compute_minvvsqrt_vsqrt
993
994! **************************************************************************************************
995!> \brief ...
996!> \param bs_env ...
997!> \param mat_chi_Gamma_tau ...
998!> \param fm_W_MIC_time ...
999! **************************************************************************************************
1000 SUBROUTINE read_w_mic_time(bs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
1001 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1002 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_gamma_tau
1003 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
1004
1005 CHARACTER(LEN=*), PARAMETER :: routinen = 'read_W_MIC_time'
1006
1007 INTEGER :: handle, i_t
1008 REAL(kind=dp) :: t1
1009
1010 CALL timeset(routinen, handle)
1011
1012 CALL dbcsr_deallocate_matrix_set(mat_chi_gamma_tau)
1013 CALL create_fm_w_mic_time(bs_env, fm_w_mic_time)
1014
1015 DO i_t = 1, bs_env%num_time_freq_points
1016
1017 t1 = m_walltime()
1018
1019 CALL fm_read(fm_w_mic_time(i_t), bs_env, bs_env%W_time_name, i_t)
1020
1021 IF (bs_env%unit_nr > 0) THEN
1022 WRITE (bs_env%unit_nr, '(T2,A,I5,A,I3,A,F10.1,A)') &
1023 τ'Read W^MIC(i) from file for time point ', i_t, ' /', bs_env%num_time_freq_points, &
1024 ', Execution time', m_walltime() - t1, ' s'
1025 END IF
1026
1027 END DO
1028
1029 IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
1030
1031 ! Marek : Reading of the W(w=0) potential for RTP
1032 ! TODO : is the condition bs_env%all_W_exist sufficient for reading?
1033 IF (bs_env%rtp_method == rtp_method_bse) THEN
1034 CALL cp_fm_create(bs_env%fm_W_MIC_freq_zero, bs_env%fm_W_MIC_freq%matrix_struct)
1035 t1 = m_walltime()
1036 CALL fm_read(bs_env%fm_W_MIC_freq_zero, bs_env, "W_freq_rtp", 0)
1037 IF (bs_env%unit_nr > 0) THEN
1038 WRITE (bs_env%unit_nr, '(T2,A,I3,A,I3,A,F10.1,A)') &
1039 'Read W^MIC(f=0) from file for freq. point ', 1, ' /', 1, &
1040 ', Execution time', m_walltime() - t1, ' s'
1041 END IF
1042 END IF
1043
1044 CALL timestop(handle)
1045
1046 END SUBROUTINE read_w_mic_time
1047
1048! **************************************************************************************************
1049!> \brief ...
1050!> \param bs_env ...
1051!> \param qs_env ...
1052!> \param mat_chi_Gamma_tau ...
1053!> \param fm_W_MIC_time ...
1054! **************************************************************************************************
1055 SUBROUTINE compute_w_mic(bs_env, qs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
1056 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1057 TYPE(qs_environment_type), POINTER :: qs_env
1058 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_gamma_tau
1059 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
1060
1061 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_W_MIC'
1062
1063 INTEGER :: handle, i_t, ikp, ikp_batch, &
1064 ikp_in_batch, j_w
1065 REAL(kind=dp) :: t1
1066 TYPE(cp_cfm_type) :: cfm_m_inv_v_sqrt_ikp, cfm_v_sqrt_ikp
1067 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_v_kp
1068
1069 CALL timeset(routinen, handle)
1070
1071 CALL create_fm_w_mic_time(bs_env, fm_w_mic_time)
1072
1073 DO ikp_batch = 1, bs_env%num_chi_eps_W_batches
1074
1075 t1 = m_walltime()
1076
1077 ! Compute V_PQ(k) = sum_R e^(ikR) <phi_P, cell 0 | 1/r | phi_Q, cell R>
1078 CALL compute_v_k_by_lattice_sum(bs_env, qs_env, fm_v_kp, ikp_batch)
1079
1080 DO ikp_in_batch = 1, bs_env%nkp_chi_eps_W_batch
1081
1082 ikp = (ikp_batch - 1)*bs_env%nkp_chi_eps_W_batch + ikp_in_batch
1083
1084 IF (ikp > bs_env%nkp_chi_eps_W_orig_plus_extra) cycle
1085
1086 CALL compute_minvvsqrt_vsqrt(bs_env, qs_env, fm_v_kp, &
1087 cfm_v_sqrt_ikp, cfm_m_inv_v_sqrt_ikp, ikp)
1088
1089 CALL bs_env%para_env%sync()
1090 CALL cp_fm_release(fm_v_kp(ikp, 1))
1091 CALL cp_fm_release(fm_v_kp(ikp, 2))
1092
1093 DO j_w = 1, bs_env%num_time_freq_points
1094
1095 ! check if we need this (ikp, ω_j) combination for approximate k-point extrapolation
1096 IF (bs_env%approx_kp_extrapol .AND. j_w > 1 .AND. &
1097 ikp > bs_env%nkp_chi_eps_W_orig) cycle
1098
1099 CALL compute_fm_w_mic_freq_j(bs_env, qs_env, bs_env%fm_W_MIC_freq, j_w, ikp, &
1100 mat_chi_gamma_tau, cfm_m_inv_v_sqrt_ikp, &
1101 cfm_v_sqrt_ikp)
1102
1103 ! Fourier trafo from W_PQ^MIC(iω_j) to W_PQ^MIC(iτ)
1104 CALL fourier_transform_w_to_t(bs_env, fm_w_mic_time, bs_env%fm_W_MIC_freq, j_w)
1105
1106 END DO ! ω_j
1107
1108 END DO ! ikp_in_batch
1109
1110 DEALLOCATE (fm_v_kp)
1111
1112 IF (bs_env%unit_nr > 0) THEN
1113 WRITE (bs_env%unit_nr, '(T2,A,I12,A,I3,A,F10.1,A)') &
1114 τ'Computed W(i,k) for k-point batch', &
1115 ikp_batch, ' /', bs_env%num_chi_eps_W_batches, &
1116 ', Execution time', m_walltime() - t1, ' s'
1117 END IF
1118
1119 END DO ! ikp_batch
1120
1121 IF (bs_env%approx_kp_extrapol) THEN
1122 CALL apply_extrapol_factor(bs_env, fm_w_mic_time)
1123 END IF
1124
1125 ! M^-1(k=0)*W^MIC(iτ)*M^-1(k=0)
1126 CALL multiply_fm_w_mic_time_with_minv_gamma(bs_env, qs_env, fm_w_mic_time)
1127
1128 DO i_t = 1, bs_env%num_time_freq_points
1129 CALL fm_write(fm_w_mic_time(i_t), i_t, bs_env%W_time_name, qs_env)
1130 END DO
1131
1132 CALL cp_cfm_release(cfm_m_inv_v_sqrt_ikp)
1133 CALL cp_cfm_release(cfm_v_sqrt_ikp)
1134 CALL dbcsr_deallocate_matrix_set(mat_chi_gamma_tau)
1135
1136 ! Marek : Fourier transform W^MIC(itau) back to get it at a specific im.frequency point - iomega = 0
1137 IF (bs_env%rtp_method == rtp_method_bse) THEN
1138 t1 = m_walltime()
1139 CALL cp_fm_create(bs_env%fm_W_MIC_freq_zero, bs_env%fm_W_MIC_freq%matrix_struct)
1140 ! Set to zero
1141 CALL cp_fm_set_all(bs_env%fm_W_MIC_freq_zero, 0.0_dp)
1142 ! Sum over all times
1143 DO i_t = 1, bs_env%num_time_freq_points
1144 ! Add the relevant structure with correct weight
1145 CALL cp_fm_scale_and_add(1.0_dp, bs_env%fm_W_MIC_freq_zero, &
1146 bs_env%imag_time_weights_freq_zero(i_t), fm_w_mic_time(i_t))
1147 END DO
1148 ! Done, save to file
1149 CALL fm_write(bs_env%fm_W_MIC_freq_zero, 0, "W_freq_rtp", qs_env)
1150 ! Report calculation
1151 IF (bs_env%unit_nr > 0) THEN
1152 WRITE (bs_env%unit_nr, '(T2,A,I11,A,I3,A,F10.1,A)') &
1153 'Computed W(f=0,k) for k-point batch', &
1154 1, ' /', 1, &
1155 ', Execution time', m_walltime() - t1, ' s'
1156 END IF
1157 END IF
1158
1159 IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
1160
1161 CALL timestop(handle)
1162
1163 END SUBROUTINE compute_w_mic
1164
1165! **************************************************************************************************
1166!> \brief ...
1167!> \param bs_env ...
1168!> \param qs_env ...
1169!> \param fm_W_MIC_freq_j ...
1170!> \param j_w ...
1171!> \param ikp ...
1172!> \param mat_chi_Gamma_tau ...
1173!> \param cfm_M_inv_V_sqrt_ikp ...
1174!> \param cfm_V_sqrt_ikp ...
1175! **************************************************************************************************
1176 SUBROUTINE compute_fm_w_mic_freq_j(bs_env, qs_env, fm_W_MIC_freq_j, j_w, ikp, mat_chi_Gamma_tau, &
1177 cfm_M_inv_V_sqrt_ikp, cfm_V_sqrt_ikp)
1178 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1179 TYPE(qs_environment_type), POINTER :: qs_env
1180 TYPE(cp_fm_type) :: fm_w_mic_freq_j
1181 INTEGER :: j_w, ikp
1182 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_gamma_tau
1183 TYPE(cp_cfm_type) :: cfm_m_inv_v_sqrt_ikp, cfm_v_sqrt_ikp
1184
1185 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_fm_W_MIC_freq_j'
1186
1187 INTEGER :: handle
1188 TYPE(cp_cfm_type) :: cfm_chi_ikp_freq_j, cfm_w_ikp_freq_j
1189
1190 CALL timeset(routinen, handle)
1191
1192 ! 1. Fourier transformation of χ_PQ(iτ,k=0) to χ_PQ(iω_j,k=0)
1193 CALL compute_fm_chi_gamma_freq(bs_env, bs_env%fm_chi_Gamma_freq, j_w, mat_chi_gamma_tau)
1194
1195 CALL cp_fm_set_all(fm_w_mic_freq_j, 0.0_dp)
1196
1197 ! 2. Get χ_PQ(iω_j,k_i) from χ_PQ(iω_j,k=0) using the minimum image convention
1198 CALL cfm_ikp_from_fm_gamma(cfm_chi_ikp_freq_j, bs_env%fm_chi_Gamma_freq, &
1199 ikp, qs_env, bs_env%kpoints_chi_eps_W, "RI_AUX")
1200
1201 ! 3. Remove all negative eigenvalues from χ_PQ(iω_j,k_i)
1202 CALL cp_cfm_power(cfm_chi_ikp_freq_j, threshold=0.0_dp, exponent=1.0_dp)
1203
1204 ! 4. ε(iω_j,k_i) = Id - V^0.5(k_i)*M^-1(k_i)*χ(iω_j,k_i)*M^-1(k_i)*V^0.5(k_i)
1205 ! W(iω_j,k_i) = V^0.5(k_i)*(ε^-1(iω_j,k_i)-Id)*V^0.5(k_i)
1206 CALL compute_cfm_w_ikp_freq_j(bs_env, cfm_chi_ikp_freq_j, cfm_v_sqrt_ikp, &
1207 cfm_m_inv_v_sqrt_ikp, cfm_w_ikp_freq_j)
1208
1209 ! 5. k-point integration W_PQ(iω_j, k_i) to W_PQ^MIC(iω_j)
1210 SELECT CASE (bs_env%approx_kp_extrapol)
1211 CASE (.false.)
1212 ! default: standard k-point extrapolation
1213 CALL mic_contribution_from_ikp(bs_env, qs_env, fm_w_mic_freq_j, cfm_w_ikp_freq_j, ikp, &
1214 bs_env%kpoints_chi_eps_W, "RI_AUX")
1215 CASE (.true.)
1216 ! for approximate kpoint extrapolation: get W_PQ^MIC(iω_1) with and without k-point
1217 ! extrapolation to compute the extrapolation factor f_PQ for every PQ-matrix element,
1218 ! f_PQ = (W_PQ^MIC(iω_1) with extrapolation) / (W_PQ^MIC(iω_1) without extrapolation)
1219
1220 ! for ω_1, we compute the k-point extrapolated result using all k-points
1221 IF (j_w == 1) THEN
1222
1223 ! k-point extrapolated
1224 CALL mic_contribution_from_ikp(bs_env, qs_env, bs_env%fm_W_MIC_freq_1_extra, &
1225 cfm_w_ikp_freq_j, ikp, bs_env%kpoints_chi_eps_W, &
1226 "RI_AUX")
1227 ! non-kpoint extrapolated
1228 IF (ikp <= bs_env%nkp_chi_eps_W_orig) THEN
1229 CALL mic_contribution_from_ikp(bs_env, qs_env, bs_env%fm_W_MIC_freq_1_no_extra, &
1230 cfm_w_ikp_freq_j, ikp, bs_env%kpoints_chi_eps_W, &
1231 "RI_AUX", wkp_ext=bs_env%wkp_orig)
1232 END IF
1233
1234 END IF
1235
1236 ! for all ω_j, we need to compute W^MIC without k-point extrpolation
1237 IF (ikp <= bs_env%nkp_chi_eps_W_orig) THEN
1238 CALL mic_contribution_from_ikp(bs_env, qs_env, fm_w_mic_freq_j, cfm_w_ikp_freq_j, &
1239 ikp, bs_env%kpoints_chi_eps_W, "RI_AUX", &
1240 wkp_ext=bs_env%wkp_orig)
1241 END IF
1242 END SELECT
1243
1244 CALL cp_cfm_release(cfm_w_ikp_freq_j)
1245
1246 CALL timestop(handle)
1247
1248 END SUBROUTINE compute_fm_w_mic_freq_j
1249
1250! **************************************************************************************************
1251!> \brief ...
1252!> \param cfm_mat ...
1253! **************************************************************************************************
1254 SUBROUTINE clean_lower_part(cfm_mat)
1255 TYPE(cp_cfm_type) :: cfm_mat
1256
1257 CHARACTER(LEN=*), PARAMETER :: routinen = 'clean_lower_part'
1258
1259 INTEGER :: handle, i_row, j_col, j_global, &
1260 ncol_local, nrow_local
1261 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1262
1263 CALL timeset(routinen, handle)
1264
1265 CALL cp_cfm_get_info(matrix=cfm_mat, &
1266 nrow_local=nrow_local, ncol_local=ncol_local, &
1267 row_indices=row_indices, col_indices=col_indices)
1268
1269 DO j_col = 1, ncol_local
1270 j_global = col_indices(j_col)
1271 DO i_row = 1, nrow_local
1272 IF (j_global < row_indices(i_row)) cfm_mat%local_data(i_row, j_col) = z_zero
1273 END DO
1274 END DO
1275
1276 CALL timestop(handle)
1277
1278 END SUBROUTINE clean_lower_part
1279
1280! **************************************************************************************************
1281!> \brief ...
1282!> \param bs_env ...
1283!> \param fm_W_MIC_time ...
1284! **************************************************************************************************
1285 SUBROUTINE apply_extrapol_factor(bs_env, fm_W_MIC_time)
1286 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1287 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
1288
1289 CHARACTER(LEN=*), PARAMETER :: routinen = 'apply_extrapol_factor'
1290
1291 INTEGER :: handle, i, i_t, j, ncol_local, nrow_local
1292 REAL(kind=dp) :: extrapol_factor, w_extra_1, w_no_extra_1
1293
1294 CALL timeset(routinen, handle)
1295
1296 CALL cp_fm_get_info(matrix=fm_w_mic_time(1), nrow_local=nrow_local, ncol_local=ncol_local)
1297
1298 DO i_t = 1, bs_env%num_time_freq_points
1299 DO j = 1, ncol_local
1300 DO i = 1, nrow_local
1301
1302 w_extra_1 = bs_env%fm_W_MIC_freq_1_extra%local_data(i, j)
1303 w_no_extra_1 = bs_env%fm_W_MIC_freq_1_no_extra%local_data(i, j)
1304
1305 IF (abs(w_no_extra_1) > 1.0e-13) THEN
1306 extrapol_factor = abs(w_extra_1/w_no_extra_1)
1307 ELSE
1308 extrapol_factor = 1.0_dp
1309 END IF
1310
1311 ! reset extrapolation factor if it is very large
1312 IF (extrapol_factor > 10.0_dp) extrapol_factor = 1.0_dp
1313
1314 fm_w_mic_time(i_t)%local_data(i, j) = fm_w_mic_time(i_t)%local_data(i, j) &
1315 *extrapol_factor
1316 END DO
1317 END DO
1318 END DO
1319
1320 CALL timestop(handle)
1321
1322 END SUBROUTINE apply_extrapol_factor
1323
1324! **************************************************************************************************
1325!> \brief ...
1326!> \param bs_env ...
1327!> \param fm_chi_Gamma_freq ...
1328!> \param j_w ...
1329!> \param mat_chi_Gamma_tau ...
1330! **************************************************************************************************
1331 SUBROUTINE compute_fm_chi_gamma_freq(bs_env, fm_chi_Gamma_freq, j_w, mat_chi_Gamma_tau)
1332 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1333 TYPE(cp_fm_type) :: fm_chi_gamma_freq
1334 INTEGER :: j_w
1335 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_gamma_tau
1336
1337 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_fm_chi_Gamma_freq'
1338
1339 INTEGER :: handle, i_t
1340 REAL(kind=dp) :: freq_j, time_i, weight_ij
1341
1342 CALL timeset(routinen, handle)
1343
1344 CALL dbcsr_set(bs_env%mat_RI_RI%matrix, 0.0_dp)
1345
1346 freq_j = bs_env%imag_freq_points(j_w)
1347
1348 DO i_t = 1, bs_env%num_time_freq_points
1349
1350 time_i = bs_env%imag_time_points(i_t)
1351 weight_ij = bs_env%weights_cos_t_to_w(j_w, i_t)
1352
1353 ! actual Fourier transform
1354 CALL dbcsr_add(bs_env%mat_RI_RI%matrix, mat_chi_gamma_tau(i_t)%matrix, &
1355 1.0_dp, cos(time_i*freq_j)*weight_ij)
1356
1357 END DO
1358
1359 CALL copy_dbcsr_to_fm(bs_env%mat_RI_RI%matrix, fm_chi_gamma_freq)
1360
1361 CALL timestop(handle)
1362
1363 END SUBROUTINE compute_fm_chi_gamma_freq
1364
1365! **************************************************************************************************
1366!> \brief ...
1367!> \param mat_ikp_re ...
1368!> \param mat_ikp_im ...
1369!> \param mat_Gamma ...
1370!> \param kpoints ...
1371!> \param ikp ...
1372!> \param qs_env ...
1373! **************************************************************************************************
1374 SUBROUTINE mat_ikp_from_mat_gamma(mat_ikp_re, mat_ikp_im, mat_Gamma, kpoints, ikp, qs_env)
1375 TYPE(dbcsr_type) :: mat_ikp_re, mat_ikp_im, mat_gamma
1376 TYPE(kpoint_type), POINTER :: kpoints
1377 INTEGER :: ikp
1378 TYPE(qs_environment_type), POINTER :: qs_env
1379
1380 CHARACTER(LEN=*), PARAMETER :: routinen = 'mat_ikp_from_mat_Gamma'
1381
1382 INTEGER :: col, handle, i_cell, j_cell, num_cells, &
1383 row
1384 INTEGER, DIMENSION(:, :), POINTER :: index_to_cell
1385 LOGICAL :: f, i_cell_is_the_minimum_image_cell
1386 REAL(kind=dp) :: abs_rab_cell_i, abs_rab_cell_j, arg
1387 REAL(kind=dp), DIMENSION(3) :: cell_vector, cell_vector_j, rab_cell_i, &
1388 rab_cell_j
1389 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1390 REAL(kind=dp), DIMENSION(:, :), POINTER :: block_im, block_re, data_block
1391 TYPE(cell_type), POINTER :: cell
1392 TYPE(dbcsr_iterator_type) :: iter
1393 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1394
1395 CALL timeset(routinen, handle)
1396
1397 ! get the same blocks in mat_ikp_re and mat_ikp_im as in mat_Gamma
1398 CALL dbcsr_copy(mat_ikp_re, mat_gamma)
1399 CALL dbcsr_copy(mat_ikp_im, mat_gamma)
1400 CALL dbcsr_set(mat_ikp_re, 0.0_dp)
1401 CALL dbcsr_set(mat_ikp_im, 0.0_dp)
1402
1403 NULLIFY (cell, particle_set)
1404 CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1405 CALL get_cell(cell=cell, h=hmat)
1406
1407 index_to_cell => kpoints%index_to_cell
1408
1409 num_cells = SIZE(index_to_cell, 2)
1410
1411 DO i_cell = 1, num_cells
1412
1413 CALL dbcsr_iterator_start(iter, mat_gamma)
1414 DO WHILE (dbcsr_iterator_blocks_left(iter))
1415 CALL dbcsr_iterator_next_block(iter, row, col, data_block)
1416
1417 cell_vector(1:3) = matmul(hmat, real(index_to_cell(1:3, i_cell), dp))
1418
1419 rab_cell_i(1:3) = pbc(particle_set(row)%r(1:3), cell) - &
1420 (pbc(particle_set(col)%r(1:3), cell) + cell_vector(1:3))
1421 abs_rab_cell_i = sqrt(rab_cell_i(1)**2 + rab_cell_i(2)**2 + rab_cell_i(3)**2)
1422
1423 ! minimum image convention
1424 i_cell_is_the_minimum_image_cell = .true.
1425 DO j_cell = 1, num_cells
1426 cell_vector_j(1:3) = matmul(hmat, real(index_to_cell(1:3, j_cell), dp))
1427 rab_cell_j(1:3) = pbc(particle_set(row)%r(1:3), cell) - &
1428 (pbc(particle_set(col)%r(1:3), cell) + cell_vector_j(1:3))
1429 abs_rab_cell_j = sqrt(rab_cell_j(1)**2 + rab_cell_j(2)**2 + rab_cell_j(3)**2)
1430
1431 IF (abs_rab_cell_i > abs_rab_cell_j + 1.0e-6_dp) THEN
1432 i_cell_is_the_minimum_image_cell = .false.
1433 END IF
1434 END DO
1435
1436 IF (i_cell_is_the_minimum_image_cell) THEN
1437 NULLIFY (block_re, block_im)
1438 CALL dbcsr_get_block_p(matrix=mat_ikp_re, row=row, col=col, block=block_re, found=f)
1439 CALL dbcsr_get_block_p(matrix=mat_ikp_im, row=row, col=col, block=block_im, found=f)
1440 cpassert(all(abs(block_re) < 1.0e-10_dp))
1441 cpassert(all(abs(block_im) < 1.0e-10_dp))
1442
1443 arg = real(index_to_cell(1, i_cell), dp)*kpoints%xkp(1, ikp) + &
1444 REAL(index_to_cell(2, i_cell), dp)*kpoints%xkp(2, ikp) + &
1445 REAL(index_to_cell(3, i_cell), dp)*kpoints%xkp(3, ikp)
1446
1447 block_re(:, :) = cos(twopi*arg)*data_block(:, :)
1448 block_im(:, :) = sin(twopi*arg)*data_block(:, :)
1449 END IF
1450
1451 END DO
1452 CALL dbcsr_iterator_stop(iter)
1453
1454 END DO
1455
1456 CALL timestop(handle)
1457
1458 END SUBROUTINE mat_ikp_from_mat_gamma
1459
1460! **************************************************************************************************
1461!> \brief ...
1462!> \param bs_env ...
1463!> \param cfm_chi_ikp_freq_j ...
1464!> \param cfm_V_sqrt_ikp ...
1465!> \param cfm_M_inv_V_sqrt_ikp ...
1466!> \param cfm_W_ikp_freq_j ...
1467! **************************************************************************************************
1468 SUBROUTINE compute_cfm_w_ikp_freq_j(bs_env, cfm_chi_ikp_freq_j, cfm_V_sqrt_ikp, &
1469 cfm_M_inv_V_sqrt_ikp, cfm_W_ikp_freq_j)
1470
1471 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1472 TYPE(cp_cfm_type) :: cfm_chi_ikp_freq_j, cfm_v_sqrt_ikp, &
1473 cfm_m_inv_v_sqrt_ikp, cfm_w_ikp_freq_j
1474
1475 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_cfm_W_ikp_freq_j'
1476
1477 INTEGER :: handle, info, n_ri
1478 TYPE(cp_cfm_type) :: cfm_eps_ikp_freq_j, cfm_work
1479
1480 CALL timeset(routinen, handle)
1481
1482 CALL cp_cfm_create(cfm_work, cfm_chi_ikp_freq_j%matrix_struct)
1483 n_ri = bs_env%n_RI
1484
1485 ! 1. ε(iω_j,k) = Id - V^0.5(k)*M^-1(k)*χ(iω_j,k)*M^-1(k)*V^0.5(k)
1486
1487 ! 1. a) work = χ(iω_j,k)*M^-1(k)*V^0.5(k)
1488 CALL parallel_gemm('N', 'N', n_ri, n_ri, n_ri, z_one, &
1489 cfm_chi_ikp_freq_j, cfm_m_inv_v_sqrt_ikp, z_zero, cfm_work)
1490 CALL cp_cfm_release(cfm_chi_ikp_freq_j)
1491
1492 ! 1. b) eps_work = V^0.5(k)*M^-1(k)*work
1493 CALL cp_cfm_create(cfm_eps_ikp_freq_j, cfm_work%matrix_struct)
1494 CALL parallel_gemm('C', 'N', n_ri, n_ri, n_ri, z_one, &
1495 cfm_m_inv_v_sqrt_ikp, cfm_work, z_zero, cfm_eps_ikp_freq_j)
1496
1497 ! 1. c) ε(iω_j,k) = eps_work - Id
1498 CALL cfm_add_on_diag(cfm_eps_ikp_freq_j, z_one)
1499
1500 ! 2. W(iω_j,k) = V^0.5(k)*(ε^-1(iω_j,k)-Id)*V^0.5(k)
1501
1502 ! 2. a) Cholesky decomposition of ε(iω_j,k) as preparation for inversion
1503 CALL cp_cfm_cholesky_decompose(matrix=cfm_eps_ikp_freq_j, n=n_ri, info_out=info)
1504 cpassert(info == 0)
1505
1506 ! 2. b) Inversion of ε(iω_j,k) using its Cholesky decomposition
1507 CALL cp_cfm_cholesky_invert(cfm_eps_ikp_freq_j)
1508 CALL cp_cfm_uplo_to_full(cfm_eps_ikp_freq_j)
1509
1510 ! 2. c) ε^-1(iω_j,k)-Id
1511 CALL cfm_add_on_diag(cfm_eps_ikp_freq_j, -z_one)
1512
1513 ! 2. d) work = (ε^-1(iω_j,k)-Id)*V^0.5(k)
1514 CALL parallel_gemm('N', 'N', n_ri, n_ri, n_ri, z_one, cfm_eps_ikp_freq_j, cfm_v_sqrt_ikp, &
1515 z_zero, cfm_work)
1516
1517 ! 2. e) W(iw,k) = V^0.5(k)*work
1518 CALL cp_cfm_create(cfm_w_ikp_freq_j, cfm_work%matrix_struct)
1519 CALL parallel_gemm('C', 'N', n_ri, n_ri, n_ri, z_one, cfm_v_sqrt_ikp, cfm_work, &
1520 z_zero, cfm_w_ikp_freq_j)
1521
1522 CALL cp_cfm_release(cfm_work)
1523 CALL cp_cfm_release(cfm_eps_ikp_freq_j)
1524
1525 CALL timestop(handle)
1526
1527 END SUBROUTINE compute_cfm_w_ikp_freq_j
1528
1529! **************************************************************************************************
1530!> \brief ...
1531!> \param cfm ...
1532!> \param alpha ...
1533! **************************************************************************************************
1534 SUBROUTINE cfm_add_on_diag(cfm, alpha)
1535
1536 TYPE(cp_cfm_type) :: cfm
1537 COMPLEX(KIND=dp) :: alpha
1538
1539 CHARACTER(LEN=*), PARAMETER :: routinen = 'cfm_add_on_diag'
1540
1541 INTEGER :: handle, i_row, j_col, j_global, &
1542 ncol_local, nrow_local
1543 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1544
1545 CALL timeset(routinen, handle)
1546
1547 CALL cp_cfm_get_info(matrix=cfm, &
1548 nrow_local=nrow_local, &
1549 ncol_local=ncol_local, &
1550 row_indices=row_indices, &
1551 col_indices=col_indices)
1552
1553 ! add 1 on the diagonal
1554 DO j_col = 1, ncol_local
1555 j_global = col_indices(j_col)
1556 DO i_row = 1, nrow_local
1557 IF (j_global == row_indices(i_row)) THEN
1558 cfm%local_data(i_row, j_col) = cfm%local_data(i_row, j_col) + alpha
1559 END IF
1560 END DO
1561 END DO
1562
1563 CALL timestop(handle)
1564
1565 END SUBROUTINE cfm_add_on_diag
1566
1567! **************************************************************************************************
1568!> \brief ...
1569!> \param bs_env ...
1570!> \param fm_W_MIC_time ...
1571! **************************************************************************************************
1572 SUBROUTINE create_fm_w_mic_time(bs_env, fm_W_MIC_time)
1573 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1574 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
1575
1576 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_fm_W_MIC_time'
1577
1578 INTEGER :: handle, i_t
1579
1580 CALL timeset(routinen, handle)
1581
1582 ALLOCATE (fm_w_mic_time(bs_env%num_time_freq_points))
1583 DO i_t = 1, bs_env%num_time_freq_points
1584 CALL cp_fm_create(fm_w_mic_time(i_t), bs_env%fm_RI_RI%matrix_struct, set_zero=.true.)
1585 END DO
1586
1587 CALL timestop(handle)
1588
1589 END SUBROUTINE create_fm_w_mic_time
1590
1591! **************************************************************************************************
1592!> \brief ...
1593!> \param bs_env ...
1594!> \param fm_W_MIC_time ...
1595!> \param fm_W_MIC_freq_j ...
1596!> \param j_w ...
1597! **************************************************************************************************
1598 SUBROUTINE fourier_transform_w_to_t(bs_env, fm_W_MIC_time, fm_W_MIC_freq_j, j_w)
1599 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1600 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
1601 TYPE(cp_fm_type) :: fm_w_mic_freq_j
1602 INTEGER :: j_w
1603
1604 CHARACTER(LEN=*), PARAMETER :: routinen = 'Fourier_transform_w_to_t'
1605
1606 INTEGER :: handle, i_t
1607 REAL(kind=dp) :: freq_j, time_i, weight_ij
1608
1609 CALL timeset(routinen, handle)
1610
1611 freq_j = bs_env%imag_freq_points(j_w)
1612
1613 DO i_t = 1, bs_env%num_time_freq_points
1614
1615 time_i = bs_env%imag_time_points(i_t)
1616 weight_ij = bs_env%weights_cos_w_to_t(i_t, j_w)
1617
1618 ! actual Fourier transform
1619 CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_w_mic_time(i_t), &
1620 beta=weight_ij*cos(time_i*freq_j), matrix_b=fm_w_mic_freq_j)
1621
1622 END DO
1623
1624 CALL timestop(handle)
1625
1626 END SUBROUTINE fourier_transform_w_to_t
1627
1628! **************************************************************************************************
1629!> \brief ...
1630!> \param bs_env ...
1631!> \param qs_env ...
1632!> \param fm_W_MIC_time ...
1633! **************************************************************************************************
1634 SUBROUTINE multiply_fm_w_mic_time_with_minv_gamma(bs_env, qs_env, fm_W_MIC_time)
1635 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1636 TYPE(qs_environment_type), POINTER :: qs_env
1637 TYPE(cp_fm_type), DIMENSION(:) :: fm_w_mic_time
1638
1639 CHARACTER(LEN=*), PARAMETER :: routinen = 'multiply_fm_W_MIC_time_with_Minv_Gamma'
1640
1641 INTEGER :: handle, i_t, n_ri, ndep
1642 TYPE(cp_fm_type) :: fm_work
1643 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_minv_gamma
1644
1645 CALL timeset(routinen, handle)
1646
1647 n_ri = bs_env%n_RI
1648
1649 CALL cp_fm_create(fm_work, fm_w_mic_time(1)%matrix_struct)
1650
1651 ! compute Gamma-only RI-metric matrix M(k=0); no regularization
1652 CALL ri_2c_integral_mat(qs_env, fm_minv_gamma, fm_w_mic_time(1), n_ri, &
1653 bs_env%ri_metric, do_kpoints=.false.)
1654
1655 CALL cp_fm_power(fm_minv_gamma(1, 1), fm_work, -1.0_dp, 0.0_dp, ndep)
1656
1657 ! M^-1(k=0)*W^MIC(iτ)*M^-1(k=0)
1658 DO i_t = 1, SIZE(fm_w_mic_time)
1659
1660 CALL parallel_gemm('N', 'N', n_ri, n_ri, n_ri, 1.0_dp, fm_minv_gamma(1, 1), &
1661 fm_w_mic_time(i_t), 0.0_dp, fm_work)
1662
1663 CALL parallel_gemm('N', 'N', n_ri, n_ri, n_ri, 1.0_dp, fm_work, &
1664 fm_minv_gamma(1, 1), 0.0_dp, fm_w_mic_time(i_t))
1665
1666 END DO
1667
1668 CALL cp_fm_release(fm_work)
1669 CALL cp_fm_release(fm_minv_gamma)
1670
1671 CALL timestop(handle)
1672
1674
1675! **************************************************************************************************
1676!> \brief ...
1677!> \param bs_env ...
1678!> \param qs_env ...
1679!> \param fm_Sigma_x_Gamma ...
1680! **************************************************************************************************
1681 SUBROUTINE get_sigma_x(bs_env, qs_env, fm_Sigma_x_Gamma)
1682 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1683 TYPE(qs_environment_type), POINTER :: qs_env
1684 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_sigma_x_gamma
1685
1686 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_Sigma_x'
1687
1688 INTEGER :: handle, ispin
1689
1690 CALL timeset(routinen, handle)
1691
1692 ALLOCATE (fm_sigma_x_gamma(bs_env%n_spin))
1693 DO ispin = 1, bs_env%n_spin
1694 CALL cp_fm_create(fm_sigma_x_gamma(ispin), bs_env%fm_s_Gamma%matrix_struct)
1695 END DO
1696
1697 IF (bs_env%Sigma_x_exists) THEN
1698 DO ispin = 1, bs_env%n_spin
1699 CALL fm_read(fm_sigma_x_gamma(ispin), bs_env, bs_env%Sigma_x_name, ispin)
1700 END DO
1701 ELSE
1702 CALL compute_sigma_x(bs_env, qs_env, fm_sigma_x_gamma)
1703 END IF
1704
1705 CALL timestop(handle)
1706
1707 END SUBROUTINE get_sigma_x
1708
1709! **************************************************************************************************
1710!> \brief ...
1711!> \param bs_env ...
1712!> \param qs_env ...
1713!> \param fm_Sigma_x_Gamma ...
1714! **************************************************************************************************
1715 SUBROUTINE compute_sigma_x(bs_env, qs_env, fm_Sigma_x_Gamma)
1716 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1717 TYPE(qs_environment_type), POINTER :: qs_env
1718 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_sigma_x_gamma
1719
1720 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_Sigma_x'
1721
1722 INTEGER :: handle, i_intval_idx, ispin, j_intval_idx
1723 INTEGER, DIMENSION(2) :: i_atoms, j_atoms
1724 REAL(kind=dp) :: t1
1725 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_vtr_gamma
1726 TYPE(dbcsr_type) :: mat_sigma_x_gamma
1727 TYPE(dbt_type) :: t_2c_d, t_2c_sigma_x, t_2c_v, t_3c_x_v
1728
1729 CALL timeset(routinen, handle)
1730
1731 t1 = m_walltime()
1732
1733 CALL dbt_create(bs_env%t_G, t_2c_d)
1734 CALL dbt_create(bs_env%t_W, t_2c_v)
1735 CALL dbt_create(bs_env%t_G, t_2c_sigma_x)
1736 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_v)
1737 CALL dbcsr_create(mat_sigma_x_gamma, template=bs_env%mat_ao_ao%matrix)
1738
1739 ! 1. Compute truncated Coulomb operator matrix V^tr(k=0) (cutoff rad: cellsize/2)
1740 CALL ri_2c_integral_mat(qs_env, fm_vtr_gamma, bs_env%fm_RI_RI, bs_env%n_RI, &
1741 bs_env%trunc_coulomb, do_kpoints=.false.)
1742
1743 ! 2. Compute M^-1(k=0) and get M^-1(k=0)*V^tr(k=0)*M^-1(k=0)
1744 CALL multiply_fm_w_mic_time_with_minv_gamma(bs_env, qs_env, fm_vtr_gamma(:, 1))
1745
1746 DO ispin = 1, bs_env%n_spin
1747
1748 ! 3. Compute density matrix D_µν
1749 CALL g_occ_vir(bs_env, 0.0_dp, bs_env%fm_work_mo(2), ispin, occ=.true., vir=.false.)
1750
1751 CALL fm_to_local_tensor(bs_env%fm_work_mo(2), bs_env%mat_ao_ao%matrix, &
1752 bs_env%mat_ao_ao_tensor%matrix, t_2c_d, bs_env, &
1753 bs_env%atoms_i_t_group)
1754
1755 CALL fm_to_local_tensor(fm_vtr_gamma(1, 1), bs_env%mat_RI_RI%matrix, &
1756 bs_env%mat_RI_RI_tensor%matrix, t_2c_v, bs_env, &
1757 bs_env%atoms_j_t_group)
1758
1759 ! every group has its own range of i_atoms and j_atoms; only deal with a
1760 ! limited number of i_atom-j_atom pairs simultaneously in a group to save memory
1761 DO i_intval_idx = 1, bs_env%n_intervals_i
1762 DO j_intval_idx = 1, bs_env%n_intervals_j
1763 i_atoms = bs_env%i_atom_intervals(1:2, i_intval_idx)
1764 j_atoms = bs_env%j_atom_intervals(1:2, j_intval_idx)
1765
1766 ! 4. compute 3-center integrals (µν|P) ("|": truncated Coulomb operator)
1767 ! 5. M_Qνσ(iτ) = sum_P (νσ|P) (M^-1(k=0)*V^tr(k=0)*M^-1(k=0))_QP(iτ)
1768 CALL compute_3c_and_contract_w(qs_env, bs_env, i_atoms, j_atoms, t_3c_x_v, t_2c_v)
1769
1770 ! 6. tensor operations with D and computation of Σ^x
1771 ! Σ^x_λσ(k=0) = sum_νQ M_Qνσ(iτ) sum_µ (Qλ|µ) D_νµ
1772 CALL contract_to_sigma(t_2c_d, t_3c_x_v, t_2c_sigma_x, i_atoms, j_atoms, &
1773 qs_env, bs_env, occ=.true., vir=.false.)
1774
1775 END DO ! j_atoms
1776 END DO ! i_atoms
1777
1778 CALL local_dbt_to_global_mat(t_2c_sigma_x, bs_env%mat_ao_ao_tensor%matrix, &
1779 mat_sigma_x_gamma, bs_env%para_env)
1780
1781 CALL write_matrix(mat_sigma_x_gamma, ispin, bs_env%Sigma_x_name, &
1782 bs_env%fm_work_mo(1), qs_env)
1783
1784 CALL copy_dbcsr_to_fm(mat_sigma_x_gamma, fm_sigma_x_gamma(ispin))
1785
1786 END DO ! ispin
1787
1788 IF (bs_env%unit_nr > 0) THEN
1789 WRITE (bs_env%unit_nr, '(T2,A,T55,A,F10.1,A)') &
1790 Σ'Computed ^x(k=0),', ' Execution time', m_walltime() - t1, ' s'
1791 WRITE (bs_env%unit_nr, '(A)') ' '
1792 END IF
1793
1794 CALL dbcsr_release(mat_sigma_x_gamma)
1795 CALL dbt_destroy(t_2c_d)
1796 CALL dbt_destroy(t_2c_v)
1797 CALL dbt_destroy(t_2c_sigma_x)
1798 CALL dbt_destroy(t_3c_x_v)
1799 CALL cp_fm_release(fm_vtr_gamma)
1800
1801 CALL timestop(handle)
1802
1803 END SUBROUTINE compute_sigma_x
1804
1805! **************************************************************************************************
1806!> \brief ...
1807!> \param bs_env ...
1808!> \param qs_env ...
1809!> \param fm_W_MIC_time ...
1810!> \param fm_Sigma_c_Gamma_time ...
1811! **************************************************************************************************
1812 SUBROUTINE get_sigma_c(bs_env, qs_env, fm_W_MIC_time, fm_Sigma_c_Gamma_time)
1813 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1814 TYPE(qs_environment_type), POINTER :: qs_env
1815 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
1816 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
1817
1818 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_Sigma_c'
1819
1820 INTEGER :: handle, i_intval_idx, i_t, ispin, &
1821 j_intval_idx, read_write_index
1822 INTEGER, DIMENSION(2) :: i_atoms, j_atoms
1823 REAL(kind=dp) :: t1, tau
1824 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_sigma_neg_tau, mat_sigma_pos_tau
1825 TYPE(dbt_type) :: t_2c_gocc, t_2c_gvir, &
1826 t_2c_sigma_neg_tau, &
1827 t_2c_sigma_pos_tau, t_2c_w, t_3c_x_w
1828
1829 CALL timeset(routinen, handle)
1830
1831 CALL create_mat_for_sigma_c(bs_env, t_2c_gocc, t_2c_gvir, t_2c_w, t_2c_sigma_neg_tau, &
1832 t_2c_sigma_pos_tau, t_3c_x_w, &
1833 mat_sigma_neg_tau, mat_sigma_pos_tau)
1834
1835 DO i_t = 1, bs_env%num_time_freq_points
1836
1837 DO ispin = 1, bs_env%n_spin
1838
1839 t1 = m_walltime()
1840
1841 read_write_index = i_t + (ispin - 1)*bs_env%num_time_freq_points
1842
1843 ! read self-energy from restart
1844 IF (bs_env%Sigma_c_exists(i_t, ispin)) THEN
1845 CALL fm_read(bs_env%fm_work_mo(1), bs_env, bs_env%Sigma_p_name, read_write_index)
1846 CALL copy_fm_to_dbcsr(bs_env%fm_work_mo(1), mat_sigma_pos_tau(i_t, ispin)%matrix, &
1847 keep_sparsity=.false.)
1848 CALL fm_read(bs_env%fm_work_mo(1), bs_env, bs_env%Sigma_n_name, read_write_index)
1849 CALL copy_fm_to_dbcsr(bs_env%fm_work_mo(1), mat_sigma_neg_tau(i_t, ispin)%matrix, &
1850 keep_sparsity=.false.)
1851 IF (bs_env%unit_nr > 0) THEN
1852 WRITE (bs_env%unit_nr, '(T2,2A,I3,A,I3,A,F10.1,A)') Στ'Read ^c(i,k=0) ', &
1853 'from file for time point ', i_t, ' /', bs_env%num_time_freq_points, &
1854 ', Execution time', m_walltime() - t1, ' s'
1855 END IF
1856
1857 cycle
1858
1859 END IF
1860
1861 tau = bs_env%imag_time_points(i_t)
1862
1863 CALL g_occ_vir(bs_env, tau, bs_env%fm_Gocc, ispin, occ=.true., vir=.false.)
1864 CALL g_occ_vir(bs_env, tau, bs_env%fm_Gvir, ispin, occ=.false., vir=.true.)
1865
1866 ! fm G^occ, G^vir and W to local tensor
1867 CALL fm_to_local_tensor(bs_env%fm_Gocc, bs_env%mat_ao_ao%matrix, &
1868 bs_env%mat_ao_ao_tensor%matrix, t_2c_gocc, bs_env, &
1869 bs_env%atoms_i_t_group)
1870 CALL fm_to_local_tensor(bs_env%fm_Gvir, bs_env%mat_ao_ao%matrix, &
1871 bs_env%mat_ao_ao_tensor%matrix, t_2c_gvir, bs_env, &
1872 bs_env%atoms_i_t_group)
1873 CALL fm_to_local_tensor(fm_w_mic_time(i_t), bs_env%mat_RI_RI%matrix, &
1874 bs_env%mat_RI_RI_tensor%matrix, t_2c_w, bs_env, &
1875 bs_env%atoms_j_t_group)
1876
1877 ! every group has its own range of i_atoms and j_atoms; only deal with a
1878 ! limited number of i_atom-j_atom pairs simultaneously in a group to save memory
1879 DO i_intval_idx = 1, bs_env%n_intervals_i
1880 DO j_intval_idx = 1, bs_env%n_intervals_j
1881 i_atoms = bs_env%i_atom_intervals(1:2, i_intval_idx)
1882 j_atoms = bs_env%j_atom_intervals(1:2, j_intval_idx)
1883
1884 IF (bs_env%skip_Sigma_occ(i_intval_idx, j_intval_idx) .AND. &
1885 bs_env%skip_Sigma_vir(i_intval_idx, j_intval_idx)) THEN
1886 ! Do that only after first timestep to avoid skips due to vanishing G
1887 ! caused by gaps
1888 IF (i_t == 2) THEN
1889 bs_env%n_skip_sigma = bs_env%n_skip_sigma + 1
1890 END IF
1891 cycle
1892 END IF
1893
1894 ! 1. compute 3-center integrals (µν|P) ("|": truncated Coulomb operator)
1895 ! 2. tensor operation M_Qνσ(iτ) = sum_P (νσ|P) W^MIC_QP(iτ)
1896 CALL compute_3c_and_contract_w(qs_env, bs_env, i_atoms, j_atoms, t_3c_x_w, t_2c_w)
1897
1898 ! 3. Σ_λσ(iτ,k=0) = sum_νQ M_Qνσ(iτ) sum_µ (Qλ|µ) G^occ_νµ(i|τ|) for τ < 0
1899 ! (recall M_Qνσ(iτ) = M_Qνσ(-iτ) because W^MIC_PQ(iτ) = W^MIC_PQ(-iτ) )
1900 CALL contract_to_sigma(t_2c_gocc, t_3c_x_w, t_2c_sigma_neg_tau, i_atoms, j_atoms, &
1901 qs_env, bs_env, occ=.true., vir=.false., &
1902 can_skip=bs_env%skip_Sigma_occ(i_intval_idx, j_intval_idx))
1903
1904 ! Σ_λσ(iτ,k=0) = sum_νQ M_Qνσ(iτ) sum_µ (Qλ|µ) G^vir_νµ(i|τ|) for τ > 0
1905 CALL contract_to_sigma(t_2c_gvir, t_3c_x_w, t_2c_sigma_pos_tau, i_atoms, j_atoms, &
1906 qs_env, bs_env, occ=.false., vir=.true., &
1907 can_skip=bs_env%skip_Sigma_vir(i_intval_idx, j_intval_idx))
1908
1909 END DO ! j_atoms
1910 END DO ! i_atoms
1911
1912 ! 4. communicate data tensor t_2c_Sigma (which is local in the subgroup)
1913 ! to the global dbcsr matrix mat_Sigma_pos/neg_tau (which stores Σ for all iτ)
1914 CALL local_dbt_to_global_mat(t_2c_sigma_neg_tau, bs_env%mat_ao_ao_tensor%matrix, &
1915 mat_sigma_neg_tau(i_t, ispin)%matrix, bs_env%para_env)
1916 CALL local_dbt_to_global_mat(t_2c_sigma_pos_tau, bs_env%mat_ao_ao_tensor%matrix, &
1917 mat_sigma_pos_tau(i_t, ispin)%matrix, bs_env%para_env)
1918
1919 CALL write_matrix(mat_sigma_pos_tau(i_t, ispin)%matrix, read_write_index, &
1920 bs_env%Sigma_p_name, bs_env%fm_work_mo(1), qs_env)
1921 CALL write_matrix(mat_sigma_neg_tau(i_t, ispin)%matrix, read_write_index, &
1922 bs_env%Sigma_n_name, bs_env%fm_work_mo(1), qs_env)
1923
1924 IF (bs_env%unit_nr > 0) THEN
1925 WRITE (bs_env%unit_nr, '(T2,A,I10,A,I3,A,F10.1,A)') &
1926 Στ'Computed ^c(i,k=0) for time point ', i_t, ' /', bs_env%num_time_freq_points, &
1927 ', Execution time', m_walltime() - t1, ' s'
1928 END IF
1929
1930 END DO ! ispin
1931
1932 END DO ! i_t
1933
1934 IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
1935
1936 CALL fill_fm_sigma_c_gamma_time(fm_sigma_c_gamma_time, bs_env, &
1937 mat_sigma_pos_tau, mat_sigma_neg_tau)
1938
1939 CALL print_skipping(bs_env)
1940
1941 CALL destroy_mat_sigma_c(t_2c_gocc, t_2c_gvir, t_2c_w, t_2c_sigma_neg_tau, &
1942 t_2c_sigma_pos_tau, t_3c_x_w, fm_w_mic_time, &
1943 mat_sigma_neg_tau, mat_sigma_pos_tau)
1944
1945 CALL delete_unnecessary_files(bs_env)
1946
1947 CALL timestop(handle)
1948
1949 END SUBROUTINE get_sigma_c
1950
1951! **************************************************************************************************
1952!> \brief ...
1953!> \param bs_env ...
1954!> \param t_2c_Gocc ...
1955!> \param t_2c_Gvir ...
1956!> \param t_2c_W ...
1957!> \param t_2c_Sigma_neg_tau ...
1958!> \param t_2c_Sigma_pos_tau ...
1959!> \param t_3c_x_W ...
1960!> \param mat_Sigma_neg_tau ...
1961!> \param mat_Sigma_pos_tau ...
1962! **************************************************************************************************
1963 SUBROUTINE create_mat_for_sigma_c(bs_env, t_2c_Gocc, t_2c_Gvir, t_2c_W, t_2c_Sigma_neg_tau, &
1964 t_2c_Sigma_pos_tau, t_3c_x_W, &
1965 mat_Sigma_neg_tau, mat_Sigma_pos_tau)
1966
1967 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1968 TYPE(dbt_type) :: t_2c_gocc, t_2c_gvir, t_2c_w, &
1969 t_2c_sigma_neg_tau, &
1970 t_2c_sigma_pos_tau, t_3c_x_w
1971 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_sigma_neg_tau, mat_sigma_pos_tau
1972
1973 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_mat_for_Sigma_c'
1974
1975 INTEGER :: handle, i_t, ispin
1976
1977 CALL timeset(routinen, handle)
1978
1979 CALL dbt_create(bs_env%t_G, t_2c_gocc)
1980 CALL dbt_create(bs_env%t_G, t_2c_gvir)
1981 CALL dbt_create(bs_env%t_W, t_2c_w)
1982 CALL dbt_create(bs_env%t_G, t_2c_sigma_neg_tau)
1983 CALL dbt_create(bs_env%t_G, t_2c_sigma_pos_tau)
1984 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_w)
1985
1986 NULLIFY (mat_sigma_neg_tau, mat_sigma_pos_tau)
1987 ALLOCATE (mat_sigma_neg_tau(bs_env%num_time_freq_points, bs_env%n_spin))
1988 ALLOCATE (mat_sigma_pos_tau(bs_env%num_time_freq_points, bs_env%n_spin))
1989
1990 DO ispin = 1, bs_env%n_spin
1991 DO i_t = 1, bs_env%num_time_freq_points
1992 ALLOCATE (mat_sigma_neg_tau(i_t, ispin)%matrix)
1993 ALLOCATE (mat_sigma_pos_tau(i_t, ispin)%matrix)
1994 CALL dbcsr_create(mat_sigma_neg_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
1995 CALL dbcsr_create(mat_sigma_pos_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
1996 END DO
1997 END DO
1998
1999 CALL timestop(handle)
2000
2001 END SUBROUTINE create_mat_for_sigma_c
2002
2003! **************************************************************************************************
2004!> \brief ...
2005!> \param qs_env ...
2006!> \param bs_env ...
2007!> \param i_atoms ...
2008!> \param j_atoms ...
2009!> \param t_3c_x_W ...
2010!> \param t_2c_W ...
2011! **************************************************************************************************
2012 SUBROUTINE compute_3c_and_contract_w(qs_env, bs_env, i_atoms, j_atoms, t_3c_x_W, t_2c_W)
2013
2014 TYPE(qs_environment_type), POINTER :: qs_env
2015 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2016 INTEGER, DIMENSION(2) :: i_atoms, j_atoms
2017 TYPE(dbt_type) :: t_3c_x_w, t_2c_w
2018
2019 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_3c_and_contract_W'
2020
2021 INTEGER :: handle, ri_intval_idx
2022 INTEGER(KIND=int_8) :: flop
2023 INTEGER, DIMENSION(2) :: bounds_p, bounds_q, ri_atoms
2024 INTEGER, DIMENSION(2, 2) :: bounds_ao
2025 TYPE(dbt_type) :: t_3c_for_w, t_3c_x_w_tmp
2026
2027 CALL timeset(routinen, handle)
2028
2029 CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_x_w_tmp)
2030 CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_for_w)
2031
2032 ! final layout will be: M_Qνσ(iτ) = sum_P (P|νσ) W^MIC_QP(iτ)
2033 ! Bounds:
2034 ! "AO"
2035 ! -> ν (AO_1 in compute_3c_integrals) bounds from i_atoms and sparse in σ and P
2036 ! -> σ (AO_2 in compute_3c_integrals) sparse in ν and P
2037 ! Q bounds from j_atoms
2038 ! P bounds from inner loop indices and sparse in ν and σ
2039
2040 bounds_q(1:2) = [bs_env%i_RI_start_from_atom(j_atoms(1)), &
2041 bs_env%i_RI_end_from_atom(j_atoms(2))]
2042
2043 DO ri_intval_idx = 1, bs_env%n_intervals_inner_loop_atoms
2044 ri_atoms = bs_env%inner_loop_atom_intervals(1:2, ri_intval_idx)
2045
2046 CALL get_bounds_from_atoms(bounds_p, i_atoms, [1, bs_env%n_atom], &
2047 bs_env%min_RI_idx_from_AO_AO_atom, &
2048 bs_env%max_RI_idx_from_AO_AO_atom, &
2049 atoms_3=ri_atoms, &
2050 indices_3_start=bs_env%i_RI_start_from_atom, &
2051 indices_3_end=bs_env%i_RI_end_from_atom)
2052
2053 ! σ
2054 CALL get_bounds_from_atoms(bounds_ao(:, 2), ri_atoms, i_atoms, &
2055 bs_env%min_AO_idx_from_RI_AO_atom, &
2056 bs_env%max_AO_idx_from_RI_AO_atom)
2057 ! ν
2058 CALL get_bounds_from_atoms(bounds_ao(:, 1), ri_atoms, [1, bs_env%n_atom], &
2059 bs_env%min_AO_idx_from_RI_AO_atom, &
2060 bs_env%max_AO_idx_from_RI_AO_atom, &
2061 atoms_3=i_atoms, &
2062 indices_3_start=bs_env%i_ao_start_from_atom, &
2063 indices_3_end=bs_env%i_ao_end_from_atom)
2064
2065 IF (bounds_p(1) > bounds_p(2) .OR. bounds_ao(1, 2) > bounds_ao(2, 2)) THEN
2066 cycle
2067 END IF
2068
2069 ! 1. compute 3-center integrals (P|µν) ("|": truncated Coulomb operator)
2070 CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_w, &
2071 atoms_ao_1=i_atoms, atoms_ri=ri_atoms)
2072
2073 ! 2. tensor operation M_Qνσ(iτ) = sum_P W^MIC_QP(iτ) (P|νσ)
2074 CALL dbt_contract(alpha=1.0_dp, &
2075 tensor_1=t_2c_w, &
2076 tensor_2=t_3c_for_w, &
2077 beta=1.0_dp, &
2078 tensor_3=t_3c_x_w_tmp, &
2079 contract_1=[2], notcontract_1=[1], map_1=[1], &
2080 contract_2=[1], notcontract_2=[2, 3], map_2=[2, 3], &
2081 bounds_1=bounds_p, &
2082 bounds_2=bounds_q, &
2083 bounds_3=bounds_ao, &
2084 flop=flop, &
2085 move_data=.false., &
2086 filter_eps=bs_env%eps_filter, &
2087 unit_nr=bs_env%unit_nr_contract, &
2088 log_verbose=bs_env%print_contract_verbose)
2089
2090 END DO ! RI_atoms
2091
2092 ! 3. reorder tensor
2093 CALL dbt_copy(t_3c_x_w_tmp, t_3c_x_w, order=[1, 2, 3], move_data=.true.)
2094
2095 CALL dbt_destroy(t_3c_x_w_tmp)
2096 CALL dbt_destroy(t_3c_for_w)
2097
2098 CALL timestop(handle)
2099
2100 END SUBROUTINE compute_3c_and_contract_w
2101
2102! **************************************************************************************************
2103!> \brief ...
2104!> \param t_2c_G ...
2105!> \param t_3c_x_W ...
2106!> \param t_2c_Sigma ...
2107!> \param i_atoms ...
2108!> \param j_atoms ...
2109!> \param qs_env ...
2110!> \param bs_env ...
2111!> \param occ ...
2112!> \param vir ...
2113!> \param can_skip ...
2114! **************************************************************************************************
2115 SUBROUTINE contract_to_sigma(t_2c_G, t_3c_x_W, t_2c_Sigma, i_atoms, j_atoms, qs_env, bs_env, &
2116 occ, vir, can_skip)
2117 TYPE(dbt_type) :: t_2c_g, t_3c_x_w, t_2c_sigma
2118 INTEGER, DIMENSION(2) :: i_atoms, j_atoms
2119 TYPE(qs_environment_type), POINTER :: qs_env
2120 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2121 LOGICAL :: occ, vir
2122 LOGICAL, OPTIONAL :: can_skip
2123
2124 CHARACTER(LEN=*), PARAMETER :: routinen = 'contract_to_Sigma'
2125
2126 INTEGER :: handle, inner_loop_atoms_interval_index
2127 INTEGER(KIND=int_8) :: flop
2128 INTEGER, DIMENSION(2) :: bounds_lambda, bounds_mu, bounds_nu, &
2129 bounds_sigma, il_atoms
2130 INTEGER, DIMENSION(2, 2) :: bounds_comb
2131 REAL(kind=dp) :: sign_sigma
2132 TYPE(dbt_type) :: t_3c_for_g, t_3c_x_g, t_3c_x_g_2
2133
2134 CALL timeset(routinen, handle)
2135
2136 cpassert(occ .EQV. (.NOT. vir))
2137 IF (occ) sign_sigma = -1.0_dp
2138 IF (vir) sign_sigma = 1.0_dp
2139
2140 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_for_g)
2141 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_g)
2142 CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_g_2)
2143
2144 ! Here, in the first step e.g., is computed: N_Qλν = sum_µ (Qλ|µ) G_νµ
2145 ! Afterwards e.g., is computed: Σ_λσ = sum_νQ M_Qνσ N_Qνλ (after reordering)
2146 ! Bounds:
2147 ! "comb" (combined index)
2148 ! -> Q bounds from j_atoms and sparse in λ
2149 ! -> λ (AO_1 in compute_3c_integrals) sparse in Q and µ
2150 ! µ (AO_2 in compute_3c_integrals) bounds from inner loop "IL" indices and sparse in Q and λ
2151 ! ν bounds from i_atoms
2152 ! σ sparse in ν
2153
2154 ! ν
2155 bounds_nu(1:2) = [bs_env%i_ao_start_from_atom(i_atoms(1)), &
2156 bs_env%i_ao_end_from_atom(i_atoms(2))]
2157
2158 DO inner_loop_atoms_interval_index = 1, bs_env%n_intervals_inner_loop_atoms
2159 il_atoms = bs_env%inner_loop_atom_intervals(1:2, inner_loop_atoms_interval_index)
2160
2161 ! µ
2162 CALL get_bounds_from_atoms(bounds_mu, j_atoms, [1, bs_env%n_atom], &
2163 bs_env%min_AO_idx_from_RI_AO_atom, &
2164 bs_env%max_AO_idx_from_RI_AO_atom, &
2165 atoms_3=il_atoms, &
2166 indices_3_start=bs_env%i_ao_start_from_atom, &
2167 indices_3_end=bs_env%i_ao_end_from_atom)
2168
2169 ! Q
2170 CALL get_bounds_from_atoms(bounds_comb(:, 1), il_atoms, [1, bs_env%n_atom], &
2171 bs_env%min_RI_idx_from_AO_AO_atom, &
2172 bs_env%max_RI_idx_from_AO_AO_atom, &
2173 atoms_3=j_atoms, &
2174 indices_3_start=bs_env%i_RI_start_from_atom, &
2175 indices_3_end=bs_env%i_RI_end_from_atom)
2176
2177 ! λ
2178 CALL get_bounds_from_atoms(bounds_comb(:, 2), j_atoms, il_atoms, &
2179 bs_env%min_AO_idx_from_RI_AO_atom, &
2180 bs_env%max_AO_idx_from_RI_AO_atom)
2181
2182 IF (bounds_mu(1) > bounds_mu(2) .OR. bounds_comb(1, 1) > bounds_comb(2, 1) .OR. &
2183 bounds_comb(1, 2) > bounds_comb(2, 2)) THEN
2184 cycle
2185 END IF
2186
2187 CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_g, &
2188 atoms_ri=j_atoms, atoms_ao_2=il_atoms)
2189
2190 CALL dbt_contract(alpha=1.0_dp, &
2191 tensor_1=t_2c_g, &
2192 tensor_2=t_3c_for_g, &
2193 beta=1.0_dp, &
2194 tensor_3=t_3c_x_g, &
2195 contract_1=[2], notcontract_1=[1], map_1=[3], &
2196 contract_2=[3], notcontract_2=[1, 2], map_2=[1, 2], &
2197 bounds_1=bounds_mu, &
2198 bounds_2=bounds_nu, &
2199 bounds_3=bounds_comb, &
2200 flop=flop, &
2201 move_data=.false., &
2202 filter_eps=bs_env%eps_filter, &
2203 unit_nr=bs_env%unit_nr_contract, &
2204 log_verbose=bs_env%print_contract_verbose)
2205 END DO ! IL_atoms
2206
2207 ! Reordering: N_Qλν -> N_Qνλ
2208 CALL dbt_copy(t_3c_x_g, t_3c_x_g_2, order=[1, 3, 2], move_data=.true.)
2209
2210 ! Here, the last contraction is done, e.g., Σ_λσ = sum_νQ M_Qνσ N_Qνλ
2211 ! Bounds as above, new "comb" with upper ingredients
2212 bounds_comb(1:2, 1) = [bs_env%i_RI_start_from_atom(j_atoms(1)), &
2213 bs_env%i_RI_end_from_atom(j_atoms(2))]
2214 bounds_comb(1:2, 2) = bounds_nu(1:2)
2215
2216 CALL get_bounds_from_atoms(bounds_lambda, j_atoms, [1, bs_env%n_atom], &
2217 bs_env%min_AO_idx_from_RI_AO_atom, &
2218 bs_env%max_AO_idx_from_RI_AO_atom)
2219 CALL get_bounds_from_atoms(bounds_sigma, [1, bs_env%n_atom], i_atoms, &
2220 bs_env%min_AO_idx_from_RI_AO_atom, &
2221 bs_env%max_AO_idx_from_RI_AO_atom)
2222
2223 IF (bounds_sigma(1) > bounds_sigma(2) .OR. bounds_lambda(1) > bounds_lambda(2)) THEN
2224 flop = 0_int_8
2225 ELSE
2226 CALL dbt_contract(alpha=sign_sigma, &
2227 tensor_1=t_3c_x_w, &
2228 tensor_2=t_3c_x_g_2, &
2229 beta=1.0_dp, &
2230 tensor_3=t_2c_sigma, &
2231 contract_1=[1, 2], notcontract_1=[3], map_1=[1], &
2232 contract_2=[1, 2], notcontract_2=[3], map_2=[2], &
2233 bounds_1=bounds_comb, &
2234 bounds_2=bounds_sigma, &
2235 bounds_3=bounds_lambda, &
2236 filter_eps=bs_env%eps_filter, move_data=.false., flop=flop, &
2237 unit_nr=bs_env%unit_nr_contract, &
2238 log_verbose=bs_env%print_contract_verbose)
2239 END IF
2240
2241 IF (PRESENT(can_skip)) THEN
2242 IF (flop == 0_int_8) can_skip = .true.
2243 END IF
2244
2245 CALL dbt_destroy(t_3c_for_g)
2246 CALL dbt_destroy(t_3c_x_g)
2247 CALL dbt_destroy(t_3c_x_g_2)
2248
2249 CALL timestop(handle)
2250
2251 END SUBROUTINE contract_to_sigma
2252
2253! **************************************************************************************************
2254!> \brief ...
2255!> \param fm_Sigma_c_Gamma_time ...
2256!> \param bs_env ...
2257!> \param mat_Sigma_pos_tau ...
2258!> \param mat_Sigma_neg_tau ...
2259! **************************************************************************************************
2260 SUBROUTINE fill_fm_sigma_c_gamma_time(fm_Sigma_c_Gamma_time, bs_env, &
2261 mat_Sigma_pos_tau, mat_Sigma_neg_tau)
2262
2263 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
2264 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2265 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_sigma_pos_tau, mat_sigma_neg_tau
2266
2267 CHARACTER(LEN=*), PARAMETER :: routinen = 'fill_fm_Sigma_c_Gamma_time'
2268
2269 INTEGER :: handle, i_t, ispin, pos_neg
2270
2271 CALL timeset(routinen, handle)
2272
2273 ALLOCATE (fm_sigma_c_gamma_time(bs_env%num_time_freq_points, 2, bs_env%n_spin))
2274 DO ispin = 1, bs_env%n_spin
2275 DO i_t = 1, bs_env%num_time_freq_points
2276 DO pos_neg = 1, 2
2277 CALL cp_fm_create(fm_sigma_c_gamma_time(i_t, pos_neg, ispin), &
2278 bs_env%fm_s_Gamma%matrix_struct)
2279 END DO
2280 CALL copy_dbcsr_to_fm(mat_sigma_pos_tau(i_t, ispin)%matrix, &
2281 fm_sigma_c_gamma_time(i_t, 1, ispin))
2282 CALL copy_dbcsr_to_fm(mat_sigma_neg_tau(i_t, ispin)%matrix, &
2283 fm_sigma_c_gamma_time(i_t, 2, ispin))
2284 END DO
2285 END DO
2286
2287 CALL timestop(handle)
2288
2289 END SUBROUTINE fill_fm_sigma_c_gamma_time
2290
2291! **************************************************************************************************
2292!> \brief ...
2293!> \param bs_env ...
2294! **************************************************************************************************
2295 SUBROUTINE print_skipping(bs_env)
2296
2297 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2298
2299 CHARACTER(LEN=*), PARAMETER :: routinen = 'print_skipping'
2300
2301 INTEGER :: handle, n_pairs
2302
2303 CALL timeset(routinen, handle)
2304
2305 n_pairs = bs_env%n_intervals_i*bs_env%n_intervals_j*bs_env%n_spin
2306
2307 CALL bs_env%para_env_tensor%sum(bs_env%n_skip_sigma)
2308 CALL bs_env%para_env_tensor%sum(bs_env%n_skip_chi)
2309 CALL bs_env%para_env_tensor%sum(n_pairs)
2310
2311 IF (bs_env%unit_nr > 0) THEN
2312 WRITE (bs_env%unit_nr, '(T2,A,T74,F7.1,A)') &
2313 Στ'Sparsity of ^c(i,k=0): Percentage of skipped atom pairs:', &
2314 REAL(100*bs_env%n_skip_sigma, kind=dp)/real(n_pairs, kind=dp), ' %'
2315 WRITE (bs_env%unit_nr, '(T2,A,T74,F7.1,A)') &
2316 χτ'Sparsity of (i,k=0): Percentage of skipped atom pairs:', &
2317 REAL(100*bs_env%n_skip_chi, kind=dp)/real(n_pairs, kind=dp), ' %'
2318 END IF
2319
2320 CALL timestop(handle)
2321
2322 END SUBROUTINE print_skipping
2323
2324! **************************************************************************************************
2325!> \brief ...
2326!> \param t_2c_Gocc ...
2327!> \param t_2c_Gvir ...
2328!> \param t_2c_W ...
2329!> \param t_2c_Sigma_neg_tau ...
2330!> \param t_2c_Sigma_pos_tau ...
2331!> \param t_3c_x_W ...
2332!> \param fm_W_MIC_time ...
2333!> \param mat_Sigma_neg_tau ...
2334!> \param mat_Sigma_pos_tau ...
2335! **************************************************************************************************
2336 SUBROUTINE destroy_mat_sigma_c(t_2c_Gocc, t_2c_Gvir, t_2c_W, t_2c_Sigma_neg_tau, &
2337 t_2c_Sigma_pos_tau, t_3c_x_W, fm_W_MIC_time, &
2338 mat_Sigma_neg_tau, mat_Sigma_pos_tau)
2339
2340 TYPE(dbt_type) :: t_2c_gocc, t_2c_gvir, t_2c_w, &
2341 t_2c_sigma_neg_tau, &
2342 t_2c_sigma_pos_tau, t_3c_x_w
2343 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_w_mic_time
2344 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_sigma_neg_tau, mat_sigma_pos_tau
2345
2346 CHARACTER(LEN=*), PARAMETER :: routinen = 'destroy_mat_Sigma_c'
2347
2348 INTEGER :: handle
2349
2350 CALL timeset(routinen, handle)
2351
2352 CALL dbt_destroy(t_2c_gocc)
2353 CALL dbt_destroy(t_2c_gvir)
2354 CALL dbt_destroy(t_2c_w)
2355 CALL dbt_destroy(t_2c_sigma_neg_tau)
2356 CALL dbt_destroy(t_2c_sigma_pos_tau)
2357 CALL dbt_destroy(t_3c_x_w)
2358 CALL cp_fm_release(fm_w_mic_time)
2359 CALL dbcsr_deallocate_matrix_set(mat_sigma_neg_tau)
2360 CALL dbcsr_deallocate_matrix_set(mat_sigma_pos_tau)
2361
2362 CALL timestop(handle)
2363
2364 END SUBROUTINE destroy_mat_sigma_c
2365
2366! **************************************************************************************************
2367!> \brief ...
2368!> \param bs_env ...
2369! **************************************************************************************************
2370 SUBROUTINE delete_unnecessary_files(bs_env)
2371 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2372
2373 CHARACTER(LEN=*), PARAMETER :: routinen = 'delete_unnecessary_files'
2374
2375 CHARACTER(LEN=default_path_length) :: f_chi, f_w_t, prefix
2376 INTEGER :: handle, i_t
2377
2378 CALL timeset(routinen, handle)
2379
2380 prefix = bs_env%prefix
2381
2382 DO i_t = 1, bs_env%num_time_freq_points
2383
2384 IF (i_t < 10) THEN
2385 WRITE (f_chi, '(3A,I1,A)') trim(prefix), bs_env%chi_name, "_00", i_t, ".matrix"
2386 WRITE (f_w_t, '(3A,I1,A)') trim(prefix), bs_env%W_time_name, "_00", i_t, ".matrix"
2387 ELSE IF (i_t < 100) THEN
2388 WRITE (f_chi, '(3A,I2,A)') trim(prefix), bs_env%chi_name, "_0", i_t, ".matrix"
2389 WRITE (f_w_t, '(3A,I2,A)') trim(prefix), bs_env%W_time_name, "_0", i_t, ".matrix"
2390 ELSE
2391 cpabort('Please implement more than 99 time/frequency points.')
2392 END IF
2393
2394 CALL safe_delete(f_chi, bs_env)
2395 CALL safe_delete(f_w_t, bs_env)
2396
2397 END DO
2398
2399 CALL timestop(handle)
2400
2401 END SUBROUTINE delete_unnecessary_files
2402
2403! **************************************************************************************************
2404!> \brief ...
2405!> \param filename ...
2406!> \param bs_env ...
2407! **************************************************************************************************
2408 SUBROUTINE safe_delete(filename, bs_env)
2409 CHARACTER(LEN=*) :: filename
2410 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2411
2412 CHARACTER(LEN=*), PARAMETER :: routinen = 'safe_delete'
2413
2414 INTEGER :: handle
2415 LOGICAL :: file_exists
2416
2417 CALL timeset(routinen, handle)
2418
2419 IF (bs_env%para_env%mepos == 0) THEN
2420
2421 INQUIRE (file=trim(filename), exist=file_exists)
2422 IF (file_exists) CALL mp_file_delete(trim(filename))
2423
2424 END IF
2425
2426 CALL timestop(handle)
2427
2428 END SUBROUTINE safe_delete
2429
2430! **************************************************************************************************
2431!> \brief ...
2432!> \param bs_env ...
2433!> \param qs_env ...
2434!> \param fm_Sigma_x_Gamma ...
2435!> \param fm_Sigma_c_Gamma_time ...
2436! **************************************************************************************************
2437 SUBROUTINE compute_qp_energies(bs_env, qs_env, fm_Sigma_x_Gamma, fm_Sigma_c_Gamma_time)
2438
2439 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2440 TYPE(qs_environment_type), POINTER :: qs_env
2441 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_sigma_x_gamma
2442 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_sigma_c_gamma_time
2443
2444 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_QP_energies'
2445
2446 INTEGER :: handle, ikp, ispin, j_t
2447 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: sigma_x_ikp_n, v_xc_ikp_n
2448 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: sigma_c_ikp_n_freq, sigma_c_ikp_n_time
2449 TYPE(cp_cfm_type) :: cfm_ks_ikp, cfm_mos_ikp, cfm_s_ikp, &
2450 cfm_sigma_x_ikp, cfm_work_ikp
2451
2452 CALL timeset(routinen, handle)
2453
2454 CALL cp_cfm_create(cfm_mos_ikp, bs_env%fm_s_Gamma%matrix_struct)
2455 CALL cp_cfm_create(cfm_work_ikp, bs_env%fm_s_Gamma%matrix_struct)
2456 ! JW TODO: fully distribute these arrays at given time; also eigenvalues in bs_env
2457 ALLOCATE (v_xc_ikp_n(bs_env%n_ao), sigma_x_ikp_n(bs_env%n_ao))
2458 ALLOCATE (sigma_c_ikp_n_time(bs_env%n_ao, bs_env%num_time_freq_points, 2))
2459 ALLOCATE (sigma_c_ikp_n_freq(bs_env%n_ao, bs_env%num_time_freq_points, 2))
2460
2461 DO ispin = 1, bs_env%n_spin
2462
2463 DO ikp = 1, bs_env%nkp_bs_and_DOS
2464
2465 ! 1. get H^KS_µν(k_i) from H^KS_µν(k=0)
2466 CALL cfm_ikp_from_fm_gamma(cfm_ks_ikp, bs_env%fm_ks_Gamma(ispin), &
2467 ikp, qs_env, bs_env%kpoints_DOS, "ORB")
2468
2469 ! 2. get S_µν(k_i) from S_µν(k=0)
2470 CALL cfm_ikp_from_fm_gamma(cfm_s_ikp, bs_env%fm_s_Gamma, &
2471 ikp, qs_env, bs_env%kpoints_DOS, "ORB")
2472
2473 ! 3. Diagonalize (Roothaan-Hall): H_KS(k_i)*C(k_i) = S(k_i)*C(k_i)*ϵ(k_i)
2474 CALL cp_cfm_geeig(cfm_ks_ikp, cfm_s_ikp, cfm_mos_ikp, &
2475 bs_env%eigenval_scf(:, ikp, ispin), cfm_work_ikp)
2476
2477 ! 4. V^xc_µν(k=0) -> V^xc_µν(k_i) -> V^xc_nn(k_i)
2478 CALL to_ikp_and_mo(v_xc_ikp_n, bs_env%fm_V_xc_Gamma(ispin), &
2479 ikp, qs_env, bs_env, cfm_mos_ikp)
2480
2481 ! 5. Σ^x_µν(k=0) -> Σ^x_µν(k_i) -> Σ^x_nn(k_i)
2482 CALL to_ikp_and_mo(sigma_x_ikp_n, fm_sigma_x_gamma(ispin), &
2483 ikp, qs_env, bs_env, cfm_mos_ikp)
2484
2485 ! 6. Σ^c_µν(k=0,+/-i|τ_j|) -> Σ^c_µν(k_i,+/-i|τ_j|) -> Σ^c_nn(k_i,+/-i|τ_j|)
2486 DO j_t = 1, bs_env%num_time_freq_points
2487 CALL to_ikp_and_mo(sigma_c_ikp_n_time(:, j_t, 1), &
2488 fm_sigma_c_gamma_time(j_t, 1, ispin), &
2489 ikp, qs_env, bs_env, cfm_mos_ikp)
2490 CALL to_ikp_and_mo(sigma_c_ikp_n_time(:, j_t, 2), &
2491 fm_sigma_c_gamma_time(j_t, 2, ispin), &
2492 ikp, qs_env, bs_env, cfm_mos_ikp)
2493 END DO
2494
2495 ! 7. Σ^c_nn(k_i,iτ) -> Σ^c_nn(k_i,iω)
2496 CALL time_to_freq(bs_env, sigma_c_ikp_n_time, sigma_c_ikp_n_freq, ispin)
2497
2498 ! 8. Analytic continuation Σ^c_nn(k_i,iω) -> Σ^c_nn(k_i,ϵ) and
2499 ! ϵ_nk_i^GW = ϵ_nk_i^DFT + Σ^c_nn(k_i,ϵ) + Σ^x_nn(k_i) - v^xc_nn(k_i)
2500 CALL analyt_conti_and_print(bs_env, sigma_c_ikp_n_freq, sigma_x_ikp_n, v_xc_ikp_n, &
2501 bs_env%eigenval_scf(:, ikp, ispin), ikp, ispin)
2502
2503 END DO ! ikp_DOS
2504
2505 END DO ! ispin
2506
2507 CALL get_all_vbm_cbm_bandgaps(bs_env)
2508
2509 CALL cp_fm_release(fm_sigma_x_gamma)
2510 CALL cp_fm_release(fm_sigma_c_gamma_time)
2511 CALL cp_cfm_release(cfm_ks_ikp)
2512 CALL cp_cfm_release(cfm_s_ikp)
2513 CALL cp_cfm_release(cfm_mos_ikp)
2514 CALL cp_cfm_release(cfm_work_ikp)
2515 CALL cp_cfm_release(cfm_sigma_x_ikp)
2516
2517 CALL timestop(handle)
2518
2519 END SUBROUTINE compute_qp_energies
2520
2521! **************************************************************************************************
2522!> \brief ...
2523!> \param array_ikp_n ...
2524!> \param fm_Gamma ...
2525!> \param ikp ...
2526!> \param qs_env ...
2527!> \param bs_env ...
2528!> \param cfm_mos_ikp ...
2529! **************************************************************************************************
2530 SUBROUTINE to_ikp_and_mo(array_ikp_n, fm_Gamma, ikp, qs_env, bs_env, cfm_mos_ikp)
2531
2532 REAL(kind=dp), DIMENSION(:) :: array_ikp_n
2533 TYPE(cp_fm_type) :: fm_gamma
2534 INTEGER :: ikp
2535 TYPE(qs_environment_type), POINTER :: qs_env
2536 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2537 TYPE(cp_cfm_type) :: cfm_mos_ikp
2538
2539 CHARACTER(LEN=*), PARAMETER :: routinen = 'to_ikp_and_mo'
2540
2541 INTEGER :: handle
2542 TYPE(cp_fm_type) :: fm_ikp_mo_re
2543
2544 CALL timeset(routinen, handle)
2545
2546 CALL cp_fm_create(fm_ikp_mo_re, fm_gamma%matrix_struct)
2547
2548 CALL fm_gamma_ao_to_cfm_ikp_mo(fm_gamma, fm_ikp_mo_re, ikp, qs_env, bs_env, cfm_mos_ikp)
2549
2550 CALL cp_fm_get_diag(fm_ikp_mo_re, array_ikp_n)
2551
2552 CALL cp_fm_release(fm_ikp_mo_re)
2553
2554 CALL timestop(handle)
2555
2556 END SUBROUTINE to_ikp_and_mo
2557
2558! **************************************************************************************************
2559!> \brief ...
2560!> \param fm_Gamma ...
2561!> \param fm_ikp_mo_re ...
2562!> \param ikp ...
2563!> \param qs_env ...
2564!> \param bs_env ...
2565!> \param cfm_mos_ikp ...
2566! **************************************************************************************************
2567 SUBROUTINE fm_gamma_ao_to_cfm_ikp_mo(fm_Gamma, fm_ikp_mo_re, ikp, qs_env, bs_env, cfm_mos_ikp)
2568 TYPE(cp_fm_type) :: fm_gamma, fm_ikp_mo_re
2569 INTEGER :: ikp
2570 TYPE(qs_environment_type), POINTER :: qs_env
2571 TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2572 TYPE(cp_cfm_type) :: cfm_mos_ikp
2573
2574 CHARACTER(LEN=*), PARAMETER :: routinen = 'fm_Gamma_ao_to_cfm_ikp_mo'
2575
2576 INTEGER :: handle, nmo
2577 TYPE(cp_cfm_type) :: cfm_ikp_ao, cfm_ikp_mo, cfm_tmp
2578
2579 CALL timeset(routinen, handle)
2580
2581 CALL cp_cfm_create(cfm_ikp_ao, fm_gamma%matrix_struct)
2582 CALL cp_cfm_create(cfm_ikp_mo, fm_gamma%matrix_struct)
2583 CALL cp_cfm_create(cfm_tmp, fm_gamma%matrix_struct)
2584
2585 ! get cfm_µν(k_i) from fm_µν(k=0)
2586 CALL cfm_ikp_from_fm_gamma(cfm_ikp_ao, fm_gamma, ikp, qs_env, bs_env%kpoints_DOS, "ORB")
2587
2588 nmo = bs_env%n_ao
2589 CALL parallel_gemm('N', 'N', nmo, nmo, nmo, z_one, cfm_ikp_ao, cfm_mos_ikp, z_zero, cfm_tmp)
2590 CALL parallel_gemm('C', 'N', nmo, nmo, nmo, z_one, cfm_mos_ikp, cfm_tmp, z_zero, cfm_ikp_mo)
2591
2592 CALL cp_cfm_to_fm(cfm_ikp_mo, fm_ikp_mo_re)
2593
2594 CALL cp_cfm_release(cfm_ikp_mo)
2595 CALL cp_cfm_release(cfm_ikp_ao)
2596 CALL cp_cfm_release(cfm_tmp)
2597
2598 CALL timestop(handle)
2599
2600 END SUBROUTINE fm_gamma_ao_to_cfm_ikp_mo
2601
2602! **************************************************************************************************
2603!> \brief Computes bounds (AO or RI) for given atom intervals atoms_1 and atoms_2 from indices_min
2604!> and indices_max and returns them in bounds_out.
2605!> In case, atoms_3 and indices_3 are given, the bounds are computed as the intersection
2606!> \param bounds_out Bounds to be computed
2607!> \param atoms_1 First atom interval
2608!> \param atoms_2 Second atom interval
2609!> \param indices_min Minimum indices for each atom pair (typically from bs_env,
2610!> computed in get_i_j_atom_ranges in gw_utils.F, e.g. bs_env%min_RI_idx_from_AO_AO_atom)
2611!> \param indices_max Maximum indices for each atom pair (typically from bs_env,
2612!> computed in get_i_j_atom_ranges in gw_utils.F)
2613!> \param atoms_3 (Optional) Third atom interval for intersection
2614!> \param indices_3_start (Optional) Indices for third atom interval for intersection
2615!> \param indices_3_end (Optional) Indices for third atom interval for intersection
2616! **************************************************************************************************
2617 SUBROUTINE get_bounds_from_atoms(bounds_out, atoms_1, atoms_2, indices_min, indices_max, &
2618 atoms_3, indices_3_start, indices_3_end)
2619
2620 INTEGER, DIMENSION(2), INTENT(OUT) :: bounds_out
2621 INTEGER, DIMENSION(2), INTENT(IN) :: atoms_1, atoms_2
2622 INTEGER, DIMENSION(:, :) :: indices_min, indices_max
2623 INTEGER, DIMENSION(2), INTENT(IN), OPTIONAL :: atoms_3
2624 INTEGER, DIMENSION(:), OPTIONAL :: indices_3_start, indices_3_end
2625
2626 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_bounds_from_atoms'
2627
2628 INTEGER :: handle, i_at, j_at
2629
2630 CALL timeset(routinen, handle)
2631 bounds_out(1) = huge(0)
2632 bounds_out(2) = -1
2633 !Loop over all atoms in the two intervals and find min/max indices
2634 DO i_at = atoms_1(1), atoms_1(2)
2635 DO j_at = atoms_2(1), atoms_2(2)
2636 bounds_out(1) = min(bounds_out(1), indices_min(i_at, j_at))
2637 bounds_out(2) = max(bounds_out(2), indices_max(i_at, j_at))
2638 END DO
2639 END DO
2640
2641 IF (PRESENT(atoms_3) .AND. PRESENT(indices_3_start) .AND. PRESENT(indices_3_end)) THEN
2642 bounds_out(1) = max(bounds_out(1), indices_3_start(atoms_3(1)))
2643 bounds_out(2) = min(bounds_out(2), indices_3_end(atoms_3(2)))
2644 END IF
2645
2646 CALL timestop(handle)
2647
2648 END SUBROUTINE get_bounds_from_atoms
2649
2650END MODULE gw_large_cell_gamma
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
Define the atomic kind types and their sub types.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public graml2024
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
Definition cell_types.F:210
constants for the different operators of the 2c-integrals
integer, parameter, public operator_coulomb
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_uplo_to_full(matrix, workspace, uplo)
...
various cholesky decomposition related routines
subroutine, public cp_cfm_cholesky_decompose(matrix, n, info_out)
Used to replace a symmetric positive definite matrix M with its Cholesky decomposition U: M = U^T * U...
subroutine, public cp_cfm_cholesky_invert(matrix, n, info_out)
Used to replace Cholesky decomposition by the inverse.
used for collecting diagonalization schemes available for cp_cfm_type
Definition cp_cfm_diag.F:14
subroutine, public cp_cfm_geeig(amatrix, bmatrix, eigenvectors, eigenvalues, work)
General Eigenvalue Problem AX = BXE Single option version: Cholesky decomposition of 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_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
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_deallocate_matrix(matrix)
...
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_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
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_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_reserve_all_blocks(matrix)
Reserves all blocks.
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
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.
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:311
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:122
logical function, public file_exists(file_name)
Checks if file exists, considering also the file discovery mechanism.
Definition cp_files.F:504
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
Definition cp_fm_diag.F:17
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_diag(matrix, diag)
returns the diagonal elements of a fm
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
subroutine, public cp_fm_write_unformatted(fm, unit)
...
subroutine, public cp_fm_read_unformatted(fm, unit)
...
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
This is the start of a dbt_api, all publically needed functions are exported here....
Definition dbt_api.F:17
subroutine, public fm_to_local_tensor(fm_global, mat_global, mat_local, tensor, bs_env, atom_ranges)
...
subroutine, public local_dbt_to_global_mat(tensor, mat_tensor, mat_global, para_env)
...
Routines from paper [Graml2024].
subroutine, public compute_fm_chi_gamma_freq(bs_env, fm_chi_gamma_freq, j_w, mat_chi_gamma_tau)
...
subroutine, public delete_unnecessary_files(bs_env)
...
subroutine, public fill_fm_sigma_c_gamma_time(fm_sigma_c_gamma_time, bs_env, mat_sigma_pos_tau, mat_sigma_neg_tau)
...
subroutine, public fm_write(fm, matrix_index, matrix_name, qs_env)
...
subroutine, public gw_calc_large_cell_gamma(qs_env, bs_env)
Perform GW band structure calculation.
subroutine, public compute_qp_energies(bs_env, qs_env, fm_sigma_x_gamma, fm_sigma_c_gamma_time)
...
subroutine, public multiply_fm_w_mic_time_with_minv_gamma(bs_env, qs_env, fm_w_mic_time)
...
subroutine, public fm_read(fm, bs_env, mat_name, idx)
...
subroutine, public get_w_mic(bs_env, qs_env, mat_chi_gamma_tau, fm_w_mic_time)
...
subroutine, public write_matrix(matrix, matrix_index, matrix_name, fm, qs_env)
...
subroutine, public g_occ_vir(bs_env, tau, fm_g_gamma, ispin, occ, vir)
...
subroutine, public create_fm_w_mic_time(bs_env, fm_w_mic_time)
...
subroutine, public compute_3c_integrals(qs_env, bs_env, t_3c, atoms_ao_1, atoms_ao_2, atoms_ri)
...
subroutine, public fourier_transform_w_to_t(bs_env, fm_w_mic_time, fm_w_mic_freq_j, j_w)
...
subroutine, public time_to_freq(bs_env, sigma_c_n_time, sigma_c_n_freq, ispin)
...
Definition gw_utils.F:3235
subroutine, public de_init_bs_env(bs_env)
...
Definition gw_utils.F:241
subroutine, public analyt_conti_and_print(bs_env, sigma_c_ikp_n_freq, sigma_x_ikp_n, v_xc_ikp_n, eigenval_scf, ikp, ispin)
...
Definition gw_utils.F:3299
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public rtp_method_bse
objects that represent the structure of input sections and the data contained in an input section
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
Routines to compute the Coulomb integral V_(alpha beta)(k) for a k-point k using lattice summation in...
subroutine, public build_2c_coulomb_matrix_kp(matrix_v_kp, kpoints, basis_type, cell, particle_set, qs_kind_set, atomic_kind_set, size_lattice_sum, operator_type, ikp_start, ikp_end)
...
Types and basic routines needed for a kpoint calculation.
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
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
subroutine, public mp_file_delete(filepath, info)
Deletes a file. Auxiliary routine to emulate 'replace' action for mp_file_open. Only the master proce...
Framework for 2c-integrals for RI.
Definition mp2_ri_2c.F:14
subroutine, public ri_2c_integral_mat(qs_env, fm_matrix_minv_l_kpoints, fm_matrix_l, dimen_ri, ri_metric, do_kpoints, kpoints, put_mat_ks_env, regularization_ri, ikp_ext, do_build_cell_index)
...
Definition mp2_ri_2c.F:564
basic linear algebra operations for full matrixes
Define the data structure for the particle information.
subroutine, public cfm_ikp_from_fm_gamma(cfm_ikp, fm_gamma, ikp, qs_env, kpoints, basis_type)
...
subroutine, public get_all_vbm_cbm_bandgaps(bs_env)
...
subroutine, public mic_contribution_from_ikp(bs_env, qs_env, fm_w_mic_freq_j, cfm_w_ikp_freq_j, ikp, kpoints, basis_type, wkp_ext)
...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
Utility methods to build 3-center integral tensors of various types.
Definition qs_tensors.F:11
subroutine, public build_3c_integrals(t3c, filter_eps, qs_env, nl_3c, basis_i, basis_j, basis_k, potential_parameter, int_eps, op_pos, do_kpoints, do_hfx_kpoints, desymmetrize, cell_sym, bounds_i, bounds_j, bounds_k, ri_range, img_to_ri_cell, cell_to_index_ext)
Build 3-center integral tensor.
Routines treating GW and RPA calculations with kpoints.
subroutine, public cp_cfm_power(matrix, threshold, exponent, min_eigval)
...
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
Represent a complex full matrix.
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Contains information about kpoints.
Provides all information about a quickstep kind.