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