Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 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 : !> \author Jan Wilhelm
11 : !> \date 07.2023
12 : ! **************************************************************************************************
13 : MODULE gw_large_cell_gamma
14 : USE atomic_kind_types, ONLY: atomic_kind_type
15 : USE cell_types, ONLY: cell_type,&
16 : get_cell,&
17 : pbc
18 : USE constants_operator, ONLY: operator_coulomb
19 : USE cp_cfm_basic_linalg, ONLY: cp_cfm_cholesky_decompose,&
20 : cp_cfm_cholesky_invert
21 : USE cp_cfm_diag, ONLY: cp_cfm_geeig
22 : USE cp_cfm_types, ONLY: cp_cfm_create,&
23 : cp_cfm_get_info,&
24 : cp_cfm_release,&
25 : cp_cfm_to_cfm,&
26 : cp_cfm_to_fm,&
27 : cp_cfm_type,&
28 : cp_fm_to_cfm
29 : USE cp_dbcsr_api, ONLY: &
30 : dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, dbcsr_get_block_p, &
31 : dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, dbcsr_iterator_start, &
32 : dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_p_type, dbcsr_release, &
33 : dbcsr_reserve_all_blocks, dbcsr_set, dbcsr_type
34 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
35 : copy_fm_to_dbcsr,&
36 : dbcsr_deallocate_matrix_set
37 : USE cp_files, ONLY: close_file,&
38 : open_file
39 : USE cp_fm_basic_linalg, ONLY: cp_fm_scale_and_add
40 : USE cp_fm_diag, ONLY: cp_fm_power
41 : USE cp_fm_types, ONLY: &
42 : cp_fm_create, cp_fm_get_diag, cp_fm_get_info, cp_fm_read_unformatted, cp_fm_release, &
43 : cp_fm_set_all, cp_fm_to_fm, cp_fm_type, cp_fm_write_unformatted
44 : USE cp_log_handling, ONLY: cp_get_default_logger,&
45 : cp_logger_type
46 : USE cp_output_handling, ONLY: cp_p_file,&
47 : cp_print_key_should_output,&
48 : cp_print_key_unit_nr
49 : USE dbt_api, ONLY: dbt_clear,&
50 : dbt_contract,&
51 : dbt_copy,&
52 : dbt_create,&
53 : dbt_destroy,&
54 : dbt_type
55 : USE gw_communication, ONLY: fm_to_local_tensor,&
56 : local_dbt_to_global_mat
57 : USE gw_utils, ONLY: analyt_conti_and_print,&
58 : de_init_bs_env,&
59 : time_to_freq
60 : USE input_section_types, ONLY: section_vals_type
61 : USE kinds, ONLY: default_string_length,&
62 : dp,&
63 : int_8
64 : USE kpoint_coulomb_2c, ONLY: build_2c_coulomb_matrix_kp
65 : USE kpoint_types, ONLY: kpoint_type
66 : USE machine, ONLY: m_walltime
67 : USE mathconstants, ONLY: twopi,&
68 : z_one,&
69 : z_zero
70 : USE message_passing, ONLY: mp_file_delete
71 : USE mp2_ri_2c, ONLY: RI_2c_integral_mat
72 : USE parallel_gemm_api, ONLY: parallel_gemm
73 : USE particle_types, ONLY: particle_type
74 : USE post_scf_bandstructure_types, ONLY: post_scf_bandstructure_type
75 : USE post_scf_bandstructure_utils, ONLY: MIC_contribution_from_ikp,&
76 : cfm_ikp_from_fm_Gamma,&
77 : get_all_VBM_CBM_bandgaps
78 : USE qs_environment_types, ONLY: get_qs_env,&
79 : qs_environment_type
80 : USE qs_kind_types, ONLY: qs_kind_type
81 : USE qs_tensors, ONLY: build_3c_integrals
82 : USE rpa_gw_kpoints_util, ONLY: cp_cfm_power,&
83 : cp_cfm_upper_to_full
84 : #include "./base/base_uses.f90"
85 :
86 : IMPLICIT NONE
87 :
88 : PRIVATE
89 :
90 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gw_large_cell_gamma'
91 :
92 : PUBLIC :: gw_calc_large_cell_Gamma
93 :
94 : CONTAINS
95 :
96 : ! **************************************************************************************************
97 : !> \brief Perform GW band structure calculation
98 : !> \param qs_env ...
99 : !> \param bs_env ...
100 : !> \par History
101 : !> * 07.2023 created [Jan Wilhelm]
102 : ! **************************************************************************************************
103 16 : SUBROUTINE gw_calc_large_cell_Gamma(qs_env, bs_env)
104 : TYPE(qs_environment_type), POINTER :: qs_env
105 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
106 :
107 : CHARACTER(LEN=*), PARAMETER :: routineN = 'gw_calc_large_cell_Gamma'
108 :
109 : INTEGER :: handle
110 16 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_Sigma_x_Gamma, fm_W_MIC_time
111 16 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_Sigma_c_Gamma_time
112 :
113 16 : CALL timeset(routineN, handle)
114 :
115 : ! G^occ_µλ(i|τ|,k=0) = sum_n^occ C_µn(k=0) e^(-|(ϵ_nk=0-ϵ_F)τ|) C_λn(k=0)
116 : ! G^vir_µλ(i|τ|,k=0) = sum_n^vir C_µn(k=0) e^(-|(ϵ_nk=0-ϵ_F)τ|) C_λn(k=0)
117 : ! χ_PQ(iτ,k=0) = sum_λν [sum_µ (µν|P) G^occ_µλ(i|τ|)] [sum_σ (σλ|Q) G^vir_σν(i|τ|)]
118 16 : CALL get_mat_chi_Gamma_tau(bs_env, qs_env, bs_env%mat_chi_Gamma_tau)
119 :
120 : ! χ_PQ(iτ,k=0) -> χ_PQ(iω,k) -> ε_PQ(iω,k) -> W_PQ(iω,k) -> W^MIC_PQ(iτ) -> M^-1*W^MIC*M^-1
121 16 : CALL get_W_MIC(bs_env, qs_env, bs_env%mat_chi_Gamma_tau, fm_W_MIC_time)
122 :
123 : ! 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>
124 : ! Σ^x_λσ(k=0) = sum_νQ [sum_P (νσ|P) V^trunc_PQ] [sum_µ (λµ|Q) D_µν)]
125 16 : CALL get_Sigma_x(bs_env, qs_env, fm_Sigma_x_Gamma)
126 :
127 : ! Σ^c_λσ(iτ,k=0) = sum_νQ [sum_P (νσ|P) W^MIC_PQ(iτ)] [sum_µ (λµ|Q) G^occ_µν(i|τ|)], τ < 0
128 : ! Σ^c_λσ(iτ,k=0) = sum_νQ [sum_P (νσ|P) W^MIC_PQ(iτ)] [sum_µ (λµ|Q) G^vir_µν(i|τ|)], τ > 0
129 16 : CALL get_Sigma_c(bs_env, qs_env, fm_W_MIC_time, fm_Sigma_c_Gamma_time)
130 :
131 : ! Σ^c_λσ(iτ,k=0) -> Σ^c_nn(ϵ,k); ϵ_nk^GW = ϵ_nk^DFT + Σ^c_nn(ϵ,k) + Σ^x_nn(k) - v^xc_nn(k)
132 16 : CALL compute_QP_energies(bs_env, qs_env, fm_Sigma_x_Gamma, fm_Sigma_c_Gamma_time)
133 :
134 16 : CALL de_init_bs_env(bs_env)
135 :
136 16 : CALL timestop(handle)
137 :
138 16 : END SUBROUTINE gw_calc_large_cell_Gamma
139 :
140 : ! **************************************************************************************************
141 : !> \brief ...
142 : !> \param bs_env ...
143 : !> \param qs_env ...
144 : !> \param mat_chi_Gamma_tau ...
145 : ! **************************************************************************************************
146 16 : SUBROUTINE get_mat_chi_Gamma_tau(bs_env, qs_env, mat_chi_Gamma_tau)
147 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
148 : TYPE(qs_environment_type), POINTER :: qs_env
149 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_Gamma_tau
150 :
151 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_mat_chi_Gamma_tau'
152 :
153 : INTEGER :: handle, i_intval_idx, i_t, inner_loop_atoms_interval_index, ispin, j_intval_idx
154 : INTEGER, DIMENSION(2) :: i_atoms, IL_atoms, j_atoms
155 : LOGICAL :: dist_too_long_i, dist_too_long_j
156 : REAL(KIND=dp) :: t1, tau
157 400 : TYPE(dbt_type) :: t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, &
158 272 : t_3c_for_Gvir, t_3c_x_Gocc, &
159 272 : t_3c_x_Gocc_2, t_3c_x_Gvir, &
160 144 : t_3c_x_Gvir_2
161 :
162 16 : CALL timeset(routineN, handle)
163 :
164 160 : DO i_t = 1, bs_env%num_time_freq_points
165 :
166 144 : t1 = m_walltime()
167 :
168 144 : IF (bs_env%read_chi(i_t)) THEN
169 :
170 0 : CALL fm_read(bs_env%fm_RI_RI, bs_env, bs_env%chi_name, i_t)
171 :
172 : CALL copy_fm_to_dbcsr(bs_env%fm_RI_RI, mat_chi_Gamma_tau(i_t)%matrix, &
173 0 : keep_sparsity=.FALSE.)
174 :
175 0 : IF (bs_env%unit_nr > 0) THEN
176 : WRITE (bs_env%unit_nr, '(T2,A,I5,A,I3,A,F7.1,A)') &
177 0 : 'Read χ(iτ,k=0) from file for time point ', i_t, ' /', &
178 0 : bs_env%num_time_freq_points, &
179 0 : ', Execution time', m_walltime() - t1, ' s'
180 : END IF
181 :
182 : CYCLE
183 :
184 : END IF
185 :
186 144 : IF (.NOT. bs_env%calc_chi(i_t)) CYCLE
187 :
188 : CALL create_tensors_chi(t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, t_3c_for_Gvir, &
189 84 : t_3c_x_Gocc, t_3c_x_Gvir, t_3c_x_Gocc_2, t_3c_x_Gvir_2, bs_env)
190 :
191 : ! 1. compute G^occ and G^vir
192 : ! Background: G^σ(iτ) = G^occ,σ(iτ) * Θ(-τ) + G^vir,σ(iτ) * Θ(τ), σ ∈ {↑,↓}
193 : ! G^occ,σ_µλ(i|τ|,k=0) = sum_n^occ C^σ_µn(k=0) e^(-|(ϵ^σ_nk=0-ϵ_F)τ|) C^σ_λn(k=0)
194 : ! G^vir,σ_µλ(i|τ|,k=0) = sum_n^vir C^σ_µn(k=0) e^(-|(ϵ^σ_nk=0-ϵ_F)τ|) C^σ_λn(k=0)
195 84 : tau = bs_env%imag_time_points(i_t)
196 :
197 188 : DO ispin = 1, bs_env%n_spin
198 104 : CALL G_occ_vir(bs_env, tau, bs_env%fm_Gocc, ispin, occ=.TRUE., vir=.FALSE.)
199 104 : CALL G_occ_vir(bs_env, tau, bs_env%fm_Gvir, ispin, occ=.FALSE., vir=.TRUE.)
200 :
201 : CALL fm_to_local_tensor(bs_env%fm_Gocc, bs_env%mat_ao_ao%matrix, &
202 : bs_env%mat_ao_ao_tensor%matrix, t_2c_Gocc, bs_env, &
203 104 : bs_env%atoms_j_t_group)
204 : CALL fm_to_local_tensor(bs_env%fm_Gvir, bs_env%mat_ao_ao%matrix, &
205 : bs_env%mat_ao_ao_tensor%matrix, t_2c_Gvir, bs_env, &
206 104 : bs_env%atoms_i_t_group)
207 :
208 : ! every group has its own range of i_atoms and j_atoms; only deal with a
209 : ! limited number of i_atom-j_atom pairs simultaneously in a group to save memory
210 292 : DO i_intval_idx = 1, bs_env%n_intervals_i
211 312 : DO j_intval_idx = 1, bs_env%n_intervals_j
212 312 : i_atoms = bs_env%i_atom_intervals(1:2, i_intval_idx)
213 312 : j_atoms = bs_env%j_atom_intervals(1:2, j_intval_idx)
214 :
215 208 : DO inner_loop_atoms_interval_index = 1, bs_env%n_intervals_inner_loop_atoms
216 :
217 312 : IL_atoms = bs_env%inner_loop_atom_intervals(1:2, inner_loop_atoms_interval_index)
218 :
219 104 : CALL check_dist(i_atoms, IL_atoms, qs_env, bs_env, dist_too_long_i)
220 104 : CALL check_dist(j_atoms, IL_atoms, qs_env, bs_env, dist_too_long_j)
221 104 : IF (dist_too_long_i .OR. dist_too_long_j) CYCLE
222 :
223 : ! 2. compute 3-center integrals (µν|P) ("|": truncated Coulomb operator)
224 104 : CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_Gocc, i_atoms, IL_atoms)
225 :
226 : ! 3. tensor operation M_λνP(iτ) = sum_µ (µν|P) G^occ_µλ(i|τ|,k=0)
227 : CALL G_times_3c(t_3c_for_Gocc, t_2c_Gocc, t_3c_x_Gocc, bs_env, &
228 104 : j_atoms, i_atoms, IL_atoms)
229 :
230 : ! 4. compute 3-center integrals (σλ|Q) ("|": truncated Coulomb operator)
231 104 : CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_Gvir, j_atoms, IL_atoms)
232 :
233 : ! 5. tensor operation N_νλQ(iτ) = sum_σ (σλ|Q) G^vir_σν(i|τ|,k=0)
234 : CALL G_times_3c(t_3c_for_Gvir, t_2c_Gvir, t_3c_x_Gvir, bs_env, &
235 208 : i_atoms, j_atoms, IL_atoms)
236 :
237 : END DO ! IL_atoms
238 :
239 : ! 6. reorder tensors
240 104 : CALL dbt_copy(t_3c_x_Gocc, t_3c_x_Gocc_2, move_data=.TRUE., order=[1, 3, 2])
241 104 : CALL dbt_copy(t_3c_x_Gvir, t_3c_x_Gvir_2, move_data=.TRUE.)
242 :
243 : ! 7. tensor operation χ_PQ(iτ,k=0) = sum_λν M_λνP(iτ) N_νλQ(iτ),
244 : CALL dbt_contract(alpha=bs_env%spin_degeneracy, &
245 : tensor_1=t_3c_x_Gocc_2, tensor_2=t_3c_x_Gvir_2, &
246 : beta=1.0_dp, tensor_3=bs_env%t_chi, &
247 : contract_1=[2, 3], notcontract_1=[1], map_1=[1], &
248 : contract_2=[2, 3], notcontract_2=[1], map_2=[2], &
249 208 : filter_eps=bs_env%eps_filter, move_data=.TRUE.)
250 :
251 : END DO ! j_atoms
252 : END DO ! i_atoms
253 : END DO ! ispin
254 :
255 : ! 8. communicate data of χ_PQ(iτ,k=0) in tensor bs_env%t_chi (which local in the
256 : ! subgroup) to the global dbcsr matrix mat_chi_Gamma_tau (which stores
257 : ! χ_PQ(iτ,k=0) for all time points)
258 : CALL local_dbt_to_global_mat(bs_env%t_chi, bs_env%mat_RI_RI_tensor%matrix, &
259 84 : mat_chi_Gamma_tau(i_t)%matrix, bs_env%para_env)
260 :
261 : CALL write_matrix(mat_chi_Gamma_tau(i_t)%matrix, i_t, bs_env%chi_name, &
262 84 : bs_env%fm_RI_RI, qs_env)
263 :
264 : CALL destroy_tensors_chi(t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, t_3c_for_Gvir, &
265 84 : t_3c_x_Gocc, t_3c_x_Gvir, t_3c_x_Gocc_2, t_3c_x_Gvir_2)
266 :
267 100 : IF (bs_env%unit_nr > 0) THEN
268 : WRITE (bs_env%unit_nr, '(T2,A,I13,A,I3,A,F7.1,A)') &
269 42 : 'Computed χ(iτ,k=0) for time point', i_t, ' /', bs_env%num_time_freq_points, &
270 84 : ', Execution time', m_walltime() - t1, ' s'
271 : END IF
272 :
273 : END DO ! i_t
274 :
275 16 : IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
276 :
277 16 : CALL timestop(handle)
278 :
279 16 : END SUBROUTINE get_mat_chi_Gamma_tau
280 :
281 : ! **************************************************************************************************
282 : !> \brief ...
283 : !> \param fm ...
284 : !> \param bs_env ...
285 : !> \param mat_name ...
286 : !> \param idx ...
287 : ! **************************************************************************************************
288 312 : SUBROUTINE fm_read(fm, bs_env, mat_name, idx)
289 : TYPE(cp_fm_type) :: fm
290 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
291 : CHARACTER(LEN=*) :: mat_name
292 : INTEGER :: idx
293 :
294 : CHARACTER(LEN=*), PARAMETER :: routineN = 'fm_read'
295 :
296 : CHARACTER(LEN=default_string_length) :: f_chi
297 : INTEGER :: handle, unit_nr
298 :
299 312 : CALL timeset(routineN, handle)
300 :
301 312 : unit_nr = -1
302 312 : IF (bs_env%para_env%is_source()) THEN
303 :
304 156 : IF (idx < 10) THEN
305 87 : WRITE (f_chi, '(3A,I1,A)') TRIM(bs_env%prefix), TRIM(mat_name), "_0", idx, ".matrix"
306 69 : ELSE IF (idx < 100) THEN
307 69 : WRITE (f_chi, '(3A,I2,A)') TRIM(bs_env%prefix), TRIM(mat_name), "_", idx, ".matrix"
308 : ELSE
309 0 : CPABORT('Please implement more than 99 time/frequency points.')
310 : END IF
311 :
312 : CALL open_file(file_name=TRIM(f_chi), file_action="READ", file_form="UNFORMATTED", &
313 156 : file_position="REWIND", file_status="OLD", unit_number=unit_nr)
314 :
315 : END IF
316 :
317 312 : CALL cp_fm_read_unformatted(fm, unit_nr)
318 :
319 312 : IF (bs_env%para_env%is_source()) CALL close_file(unit_number=unit_nr)
320 :
321 312 : CALL timestop(handle)
322 :
323 312 : END SUBROUTINE fm_read
324 :
325 : ! **************************************************************************************************
326 : !> \brief ...
327 : !> \param t_2c_Gocc ...
328 : !> \param t_2c_Gvir ...
329 : !> \param t_3c_for_Gocc ...
330 : !> \param t_3c_for_Gvir ...
331 : !> \param t_3c_x_Gocc ...
332 : !> \param t_3c_x_Gvir ...
333 : !> \param t_3c_x_Gocc_2 ...
334 : !> \param t_3c_x_Gvir_2 ...
335 : !> \param bs_env ...
336 : ! **************************************************************************************************
337 84 : SUBROUTINE create_tensors_chi(t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, t_3c_for_Gvir, &
338 : t_3c_x_Gocc, t_3c_x_Gvir, t_3c_x_Gocc_2, t_3c_x_Gvir_2, bs_env)
339 :
340 : TYPE(dbt_type) :: t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, &
341 : t_3c_for_Gvir, t_3c_x_Gocc, &
342 : t_3c_x_Gvir, t_3c_x_Gocc_2, &
343 : t_3c_x_Gvir_2
344 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
345 :
346 : CHARACTER(LEN=*), PARAMETER :: routineN = 'create_tensors_chi'
347 :
348 : INTEGER :: handle
349 :
350 84 : CALL timeset(routineN, handle)
351 :
352 84 : CALL dbt_create(bs_env%t_G, t_2c_Gocc)
353 84 : CALL dbt_create(bs_env%t_G, t_2c_Gvir)
354 84 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_for_Gocc)
355 84 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_for_Gvir)
356 84 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_Gocc)
357 84 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_Gvir)
358 84 : CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_x_Gocc_2)
359 84 : CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_x_Gvir_2)
360 :
361 84 : CALL timestop(handle)
362 :
363 84 : END SUBROUTINE create_tensors_chi
364 :
365 : ! **************************************************************************************************
366 : !> \brief ...
367 : !> \param t_2c_Gocc ...
368 : !> \param t_2c_Gvir ...
369 : !> \param t_3c_for_Gocc ...
370 : !> \param t_3c_for_Gvir ...
371 : !> \param t_3c_x_Gocc ...
372 : !> \param t_3c_x_Gvir ...
373 : !> \param t_3c_x_Gocc_2 ...
374 : !> \param t_3c_x_Gvir_2 ...
375 : ! **************************************************************************************************
376 84 : SUBROUTINE destroy_tensors_chi(t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, t_3c_for_Gvir, &
377 : t_3c_x_Gocc, t_3c_x_Gvir, t_3c_x_Gocc_2, t_3c_x_Gvir_2)
378 : TYPE(dbt_type) :: t_2c_Gocc, t_2c_Gvir, t_3c_for_Gocc, &
379 : t_3c_for_Gvir, t_3c_x_Gocc, &
380 : t_3c_x_Gvir, t_3c_x_Gocc_2, &
381 : t_3c_x_Gvir_2
382 :
383 : CHARACTER(LEN=*), PARAMETER :: routineN = 'destroy_tensors_chi'
384 :
385 : INTEGER :: handle
386 :
387 84 : CALL timeset(routineN, handle)
388 :
389 84 : CALL dbt_destroy(t_2c_Gocc)
390 84 : CALL dbt_destroy(t_2c_Gvir)
391 84 : CALL dbt_destroy(t_3c_for_Gocc)
392 84 : CALL dbt_destroy(t_3c_for_Gvir)
393 84 : CALL dbt_destroy(t_3c_x_Gocc)
394 84 : CALL dbt_destroy(t_3c_x_Gvir)
395 84 : CALL dbt_destroy(t_3c_x_Gocc_2)
396 84 : CALL dbt_destroy(t_3c_x_Gvir_2)
397 :
398 84 : CALL timestop(handle)
399 :
400 84 : END SUBROUTINE destroy_tensors_chi
401 :
402 : ! **************************************************************************************************
403 : !> \brief ...
404 : !> \param matrix ...
405 : !> \param matrix_index ...
406 : !> \param matrix_name ...
407 : !> \param fm ...
408 : !> \param qs_env ...
409 : ! **************************************************************************************************
410 304 : SUBROUTINE write_matrix(matrix, matrix_index, matrix_name, fm, qs_env)
411 : TYPE(dbcsr_type) :: matrix
412 : INTEGER :: matrix_index
413 : CHARACTER(LEN=*) :: matrix_name
414 : TYPE(cp_fm_type), INTENT(IN), POINTER :: fm
415 : TYPE(qs_environment_type), POINTER :: qs_env
416 :
417 : CHARACTER(LEN=*), PARAMETER :: routineN = 'write_matrix'
418 :
419 : INTEGER :: handle
420 :
421 304 : CALL timeset(routineN, handle)
422 :
423 304 : CALL cp_fm_set_all(fm, 0.0_dp)
424 :
425 304 : CALL copy_dbcsr_to_fm(matrix, fm)
426 :
427 304 : CALL fm_write(fm, matrix_index, matrix_name, qs_env)
428 :
429 304 : CALL timestop(handle)
430 :
431 304 : END SUBROUTINE write_matrix
432 :
433 : ! **************************************************************************************************
434 : !> \brief ...
435 : !> \param fm ...
436 : !> \param matrix_index ...
437 : !> \param matrix_name ...
438 : !> \param qs_env ...
439 : ! **************************************************************************************************
440 388 : SUBROUTINE fm_write(fm, matrix_index, matrix_name, qs_env)
441 : TYPE(cp_fm_type) :: fm
442 : INTEGER :: matrix_index
443 : CHARACTER(LEN=*) :: matrix_name
444 : TYPE(qs_environment_type), POINTER :: qs_env
445 :
446 : CHARACTER(LEN=*), PARAMETER :: key = 'PROPERTIES%BANDSTRUCTURE%GW%PRINT%RESTART', &
447 : routineN = 'fm_write'
448 :
449 : CHARACTER(LEN=default_string_length) :: filename
450 : INTEGER :: handle, unit_nr
451 : TYPE(cp_logger_type), POINTER :: logger
452 : TYPE(section_vals_type), POINTER :: input
453 :
454 388 : CALL timeset(routineN, handle)
455 :
456 388 : CALL get_qs_env(qs_env, input=input)
457 :
458 388 : logger => cp_get_default_logger()
459 :
460 388 : IF (BTEST(cp_print_key_should_output(logger%iter_info, input, key), cp_p_file)) THEN
461 :
462 124 : IF (matrix_index < 10) THEN
463 76 : WRITE (filename, '(3A,I1)') "RESTART_", matrix_name, "_0", matrix_index
464 48 : ELSE IF (matrix_index < 100) THEN
465 48 : WRITE (filename, '(3A,I2)') "RESTART_", matrix_name, "_", matrix_index
466 : ELSE
467 0 : CPABORT('Please implement more than 99 time/frequency points.')
468 : END IF
469 :
470 : unit_nr = cp_print_key_unit_nr(logger, input, key, extension=".matrix", &
471 : file_form="UNFORMATTED", middle_name=TRIM(filename), &
472 124 : file_position="REWIND", file_action="WRITE")
473 :
474 124 : CALL cp_fm_write_unformatted(fm, unit_nr)
475 124 : IF (unit_nr > 0) THEN
476 62 : CALL close_file(unit_nr)
477 : END IF
478 : END IF
479 :
480 388 : CALL timestop(handle)
481 :
482 388 : END SUBROUTINE fm_write
483 :
484 : ! **************************************************************************************************
485 : !> \brief ...
486 : !> \param bs_env ...
487 : !> \param tau ...
488 : !> \param fm_G_Gamma ...
489 : !> \param ispin ...
490 : !> \param occ ...
491 : !> \param vir ...
492 : ! **************************************************************************************************
493 856 : SUBROUTINE G_occ_vir(bs_env, tau, fm_G_Gamma, ispin, occ, vir)
494 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
495 : REAL(KIND=dp) :: tau
496 : TYPE(cp_fm_type) :: fm_G_Gamma
497 : INTEGER :: ispin
498 : LOGICAL :: occ, vir
499 :
500 : CHARACTER(LEN=*), PARAMETER :: routineN = 'G_occ_vir'
501 :
502 : INTEGER :: handle, homo, i_row_local, j_col, &
503 : j_col_local, n_mo, ncol_local, &
504 : nrow_local
505 428 : INTEGER, DIMENSION(:), POINTER :: col_indices
506 : REAL(KIND=dp) :: tau_E
507 :
508 428 : CALL timeset(routineN, handle)
509 :
510 428 : CPASSERT(occ .NEQV. vir)
511 :
512 : CALL cp_fm_get_info(matrix=bs_env%fm_work_mo(1), &
513 : nrow_local=nrow_local, &
514 : ncol_local=ncol_local, &
515 428 : col_indices=col_indices)
516 :
517 428 : n_mo = bs_env%n_ao
518 428 : homo = bs_env%n_occ(ispin)
519 :
520 428 : CALL cp_fm_to_fm(bs_env%fm_mo_coeff_Gamma(ispin), bs_env%fm_work_mo(1))
521 :
522 3054 : DO i_row_local = 1, nrow_local
523 42788 : DO j_col_local = 1, ncol_local
524 :
525 39734 : j_col = col_indices(j_col_local)
526 :
527 39734 : tau_E = ABS(tau*0.5_dp*(bs_env%eigenval_scf_Gamma(j_col, ispin) - bs_env%e_fermi(ispin)))
528 :
529 39734 : IF (tau_E < bs_env%stabilize_exp) THEN
530 : bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local) = &
531 38942 : bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local)*EXP(-tau_E)
532 : ELSE
533 792 : bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local) = 0.0_dp
534 : END IF
535 :
536 42360 : IF ((occ .AND. j_col > homo) .OR. (vir .AND. j_col <= homo)) THEN
537 20239 : bs_env%fm_work_mo(1)%local_data(i_row_local, j_col_local) = 0.0_dp
538 : END IF
539 :
540 : END DO
541 : END DO
542 :
543 : CALL parallel_gemm(transa="N", transb="T", m=n_mo, n=n_mo, k=n_mo, alpha=1.0_dp, &
544 : matrix_a=bs_env%fm_work_mo(1), matrix_b=bs_env%fm_work_mo(1), &
545 428 : beta=0.0_dp, matrix_c=fm_G_Gamma)
546 :
547 428 : CALL timestop(handle)
548 :
549 428 : END SUBROUTINE G_occ_vir
550 :
551 : ! **************************************************************************************************
552 : !> \brief ...
553 : !> \param qs_env ...
554 : !> \param bs_env ...
555 : !> \param t_3c ...
556 : !> \param atoms_AO_1 ...
557 : !> \param atoms_AO_2 ...
558 : !> \param atoms_RI ...
559 : ! **************************************************************************************************
560 490 : SUBROUTINE compute_3c_integrals(qs_env, bs_env, t_3c, atoms_AO_1, atoms_AO_2, atoms_RI)
561 : TYPE(qs_environment_type), POINTER :: qs_env
562 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
563 : TYPE(dbt_type) :: t_3c
564 : INTEGER, DIMENSION(2), OPTIONAL :: atoms_AO_1, atoms_AO_2, atoms_RI
565 :
566 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_3c_integrals'
567 :
568 : INTEGER :: handle
569 : INTEGER, DIMENSION(2) :: my_atoms_AO_1, my_atoms_AO_2, my_atoms_RI
570 490 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_array
571 :
572 490 : CALL timeset(routineN, handle)
573 :
574 : ! free memory (not clear whether memory has been freed previously)
575 490 : CALL dbt_clear(t_3c)
576 :
577 5390 : ALLOCATE (t_3c_array(1, 1))
578 490 : CALL dbt_create(t_3c, t_3c_array(1, 1))
579 :
580 490 : IF (PRESENT(atoms_AO_1)) THEN
581 : my_atoms_AO_1 = atoms_AO_1
582 : ELSE
583 552 : my_atoms_AO_1 = [1, bs_env%n_atom]
584 : END IF
585 490 : IF (PRESENT(atoms_AO_2)) THEN
586 : my_atoms_AO_2 = atoms_AO_2
587 : ELSE
588 294 : my_atoms_AO_2 = [1, bs_env%n_atom]
589 : END IF
590 490 : IF (PRESENT(atoms_RI)) THEN
591 : my_atoms_RI = atoms_RI
592 : ELSE
593 624 : my_atoms_RI = [1, bs_env%n_atom]
594 : END IF
595 :
596 : CALL build_3c_integrals(t_3c_array, &
597 : bs_env%eps_filter, &
598 : qs_env, &
599 : bs_env%nl_3c, &
600 : int_eps=bs_env%eps_filter, &
601 : basis_i=bs_env%basis_set_RI, &
602 : basis_j=bs_env%basis_set_AO, &
603 : basis_k=bs_env%basis_set_AO, &
604 : potential_parameter=bs_env%ri_metric, &
605 : bounds_i=atoms_RI, &
606 : bounds_j=atoms_AO_1, &
607 : bounds_k=atoms_AO_2, &
608 490 : desymmetrize=.FALSE.)
609 :
610 490 : CALL dbt_copy(t_3c_array(1, 1), t_3c, move_data=.TRUE.)
611 :
612 490 : CALL dbt_destroy(t_3c_array(1, 1))
613 980 : DEALLOCATE (t_3c_array)
614 :
615 490 : CALL timestop(handle)
616 :
617 980 : END SUBROUTINE compute_3c_integrals
618 :
619 : ! **************************************************************************************************
620 : !> \brief ...
621 : !> \param t_3c_for_G ...
622 : !> \param t_G ...
623 : !> \param t_M ...
624 : !> \param bs_env ...
625 : !> \param atoms_AO_1 ...
626 : !> \param atoms_AO_2 ...
627 : !> \param atoms_IL ...
628 : ! **************************************************************************************************
629 208 : SUBROUTINE G_times_3c(t_3c_for_G, t_G, t_M, bs_env, atoms_AO_1, atoms_AO_2, atoms_IL)
630 : TYPE(dbt_type) :: t_3c_for_G, t_G, t_M
631 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
632 : INTEGER, DIMENSION(2) :: atoms_AO_1, atoms_AO_2, atoms_IL
633 :
634 : CHARACTER(LEN=*), PARAMETER :: routineN = 'G_times_3c'
635 :
636 : INTEGER :: handle
637 : INTEGER, DIMENSION(2) :: bounds_IL, bounds_l
638 : INTEGER, DIMENSION(2, 2) :: bounds_k
639 :
640 208 : CALL timeset(routineN, handle)
641 :
642 : ! JW bounds_IL and bounds_k do not safe any operations, but maybe communication
643 : ! maybe remove "bounds_1=bounds_IL, &" and "bounds_2=bounds_k, &" later and
644 : ! check whether performance improves
645 :
646 : bounds_IL(1:2) = [bs_env%i_ao_start_from_atom(atoms_IL(1)), &
647 624 : bs_env%i_ao_end_from_atom(atoms_IL(2))]
648 624 : bounds_k(1:2, 1) = [1, bs_env%n_RI]
649 : bounds_k(1:2, 2) = [bs_env%i_ao_start_from_atom(atoms_AO_2(1)), &
650 624 : bs_env%i_ao_end_from_atom(atoms_AO_2(2))]
651 : bounds_l(1:2) = [bs_env%i_ao_start_from_atom(atoms_AO_1(1)), &
652 624 : bs_env%i_ao_end_from_atom(atoms_AO_1(2))]
653 :
654 : CALL dbt_contract(alpha=1.0_dp, &
655 : tensor_1=t_3c_for_G, &
656 : tensor_2=t_G, &
657 : beta=1.0_dp, &
658 : tensor_3=t_M, &
659 : contract_1=[3], notcontract_1=[1, 2], map_1=[1, 2], &
660 : contract_2=[2], notcontract_2=[1], map_2=[3], &
661 : bounds_1=bounds_IL, &
662 : bounds_2=bounds_k, &
663 : bounds_3=bounds_l, &
664 208 : filter_eps=bs_env%eps_filter)
665 :
666 208 : CALL dbt_clear(t_3c_for_G)
667 :
668 208 : CALL timestop(handle)
669 :
670 208 : END SUBROUTINE G_times_3c
671 :
672 : ! **************************************************************************************************
673 : !> \brief ...
674 : !> \param atoms_1 ...
675 : !> \param atoms_2 ...
676 : !> \param qs_env ...
677 : !> \param bs_env ...
678 : !> \param dist_too_long ...
679 : ! **************************************************************************************************
680 208 : SUBROUTINE check_dist(atoms_1, atoms_2, qs_env, bs_env, dist_too_long)
681 : INTEGER, DIMENSION(2) :: atoms_1, atoms_2
682 : TYPE(qs_environment_type), POINTER :: qs_env
683 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
684 : LOGICAL :: dist_too_long
685 :
686 : CHARACTER(LEN=*), PARAMETER :: routineN = 'check_dist'
687 :
688 : INTEGER :: atom_1, atom_2, handle
689 : REAL(dp) :: abs_rab, min_dist_AO_atoms
690 : REAL(KIND=dp), DIMENSION(3) :: rab
691 : TYPE(cell_type), POINTER :: cell
692 208 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
693 :
694 208 : CALL timeset(routineN, handle)
695 :
696 208 : CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
697 :
698 208 : min_dist_AO_atoms = 1.0E5_dp
699 672 : DO atom_1 = atoms_1(1), atoms_1(2)
700 1744 : DO atom_2 = atoms_2(1), atoms_2(2)
701 :
702 1072 : rab = pbc(particle_set(atom_1)%r(1:3), particle_set(atom_2)%r(1:3), cell)
703 :
704 1072 : abs_rab = SQRT(rab(1)**2 + rab(2)**2 + rab(3)**2)
705 :
706 1536 : min_dist_AO_atoms = MIN(min_dist_AO_atoms, abs_rab)
707 :
708 : END DO
709 : END DO
710 :
711 208 : dist_too_long = (min_dist_AO_atoms > bs_env%max_dist_AO_atoms)
712 :
713 208 : CALL timestop(handle)
714 :
715 208 : END SUBROUTINE check_dist
716 :
717 : ! **************************************************************************************************
718 : !> \brief ...
719 : !> \param bs_env ...
720 : !> \param qs_env ...
721 : !> \param mat_chi_Gamma_tau ...
722 : !> \param fm_W_MIC_time ...
723 : ! **************************************************************************************************
724 16 : SUBROUTINE get_W_MIC(bs_env, qs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
725 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
726 : TYPE(qs_environment_type), POINTER :: qs_env
727 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_Gamma_tau
728 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
729 :
730 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_W_MIC'
731 :
732 : INTEGER :: handle
733 :
734 16 : CALL timeset(routineN, handle)
735 :
736 16 : IF (bs_env%all_W_exist) THEN
737 6 : CALL read_W_MIC_time(bs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
738 : ELSE
739 10 : CALL compute_W_MIC(bs_env, qs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
740 : END IF
741 :
742 16 : CALL timestop(handle)
743 :
744 16 : END SUBROUTINE get_W_MIC
745 :
746 : ! **************************************************************************************************
747 : !> \brief ...
748 : !> \param bs_env ...
749 : !> \param qs_env ...
750 : !> \param fm_V_kp ...
751 : !> \param ikp_batch ...
752 : ! **************************************************************************************************
753 70 : SUBROUTINE compute_V_k_by_lattice_sum(bs_env, qs_env, fm_V_kp, ikp_batch)
754 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
755 : TYPE(qs_environment_type), POINTER :: qs_env
756 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_V_kp
757 : INTEGER :: ikp_batch
758 :
759 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_V_k_by_lattice_sum'
760 :
761 : INTEGER :: handle, ikp, ikp_end, ikp_start, &
762 : nkp_chi_eps_W_batch, re_im
763 70 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
764 : TYPE(cell_type), POINTER :: cell
765 70 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_V_kp
766 70 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
767 70 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
768 :
769 70 : CALL timeset(routineN, handle)
770 :
771 70 : nkp_chi_eps_W_batch = bs_env%nkp_chi_eps_W_batch
772 :
773 70 : ikp_start = (ikp_batch - 1)*bs_env%nkp_chi_eps_W_batch + 1
774 70 : ikp_end = MIN(ikp_batch*bs_env%nkp_chi_eps_W_batch, bs_env%kpoints_chi_eps_W%nkp)
775 :
776 70 : NULLIFY (mat_V_kp)
777 940 : ALLOCATE (mat_V_kp(ikp_start:ikp_end, 2))
778 :
779 330 : DO ikp = ikp_start, ikp_end
780 850 : DO re_im = 1, 2
781 520 : NULLIFY (mat_V_kp(ikp, re_im)%matrix)
782 520 : ALLOCATE (mat_V_kp(ikp, re_im)%matrix)
783 520 : CALL dbcsr_create(mat_V_kp(ikp, re_im)%matrix, template=bs_env%mat_RI_RI%matrix)
784 520 : CALL dbcsr_reserve_all_blocks(mat_V_kp(ikp, re_im)%matrix)
785 780 : CALL dbcsr_set(mat_V_kp(ikp, re_im)%matrix, 0.0_dp)
786 :
787 : END DO ! re_im
788 : END DO ! ikp
789 :
790 : CALL get_qs_env(qs_env=qs_env, &
791 : particle_set=particle_set, &
792 : cell=cell, &
793 : qs_kind_set=qs_kind_set, &
794 70 : atomic_kind_set=atomic_kind_set)
795 :
796 70 : IF (ikp_end .LE. bs_env%nkp_chi_eps_W_orig) THEN
797 :
798 : ! 1. 2c Coulomb integrals for the first "original" k-point grid
799 80 : bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_orig
800 :
801 50 : ELSE IF (ikp_start > bs_env%nkp_chi_eps_W_orig .AND. &
802 : ikp_end .LE. bs_env%nkp_chi_eps_W_orig_plus_extra) THEN
803 :
804 : ! 2. 2c Coulomb integrals for the second "extrapolation" k-point grid
805 200 : bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_extra
806 :
807 : ELSE
808 :
809 0 : CPABORT("Error with k-point parallelization.")
810 :
811 : END IF
812 :
813 : CALL build_2c_coulomb_matrix_kp(mat_V_kp, &
814 : bs_env%kpoints_chi_eps_W, &
815 : basis_type="RI_AUX", &
816 : cell=cell, &
817 : particle_set=particle_set, &
818 : qs_kind_set=qs_kind_set, &
819 : atomic_kind_set=atomic_kind_set, &
820 : size_lattice_sum=bs_env%size_lattice_sum_V, &
821 : operator_type=operator_coulomb, &
822 : ikp_start=ikp_start, &
823 70 : ikp_end=ikp_end)
824 :
825 280 : bs_env%kpoints_chi_eps_W%nkp_grid = bs_env%nkp_grid_chi_eps_W_orig
826 :
827 940 : ALLOCATE (fm_V_kp(ikp_start:ikp_end, 2))
828 330 : DO ikp = ikp_start, ikp_end
829 850 : DO re_im = 1, 2
830 520 : CALL cp_fm_create(fm_V_kp(ikp, re_im), bs_env%fm_RI_RI%matrix_struct)
831 520 : CALL copy_dbcsr_to_fm(mat_V_kp(ikp, re_im)%matrix, fm_V_kp(ikp, re_im))
832 780 : CALL dbcsr_deallocate_matrix(mat_V_kp(ikp, re_im)%matrix)
833 : END DO
834 : END DO
835 70 : DEALLOCATE (mat_V_kp)
836 :
837 70 : CALL timestop(handle)
838 :
839 70 : END SUBROUTINE compute_V_k_by_lattice_sum
840 :
841 : ! **************************************************************************************************
842 : !> \brief ...
843 : !> \param bs_env ...
844 : !> \param qs_env ...
845 : !> \param fm_V_kp ...
846 : !> \param cfm_V_sqrt_ikp ...
847 : !> \param cfm_M_inv_V_sqrt_ikp ...
848 : !> \param ikp ...
849 : ! **************************************************************************************************
850 260 : SUBROUTINE compute_MinvVsqrt_Vsqrt(bs_env, qs_env, fm_V_kp, cfm_V_sqrt_ikp, &
851 : cfm_M_inv_V_sqrt_ikp, ikp)
852 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
853 : TYPE(qs_environment_type), POINTER :: qs_env
854 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_V_kp
855 : TYPE(cp_cfm_type) :: cfm_V_sqrt_ikp, cfm_M_inv_V_sqrt_ikp
856 : INTEGER :: ikp
857 :
858 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_MinvVsqrt_Vsqrt'
859 :
860 : INTEGER :: handle, info, n_RI
861 : TYPE(cp_cfm_type) :: cfm_M_inv_ikp, cfm_work
862 260 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_M_ikp
863 :
864 260 : CALL timeset(routineN, handle)
865 :
866 260 : n_RI = bs_env%n_RI
867 :
868 : ! get here M(k) and write it to fm_M_ikp
869 : CALL RI_2c_integral_mat(qs_env, fm_M_ikp, fm_V_kp(ikp, 1), &
870 : n_RI, bs_env%ri_metric, do_kpoints=.TRUE., &
871 : kpoints=bs_env%kpoints_chi_eps_W, &
872 : regularization_RI=bs_env%regularization_RI, ikp_ext=ikp, &
873 260 : do_build_cell_index=(ikp == 1))
874 :
875 260 : IF (ikp == 1) THEN
876 10 : CALL cp_cfm_create(cfm_V_sqrt_ikp, fm_V_kp(ikp, 1)%matrix_struct)
877 10 : CALL cp_cfm_create(cfm_M_inv_V_sqrt_ikp, fm_V_kp(ikp, 1)%matrix_struct)
878 : END IF
879 260 : CALL cp_cfm_create(cfm_M_inv_ikp, fm_V_kp(ikp, 1)%matrix_struct)
880 :
881 260 : CALL cp_fm_to_cfm(fm_M_ikp(1, 1), fm_M_ikp(1, 2), cfm_M_inv_ikp)
882 260 : CALL cp_fm_to_cfm(fm_V_kp(ikp, 1), fm_V_kp(ikp, 2), cfm_V_sqrt_ikp)
883 :
884 260 : CALL cp_fm_release(fm_M_ikp)
885 :
886 260 : CALL cp_cfm_create(cfm_work, fm_V_kp(ikp, 1)%matrix_struct)
887 :
888 : ! M(k) -> M^-1(k)
889 260 : CALL cp_cfm_to_cfm(cfm_M_inv_ikp, cfm_work)
890 260 : CALL cp_cfm_cholesky_decompose(matrix=cfm_M_inv_ikp, n=n_RI, info_out=info)
891 260 : IF (info == 0) THEN
892 : ! successful Cholesky decomposition
893 260 : CALL cp_cfm_cholesky_invert(cfm_M_inv_ikp)
894 : ! symmetrize the result
895 260 : CALL cp_cfm_upper_to_full(cfm_M_inv_ikp)
896 : ELSE
897 : ! Cholesky decomposition not successful: use expensive diagonalization
898 0 : CALL cp_cfm_power(cfm_work, threshold=bs_env%eps_eigval_mat_RI, exponent=-1.0_dp)
899 0 : CALL cp_cfm_to_cfm(cfm_work, cfm_M_inv_ikp)
900 : END IF
901 :
902 : ! V(k) -> L(k) with L^H(k)*L(k) = V(k) [L(k) can be just considered to be V^0.5(k)]
903 260 : CALL cp_cfm_to_cfm(cfm_V_sqrt_ikp, cfm_work)
904 260 : CALL cp_cfm_cholesky_decompose(matrix=cfm_V_sqrt_ikp, n=n_RI, info_out=info)
905 260 : IF (info == 0) THEN
906 : ! successful Cholesky decomposition
907 260 : CALL clean_lower_part(cfm_V_sqrt_ikp)
908 : ELSE
909 : ! Cholesky decomposition not successful: use expensive diagonalization
910 0 : CALL cp_cfm_power(cfm_work, threshold=0.0_dp, exponent=0.5_dp)
911 0 : CALL cp_cfm_to_cfm(cfm_work, cfm_V_sqrt_ikp)
912 : END IF
913 260 : CALL cp_cfm_release(cfm_work)
914 :
915 : ! get M^-1(k)*V^0.5(k)
916 : CALL parallel_gemm("N", "C", n_RI, n_RI, n_RI, z_one, cfm_M_inv_ikp, cfm_V_sqrt_ikp, &
917 260 : z_zero, cfm_M_inv_V_sqrt_ikp)
918 :
919 260 : CALL cp_cfm_release(cfm_M_inv_ikp)
920 :
921 260 : CALL timestop(handle)
922 :
923 520 : END SUBROUTINE compute_MinvVsqrt_Vsqrt
924 :
925 : ! **************************************************************************************************
926 : !> \brief ...
927 : !> \param bs_env ...
928 : !> \param mat_chi_Gamma_tau ...
929 : !> \param fm_W_MIC_time ...
930 : ! **************************************************************************************************
931 6 : SUBROUTINE read_W_MIC_time(bs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
932 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
933 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_Gamma_tau
934 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
935 :
936 : CHARACTER(LEN=*), PARAMETER :: routineN = 'read_W_MIC_time'
937 :
938 : INTEGER :: handle, i_t
939 : REAL(KIND=dp) :: t1
940 :
941 6 : CALL timeset(routineN, handle)
942 :
943 6 : CALL dbcsr_deallocate_matrix_set(mat_chi_Gamma_tau)
944 6 : CALL create_fm_W_MIC_time(bs_env, fm_W_MIC_time)
945 :
946 66 : DO i_t = 1, bs_env%num_time_freq_points
947 :
948 60 : t1 = m_walltime()
949 :
950 60 : CALL fm_read(fm_W_MIC_time(i_t), bs_env, bs_env%W_time_name, i_t)
951 :
952 66 : IF (bs_env%unit_nr > 0) THEN
953 : WRITE (bs_env%unit_nr, '(T2,A,I5,A,I3,A,F7.1,A)') &
954 30 : 'Read W^MIC(iτ) from file for time point ', i_t, ' /', bs_env%num_time_freq_points, &
955 60 : ', Execution time', m_walltime() - t1, ' s'
956 : END IF
957 :
958 : END DO
959 :
960 6 : IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
961 :
962 6 : CALL timestop(handle)
963 :
964 6 : END SUBROUTINE read_W_MIC_time
965 :
966 : ! **************************************************************************************************
967 : !> \brief ...
968 : !> \param bs_env ...
969 : !> \param qs_env ...
970 : !> \param mat_chi_Gamma_tau ...
971 : !> \param fm_W_MIC_time ...
972 : ! **************************************************************************************************
973 10 : SUBROUTINE compute_W_MIC(bs_env, qs_env, mat_chi_Gamma_tau, fm_W_MIC_time)
974 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
975 : TYPE(qs_environment_type), POINTER :: qs_env
976 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_Gamma_tau
977 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
978 :
979 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_W_MIC'
980 :
981 : INTEGER :: handle, i_t, ikp, ikp_batch, &
982 : ikp_in_batch, j_w
983 : REAL(KIND=dp) :: t1
984 : TYPE(cp_cfm_type) :: cfm_M_inv_V_sqrt_ikp, cfm_V_sqrt_ikp
985 10 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_V_kp
986 :
987 10 : CALL timeset(routineN, handle)
988 :
989 10 : CALL create_fm_W_MIC_time(bs_env, fm_W_MIC_time)
990 :
991 80 : DO ikp_batch = 1, bs_env%num_chi_eps_W_batches
992 :
993 70 : t1 = m_walltime()
994 :
995 : ! Compute V_PQ(k) = sum_R e^(ikR) <phi_P, cell 0 | 1/r | phi_Q, cell R>
996 70 : CALL compute_V_k_by_lattice_sum(bs_env, qs_env, fm_V_kp, ikp_batch)
997 :
998 350 : DO ikp_in_batch = 1, bs_env%nkp_chi_eps_W_batch
999 :
1000 280 : ikp = (ikp_batch - 1)*bs_env%nkp_chi_eps_W_batch + ikp_in_batch
1001 :
1002 280 : IF (ikp > bs_env%nkp_chi_eps_W_orig_plus_extra) CYCLE
1003 :
1004 : CALL compute_MinvVsqrt_Vsqrt(bs_env, qs_env, fm_V_kp, &
1005 260 : cfm_V_sqrt_ikp, cfm_M_inv_V_sqrt_ikp, ikp)
1006 :
1007 260 : CALL bs_env%para_env%sync()
1008 :
1009 2444 : DO j_w = 1, bs_env%num_time_freq_points
1010 :
1011 : ! check if we need this (ikp, ω_j) combination for approximate k-point extrapolation
1012 2184 : IF (bs_env%approx_kp_extrapol .AND. j_w > 1 .AND. &
1013 : ikp > bs_env%nkp_chi_eps_W_orig) CYCLE
1014 :
1015 : CALL compute_fm_W_MIC_freq_j(bs_env, qs_env, bs_env%fm_W_MIC_freq, j_w, ikp, &
1016 : mat_chi_Gamma_tau, cfm_M_inv_V_sqrt_ikp, &
1017 1860 : cfm_V_sqrt_ikp)
1018 :
1019 : ! Fourier trafo from W_PQ^MIC(iω_j) to W_PQ^MIC(iτ)
1020 2444 : CALL Fourier_transform_w_to_t(bs_env, fm_W_MIC_time, bs_env%fm_W_MIC_freq, j_w)
1021 :
1022 : END DO ! ω_j
1023 :
1024 260 : CALL cp_fm_release(fm_V_kp(ikp, 1))
1025 350 : CALL cp_fm_release(fm_V_kp(ikp, 2))
1026 :
1027 : END DO ! ikp_in_batch
1028 :
1029 70 : DEALLOCATE (fm_V_kp)
1030 :
1031 80 : IF (bs_env%unit_nr > 0) THEN
1032 : WRITE (bs_env%unit_nr, '(T2,A,I12,A,I3,A,F7.1,A)') &
1033 35 : 'Computed W(iτ,k) for k-point batch', &
1034 35 : ikp_batch, ' /', bs_env%num_chi_eps_W_batches, &
1035 70 : ', Execution time', m_walltime() - t1, ' s'
1036 : END IF
1037 :
1038 : END DO ! ikp_batch
1039 :
1040 10 : IF (bs_env%approx_kp_extrapol) THEN
1041 2 : CALL apply_extrapol_factor(bs_env, fm_W_MIC_time)
1042 : END IF
1043 :
1044 : ! M^-1(k=0)*W^MIC(iτ)*M^-1(k=0)
1045 10 : CALL multiply_fm_W_MIC_time_with_Minv_Gamma(bs_env, qs_env, fm_W_MIC_time)
1046 :
1047 94 : DO i_t = 1, bs_env%num_time_freq_points
1048 94 : CALL fm_write(fm_W_MIC_time(i_t), i_t, bs_env%W_time_name, qs_env)
1049 : END DO
1050 :
1051 10 : CALL cp_cfm_release(cfm_M_inv_V_sqrt_ikp)
1052 10 : CALL cp_cfm_release(cfm_V_sqrt_ikp)
1053 10 : CALL dbcsr_deallocate_matrix_set(mat_chi_Gamma_tau)
1054 :
1055 10 : IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
1056 :
1057 10 : CALL timestop(handle)
1058 :
1059 20 : END SUBROUTINE compute_W_MIC
1060 :
1061 : ! **************************************************************************************************
1062 : !> \brief ...
1063 : !> \param bs_env ...
1064 : !> \param qs_env ...
1065 : !> \param fm_W_MIC_freq_j ...
1066 : !> \param j_w ...
1067 : !> \param ikp ...
1068 : !> \param mat_chi_Gamma_tau ...
1069 : !> \param cfm_M_inv_V_sqrt_ikp ...
1070 : !> \param cfm_V_sqrt_ikp ...
1071 : ! **************************************************************************************************
1072 1860 : SUBROUTINE compute_fm_W_MIC_freq_j(bs_env, qs_env, fm_W_MIC_freq_j, j_w, ikp, mat_chi_Gamma_tau, &
1073 : cfm_M_inv_V_sqrt_ikp, cfm_V_sqrt_ikp)
1074 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1075 : TYPE(qs_environment_type), POINTER :: qs_env
1076 : TYPE(cp_fm_type) :: fm_W_MIC_freq_j
1077 : INTEGER :: j_w, ikp
1078 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_Gamma_tau
1079 : TYPE(cp_cfm_type) :: cfm_M_inv_V_sqrt_ikp, cfm_V_sqrt_ikp
1080 :
1081 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_fm_W_MIC_freq_j'
1082 :
1083 : INTEGER :: handle
1084 : TYPE(cp_cfm_type) :: cfm_chi_ikp_freq_j, cfm_W_ikp_freq_j
1085 :
1086 1860 : CALL timeset(routineN, handle)
1087 :
1088 : ! 1. Fourier transformation of χ_PQ(iτ,k=0) to χ_PQ(iω_j,k=0)
1089 1860 : CALL compute_fm_chi_Gamma_freq(bs_env, bs_env%fm_chi_Gamma_freq, j_w, mat_chi_Gamma_tau)
1090 :
1091 1860 : CALL cp_fm_set_all(fm_W_MIC_freq_j, 0.0_dp)
1092 :
1093 : ! 2. Get χ_PQ(iω_j,k_i) from χ_PQ(iω_j,k=0) using the minimum image convention
1094 : CALL cfm_ikp_from_fm_Gamma(cfm_chi_ikp_freq_j, bs_env%fm_chi_Gamma_freq, &
1095 1860 : ikp, qs_env, bs_env%kpoints_chi_eps_W, "RI_AUX")
1096 :
1097 : ! 3. Remove all negative eigenvalues from χ_PQ(iω_j,k_i)
1098 1860 : CALL cp_cfm_power(cfm_chi_ikp_freq_j, threshold=0.0_dp, exponent=1.0_dp)
1099 :
1100 : ! 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)
1101 : ! W(iω_j,k_i) = V^0.5(k_i)*(ε^-1(iω_j,k_i)-Id)*V^0.5(k_i)
1102 : CALL compute_cfm_W_ikp_freq_j(bs_env, cfm_chi_ikp_freq_j, cfm_V_sqrt_ikp, &
1103 1860 : cfm_M_inv_V_sqrt_ikp, cfm_W_ikp_freq_j)
1104 :
1105 : ! 5. k-point integration W_PQ(iω_j, k_i) to W_PQ^MIC(iω_j)
1106 1860 : SELECT CASE (bs_env%approx_kp_extrapol)
1107 : CASE (.FALSE.)
1108 : ! default: standard k-point extrapolation
1109 : CALL MIC_contribution_from_ikp(bs_env, qs_env, fm_W_MIC_freq_j, cfm_W_ikp_freq_j, ikp, &
1110 1860 : bs_env%kpoints_chi_eps_W, "RI_AUX")
1111 : CASE (.TRUE.)
1112 : ! for approximate kpoint extrapolation: get W_PQ^MIC(iω_1) with and without k-point
1113 : ! extrapolation to compute the extrapolation factor f_PQ for every PQ-matrix element,
1114 : ! f_PQ = (W_PQ^MIC(iω_1) with extrapolation) / (W_PQ^MIC(iω_1) without extrapolation)
1115 :
1116 : ! for ω_1, we compute the k-point extrapolated result using all k-points
1117 196 : IF (j_w == 1) THEN
1118 :
1119 : ! k-point extrapolated
1120 : CALL MIC_contribution_from_ikp(bs_env, qs_env, bs_env%fm_W_MIC_freq_1_extra, &
1121 : cfm_W_ikp_freq_j, ikp, bs_env%kpoints_chi_eps_W, &
1122 52 : "RI_AUX")
1123 : ! non-kpoint extrapolated
1124 52 : IF (ikp .LE. bs_env%nkp_chi_eps_W_orig) THEN
1125 : CALL MIC_contribution_from_ikp(bs_env, qs_env, bs_env%fm_W_MIC_freq_1_no_extra, &
1126 : cfm_W_ikp_freq_j, ikp, bs_env%kpoints_chi_eps_W, &
1127 16 : "RI_AUX", wkp_ext=bs_env%wkp_orig)
1128 : END IF
1129 :
1130 : END IF
1131 :
1132 : ! for all ω_j, we need to compute W^MIC without k-point extrpolation
1133 196 : IF (ikp .LE. bs_env%nkp_chi_eps_W_orig) THEN
1134 : CALL MIC_contribution_from_ikp(bs_env, qs_env, fm_W_MIC_freq_j, cfm_W_ikp_freq_j, &
1135 : ikp, bs_env%kpoints_chi_eps_W, "RI_AUX", &
1136 160 : wkp_ext=bs_env%wkp_orig)
1137 : END IF
1138 : END SELECT
1139 :
1140 1860 : CALL cp_cfm_release(cfm_W_ikp_freq_j)
1141 :
1142 1860 : CALL timestop(handle)
1143 :
1144 1860 : END SUBROUTINE compute_fm_W_MIC_freq_j
1145 :
1146 : ! **************************************************************************************************
1147 : !> \brief ...
1148 : !> \param cfm_mat ...
1149 : ! **************************************************************************************************
1150 520 : SUBROUTINE clean_lower_part(cfm_mat)
1151 : TYPE(cp_cfm_type) :: cfm_mat
1152 :
1153 : CHARACTER(LEN=*), PARAMETER :: routineN = 'clean_lower_part'
1154 :
1155 : INTEGER :: handle, i_global, i_row, j_col, &
1156 : j_global, ncol_local, nrow_local
1157 260 : INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1158 :
1159 260 : CALL timeset(routineN, handle)
1160 :
1161 : CALL cp_cfm_get_info(matrix=cfm_mat, &
1162 : nrow_local=nrow_local, ncol_local=ncol_local, &
1163 260 : row_indices=row_indices, col_indices=col_indices)
1164 :
1165 1066 : DO i_row = 1, nrow_local
1166 6344 : DO j_col = 1, ncol_local
1167 5278 : i_global = row_indices(i_row)
1168 5278 : j_global = col_indices(j_col)
1169 6084 : IF (j_global < i_global) cfm_mat%local_data(i_row, j_col) = z_zero
1170 : END DO
1171 : END DO
1172 :
1173 260 : CALL timestop(handle)
1174 :
1175 260 : END SUBROUTINE clean_lower_part
1176 :
1177 : ! **************************************************************************************************
1178 : !> \brief ...
1179 : !> \param bs_env ...
1180 : !> \param fm_W_MIC_time ...
1181 : ! **************************************************************************************************
1182 4 : SUBROUTINE apply_extrapol_factor(bs_env, fm_W_MIC_time)
1183 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1184 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
1185 :
1186 : CHARACTER(LEN=*), PARAMETER :: routineN = 'apply_extrapol_factor'
1187 :
1188 : INTEGER :: handle, i, i_t, j, ncol_local, nrow_local
1189 : REAL(KIND=dp) :: extrapol_factor, W_extra_1, W_no_extra_1
1190 :
1191 2 : CALL timeset(routineN, handle)
1192 :
1193 2 : CALL cp_fm_get_info(matrix=fm_W_MIC_time(1), nrow_local=nrow_local, ncol_local=ncol_local)
1194 :
1195 22 : DO i_t = 1, bs_env%num_time_freq_points
1196 72 : DO i = 1, nrow_local
1197 320 : DO j = 1, ncol_local
1198 :
1199 250 : W_extra_1 = bs_env%fm_W_MIC_freq_1_extra%local_data(i, j)
1200 250 : W_no_extra_1 = bs_env%fm_W_MIC_freq_1_no_extra%local_data(i, j)
1201 :
1202 250 : IF (ABS(W_no_extra_1) > 1.0E-13) THEN
1203 190 : extrapol_factor = W_extra_1/W_no_extra_1
1204 : ELSE
1205 : extrapol_factor = 1.0_dp
1206 : END IF
1207 :
1208 : ! reset extrapolation factor if it is very large
1209 250 : IF (ABS(extrapol_factor) > 10.0_dp) extrapol_factor = 1.0_dp
1210 :
1211 : fm_W_MIC_time(i_t)%local_data(i, j) = fm_W_MIC_time(i_t)%local_data(i, j) &
1212 300 : *extrapol_factor
1213 : END DO
1214 : END DO
1215 : END DO
1216 :
1217 2 : CALL timestop(handle)
1218 :
1219 2 : END SUBROUTINE apply_extrapol_factor
1220 :
1221 : ! **************************************************************************************************
1222 : !> \brief ...
1223 : !> \param bs_env ...
1224 : !> \param fm_chi_Gamma_freq ...
1225 : !> \param j_w ...
1226 : !> \param mat_chi_Gamma_tau ...
1227 : ! **************************************************************************************************
1228 1860 : SUBROUTINE compute_fm_chi_Gamma_freq(bs_env, fm_chi_Gamma_freq, j_w, mat_chi_Gamma_tau)
1229 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1230 : TYPE(cp_fm_type) :: fm_chi_Gamma_freq
1231 : INTEGER :: j_w
1232 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_chi_Gamma_tau
1233 :
1234 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_fm_chi_Gamma_freq'
1235 :
1236 : INTEGER :: handle, i_t
1237 : REAL(KIND=dp) :: freq_j, time_i, weight_ij
1238 :
1239 1860 : CALL timeset(routineN, handle)
1240 :
1241 1860 : CALL dbcsr_set(bs_env%mat_RI_RI%matrix, 0.0_dp)
1242 :
1243 1860 : freq_j = bs_env%imag_freq_points(j_w)
1244 :
1245 17964 : DO i_t = 1, bs_env%num_time_freq_points
1246 :
1247 16104 : time_i = bs_env%imag_time_points(i_t)
1248 16104 : weight_ij = bs_env%weights_cos_t_to_w(j_w, i_t)
1249 :
1250 : ! actual Fourier transform
1251 : CALL dbcsr_add(bs_env%mat_RI_RI%matrix, mat_chi_Gamma_tau(i_t)%matrix, &
1252 17964 : 1.0_dp, COS(time_i*freq_j)*weight_ij)
1253 :
1254 : END DO
1255 :
1256 1860 : CALL copy_dbcsr_to_fm(bs_env%mat_RI_RI%matrix, fm_chi_Gamma_freq)
1257 :
1258 1860 : CALL timestop(handle)
1259 :
1260 1860 : END SUBROUTINE compute_fm_chi_Gamma_freq
1261 :
1262 : ! **************************************************************************************************
1263 : !> \brief ...
1264 : !> \param mat_ikp_re ...
1265 : !> \param mat_ikp_im ...
1266 : !> \param mat_Gamma ...
1267 : !> \param kpoints ...
1268 : !> \param ikp ...
1269 : !> \param qs_env ...
1270 : ! **************************************************************************************************
1271 0 : SUBROUTINE mat_ikp_from_mat_Gamma(mat_ikp_re, mat_ikp_im, mat_Gamma, kpoints, ikp, qs_env)
1272 : TYPE(dbcsr_type) :: mat_ikp_re, mat_ikp_im, mat_Gamma
1273 : TYPE(kpoint_type), POINTER :: kpoints
1274 : INTEGER :: ikp
1275 : TYPE(qs_environment_type), POINTER :: qs_env
1276 :
1277 : CHARACTER(LEN=*), PARAMETER :: routineN = 'mat_ikp_from_mat_Gamma'
1278 :
1279 : INTEGER :: col, handle, i_cell, j_cell, num_cells, &
1280 : row
1281 0 : INTEGER, DIMENSION(:, :), POINTER :: index_to_cell
1282 : LOGICAL :: f, i_cell_is_the_minimum_image_cell
1283 : REAL(KIND=dp) :: abs_rab_cell_i, abs_rab_cell_j, arg
1284 : REAL(KIND=dp), DIMENSION(3) :: cell_vector, cell_vector_j, rab_cell_i, &
1285 : rab_cell_j
1286 : REAL(KIND=dp), DIMENSION(3, 3) :: hmat
1287 0 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: block_im, block_re, data_block
1288 : TYPE(cell_type), POINTER :: cell
1289 : TYPE(dbcsr_iterator_type) :: iter
1290 0 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1291 :
1292 0 : CALL timeset(routineN, handle)
1293 :
1294 : ! get the same blocks in mat_ikp_re and mat_ikp_im as in mat_Gamma
1295 0 : CALL dbcsr_copy(mat_ikp_re, mat_Gamma)
1296 0 : CALL dbcsr_copy(mat_ikp_im, mat_Gamma)
1297 0 : CALL dbcsr_set(mat_ikp_re, 0.0_dp)
1298 0 : CALL dbcsr_set(mat_ikp_im, 0.0_dp)
1299 :
1300 0 : NULLIFY (cell, particle_set)
1301 0 : CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1302 0 : CALL get_cell(cell=cell, h=hmat)
1303 :
1304 0 : index_to_cell => kpoints%index_to_cell
1305 :
1306 0 : num_cells = SIZE(index_to_cell, 2)
1307 :
1308 0 : DO i_cell = 1, num_cells
1309 :
1310 0 : CALL dbcsr_iterator_start(iter, mat_Gamma)
1311 0 : DO WHILE (dbcsr_iterator_blocks_left(iter))
1312 0 : CALL dbcsr_iterator_next_block(iter, row, col, data_block)
1313 :
1314 0 : cell_vector(1:3) = MATMUL(hmat, REAL(index_to_cell(1:3, i_cell), dp))
1315 :
1316 : rab_cell_i(1:3) = pbc(particle_set(row)%r(1:3), cell) - &
1317 0 : (pbc(particle_set(col)%r(1:3), cell) + cell_vector(1:3))
1318 0 : abs_rab_cell_i = SQRT(rab_cell_i(1)**2 + rab_cell_i(2)**2 + rab_cell_i(3)**2)
1319 :
1320 : ! minimum image convention
1321 0 : i_cell_is_the_minimum_image_cell = .TRUE.
1322 0 : DO j_cell = 1, num_cells
1323 0 : cell_vector_j(1:3) = MATMUL(hmat, REAL(index_to_cell(1:3, j_cell), dp))
1324 : rab_cell_j(1:3) = pbc(particle_set(row)%r(1:3), cell) - &
1325 0 : (pbc(particle_set(col)%r(1:3), cell) + cell_vector_j(1:3))
1326 0 : abs_rab_cell_j = SQRT(rab_cell_j(1)**2 + rab_cell_j(2)**2 + rab_cell_j(3)**2)
1327 :
1328 0 : IF (abs_rab_cell_i > abs_rab_cell_j + 1.0E-6_dp) THEN
1329 0 : i_cell_is_the_minimum_image_cell = .FALSE.
1330 : END IF
1331 : END DO
1332 :
1333 0 : IF (i_cell_is_the_minimum_image_cell) THEN
1334 0 : NULLIFY (block_re, block_im)
1335 0 : CALL dbcsr_get_block_p(matrix=mat_ikp_re, row=row, col=col, block=block_re, found=f)
1336 0 : CALL dbcsr_get_block_p(matrix=mat_ikp_im, row=row, col=col, block=block_im, found=f)
1337 0 : CPASSERT(ALL(ABS(block_re) < 1.0E-10_dp))
1338 0 : CPASSERT(ALL(ABS(block_im) < 1.0E-10_dp))
1339 :
1340 : arg = REAL(index_to_cell(1, i_cell), dp)*kpoints%xkp(1, ikp) + &
1341 : REAL(index_to_cell(2, i_cell), dp)*kpoints%xkp(2, ikp) + &
1342 0 : REAL(index_to_cell(3, i_cell), dp)*kpoints%xkp(3, ikp)
1343 :
1344 0 : block_re(:, :) = COS(twopi*arg)*data_block(:, :)
1345 0 : block_im(:, :) = SIN(twopi*arg)*data_block(:, :)
1346 : END IF
1347 :
1348 : END DO
1349 0 : CALL dbcsr_iterator_stop(iter)
1350 :
1351 : END DO
1352 :
1353 0 : CALL timestop(handle)
1354 :
1355 0 : END SUBROUTINE mat_ikp_from_mat_Gamma
1356 :
1357 : ! **************************************************************************************************
1358 : !> \brief ...
1359 : !> \param bs_env ...
1360 : !> \param cfm_chi_ikp_freq_j ...
1361 : !> \param cfm_V_sqrt_ikp ...
1362 : !> \param cfm_M_inv_V_sqrt_ikp ...
1363 : !> \param cfm_W_ikp_freq_j ...
1364 : ! **************************************************************************************************
1365 9300 : SUBROUTINE compute_cfm_W_ikp_freq_j(bs_env, cfm_chi_ikp_freq_j, cfm_V_sqrt_ikp, &
1366 : cfm_M_inv_V_sqrt_ikp, cfm_W_ikp_freq_j)
1367 :
1368 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1369 : TYPE(cp_cfm_type) :: cfm_chi_ikp_freq_j, cfm_V_sqrt_ikp, &
1370 : cfm_M_inv_V_sqrt_ikp, cfm_W_ikp_freq_j
1371 :
1372 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_cfm_W_ikp_freq_j'
1373 :
1374 : INTEGER :: handle, info, n_RI
1375 : TYPE(cp_cfm_type) :: cfm_eps_ikp_freq_j, cfm_work
1376 :
1377 1860 : CALL timeset(routineN, handle)
1378 :
1379 1860 : CALL cp_cfm_create(cfm_work, cfm_chi_ikp_freq_j%matrix_struct)
1380 1860 : n_RI = bs_env%n_RI
1381 :
1382 : ! 1. ε(iω_j,k) = Id - V^0.5(k)*M^-1(k)*χ(iω_j,k)*M^-1(k)*V^0.5(k)
1383 :
1384 : ! 1. a) work = χ(iω_j,k)*M^-1(k)*V^0.5(k)
1385 : CALL parallel_gemm('N', 'N', n_RI, n_RI, n_RI, z_one, &
1386 1860 : cfm_chi_ikp_freq_j, cfm_M_inv_V_sqrt_ikp, z_zero, cfm_work)
1387 1860 : CALL cp_cfm_release(cfm_chi_ikp_freq_j)
1388 :
1389 : ! 1. b) eps_work = V^0.5(k)*M^-1(k)*work
1390 1860 : CALL cp_cfm_create(cfm_eps_ikp_freq_j, cfm_work%matrix_struct)
1391 : CALL parallel_gemm('C', 'N', n_RI, n_RI, n_RI, z_one, &
1392 1860 : cfm_M_inv_V_sqrt_ikp, cfm_work, z_zero, cfm_eps_ikp_freq_j)
1393 :
1394 : ! 1. c) ε(iω_j,k) = eps_work - Id
1395 1860 : CALL cfm_add_on_diag(cfm_eps_ikp_freq_j, z_one)
1396 :
1397 : ! 2. W(iω_j,k) = V^0.5(k)*(ε^-1(iω_j,k)-Id)*V^0.5(k)
1398 :
1399 : ! 2. a) Cholesky decomposition of ε(iω_j,k) as preparation for inversion
1400 1860 : CALL cp_cfm_cholesky_decompose(matrix=cfm_eps_ikp_freq_j, n=n_RI, info_out=info)
1401 1860 : CPASSERT(info == 0)
1402 :
1403 : ! 2. b) Inversion of ε(iω_j,k) using its Cholesky decomposition
1404 1860 : CALL cp_cfm_cholesky_invert(cfm_eps_ikp_freq_j)
1405 1860 : CALL cp_cfm_upper_to_full(cfm_eps_ikp_freq_j)
1406 :
1407 : ! 2. c) ε^-1(iω_j,k)-Id
1408 1860 : CALL cfm_add_on_diag(cfm_eps_ikp_freq_j, -z_one)
1409 :
1410 : ! 2. d) work = (ε^-1(iω_j,k)-Id)*V^0.5(k)
1411 : CALL parallel_gemm('N', 'N', n_RI, n_RI, n_RI, z_one, cfm_eps_ikp_freq_j, cfm_V_sqrt_ikp, &
1412 1860 : z_zero, cfm_work)
1413 :
1414 : ! 2. e) W(iw,k) = V^0.5(k)*work
1415 1860 : CALL cp_cfm_create(cfm_W_ikp_freq_j, cfm_work%matrix_struct)
1416 : CALL parallel_gemm('C', 'N', n_RI, n_RI, n_RI, z_one, cfm_V_sqrt_ikp, cfm_work, &
1417 1860 : z_zero, cfm_W_ikp_freq_j)
1418 :
1419 1860 : CALL cp_cfm_release(cfm_work)
1420 1860 : CALL cp_cfm_release(cfm_eps_ikp_freq_j)
1421 :
1422 1860 : CALL timestop(handle)
1423 :
1424 1860 : END SUBROUTINE compute_cfm_W_ikp_freq_j
1425 :
1426 : ! **************************************************************************************************
1427 : !> \brief ...
1428 : !> \param cfm ...
1429 : !> \param alpha ...
1430 : ! **************************************************************************************************
1431 7440 : SUBROUTINE cfm_add_on_diag(cfm, alpha)
1432 :
1433 : TYPE(cp_cfm_type) :: cfm
1434 : COMPLEX(KIND=dp) :: alpha
1435 :
1436 : CHARACTER(LEN=*), PARAMETER :: routineN = 'cfm_add_on_diag'
1437 :
1438 : INTEGER :: handle, i_global, i_row, j_col, &
1439 : j_global, ncol_local, nrow_local
1440 3720 : INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1441 :
1442 3720 : CALL timeset(routineN, handle)
1443 :
1444 : CALL cp_cfm_get_info(matrix=cfm, &
1445 : nrow_local=nrow_local, &
1446 : ncol_local=ncol_local, &
1447 : row_indices=row_indices, &
1448 3720 : col_indices=col_indices)
1449 :
1450 : ! add 1 on the diagonal
1451 26064 : DO j_col = 1, ncol_local
1452 22344 : j_global = col_indices(j_col)
1453 96900 : DO i_row = 1, nrow_local
1454 70836 : i_global = row_indices(i_row)
1455 93180 : IF (j_global == i_global) THEN
1456 11172 : cfm%local_data(i_row, j_col) = cfm%local_data(i_row, j_col) + alpha
1457 : END IF
1458 : END DO
1459 : END DO
1460 :
1461 3720 : CALL timestop(handle)
1462 :
1463 3720 : END SUBROUTINE cfm_add_on_diag
1464 :
1465 : ! **************************************************************************************************
1466 : !> \brief ...
1467 : !> \param bs_env ...
1468 : !> \param fm_W_MIC_time ...
1469 : ! **************************************************************************************************
1470 16 : SUBROUTINE create_fm_W_MIC_time(bs_env, fm_W_MIC_time)
1471 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1472 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
1473 :
1474 : CHARACTER(LEN=*), PARAMETER :: routineN = 'create_fm_W_MIC_time'
1475 :
1476 : INTEGER :: handle, i_t
1477 :
1478 16 : CALL timeset(routineN, handle)
1479 :
1480 192 : ALLOCATE (fm_W_MIC_time(bs_env%num_time_freq_points))
1481 160 : DO i_t = 1, bs_env%num_time_freq_points
1482 160 : CALL cp_fm_create(fm_W_MIC_time(i_t), bs_env%fm_RI_RI%matrix_struct)
1483 : END DO
1484 :
1485 16 : CALL timestop(handle)
1486 :
1487 16 : END SUBROUTINE create_fm_W_MIC_time
1488 :
1489 : ! **************************************************************************************************
1490 : !> \brief ...
1491 : !> \param bs_env ...
1492 : !> \param fm_W_MIC_time ...
1493 : !> \param fm_W_MIC_freq_j ...
1494 : !> \param j_w ...
1495 : ! **************************************************************************************************
1496 1860 : SUBROUTINE Fourier_transform_w_to_t(bs_env, fm_W_MIC_time, fm_W_MIC_freq_j, j_w)
1497 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1498 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
1499 : TYPE(cp_fm_type) :: fm_W_MIC_freq_j
1500 : INTEGER :: j_w
1501 :
1502 : CHARACTER(LEN=*), PARAMETER :: routineN = 'Fourier_transform_w_to_t'
1503 :
1504 : INTEGER :: handle, i_t
1505 : REAL(KIND=dp) :: freq_j, time_i, weight_ij
1506 :
1507 1860 : CALL timeset(routineN, handle)
1508 :
1509 1860 : freq_j = bs_env%imag_freq_points(j_w)
1510 :
1511 17964 : DO i_t = 1, bs_env%num_time_freq_points
1512 :
1513 16104 : time_i = bs_env%imag_time_points(i_t)
1514 16104 : weight_ij = bs_env%weights_cos_w_to_t(i_t, j_w)
1515 :
1516 : ! actual Fourier transform
1517 : CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_W_MIC_time(i_t), &
1518 17964 : beta=weight_ij*COS(time_i*freq_j), matrix_b=fm_W_MIC_freq_j)
1519 :
1520 : END DO
1521 :
1522 1860 : CALL timestop(handle)
1523 :
1524 1860 : END SUBROUTINE Fourier_transform_w_to_t
1525 :
1526 : ! **************************************************************************************************
1527 : !> \brief ...
1528 : !> \param bs_env ...
1529 : !> \param qs_env ...
1530 : !> \param fm_W_MIC_time ...
1531 : ! **************************************************************************************************
1532 20 : SUBROUTINE multiply_fm_W_MIC_time_with_Minv_Gamma(bs_env, qs_env, fm_W_MIC_time)
1533 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1534 : TYPE(qs_environment_type), POINTER :: qs_env
1535 : TYPE(cp_fm_type), DIMENSION(:) :: fm_W_MIC_time
1536 :
1537 : CHARACTER(LEN=*), PARAMETER :: routineN = 'multiply_fm_W_MIC_time_with_Minv_Gamma'
1538 :
1539 : INTEGER :: handle, i_t, n_RI, ndep
1540 : TYPE(cp_fm_type) :: fm_work
1541 20 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_Minv_Gamma
1542 :
1543 20 : CALL timeset(routineN, handle)
1544 :
1545 20 : n_RI = bs_env%n_RI
1546 :
1547 20 : CALL cp_fm_create(fm_work, fm_W_MIC_time(1)%matrix_struct)
1548 :
1549 : ! compute Gamma-only RI-metric matrix M(k=0); no regularization
1550 : CALL RI_2c_integral_mat(qs_env, fm_Minv_Gamma, fm_W_MIC_time(1), n_RI, &
1551 20 : bs_env%ri_metric, do_kpoints=.FALSE.)
1552 :
1553 20 : CALL cp_fm_power(fm_Minv_Gamma(1, 1), fm_work, -1.0_dp, 0.0_dp, ndep)
1554 :
1555 : ! M^-1(k=0)*W^MIC(iτ)*M^-1(k=0)
1556 114 : DO i_t = 1, SIZE(fm_W_MIC_time)
1557 :
1558 : CALL parallel_gemm('N', 'N', n_RI, n_RI, n_RI, 1.0_dp, fm_Minv_Gamma(1, 1), &
1559 94 : fm_W_MIC_time(i_t), 0.0_dp, fm_work)
1560 :
1561 : CALL parallel_gemm('N', 'N', n_RI, n_RI, n_RI, 1.0_dp, fm_work, &
1562 114 : fm_Minv_Gamma(1, 1), 0.0_dp, fm_W_MIC_time(i_t))
1563 :
1564 : END DO
1565 :
1566 20 : CALL cp_fm_release(fm_work)
1567 20 : CALL cp_fm_release(fm_Minv_Gamma)
1568 :
1569 20 : CALL timestop(handle)
1570 :
1571 40 : END SUBROUTINE multiply_fm_W_MIC_time_with_Minv_Gamma
1572 :
1573 : ! **************************************************************************************************
1574 : !> \brief ...
1575 : !> \param bs_env ...
1576 : !> \param qs_env ...
1577 : !> \param fm_Sigma_x_Gamma ...
1578 : ! **************************************************************************************************
1579 16 : SUBROUTINE get_Sigma_x(bs_env, qs_env, fm_Sigma_x_Gamma)
1580 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1581 : TYPE(qs_environment_type), POINTER :: qs_env
1582 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_Sigma_x_Gamma
1583 :
1584 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_Sigma_x'
1585 :
1586 : INTEGER :: handle, ispin
1587 :
1588 16 : CALL timeset(routineN, handle)
1589 :
1590 72 : ALLOCATE (fm_Sigma_x_Gamma(bs_env%n_spin))
1591 40 : DO ispin = 1, bs_env%n_spin
1592 40 : CALL cp_fm_create(fm_Sigma_x_Gamma(ispin), bs_env%fm_s_Gamma%matrix_struct)
1593 : END DO
1594 :
1595 16 : IF (bs_env%Sigma_x_exists) THEN
1596 18 : DO ispin = 1, bs_env%n_spin
1597 18 : CALL fm_read(fm_Sigma_x_Gamma(ispin), bs_env, bs_env%Sigma_x_name, ispin)
1598 : END DO
1599 : ELSE
1600 10 : CALL compute_Sigma_x(bs_env, qs_env, fm_Sigma_x_Gamma)
1601 : END IF
1602 :
1603 16 : CALL timestop(handle)
1604 :
1605 16 : END SUBROUTINE get_Sigma_x
1606 :
1607 : ! **************************************************************************************************
1608 : !> \brief ...
1609 : !> \param bs_env ...
1610 : !> \param qs_env ...
1611 : !> \param fm_Sigma_x_Gamma ...
1612 : ! **************************************************************************************************
1613 10 : SUBROUTINE compute_Sigma_x(bs_env, qs_env, fm_Sigma_x_Gamma)
1614 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1615 : TYPE(qs_environment_type), POINTER :: qs_env
1616 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_Sigma_x_Gamma
1617 :
1618 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_Sigma_x'
1619 :
1620 : INTEGER :: handle, i_intval_idx, ispin, j_intval_idx
1621 : INTEGER, DIMENSION(2) :: i_atoms, j_atoms
1622 : REAL(KIND=dp) :: t1
1623 10 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_Vtr_Gamma
1624 : TYPE(dbcsr_type) :: mat_Sigma_x_Gamma
1625 330 : TYPE(dbt_type) :: t_2c_D, t_2c_Sigma_x, t_2c_V, t_3c_x_V
1626 :
1627 10 : CALL timeset(routineN, handle)
1628 :
1629 10 : t1 = m_walltime()
1630 :
1631 10 : CALL dbt_create(bs_env%t_G, t_2c_D)
1632 10 : CALL dbt_create(bs_env%t_W, t_2c_V)
1633 10 : CALL dbt_create(bs_env%t_G, t_2c_Sigma_x)
1634 10 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_V)
1635 10 : CALL dbcsr_create(mat_Sigma_x_Gamma, template=bs_env%mat_ao_ao%matrix)
1636 :
1637 : ! 1. Compute truncated Coulomb operator matrix V^tr(k=0) (cutoff rad: cellsize/2)
1638 : CALL RI_2c_integral_mat(qs_env, fm_Vtr_Gamma, bs_env%fm_RI_RI, bs_env%n_RI, &
1639 10 : bs_env%trunc_coulomb, do_kpoints=.FALSE.)
1640 :
1641 : ! 2. Compute M^-1(k=0) and get M^-1(k=0)*V^tr(k=0)*M^-1(k=0)
1642 10 : CALL multiply_fm_W_MIC_time_with_Minv_Gamma(bs_env, qs_env, fm_Vtr_Gamma(:, 1))
1643 :
1644 22 : DO ispin = 1, bs_env%n_spin
1645 :
1646 : ! 3. Compute density matrix D_µν
1647 12 : CALL G_occ_vir(bs_env, 0.0_dp, bs_env%fm_work_mo(2), ispin, occ=.TRUE., vir=.FALSE.)
1648 :
1649 : CALL fm_to_local_tensor(bs_env%fm_work_mo(2), bs_env%mat_ao_ao%matrix, &
1650 : bs_env%mat_ao_ao_tensor%matrix, t_2c_D, bs_env, &
1651 12 : bs_env%atoms_i_t_group)
1652 :
1653 : CALL fm_to_local_tensor(fm_Vtr_Gamma(1, 1), bs_env%mat_RI_RI%matrix, &
1654 : bs_env%mat_RI_RI_tensor%matrix, t_2c_V, bs_env, &
1655 12 : bs_env%atoms_j_t_group)
1656 :
1657 : ! every group has its own range of i_atoms and j_atoms; only deal with a
1658 : ! limited number of i_atom-j_atom pairs simultaneously in a group to save memory
1659 24 : DO i_intval_idx = 1, bs_env%n_intervals_i
1660 36 : DO j_intval_idx = 1, bs_env%n_intervals_j
1661 36 : i_atoms = bs_env%i_atom_intervals(1:2, i_intval_idx)
1662 36 : j_atoms = bs_env%j_atom_intervals(1:2, j_intval_idx)
1663 :
1664 : ! 4. compute 3-center integrals (µν|P) ("|": truncated Coulomb operator)
1665 : ! 5. M_νσQ(iτ) = sum_P (νσ|P) (M^-1(k=0)*V^tr(k=0)*M^-1(k=0))_PQ(iτ)
1666 12 : CALL compute_3c_and_contract_W(qs_env, bs_env, i_atoms, j_atoms, t_3c_x_V, t_2c_V)
1667 :
1668 : ! 6. tensor operations with D and computation of Σ^x
1669 : ! Σ^x_λσ(k=0) = sum_νQ M_νσQ(iτ) sum_µ (λµ|Q) D_µν
1670 : CALL contract_to_Sigma(t_2c_D, t_3c_x_V, t_2c_Sigma_x, i_atoms, j_atoms, &
1671 24 : qs_env, bs_env, occ=.TRUE., vir=.FALSE., clear_W=.TRUE.)
1672 :
1673 : END DO ! j_atoms
1674 : END DO ! i_atoms
1675 :
1676 : CALL local_dbt_to_global_mat(t_2c_Sigma_x, bs_env%mat_ao_ao_tensor%matrix, &
1677 12 : mat_Sigma_x_Gamma, bs_env%para_env)
1678 :
1679 : CALL write_matrix(mat_Sigma_x_Gamma, ispin, bs_env%Sigma_x_name, &
1680 12 : bs_env%fm_work_mo(1), qs_env)
1681 :
1682 22 : CALL copy_dbcsr_to_fm(mat_Sigma_x_Gamma, fm_Sigma_x_Gamma(ispin))
1683 :
1684 : END DO ! ispin
1685 :
1686 10 : IF (bs_env%unit_nr > 0) THEN
1687 : WRITE (bs_env%unit_nr, '(T2,A,T58,A,F7.1,A)') &
1688 5 : 'Computed Σ^x(k=0),', ' Execution time', m_walltime() - t1, ' s'
1689 5 : WRITE (bs_env%unit_nr, '(A)') ' '
1690 : END IF
1691 :
1692 10 : CALL dbcsr_release(mat_Sigma_x_Gamma)
1693 10 : CALL dbt_destroy(t_2c_D)
1694 10 : CALL dbt_destroy(t_2c_V)
1695 10 : CALL dbt_destroy(t_2c_Sigma_x)
1696 10 : CALL dbt_destroy(t_3c_x_V)
1697 10 : CALL cp_fm_release(fm_Vtr_Gamma)
1698 :
1699 10 : CALL timestop(handle)
1700 :
1701 20 : END SUBROUTINE compute_Sigma_x
1702 :
1703 : ! **************************************************************************************************
1704 : !> \brief ...
1705 : !> \param bs_env ...
1706 : !> \param qs_env ...
1707 : !> \param fm_W_MIC_time ...
1708 : !> \param fm_Sigma_c_Gamma_time ...
1709 : ! **************************************************************************************************
1710 16 : SUBROUTINE get_Sigma_c(bs_env, qs_env, fm_W_MIC_time, fm_Sigma_c_Gamma_time)
1711 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1712 : TYPE(qs_environment_type), POINTER :: qs_env
1713 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
1714 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_Sigma_c_Gamma_time
1715 :
1716 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_Sigma_c'
1717 :
1718 : INTEGER :: handle, i_intval_idx, i_t, ispin, &
1719 : j_intval_idx, read_write_index
1720 : INTEGER, DIMENSION(2) :: i_atoms, j_atoms
1721 : REAL(KIND=dp) :: t1, tau
1722 16 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_Sigma_neg_tau, mat_Sigma_pos_tau
1723 272 : TYPE(dbt_type) :: t_2c_Gocc, t_2c_Gvir, &
1724 144 : t_2c_Sigma_neg_tau, &
1725 400 : t_2c_Sigma_pos_tau, t_2c_W, t_3c_x_W
1726 :
1727 16 : CALL timeset(routineN, handle)
1728 :
1729 : CALL create_mat_for_Sigma_c(bs_env, t_2c_Gocc, t_2c_Gvir, t_2c_W, t_2c_Sigma_neg_tau, &
1730 : t_2c_Sigma_pos_tau, t_3c_x_W, &
1731 16 : mat_Sigma_neg_tau, mat_Sigma_pos_tau)
1732 :
1733 160 : DO i_t = 1, bs_env%num_time_freq_points
1734 :
1735 384 : DO ispin = 1, bs_env%n_spin
1736 :
1737 224 : t1 = m_walltime()
1738 :
1739 224 : read_write_index = i_t + (ispin - 1)*bs_env%num_time_freq_points
1740 :
1741 : ! read self-energy from restart
1742 224 : IF (bs_env%Sigma_c_exists(i_t, ispin)) THEN
1743 120 : CALL fm_read(bs_env%fm_work_mo(1), bs_env, bs_env%Sigma_p_name, read_write_index)
1744 : CALL copy_fm_to_dbcsr(bs_env%fm_work_mo(1), mat_Sigma_pos_tau(i_t, ispin)%matrix, &
1745 120 : keep_sparsity=.FALSE.)
1746 120 : CALL fm_read(bs_env%fm_work_mo(1), bs_env, bs_env%Sigma_n_name, read_write_index)
1747 : CALL copy_fm_to_dbcsr(bs_env%fm_work_mo(1), mat_Sigma_neg_tau(i_t, ispin)%matrix, &
1748 120 : keep_sparsity=.FALSE.)
1749 120 : IF (bs_env%unit_nr > 0) THEN
1750 60 : WRITE (bs_env%unit_nr, '(T2,2A,I3,A,I3,A,F7.1,A)') 'Read Σ^c(iτ,k=0) ', &
1751 60 : 'from file for time point ', i_t, ' /', bs_env%num_time_freq_points, &
1752 120 : ', Execution time', m_walltime() - t1, ' s'
1753 : END IF
1754 :
1755 : CYCLE
1756 :
1757 : END IF
1758 :
1759 104 : tau = bs_env%imag_time_points(i_t)
1760 :
1761 104 : CALL G_occ_vir(bs_env, tau, bs_env%fm_Gocc, ispin, occ=.TRUE., vir=.FALSE.)
1762 104 : CALL G_occ_vir(bs_env, tau, bs_env%fm_Gvir, ispin, occ=.FALSE., vir=.TRUE.)
1763 :
1764 : ! fm G^occ, G^vir and W to local tensor
1765 : CALL fm_to_local_tensor(bs_env%fm_Gocc, bs_env%mat_ao_ao%matrix, &
1766 : bs_env%mat_ao_ao_tensor%matrix, t_2c_Gocc, bs_env, &
1767 104 : bs_env%atoms_i_t_group)
1768 : CALL fm_to_local_tensor(bs_env%fm_Gvir, bs_env%mat_ao_ao%matrix, &
1769 : bs_env%mat_ao_ao_tensor%matrix, t_2c_Gvir, bs_env, &
1770 104 : bs_env%atoms_i_t_group)
1771 : CALL fm_to_local_tensor(fm_W_MIC_time(i_t), bs_env%mat_RI_RI%matrix, &
1772 : bs_env%mat_RI_RI_tensor%matrix, t_2c_W, bs_env, &
1773 104 : bs_env%atoms_j_t_group)
1774 :
1775 : ! every group has its own range of i_atoms and j_atoms; only deal with a
1776 : ! limited number of i_atom-j_atom pairs simultaneously in a group to save memory
1777 208 : DO i_intval_idx = 1, bs_env%n_intervals_i
1778 312 : DO j_intval_idx = 1, bs_env%n_intervals_j
1779 312 : i_atoms = bs_env%i_atom_intervals(1:2, i_intval_idx)
1780 312 : j_atoms = bs_env%j_atom_intervals(1:2, j_intval_idx)
1781 :
1782 104 : IF (bs_env%skip_Sigma_occ(i_intval_idx, j_intval_idx) .AND. &
1783 : bs_env%skip_Sigma_vir(i_intval_idx, j_intval_idx)) CYCLE
1784 :
1785 : ! 1. compute 3-center integrals (µν|P) ("|": truncated Coulomb operator)
1786 : ! 2. tensor operation M_νσQ(iτ) = sum_P (νσ|P) W^MIC_PQ(iτ)
1787 86 : CALL compute_3c_and_contract_W(qs_env, bs_env, i_atoms, j_atoms, t_3c_x_W, t_2c_W)
1788 :
1789 : ! 3. Σ_λσ(iτ,k=0) = sum_νQ M_νσQ(iτ) sum_µ (λµ|Q) G^occ_µν(i|τ|) for τ < 0
1790 : ! (recall M_νσQ(iτ) = M_νσQ(-iτ) because W^MIC_PQ(iτ) = W^MIC_PQ(-iτ) )
1791 : CALL contract_to_Sigma(t_2c_Gocc, t_3c_x_W, t_2c_Sigma_neg_tau, i_atoms, j_atoms, &
1792 : qs_env, bs_env, occ=.TRUE., vir=.FALSE., clear_W=.FALSE., &
1793 86 : can_skip=bs_env%skip_Sigma_occ(i_intval_idx, j_intval_idx))
1794 :
1795 : ! Σ_λσ(iτ,k=0) = sum_νQ M_νσQ(iτ) sum_µ (λµ|Q) G^vir_µν(i|τ|) for τ > 0
1796 : CALL contract_to_Sigma(t_2c_Gvir, t_3c_x_W, t_2c_Sigma_pos_tau, i_atoms, j_atoms, &
1797 : qs_env, bs_env, occ=.FALSE., vir=.TRUE., clear_W=.TRUE., &
1798 208 : can_skip=bs_env%skip_Sigma_vir(i_intval_idx, j_intval_idx))
1799 :
1800 : END DO ! j_atoms
1801 : END DO ! i_atoms
1802 :
1803 : ! 4. communicate data tensor t_2c_Sigma (which is local in the subgroup)
1804 : ! to the global dbcsr matrix mat_Sigma_pos/neg_tau (which stores Σ for all iτ)
1805 : CALL local_dbt_to_global_mat(t_2c_Sigma_neg_tau, bs_env%mat_ao_ao_tensor%matrix, &
1806 104 : mat_Sigma_neg_tau(i_t, ispin)%matrix, bs_env%para_env)
1807 : CALL local_dbt_to_global_mat(t_2c_Sigma_pos_tau, bs_env%mat_ao_ao_tensor%matrix, &
1808 104 : mat_Sigma_pos_tau(i_t, ispin)%matrix, bs_env%para_env)
1809 :
1810 : CALL write_matrix(mat_Sigma_pos_tau(i_t, ispin)%matrix, read_write_index, &
1811 104 : bs_env%Sigma_p_name, bs_env%fm_work_mo(1), qs_env)
1812 : CALL write_matrix(mat_Sigma_neg_tau(i_t, ispin)%matrix, read_write_index, &
1813 104 : bs_env%Sigma_n_name, bs_env%fm_work_mo(1), qs_env)
1814 :
1815 248 : IF (bs_env%unit_nr > 0) THEN
1816 : WRITE (bs_env%unit_nr, '(T2,A,I10,A,I3,A,F7.1,A)') &
1817 52 : 'Computed Σ^c(iτ,k=0) for time point ', i_t, ' /', bs_env%num_time_freq_points, &
1818 104 : ', Execution time', m_walltime() - t1, ' s'
1819 : END IF
1820 :
1821 : END DO ! ispin
1822 :
1823 : END DO ! i_t
1824 :
1825 16 : IF (bs_env%unit_nr > 0) WRITE (bs_env%unit_nr, '(A)') ' '
1826 :
1827 : CALL fill_fm_Sigma_c_Gamma_time(fm_Sigma_c_Gamma_time, bs_env, &
1828 16 : mat_Sigma_pos_tau, mat_Sigma_neg_tau)
1829 :
1830 16 : CALL print_skipping(bs_env)
1831 :
1832 : CALL destroy_mat_Sigma_c(t_2c_Gocc, t_2c_Gvir, t_2c_W, t_2c_Sigma_neg_tau, &
1833 : t_2c_Sigma_pos_tau, t_3c_x_W, fm_W_MIC_time, &
1834 16 : mat_Sigma_neg_tau, mat_Sigma_pos_tau)
1835 :
1836 16 : CALL delete_unnecessary_files(bs_env)
1837 :
1838 16 : CALL timestop(handle)
1839 :
1840 32 : END SUBROUTINE get_Sigma_c
1841 :
1842 : ! **************************************************************************************************
1843 : !> \brief ...
1844 : !> \param bs_env ...
1845 : !> \param t_2c_Gocc ...
1846 : !> \param t_2c_Gvir ...
1847 : !> \param t_2c_W ...
1848 : !> \param t_2c_Sigma_neg_tau ...
1849 : !> \param t_2c_Sigma_pos_tau ...
1850 : !> \param t_3c_x_W ...
1851 : !> \param mat_Sigma_neg_tau ...
1852 : !> \param mat_Sigma_pos_tau ...
1853 : ! **************************************************************************************************
1854 16 : SUBROUTINE create_mat_for_Sigma_c(bs_env, t_2c_Gocc, t_2c_Gvir, t_2c_W, t_2c_Sigma_neg_tau, &
1855 : t_2c_Sigma_pos_tau, t_3c_x_W, &
1856 : mat_Sigma_neg_tau, mat_Sigma_pos_tau)
1857 :
1858 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1859 : TYPE(dbt_type) :: t_2c_Gocc, t_2c_Gvir, t_2c_W, &
1860 : t_2c_Sigma_neg_tau, &
1861 : t_2c_Sigma_pos_tau, t_3c_x_W
1862 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_Sigma_neg_tau, mat_Sigma_pos_tau
1863 :
1864 : CHARACTER(LEN=*), PARAMETER :: routineN = 'create_mat_for_Sigma_c'
1865 :
1866 : INTEGER :: handle, i_t, ispin
1867 :
1868 16 : CALL timeset(routineN, handle)
1869 :
1870 16 : CALL dbt_create(bs_env%t_G, t_2c_Gocc)
1871 16 : CALL dbt_create(bs_env%t_G, t_2c_Gvir)
1872 16 : CALL dbt_create(bs_env%t_W, t_2c_W)
1873 16 : CALL dbt_create(bs_env%t_G, t_2c_Sigma_neg_tau)
1874 16 : CALL dbt_create(bs_env%t_G, t_2c_Sigma_pos_tau)
1875 16 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_W)
1876 :
1877 16 : NULLIFY (mat_Sigma_neg_tau, mat_Sigma_pos_tau)
1878 312 : ALLOCATE (mat_Sigma_neg_tau(bs_env%num_time_freq_points, bs_env%n_spin))
1879 312 : ALLOCATE (mat_Sigma_pos_tau(bs_env%num_time_freq_points, bs_env%n_spin))
1880 :
1881 160 : DO i_t = 1, bs_env%num_time_freq_points
1882 384 : DO ispin = 1, bs_env%n_spin
1883 224 : ALLOCATE (mat_Sigma_neg_tau(i_t, ispin)%matrix)
1884 224 : ALLOCATE (mat_Sigma_pos_tau(i_t, ispin)%matrix)
1885 224 : CALL dbcsr_create(mat_Sigma_neg_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
1886 368 : CALL dbcsr_create(mat_Sigma_pos_tau(i_t, ispin)%matrix, template=bs_env%mat_ao_ao%matrix)
1887 : END DO
1888 : END DO
1889 :
1890 16 : CALL timestop(handle)
1891 :
1892 16 : END SUBROUTINE create_mat_for_Sigma_c
1893 :
1894 : ! **************************************************************************************************
1895 : !> \brief ...
1896 : !> \param qs_env ...
1897 : !> \param bs_env ...
1898 : !> \param i_atoms ...
1899 : !> \param j_atoms ...
1900 : !> \param t_3c_x_W ...
1901 : !> \param t_2c_W ...
1902 : ! **************************************************************************************************
1903 98 : SUBROUTINE compute_3c_and_contract_W(qs_env, bs_env, i_atoms, j_atoms, t_3c_x_W, t_2c_W)
1904 :
1905 : TYPE(qs_environment_type), POINTER :: qs_env
1906 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1907 : INTEGER, DIMENSION(2) :: i_atoms, j_atoms
1908 : TYPE(dbt_type) :: t_3c_x_W, t_2c_W
1909 :
1910 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_3c_and_contract_W'
1911 :
1912 : INTEGER :: handle, RI_intval_idx
1913 : INTEGER, DIMENSION(2) :: bounds_j, RI_atoms
1914 1666 : TYPE(dbt_type) :: t_3c_for_W, t_3c_x_W_tmp
1915 :
1916 98 : CALL timeset(routineN, handle)
1917 :
1918 98 : CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_x_W_tmp)
1919 98 : CALL dbt_create(bs_env%t_RI__AO_AO, t_3c_for_W)
1920 :
1921 : bounds_j(1:2) = [bs_env%i_RI_start_from_atom(j_atoms(1)), &
1922 294 : bs_env%i_RI_end_from_atom(j_atoms(2))]
1923 :
1924 196 : DO RI_intval_idx = 1, bs_env%n_intervals_inner_loop_atoms
1925 294 : RI_atoms = bs_env%inner_loop_atom_intervals(1:2, RI_intval_idx)
1926 :
1927 : ! 1. compute 3-center integrals (µν|P) ("|": truncated Coulomb operator)
1928 : CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_W, &
1929 98 : atoms_AO_1=i_atoms, atoms_RI=RI_atoms)
1930 :
1931 : ! 2. tensor operation M_νσQ(iτ) = sum_P (νσ|P) W^MIC_PQ(iτ)
1932 : CALL dbt_contract(alpha=1.0_dp, &
1933 : tensor_1=t_2c_W, &
1934 : tensor_2=t_3c_for_W, &
1935 : beta=1.0_dp, &
1936 : tensor_3=t_3c_x_W_tmp, &
1937 : contract_1=[2], notcontract_1=[1], map_1=[1], &
1938 : contract_2=[1], notcontract_2=[2, 3], map_2=[2, 3], &
1939 : bounds_2=bounds_j, &
1940 196 : filter_eps=bs_env%eps_filter)
1941 :
1942 : END DO ! RI_atoms
1943 :
1944 : ! 3. reorder tensor
1945 98 : CALL dbt_copy(t_3c_x_W_tmp, t_3c_x_W, order=[1, 2, 3], move_data=.TRUE.)
1946 :
1947 98 : CALL dbt_destroy(t_3c_x_W_tmp)
1948 98 : CALL dbt_destroy(t_3c_for_W)
1949 :
1950 98 : CALL timestop(handle)
1951 :
1952 98 : END SUBROUTINE compute_3c_and_contract_W
1953 :
1954 : ! **************************************************************************************************
1955 : !> \brief ...
1956 : !> \param t_2c_G ...
1957 : !> \param t_3c_x_W ...
1958 : !> \param t_2c_Sigma ...
1959 : !> \param i_atoms ...
1960 : !> \param j_atoms ...
1961 : !> \param qs_env ...
1962 : !> \param bs_env ...
1963 : !> \param occ ...
1964 : !> \param vir ...
1965 : !> \param clear_W ...
1966 : !> \param can_skip ...
1967 : ! **************************************************************************************************
1968 184 : SUBROUTINE contract_to_Sigma(t_2c_G, t_3c_x_W, t_2c_Sigma, i_atoms, j_atoms, qs_env, bs_env, &
1969 : occ, vir, clear_W, can_skip)
1970 : TYPE(dbt_type) :: t_2c_G, t_3c_x_W, t_2c_Sigma
1971 : INTEGER, DIMENSION(2) :: i_atoms, j_atoms
1972 : TYPE(qs_environment_type), POINTER :: qs_env
1973 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
1974 : LOGICAL :: occ, vir, clear_W
1975 : LOGICAL, OPTIONAL :: can_skip
1976 :
1977 : CHARACTER(LEN=*), PARAMETER :: routineN = 'contract_to_Sigma'
1978 :
1979 : INTEGER :: handle, inner_loop_atoms_interval_index
1980 : INTEGER(KIND=int_8) :: flop
1981 : INTEGER, DIMENSION(2) :: bounds_i, IL_atoms
1982 : REAL(KIND=dp) :: sign_Sigma
1983 4600 : TYPE(dbt_type) :: t_3c_for_G, t_3c_x_G, t_3c_x_G_2
1984 :
1985 184 : CALL timeset(routineN, handle)
1986 :
1987 184 : CPASSERT(occ .EQV. (.NOT. vir))
1988 184 : IF (occ) sign_Sigma = -1.0_dp
1989 184 : IF (vir) sign_Sigma = 1.0_dp
1990 :
1991 184 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_for_G)
1992 184 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_G)
1993 184 : CALL dbt_create(bs_env%t_RI_AO__AO, t_3c_x_G_2)
1994 :
1995 : bounds_i(1:2) = [bs_env%i_ao_start_from_atom(i_atoms(1)), &
1996 552 : bs_env%i_ao_end_from_atom(i_atoms(2))]
1997 :
1998 368 : DO inner_loop_atoms_interval_index = 1, bs_env%n_intervals_inner_loop_atoms
1999 552 : IL_atoms = bs_env%inner_loop_atom_intervals(1:2, inner_loop_atoms_interval_index)
2000 :
2001 : CALL compute_3c_integrals(qs_env, bs_env, t_3c_for_G, &
2002 184 : atoms_RI=j_atoms, atoms_AO_2=IL_atoms)
2003 :
2004 : CALL dbt_contract(alpha=1.0_dp, &
2005 : tensor_1=t_2c_G, &
2006 : tensor_2=t_3c_for_G, &
2007 : beta=1.0_dp, &
2008 : tensor_3=t_3c_x_G, &
2009 : contract_1=[2], notcontract_1=[1], map_1=[3], &
2010 : contract_2=[3], notcontract_2=[1, 2], map_2=[1, 2], &
2011 : bounds_2=bounds_i, &
2012 368 : filter_eps=bs_env%eps_filter)
2013 :
2014 : END DO ! IL_atoms
2015 :
2016 184 : CALL dbt_copy(t_3c_x_G, t_3c_x_G_2, order=[1, 3, 2], move_data=.TRUE.)
2017 :
2018 : CALL dbt_contract(alpha=sign_Sigma, &
2019 : tensor_1=t_3c_x_W, &
2020 : tensor_2=t_3c_x_G_2, &
2021 : beta=1.0_dp, &
2022 : tensor_3=t_2c_Sigma, &
2023 : contract_1=[1, 2], notcontract_1=[3], map_1=[1], &
2024 : contract_2=[1, 2], notcontract_2=[3], map_2=[2], &
2025 184 : filter_eps=bs_env%eps_filter, move_data=clear_W, flop=flop)
2026 :
2027 184 : IF (PRESENT(can_skip)) THEN
2028 172 : IF (flop == 0_int_8) can_skip = .TRUE.
2029 : END IF
2030 :
2031 184 : CALL dbt_destroy(t_3c_for_G)
2032 184 : CALL dbt_destroy(t_3c_x_G)
2033 184 : CALL dbt_destroy(t_3c_x_G_2)
2034 :
2035 184 : CALL timestop(handle)
2036 :
2037 184 : END SUBROUTINE contract_to_Sigma
2038 :
2039 : ! **************************************************************************************************
2040 : !> \brief ...
2041 : !> \param fm_Sigma_c_Gamma_time ...
2042 : !> \param bs_env ...
2043 : !> \param mat_Sigma_pos_tau ...
2044 : !> \param mat_Sigma_neg_tau ...
2045 : ! **************************************************************************************************
2046 16 : SUBROUTINE fill_fm_Sigma_c_Gamma_time(fm_Sigma_c_Gamma_time, bs_env, &
2047 : mat_Sigma_pos_tau, mat_Sigma_neg_tau)
2048 :
2049 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_Sigma_c_Gamma_time
2050 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2051 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_Sigma_pos_tau, mat_Sigma_neg_tau
2052 :
2053 : CHARACTER(LEN=*), PARAMETER :: routineN = 'fill_fm_Sigma_c_Gamma_time'
2054 :
2055 : INTEGER :: handle, i_t, ispin, pos_neg
2056 :
2057 16 : CALL timeset(routineN, handle)
2058 :
2059 584 : ALLOCATE (fm_Sigma_c_Gamma_time(bs_env%num_time_freq_points, 2, bs_env%n_spin))
2060 160 : DO i_t = 1, bs_env%num_time_freq_points
2061 384 : DO ispin = 1, bs_env%n_spin
2062 672 : DO pos_neg = 1, 2
2063 : CALL cp_fm_create(fm_Sigma_c_Gamma_time(i_t, pos_neg, ispin), &
2064 672 : bs_env%fm_s_Gamma%matrix_struct)
2065 : END DO
2066 : CALL copy_dbcsr_to_fm(mat_Sigma_pos_tau(i_t, ispin)%matrix, &
2067 224 : fm_Sigma_c_Gamma_time(i_t, 1, ispin))
2068 : CALL copy_dbcsr_to_fm(mat_Sigma_neg_tau(i_t, ispin)%matrix, &
2069 368 : fm_Sigma_c_Gamma_time(i_t, 2, ispin))
2070 : END DO
2071 : END DO
2072 :
2073 16 : CALL timestop(handle)
2074 :
2075 16 : END SUBROUTINE fill_fm_Sigma_c_Gamma_time
2076 :
2077 : ! **************************************************************************************************
2078 : !> \brief ...
2079 : !> \param bs_env ...
2080 : ! **************************************************************************************************
2081 16 : SUBROUTINE print_skipping(bs_env)
2082 :
2083 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2084 :
2085 : CHARACTER(LEN=*), PARAMETER :: routineN = 'print_skipping'
2086 :
2087 : INTEGER :: handle, i_intval_idx, j_intval_idx, &
2088 : n_skip
2089 :
2090 16 : CALL timeset(routineN, handle)
2091 :
2092 16 : n_skip = 0
2093 :
2094 32 : DO i_intval_idx = 1, bs_env%n_intervals_i
2095 48 : DO j_intval_idx = 1, bs_env%n_intervals_j
2096 16 : IF (bs_env%skip_Sigma_occ(i_intval_idx, j_intval_idx) .AND. &
2097 16 : bs_env%skip_Sigma_vir(i_intval_idx, j_intval_idx)) THEN
2098 2 : n_skip = n_skip + 1
2099 : END IF
2100 : END DO
2101 : END DO
2102 :
2103 16 : IF (bs_env%unit_nr > 0) THEN
2104 : WRITE (bs_env%unit_nr, '(T2,A,T74,F7.1,A)') &
2105 8 : 'Sparsity of Σ^c(iτ,k=0): Percentage of skipped atom pairs:', &
2106 16 : REAL(100*n_skip, KIND=dp)/REAL(i_intval_idx*j_intval_idx, KIND=dp), ' %'
2107 : END IF
2108 :
2109 16 : CALL timestop(handle)
2110 :
2111 16 : END SUBROUTINE print_skipping
2112 :
2113 : ! **************************************************************************************************
2114 : !> \brief ...
2115 : !> \param t_2c_Gocc ...
2116 : !> \param t_2c_Gvir ...
2117 : !> \param t_2c_W ...
2118 : !> \param t_2c_Sigma_neg_tau ...
2119 : !> \param t_2c_Sigma_pos_tau ...
2120 : !> \param t_3c_x_W ...
2121 : !> \param fm_W_MIC_time ...
2122 : !> \param mat_Sigma_neg_tau ...
2123 : !> \param mat_Sigma_pos_tau ...
2124 : ! **************************************************************************************************
2125 16 : SUBROUTINE destroy_mat_Sigma_c(t_2c_Gocc, t_2c_Gvir, t_2c_W, t_2c_Sigma_neg_tau, &
2126 : t_2c_Sigma_pos_tau, t_3c_x_W, fm_W_MIC_time, &
2127 : mat_Sigma_neg_tau, mat_Sigma_pos_tau)
2128 :
2129 : TYPE(dbt_type) :: t_2c_Gocc, t_2c_Gvir, t_2c_W, &
2130 : t_2c_Sigma_neg_tau, &
2131 : t_2c_Sigma_pos_tau, t_3c_x_W
2132 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_W_MIC_time
2133 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_Sigma_neg_tau, mat_Sigma_pos_tau
2134 :
2135 : CHARACTER(LEN=*), PARAMETER :: routineN = 'destroy_mat_Sigma_c'
2136 :
2137 : INTEGER :: handle
2138 :
2139 16 : CALL timeset(routineN, handle)
2140 :
2141 16 : CALL dbt_destroy(t_2c_Gocc)
2142 16 : CALL dbt_destroy(t_2c_Gvir)
2143 16 : CALL dbt_destroy(t_2c_W)
2144 16 : CALL dbt_destroy(t_2c_Sigma_neg_tau)
2145 16 : CALL dbt_destroy(t_2c_Sigma_pos_tau)
2146 16 : CALL dbt_destroy(t_3c_x_W)
2147 16 : CALL cp_fm_release(fm_W_MIC_time)
2148 16 : CALL dbcsr_deallocate_matrix_set(mat_Sigma_neg_tau)
2149 16 : CALL dbcsr_deallocate_matrix_set(mat_Sigma_pos_tau)
2150 :
2151 16 : CALL timestop(handle)
2152 :
2153 16 : END SUBROUTINE destroy_mat_Sigma_c
2154 :
2155 : ! **************************************************************************************************
2156 : !> \brief ...
2157 : !> \param bs_env ...
2158 : ! **************************************************************************************************
2159 16 : SUBROUTINE delete_unnecessary_files(bs_env)
2160 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2161 :
2162 : CHARACTER(LEN=*), PARAMETER :: routineN = 'delete_unnecessary_files'
2163 :
2164 : CHARACTER(LEN=default_string_length) :: f_chi, f_W_t, prefix
2165 : INTEGER :: handle, i_t
2166 :
2167 16 : CALL timeset(routineN, handle)
2168 :
2169 16 : prefix = bs_env%prefix
2170 :
2171 160 : DO i_t = 1, bs_env%num_time_freq_points
2172 :
2173 144 : IF (i_t < 10) THEN
2174 132 : WRITE (f_chi, '(3A,I1,A)') TRIM(prefix), bs_env%chi_name, "_00", i_t, ".matrix"
2175 132 : WRITE (f_W_t, '(3A,I1,A)') TRIM(prefix), bs_env%W_time_name, "_00", i_t, ".matrix"
2176 12 : ELSE IF (i_t < 100) THEN
2177 12 : WRITE (f_chi, '(3A,I2,A)') TRIM(prefix), bs_env%chi_name, "_0", i_t, ".matrix"
2178 12 : WRITE (f_W_t, '(3A,I2,A)') TRIM(prefix), bs_env%W_time_name, "_0", i_t, ".matrix"
2179 : ELSE
2180 0 : CPABORT('Please implement more than 99 time/frequency points.')
2181 : END IF
2182 :
2183 144 : CALL safe_delete(f_chi, bs_env)
2184 160 : CALL safe_delete(f_W_t, bs_env)
2185 :
2186 : END DO
2187 :
2188 16 : CALL timestop(handle)
2189 :
2190 16 : END SUBROUTINE delete_unnecessary_files
2191 :
2192 : ! **************************************************************************************************
2193 : !> \brief ...
2194 : !> \param filename ...
2195 : !> \param bs_env ...
2196 : ! **************************************************************************************************
2197 288 : SUBROUTINE safe_delete(filename, bs_env)
2198 : CHARACTER(LEN=*) :: filename
2199 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2200 :
2201 : CHARACTER(LEN=*), PARAMETER :: routineN = 'safe_delete'
2202 :
2203 : INTEGER :: handle
2204 : LOGICAL :: file_exists
2205 :
2206 288 : CALL timeset(routineN, handle)
2207 :
2208 288 : IF (bs_env%para_env%mepos == 0) THEN
2209 :
2210 144 : INQUIRE (file=TRIM(filename), exist=file_exists)
2211 144 : IF (file_exists) CALL mp_file_delete(TRIM(filename))
2212 :
2213 : END IF
2214 :
2215 288 : CALL timestop(handle)
2216 :
2217 288 : END SUBROUTINE safe_delete
2218 :
2219 : ! **************************************************************************************************
2220 : !> \brief ...
2221 : !> \param bs_env ...
2222 : !> \param qs_env ...
2223 : !> \param fm_Sigma_x_Gamma ...
2224 : !> \param fm_Sigma_c_Gamma_time ...
2225 : ! **************************************************************************************************
2226 16 : SUBROUTINE compute_QP_energies(bs_env, qs_env, fm_Sigma_x_Gamma, fm_Sigma_c_Gamma_time)
2227 :
2228 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2229 : TYPE(qs_environment_type), POINTER :: qs_env
2230 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_Sigma_x_Gamma
2231 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: fm_Sigma_c_Gamma_time
2232 :
2233 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_QP_energies'
2234 :
2235 : INTEGER :: handle, ikp, ispin, j_t
2236 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: Sigma_x_ikp_n, V_xc_ikp_n
2237 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: Sigma_c_ikp_n_freq, Sigma_c_ikp_n_time
2238 : TYPE(cp_cfm_type) :: cfm_ks_ikp, cfm_mos_ikp, cfm_s_ikp, &
2239 : cfm_Sigma_x_ikp, cfm_work_ikp
2240 :
2241 16 : CALL timeset(routineN, handle)
2242 :
2243 16 : CALL cp_cfm_create(cfm_mos_ikp, bs_env%fm_s_Gamma%matrix_struct)
2244 16 : CALL cp_cfm_create(cfm_work_ikp, bs_env%fm_s_Gamma%matrix_struct)
2245 : ! JW TODO: fully distribute these arrays at given time; also eigenvalues in bs_env
2246 80 : ALLOCATE (V_xc_ikp_n(bs_env%n_ao), Sigma_x_ikp_n(bs_env%n_ao))
2247 80 : ALLOCATE (Sigma_c_ikp_n_time(bs_env%n_ao, bs_env%num_time_freq_points, 2))
2248 64 : ALLOCATE (Sigma_c_ikp_n_freq(bs_env%n_ao, bs_env%num_time_freq_points, 2))
2249 :
2250 40 : DO ispin = 1, bs_env%n_spin
2251 :
2252 84 : DO ikp = 1, bs_env%nkp_bs_and_DOS
2253 :
2254 : ! 1. get H^KS_µν(k_i) from H^KS_µν(k=0)
2255 : CALL cfm_ikp_from_fm_Gamma(cfm_ks_ikp, bs_env%fm_ks_Gamma(ispin), &
2256 44 : ikp, qs_env, bs_env%kpoints_DOS, "ORB")
2257 :
2258 : ! 2. get S_µν(k_i) from S_µν(k=0)
2259 : CALL cfm_ikp_from_fm_Gamma(cfm_s_ikp, bs_env%fm_s_Gamma, &
2260 44 : ikp, qs_env, bs_env%kpoints_DOS, "ORB")
2261 :
2262 : ! 3. Diagonalize (Roothaan-Hall): H_KS(k_i)*C(k_i) = S(k_i)*C(k_i)*ϵ(k_i)
2263 : CALL cp_cfm_geeig(cfm_ks_ikp, cfm_s_ikp, cfm_mos_ikp, &
2264 44 : bs_env%eigenval_scf(:, ikp, ispin), cfm_work_ikp)
2265 :
2266 : ! 4. V^xc_µν(k=0) -> V^xc_µν(k_i) -> V^xc_nn(k_i)
2267 : CALL to_ikp_and_mo(V_xc_ikp_n, bs_env%fm_V_xc_Gamma(ispin), &
2268 44 : ikp, qs_env, bs_env, cfm_mos_ikp)
2269 :
2270 : ! 5. Σ^x_µν(k=0) -> Σ^x_µν(k_i) -> Σ^x_nn(k_i)
2271 : CALL to_ikp_and_mo(Sigma_x_ikp_n, fm_Sigma_x_Gamma(ispin), &
2272 44 : ikp, qs_env, bs_env, cfm_mos_ikp)
2273 :
2274 : ! 6. Σ^c_µν(k=0,+/-i|τ_j|) -> Σ^c_µν(k_i,+/-i|τ_j|) -> Σ^c_nn(k_i,+/-i|τ_j|)
2275 452 : DO j_t = 1, bs_env%num_time_freq_points
2276 : CALL to_ikp_and_mo(Sigma_c_ikp_n_time(:, j_t, 1), &
2277 : fm_Sigma_c_Gamma_time(j_t, 1, ispin), &
2278 408 : ikp, qs_env, bs_env, cfm_mos_ikp)
2279 : CALL to_ikp_and_mo(Sigma_c_ikp_n_time(:, j_t, 2), &
2280 : fm_Sigma_c_Gamma_time(j_t, 2, ispin), &
2281 452 : ikp, qs_env, bs_env, cfm_mos_ikp)
2282 : END DO
2283 :
2284 : ! 7. Σ^c_nn(k_i,iτ) -> Σ^c_nn(k_i,iω)
2285 44 : CALL time_to_freq(bs_env, Sigma_c_ikp_n_time, Sigma_c_ikp_n_freq, ispin)
2286 :
2287 : ! 8. Analytic continuation Σ^c_nn(k_i,iω) -> Σ^c_nn(k_i,ϵ) and
2288 : ! ϵ_nk_i^GW = ϵ_nk_i^DFT + Σ^c_nn(k_i,ϵ) + Σ^x_nn(k_i) - v^xc_nn(k_i)
2289 : CALL analyt_conti_and_print(bs_env, Sigma_c_ikp_n_freq, Sigma_x_ikp_n, V_xc_ikp_n, &
2290 68 : bs_env%eigenval_scf(:, ikp, ispin), ikp, ispin)
2291 :
2292 : END DO ! ikp_DOS
2293 :
2294 : END DO ! ispin
2295 :
2296 16 : CALL get_all_VBM_CBM_bandgaps(bs_env)
2297 :
2298 16 : CALL cp_fm_release(fm_Sigma_x_Gamma)
2299 16 : CALL cp_fm_release(fm_Sigma_c_Gamma_time)
2300 16 : CALL cp_cfm_release(cfm_ks_ikp)
2301 16 : CALL cp_cfm_release(cfm_s_ikp)
2302 16 : CALL cp_cfm_release(cfm_mos_ikp)
2303 16 : CALL cp_cfm_release(cfm_work_ikp)
2304 16 : CALL cp_cfm_release(cfm_Sigma_x_ikp)
2305 :
2306 16 : CALL timestop(handle)
2307 :
2308 32 : END SUBROUTINE compute_QP_energies
2309 :
2310 : ! **************************************************************************************************
2311 : !> \brief ...
2312 : !> \param array_ikp_n ...
2313 : !> \param fm_Gamma ...
2314 : !> \param ikp ...
2315 : !> \param qs_env ...
2316 : !> \param bs_env ...
2317 : !> \param cfm_mos_ikp ...
2318 : ! **************************************************************************************************
2319 904 : SUBROUTINE to_ikp_and_mo(array_ikp_n, fm_Gamma, ikp, qs_env, bs_env, cfm_mos_ikp)
2320 :
2321 : REAL(KIND=dp), DIMENSION(:) :: array_ikp_n
2322 : TYPE(cp_fm_type) :: fm_Gamma
2323 : INTEGER :: ikp
2324 : TYPE(qs_environment_type), POINTER :: qs_env
2325 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2326 : TYPE(cp_cfm_type) :: cfm_mos_ikp
2327 :
2328 : CHARACTER(LEN=*), PARAMETER :: routineN = 'to_ikp_and_mo'
2329 :
2330 : INTEGER :: handle
2331 : TYPE(cp_fm_type) :: fm_ikp_mo_re
2332 :
2333 904 : CALL timeset(routineN, handle)
2334 :
2335 904 : CALL cp_fm_create(fm_ikp_mo_re, fm_Gamma%matrix_struct)
2336 :
2337 904 : CALL fm_Gamma_ao_to_cfm_ikp_mo(fm_Gamma, fm_ikp_mo_re, ikp, qs_env, bs_env, cfm_mos_ikp)
2338 :
2339 904 : CALL cp_fm_get_diag(fm_ikp_mo_re, array_ikp_n)
2340 :
2341 904 : CALL cp_fm_release(fm_ikp_mo_re)
2342 :
2343 904 : CALL timestop(handle)
2344 :
2345 904 : END SUBROUTINE to_ikp_and_mo
2346 :
2347 : ! **************************************************************************************************
2348 : !> \brief ...
2349 : !> \param fm_Gamma ...
2350 : !> \param fm_ikp_mo_re ...
2351 : !> \param ikp ...
2352 : !> \param qs_env ...
2353 : !> \param bs_env ...
2354 : !> \param cfm_mos_ikp ...
2355 : ! **************************************************************************************************
2356 3616 : SUBROUTINE fm_Gamma_ao_to_cfm_ikp_mo(fm_Gamma, fm_ikp_mo_re, ikp, qs_env, bs_env, cfm_mos_ikp)
2357 : TYPE(cp_fm_type) :: fm_Gamma, fm_ikp_mo_re
2358 : INTEGER :: ikp
2359 : TYPE(qs_environment_type), POINTER :: qs_env
2360 : TYPE(post_scf_bandstructure_type), POINTER :: bs_env
2361 : TYPE(cp_cfm_type) :: cfm_mos_ikp
2362 :
2363 : CHARACTER(LEN=*), PARAMETER :: routineN = 'fm_Gamma_ao_to_cfm_ikp_mo'
2364 :
2365 : INTEGER :: handle, nmo
2366 : TYPE(cp_cfm_type) :: cfm_ikp_ao, cfm_ikp_mo, cfm_tmp
2367 :
2368 904 : CALL timeset(routineN, handle)
2369 :
2370 904 : CALL cp_cfm_create(cfm_ikp_ao, fm_Gamma%matrix_struct)
2371 904 : CALL cp_cfm_create(cfm_ikp_mo, fm_Gamma%matrix_struct)
2372 904 : CALL cp_cfm_create(cfm_tmp, fm_Gamma%matrix_struct)
2373 :
2374 : ! get cfm_µν(k_i) from fm_µν(k=0)
2375 904 : CALL cfm_ikp_from_fm_Gamma(cfm_ikp_ao, fm_Gamma, ikp, qs_env, bs_env%kpoints_DOS, "ORB")
2376 :
2377 904 : nmo = bs_env%n_ao
2378 904 : CALL parallel_gemm('N', 'N', nmo, nmo, nmo, z_one, cfm_ikp_ao, cfm_mos_ikp, z_zero, cfm_tmp)
2379 904 : CALL parallel_gemm('C', 'N', nmo, nmo, nmo, z_one, cfm_mos_ikp, cfm_tmp, z_zero, cfm_ikp_mo)
2380 :
2381 904 : CALL cp_cfm_to_fm(cfm_ikp_mo, fm_ikp_mo_re)
2382 :
2383 904 : CALL cp_cfm_release(cfm_ikp_mo)
2384 904 : CALL cp_cfm_release(cfm_ikp_ao)
2385 904 : CALL cp_cfm_release(cfm_tmp)
2386 :
2387 904 : CALL timestop(handle)
2388 :
2389 904 : END SUBROUTINE fm_Gamma_ao_to_cfm_ikp_mo
2390 :
2391 : END MODULE gw_large_cell_gamma
|