Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Routines treating GW and RPA calculations with kpoints
10 : !> \par History
11 : !> since 2018 continuous development [J. Wilhelm]
12 : ! **************************************************************************************************
13 : MODULE rpa_gw_kpoints_util
14 : USE cell_types, ONLY: cell_type,&
15 : get_cell,&
16 : pbc
17 : USE cp_blacs_env, ONLY: cp_blacs_env_type
18 : USE cp_cfm_basic_linalg, ONLY: cp_cfm_column_scale,&
19 : cp_cfm_scale_and_add_fm,&
20 : cp_cfm_uplo_to_full
21 : USE cp_cfm_cholesky, ONLY: cp_cfm_cholesky_decompose,&
22 : cp_cfm_cholesky_invert
23 : USE cp_cfm_diag, ONLY: cp_cfm_geeig,&
24 : cp_cfm_geeig_canon,&
25 : cp_cfm_heevd
26 : USE cp_cfm_types, ONLY: cp_cfm_create,&
27 : cp_cfm_get_info,&
28 : cp_cfm_release,&
29 : cp_cfm_set_all,&
30 : cp_cfm_to_cfm,&
31 : cp_cfm_to_fm,&
32 : cp_cfm_type
33 : USE cp_control_types, ONLY: dft_control_type
34 : USE cp_dbcsr_api, ONLY: &
35 : dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, dbcsr_desymmetrize, dbcsr_filter, &
36 : dbcsr_get_block_p, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
37 : dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_p_type, &
38 : dbcsr_release, dbcsr_set, dbcsr_transposed, dbcsr_type, dbcsr_type_no_symmetry
39 : USE cp_dbcsr_contrib, ONLY: dbcsr_reserve_all_blocks
40 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
41 : copy_fm_to_dbcsr,&
42 : dbcsr_allocate_matrix_set
43 : USE cp_fm_basic_linalg, ONLY: cp_fm_scale_and_add
44 : USE cp_fm_struct, ONLY: cp_fm_struct_type
45 : USE cp_fm_types, ONLY: cp_fm_copy_general,&
46 : cp_fm_create,&
47 : cp_fm_release,&
48 : cp_fm_set_all,&
49 : cp_fm_type
50 : USE hfx_types, ONLY: hfx_release
51 : USE input_constants, ONLY: cholesky_off,&
52 : kp_weights_W_auto,&
53 : kp_weights_W_tailored,&
54 : kp_weights_W_uniform
55 : USE kinds, ONLY: dp
56 : USE kpoint_methods, ONLY: kpoint_env_initialize,&
57 : kpoint_initialize_mo_set,&
58 : kpoint_initialize_mos
59 : USE kpoint_types, ONLY: get_kpoint_info,&
60 : kpoint_env_type,&
61 : kpoint_type
62 : USE machine, ONLY: m_walltime
63 : USE mathconstants, ONLY: gaussi,&
64 : twopi,&
65 : z_one,&
66 : z_zero
67 : USE mathlib, ONLY: invmat
68 : USE message_passing, ONLY: mp_para_env_type
69 : USE parallel_gemm_api, ONLY: parallel_gemm
70 : USE particle_types, ONLY: particle_type
71 : USE qs_band_structure, ONLY: calculate_kpoints_for_bs
72 : USE qs_environment_types, ONLY: get_qs_env,&
73 : qs_environment_type
74 : USE qs_mo_types, ONLY: get_mo_set
75 : USE qs_scf_types, ONLY: qs_scf_env_type
76 : USE rpa_gw_im_time_util, ONLY: compute_weight_re_im,&
77 : get_atom_index_from_basis_function_index
78 : USE rpa_im_time, ONLY: init_cell_index_rpa
79 : USE scf_control_types, ONLY: scf_control_type
80 : #include "./base/base_uses.f90"
81 :
82 : IMPLICIT NONE
83 :
84 : PRIVATE
85 :
86 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rpa_gw_kpoints_util'
87 :
88 : PUBLIC :: invert_eps_compute_W_and_Erpa_kp, cp_cfm_power, real_space_to_kpoint_transform_rpa, &
89 : get_mat_cell_T_from_mat_gamma, get_bandstruc_and_k_dependent_MOs, &
90 : compute_wkp_W, mat_kp_from_mat_gamma
91 :
92 : CONTAINS
93 :
94 : ! **************************************************************************************************
95 : !> \brief ...
96 : !> \param dimen_RI ...
97 : !> \param num_integ_points ...
98 : !> \param jquad ...
99 : !> \param nkp ...
100 : !> \param count_ev_sc_GW ...
101 : !> \param para_env ...
102 : !> \param Erpa ...
103 : !> \param tau_tj ...
104 : !> \param tj ...
105 : !> \param wj ...
106 : !> \param weights_cos_tf_w_to_t ...
107 : !> \param wkp_W ...
108 : !> \param do_gw_im_time ...
109 : !> \param do_ri_Sigma_x ...
110 : !> \param do_kpoints_from_Gamma ...
111 : !> \param cfm_mat_Q ...
112 : !> \param ikp_local ...
113 : !> \param mat_P_omega ...
114 : !> \param mat_P_omega_kp ...
115 : !> \param qs_env ...
116 : !> \param eps_filter_im_time ...
117 : !> \param unit_nr ...
118 : !> \param kpoints ...
119 : !> \param fm_mat_Minv_L_kpoints ...
120 : !> \param fm_matrix_L_kpoints ...
121 : !> \param fm_mat_W ...
122 : !> \param fm_mat_RI_global_work ...
123 : !> \param mat_MinvVMinv ...
124 : !> \param fm_matrix_Minv ...
125 : !> \param fm_matrix_Minv_Vtrunc_Minv ...
126 : ! **************************************************************************************************
127 120 : SUBROUTINE invert_eps_compute_W_and_Erpa_kp(dimen_RI, num_integ_points, jquad, nkp, count_ev_sc_GW, para_env, &
128 120 : Erpa, tau_tj, tj, wj, weights_cos_tf_w_to_t, wkp_W, do_gw_im_time, &
129 : do_ri_Sigma_x, do_kpoints_from_Gamma, &
130 120 : cfm_mat_Q, ikp_local, mat_P_omega, mat_P_omega_kp, &
131 : qs_env, eps_filter_im_time, unit_nr, kpoints, fm_mat_Minv_L_kpoints, &
132 144 : fm_matrix_L_kpoints, fm_mat_W, &
133 : fm_mat_RI_global_work, mat_MinvVMinv, fm_matrix_Minv, &
134 : fm_matrix_Minv_Vtrunc_Minv)
135 :
136 : INTEGER, INTENT(IN) :: dimen_RI, num_integ_points, jquad, nkp, &
137 : count_ev_sc_GW
138 : TYPE(mp_para_env_type), POINTER :: para_env
139 : REAL(KIND=dp), INTENT(INOUT) :: Erpa
140 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: tau_tj, tj, wj
141 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
142 : INTENT(IN) :: weights_cos_tf_w_to_t
143 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: wkp_W
144 : LOGICAL, INTENT(IN) :: do_gw_im_time, do_ri_Sigma_x, &
145 : do_kpoints_from_Gamma
146 : TYPE(cp_cfm_type), INTENT(IN) :: cfm_mat_Q
147 : INTEGER, INTENT(IN) :: ikp_local
148 : TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(INOUT) :: mat_P_omega, mat_P_omega_kp
149 : TYPE(qs_environment_type), POINTER :: qs_env
150 : REAL(KIND=dp), INTENT(IN) :: eps_filter_im_time
151 : INTEGER, INTENT(IN) :: unit_nr
152 : TYPE(kpoint_type), POINTER :: kpoints
153 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_mat_Minv_L_kpoints, &
154 : fm_matrix_L_kpoints
155 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_W
156 : TYPE(cp_fm_type) :: fm_mat_RI_global_work
157 : TYPE(dbcsr_p_type), INTENT(IN) :: mat_MinvVMinv
158 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_Minv, &
159 : fm_matrix_Minv_Vtrunc_Minv
160 :
161 : CHARACTER(LEN=*), PARAMETER :: routineN = 'invert_eps_compute_W_and_Erpa_kp'
162 :
163 : INTEGER :: handle, ikp
164 : LOGICAL :: do_this_ikp
165 : REAL(KIND=dp) :: t1, t2
166 120 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: trace_Qomega
167 :
168 120 : CALL timeset(routineN, handle)
169 :
170 120 : t1 = m_walltime()
171 :
172 120 : IF (do_kpoints_from_Gamma) THEN
173 96 : CALL get_mat_cell_T_from_mat_gamma(mat_P_omega(jquad, :), qs_env, kpoints, jquad, unit_nr)
174 : END IF
175 :
176 : CALL transform_P_from_real_space_to_kpoints(mat_P_omega, mat_P_omega_kp, &
177 120 : kpoints, eps_filter_im_time, jquad)
178 :
179 360 : ALLOCATE (trace_Qomega(dimen_RI))
180 :
181 120 : IF (unit_nr > 0) WRITE (unit_nr, '(/T3,A,1X,I3)') &
182 60 : 'GW_INFO| Computing chi and W frequency point', jquad
183 :
184 2664 : DO ikp = 1, nkp
185 :
186 : ! parallization, we either have all kpoints on all processors or a single kpoint per group
187 2544 : do_this_ikp = (ikp_local == -1) .OR. (ikp_local == 0 .AND. ikp == 1) .OR. (ikp_local == ikp)
188 : IF (.NOT. do_this_ikp) CYCLE
189 :
190 : ! 1. remove all spurious negative eigenvalues from P(iw,k), multiplication Q(iw,k) = K^H(k)P(iw,k)K(k)
191 : CALL compute_Q_kp_RPA(cfm_mat_Q, &
192 : mat_P_omega_kp, &
193 : fm_mat_Minv_L_kpoints(ikp, 1), &
194 : fm_mat_Minv_L_kpoints(ikp, 2), &
195 : fm_mat_RI_global_work, &
196 : dimen_RI, ikp, nkp, ikp_local, para_env, &
197 2544 : qs_env%mp2_env%ri_rpa_im_time%make_chi_pos_definite)
198 :
199 : ! 2. Cholesky decomposition of Id + Q(iw,k)
200 2544 : CALL cholesky_decomp_Q(cfm_mat_Q, para_env, trace_Qomega, dimen_RI)
201 :
202 : ! 3. Computing E_c^RPA = E_c^RPA + a_w/N_k*sum_k ln[det(1+Q(iw,k))-Tr(Q(iw,k))]
203 : CALL frequency_and_kpoint_integration(Erpa, cfm_mat_Q, para_env, trace_Qomega, &
204 2544 : dimen_RI, wj(jquad), kpoints%wkp(ikp))
205 :
206 2664 : IF (do_gw_im_time) THEN
207 :
208 : ! compute S^-1*V*S^-1 for exchange part of the self-energy in real space as W in real space
209 2496 : IF (do_ri_Sigma_x .AND. jquad == 1 .AND. count_ev_sc_GW == 1 .AND. do_kpoints_from_Gamma) THEN
210 :
211 312 : CALL dbcsr_set(mat_MinvVMinv%matrix, 0.0_dp)
212 312 : CALL copy_fm_to_dbcsr(fm_matrix_Minv_Vtrunc_Minv(1, 1), mat_MinvVMinv%matrix, keep_sparsity=.FALSE.)
213 :
214 : END IF
215 2496 : IF (do_kpoints_from_Gamma) THEN
216 : CALL compute_Wc_real_space_tau_GW(fm_mat_W, cfm_mat_Q, &
217 : fm_matrix_L_kpoints(ikp, 1), &
218 : fm_matrix_L_kpoints(ikp, 2), &
219 : dimen_RI, num_integ_points, jquad, &
220 : ikp, tj, tau_tj, weights_cos_tf_w_to_t, &
221 2496 : ikp_local, para_env, kpoints, qs_env, wkp_W)
222 : END IF
223 :
224 : END IF
225 : END DO
226 :
227 : ! after the transform of (eps(iw)-1)^-1 from iw to it is done, multiply with V^1/2 to obtain W(it)
228 120 : IF (do_gw_im_time .AND. do_kpoints_from_Gamma .AND. jquad == num_integ_points) THEN
229 16 : CALL Wc_to_Minv_Wc_Minv(fm_mat_W, fm_matrix_Minv, para_env, dimen_RI, num_integ_points)
230 16 : CALL deallocate_kp_matrices(fm_matrix_L_kpoints, fm_mat_Minv_L_kpoints)
231 : END IF
232 :
233 120 : DEALLOCATE (trace_Qomega)
234 :
235 120 : t2 = m_walltime()
236 :
237 120 : IF (unit_nr > 0) WRITE (unit_nr, '(T6,A,T56,F25.1)') 'Execution time (s):', t2 - t1
238 :
239 120 : CALL timestop(handle)
240 :
241 120 : END SUBROUTINE invert_eps_compute_W_and_Erpa_kp
242 :
243 : ! **************************************************************************************************
244 : !> \brief ...
245 : !> \param fm_matrix_L_kpoints ...
246 : !> \param fm_mat_Minv_L_kpoints ...
247 : ! **************************************************************************************************
248 16 : SUBROUTINE deallocate_kp_matrices(fm_matrix_L_kpoints, fm_mat_Minv_L_kpoints)
249 :
250 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_L_kpoints, &
251 : fm_mat_Minv_L_kpoints
252 :
253 : CHARACTER(LEN=*), PARAMETER :: routineN = 'deallocate_kp_matrices'
254 :
255 : INTEGER :: handle
256 :
257 16 : CALL timeset(routineN, handle)
258 :
259 16 : CALL cp_fm_release(fm_mat_Minv_L_kpoints)
260 16 : CALL cp_fm_release(fm_matrix_L_kpoints)
261 :
262 16 : CALL timestop(handle)
263 :
264 16 : END SUBROUTINE deallocate_kp_matrices
265 :
266 : ! **************************************************************************************************
267 : !> \brief ...
268 : !> \param matrix ...
269 : !> \param threshold ...
270 : !> \param exponent ...
271 : !> \param min_eigval ...
272 : ! **************************************************************************************************
273 4892 : SUBROUTINE cp_cfm_power(matrix, threshold, exponent, min_eigval)
274 : TYPE(cp_cfm_type), INTENT(INOUT) :: matrix
275 : REAL(KIND=dp) :: threshold, exponent
276 : REAL(KIND=dp), OPTIONAL :: min_eigval
277 :
278 : CHARACTER(LEN=*), PARAMETER :: routineN = 'cp_cfm_power'
279 :
280 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues_exponent
281 : INTEGER :: handle, i, ncol_global, nrow_global
282 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
283 : TYPE(cp_cfm_type) :: cfm_work
284 :
285 4892 : CALL timeset(routineN, handle)
286 :
287 4892 : CALL cp_cfm_create(cfm_work, matrix%matrix_struct)
288 4892 : CALL cp_cfm_set_all(cfm_work, z_zero)
289 :
290 : ! Test that matrix is square
291 4892 : CALL cp_cfm_get_info(matrix, nrow_global=nrow_global, ncol_global=ncol_global)
292 4892 : CPASSERT(nrow_global == ncol_global)
293 264208 : ALLOCATE (eigenvalues(nrow_global), SOURCE=0.0_dp)
294 264208 : ALLOCATE (eigenvalues_exponent(nrow_global), SOURCE=z_zero)
295 :
296 : ! Diagonalize matrix: get eigenvectors and eigenvalues
297 4892 : CALL cp_cfm_heevd(matrix, cfm_work, eigenvalues)
298 :
299 254424 : DO i = 1, nrow_global
300 254424 : IF (eigenvalues(i) > threshold) THEN
301 237570 : eigenvalues_exponent(i) = CMPLX((eigenvalues(i))**(0.5_dp*exponent), threshold, KIND=dp)
302 : ELSE
303 11962 : IF (PRESENT(min_eigval)) THEN
304 0 : eigenvalues_exponent(i) = CMPLX(min_eigval, 0.0_dp, KIND=dp)
305 : ELSE
306 11962 : eigenvalues_exponent(i) = z_zero
307 : END IF
308 : END IF
309 : END DO
310 :
311 4892 : CALL cp_cfm_column_scale(cfm_work, eigenvalues_exponent)
312 :
313 : CALL parallel_gemm("N", "C", nrow_global, nrow_global, nrow_global, z_one, &
314 4892 : cfm_work, cfm_work, z_zero, matrix)
315 :
316 4892 : DEALLOCATE (eigenvalues, eigenvalues_exponent)
317 :
318 4892 : CALL cp_cfm_release(cfm_work)
319 :
320 4892 : CALL timestop(handle)
321 :
322 9784 : END SUBROUTINE cp_cfm_power
323 :
324 : ! **************************************************************************************************
325 : !> \brief ...
326 : !> \param cfm_mat_Q ...
327 : !> \param mat_P_omega_kp ...
328 : !> \param fm_mat_L_re ...
329 : !> \param fm_mat_L_im ...
330 : !> \param fm_mat_RI_global_work ...
331 : !> \param dimen_RI ...
332 : !> \param ikp ...
333 : !> \param nkp ...
334 : !> \param ikp_local ...
335 : !> \param para_env ...
336 : !> \param make_chi_pos_definite ...
337 : ! **************************************************************************************************
338 2544 : SUBROUTINE compute_Q_kp_RPA(cfm_mat_Q, mat_P_omega_kp, fm_mat_L_re, fm_mat_L_im, &
339 : fm_mat_RI_global_work, dimen_RI, ikp, nkp, ikp_local, para_env, &
340 : make_chi_pos_definite)
341 :
342 : TYPE(cp_cfm_type) :: cfm_mat_Q
343 : TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(INOUT) :: mat_P_omega_kp
344 : TYPE(cp_fm_type) :: fm_mat_L_re, fm_mat_L_im, &
345 : fm_mat_RI_global_work
346 : INTEGER, INTENT(IN) :: dimen_RI, ikp, nkp, ikp_local
347 : TYPE(mp_para_env_type), POINTER :: para_env
348 : LOGICAL, INTENT(IN) :: make_chi_pos_definite
349 :
350 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_Q_kp_RPA'
351 :
352 : INTEGER :: handle
353 : TYPE(cp_cfm_type) :: cfm_mat_L, cfm_mat_work
354 : TYPE(cp_fm_type) :: fm_mat_work
355 :
356 2544 : CALL timeset(routineN, handle)
357 :
358 2544 : CALL cp_cfm_create(cfm_mat_work, fm_mat_L_re%matrix_struct)
359 2544 : CALL cp_cfm_set_all(cfm_mat_work, z_zero)
360 :
361 2544 : CALL cp_cfm_create(cfm_mat_L, fm_mat_L_re%matrix_struct)
362 2544 : CALL cp_cfm_set_all(cfm_mat_L, z_zero)
363 :
364 2544 : CALL cp_fm_create(fm_mat_work, fm_mat_L_re%matrix_struct)
365 2544 : CALL cp_fm_set_all(fm_mat_work, 0.0_dp)
366 :
367 : ! 1. Convert the dbcsr matrix mat_P_omega_kp (that is chi(k,iw)) to a full matrix and
368 : ! distribute it to subgroups
369 : CALL mat_P_to_subgroup(mat_P_omega_kp, fm_mat_RI_global_work, &
370 2544 : fm_mat_work, cfm_mat_Q, ikp, nkp, ikp_local, para_env)
371 :
372 : ! 2. Remove all negative eigenvalues from chi(k,iw)
373 2544 : IF (make_chi_pos_definite) THEN
374 2544 : CALL cp_cfm_power(cfm_mat_Q, threshold=0.0_dp, exponent=1.0_dp)
375 : END IF
376 :
377 : ! 3. Copy fm_mat_L_re and fm_mat_L_re to cfm_mat_L
378 2544 : CALL cp_cfm_scale_and_add_fm(z_zero, cfm_mat_L, z_one, fm_mat_L_re)
379 2544 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_L, gaussi, fm_mat_L_im)
380 :
381 : ! 4. work = P(iw,k)*L(k)
382 : CALL parallel_gemm('N', 'N', dimen_RI, dimen_RI, dimen_RI, z_one, cfm_mat_Q, cfm_mat_L, &
383 2544 : z_zero, cfm_mat_work)
384 :
385 : ! 5. Q(iw,k) = L^H(k)*work
386 : CALL parallel_gemm('C', 'N', dimen_RI, dimen_RI, dimen_RI, z_one, cfm_mat_L, cfm_mat_work, &
387 2544 : z_zero, cfm_mat_Q)
388 :
389 2544 : CALL cp_cfm_release(cfm_mat_work)
390 2544 : CALL cp_cfm_release(cfm_mat_L)
391 2544 : CALL cp_fm_release(fm_mat_work)
392 :
393 2544 : CALL timestop(handle)
394 :
395 2544 : END SUBROUTINE compute_Q_kp_RPA
396 :
397 : ! **************************************************************************************************
398 : !> \brief ...
399 : !> \param mat_P_omega_kp ...
400 : !> \param fm_mat_RI_global_work ...
401 : !> \param fm_mat_work ...
402 : !> \param cfm_mat_Q ...
403 : !> \param ikp ...
404 : !> \param nkp ...
405 : !> \param ikp_local ...
406 : !> \param para_env ...
407 : ! **************************************************************************************************
408 2544 : SUBROUTINE mat_P_to_subgroup(mat_P_omega_kp, fm_mat_RI_global_work, &
409 : fm_mat_work, cfm_mat_Q, ikp, nkp, ikp_local, para_env)
410 :
411 : TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(INOUT) :: mat_P_omega_kp
412 : TYPE(cp_fm_type), INTENT(INOUT) :: fm_mat_RI_global_work, fm_mat_work
413 : TYPE(cp_cfm_type), INTENT(IN) :: cfm_mat_Q
414 : INTEGER, INTENT(IN) :: ikp, nkp, ikp_local
415 : TYPE(mp_para_env_type), POINTER :: para_env
416 :
417 : CHARACTER(LEN=*), PARAMETER :: routineN = 'mat_P_to_subgroup'
418 :
419 : INTEGER :: handle, jkp
420 : TYPE(cp_fm_type) :: fm_dummy
421 : TYPE(dbcsr_type), POINTER :: mat_P_omega_im, mat_P_omega_re
422 :
423 2544 : CALL timeset(routineN, handle)
424 :
425 2544 : IF (ikp_local == -1) THEN
426 :
427 2544 : mat_P_omega_re => mat_P_omega_kp(1, ikp)%matrix
428 2544 : CALL cp_fm_set_all(fm_mat_work, 0.0_dp)
429 2544 : CALL copy_dbcsr_to_fm(mat_P_omega_re, fm_mat_work)
430 2544 : CALL cp_cfm_scale_and_add_fm(z_zero, cfm_mat_Q, z_one, fm_mat_work)
431 :
432 2544 : mat_P_omega_im => mat_P_omega_kp(2, ikp)%matrix
433 2544 : CALL cp_fm_set_all(fm_mat_work, 0.0_dp)
434 2544 : CALL copy_dbcsr_to_fm(mat_P_omega_im, fm_mat_work)
435 2544 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_Q, gaussi, fm_mat_work)
436 :
437 : ELSE
438 :
439 0 : CALL cp_fm_set_all(fm_mat_work, 0.0_dp)
440 :
441 0 : DO jkp = 1, nkp
442 :
443 0 : mat_P_omega_re => mat_P_omega_kp(1, jkp)%matrix
444 :
445 0 : CALL cp_fm_set_all(fm_mat_RI_global_work, 0.0_dp)
446 0 : CALL copy_dbcsr_to_fm(mat_P_omega_re, fm_mat_RI_global_work)
447 :
448 0 : CALL para_env%sync()
449 :
450 0 : IF (ikp_local == jkp) THEN
451 0 : CALL cp_fm_copy_general(fm_mat_RI_global_work, fm_mat_work, para_env)
452 : ELSE
453 0 : CALL cp_fm_copy_general(fm_mat_RI_global_work, fm_dummy, para_env)
454 : END IF
455 :
456 0 : CALL para_env%sync()
457 :
458 : END DO
459 :
460 0 : CALL cp_cfm_scale_and_add_fm(z_zero, cfm_mat_Q, z_one, fm_mat_work)
461 :
462 0 : CALL cp_fm_set_all(fm_mat_work, 0.0_dp)
463 :
464 0 : DO jkp = 1, nkp
465 :
466 0 : mat_P_omega_im => mat_P_omega_kp(2, jkp)%matrix
467 :
468 0 : CALL cp_fm_set_all(fm_mat_RI_global_work, 0.0_dp)
469 0 : CALL copy_dbcsr_to_fm(mat_P_omega_im, fm_mat_RI_global_work)
470 :
471 0 : CALL para_env%sync()
472 :
473 0 : IF (ikp_local == jkp) THEN
474 0 : CALL cp_fm_copy_general(fm_mat_RI_global_work, fm_mat_work, para_env)
475 : ELSE
476 0 : CALL cp_fm_copy_general(fm_mat_RI_global_work, fm_dummy, para_env)
477 : END IF
478 :
479 0 : CALL para_env%sync()
480 :
481 : END DO
482 :
483 0 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_Q, gaussi, fm_mat_work)
484 :
485 0 : CALL cp_fm_set_all(fm_mat_work, 0.0_dp)
486 :
487 : END IF
488 :
489 2544 : CALL para_env%sync()
490 :
491 2544 : CALL timestop(handle)
492 :
493 2544 : END SUBROUTINE mat_P_to_subgroup
494 :
495 : ! **************************************************************************************************
496 : !> \brief ...
497 : !> \param cfm_mat_Q ...
498 : !> \param para_env ...
499 : !> \param trace_Qomega ...
500 : !> \param dimen_RI ...
501 : ! **************************************************************************************************
502 2544 : SUBROUTINE cholesky_decomp_Q(cfm_mat_Q, para_env, trace_Qomega, dimen_RI)
503 :
504 : TYPE(cp_cfm_type), INTENT(IN) :: cfm_mat_Q
505 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
506 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: trace_Qomega
507 : INTEGER, INTENT(IN) :: dimen_RI
508 :
509 : CHARACTER(LEN=*), PARAMETER :: routineN = 'cholesky_decomp_Q'
510 :
511 : INTEGER :: handle, i_global, iiB, info_chol, &
512 : j_global, jjB, ncol_local, nrow_local
513 2544 : INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
514 : TYPE(cp_cfm_type) :: cfm_mat_Q_tmp, cfm_mat_work
515 :
516 2544 : CALL timeset(routineN, handle)
517 :
518 2544 : CALL cp_cfm_create(cfm_mat_work, cfm_mat_Q%matrix_struct)
519 2544 : CALL cp_cfm_set_all(cfm_mat_work, z_zero)
520 :
521 2544 : CALL cp_cfm_create(cfm_mat_Q_tmp, cfm_mat_Q%matrix_struct)
522 2544 : CALL cp_cfm_set_all(cfm_mat_Q_tmp, z_zero)
523 :
524 : ! get info of fm_mat_Q
525 : CALL cp_cfm_get_info(matrix=cfm_mat_Q, &
526 : nrow_local=nrow_local, &
527 : ncol_local=ncol_local, &
528 : row_indices=row_indices, &
529 2544 : col_indices=col_indices)
530 :
531 : ! calculate the trace of Q and add 1 on the diagonal
532 180624 : trace_Qomega = 0.0_dp
533 : !$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,iiB,i_global,j_global) &
534 2544 : !$OMP SHARED(ncol_local,nrow_local,col_indices,row_indices,trace_Qomega,cfm_mat_Q,dimen_RI)
535 : DO jjB = 1, ncol_local
536 : j_global = col_indices(jjB)
537 : DO iiB = 1, nrow_local
538 : i_global = row_indices(iiB)
539 : IF (j_global == i_global .AND. i_global <= dimen_RI) THEN
540 : trace_Qomega(i_global) = REAL(cfm_mat_Q%local_data(iiB, jjB))
541 : cfm_mat_Q%local_data(iiB, jjB) = cfm_mat_Q%local_data(iiB, jjB) + z_one
542 : END IF
543 : END DO
544 : END DO
545 358704 : CALL para_env%sum(trace_Qomega)
546 :
547 2544 : CALL cp_cfm_to_cfm(cfm_mat_Q, cfm_mat_Q_tmp)
548 :
549 2544 : CALL cp_cfm_cholesky_decompose(matrix=cfm_mat_Q, n=dimen_RI, info_out=info_chol)
550 :
551 2544 : CPASSERT(info_chol == 0)
552 :
553 2544 : CALL cp_cfm_release(cfm_mat_work)
554 2544 : CALL cp_cfm_release(cfm_mat_Q_tmp)
555 :
556 2544 : CALL timestop(handle)
557 :
558 2544 : END SUBROUTINE cholesky_decomp_Q
559 :
560 : ! **************************************************************************************************
561 : !> \brief ...
562 : !> \param Erpa ...
563 : !> \param cfm_mat_Q ...
564 : !> \param para_env ...
565 : !> \param trace_Qomega ...
566 : !> \param dimen_RI ...
567 : !> \param freq_weight ...
568 : !> \param kp_weight ...
569 : ! **************************************************************************************************
570 2544 : SUBROUTINE frequency_and_kpoint_integration(Erpa, cfm_mat_Q, para_env, trace_Qomega, &
571 : dimen_RI, freq_weight, kp_weight)
572 :
573 : REAL(KIND=dp), INTENT(INOUT) :: Erpa
574 : TYPE(cp_cfm_type), INTENT(IN) :: cfm_mat_Q
575 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
576 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: trace_Qomega
577 : INTEGER, INTENT(IN) :: dimen_RI
578 : REAL(KIND=dp), INTENT(IN) :: freq_weight, kp_weight
579 :
580 : CHARACTER(LEN=*), PARAMETER :: routineN = 'frequency_and_kpoint_integration'
581 :
582 : INTEGER :: handle, i_global, iiB, j_global, jjB, &
583 : ncol_local, nrow_local
584 2544 : INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
585 : REAL(KIND=dp) :: FComega
586 2544 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: Q_log
587 :
588 2544 : CALL timeset(routineN, handle)
589 :
590 : ! get info of cholesky_decomposed(fm_mat_Q)
591 : CALL cp_cfm_get_info(matrix=cfm_mat_Q, &
592 : nrow_local=nrow_local, &
593 : ncol_local=ncol_local, &
594 : row_indices=row_indices, &
595 2544 : col_indices=col_indices)
596 :
597 7632 : ALLOCATE (Q_log(dimen_RI))
598 180624 : Q_log = 0.0_dp
599 : !$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,iiB,i_global,j_global) &
600 2544 : !$OMP SHARED(ncol_local,nrow_local,col_indices,row_indices,Q_log,cfm_mat_Q,dimen_RI)
601 : DO jjB = 1, ncol_local
602 : j_global = col_indices(jjB)
603 : DO iiB = 1, nrow_local
604 : i_global = row_indices(iiB)
605 : IF (j_global == i_global .AND. i_global <= dimen_RI) THEN
606 : Q_log(i_global) = 2.0_dp*LOG(REAL(cfm_mat_Q%local_data(iiB, jjB)))
607 : END IF
608 : END DO
609 : END DO
610 2544 : CALL para_env%sum(Q_log)
611 :
612 2544 : FComega = 0.0_dp
613 180624 : DO iiB = 1, dimen_RI
614 178080 : IF (MODULO(iiB, para_env%num_pe) /= para_env%mepos) CYCLE
615 : ! FComega=FComega+(LOG(Q_log(iiB))-trace_Qomega(iiB))/2.0_dp
616 180624 : FComega = FComega + (Q_log(iiB) - trace_Qomega(iiB))/2.0_dp
617 : END DO
618 :
619 2544 : Erpa = Erpa + FComega*freq_weight*kp_weight
620 :
621 2544 : DEALLOCATE (Q_log)
622 :
623 2544 : CALL timestop(handle)
624 :
625 5088 : END SUBROUTINE frequency_and_kpoint_integration
626 :
627 : ! **************************************************************************************************
628 : !> \brief ...
629 : !> \param tj_dummy ...
630 : !> \param tau_tj_dummy ...
631 : !> \param weights_cos_tf_w_to_t_dummy ...
632 : ! **************************************************************************************************
633 0 : SUBROUTINE get_dummys(tj_dummy, tau_tj_dummy, weights_cos_tf_w_to_t_dummy)
634 :
635 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
636 : INTENT(INOUT) :: tj_dummy, tau_tj_dummy
637 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
638 : INTENT(INOUT) :: weights_cos_tf_w_to_t_dummy
639 :
640 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_dummys'
641 :
642 : INTEGER :: handle
643 :
644 0 : CALL timeset(routineN, handle)
645 :
646 0 : ALLOCATE (weights_cos_tf_w_to_t_dummy(1, 1))
647 0 : ALLOCATE (tj_dummy(1))
648 0 : ALLOCATE (tau_tj_dummy(1))
649 :
650 0 : tj_dummy(1) = 0.0_dp
651 0 : tau_tj_dummy(1) = 0.0_dp
652 0 : weights_cos_tf_w_to_t_dummy(1, 1) = 1.0_dp
653 :
654 0 : CALL timestop(handle)
655 :
656 0 : END SUBROUTINE get_dummys
657 :
658 : ! **************************************************************************************************
659 : !> \brief ...
660 : !> \param tj_dummy ...
661 : !> \param tau_tj_dummy ...
662 : !> \param weights_cos_tf_w_to_t_dummy ...
663 : ! **************************************************************************************************
664 0 : SUBROUTINE release_dummys(tj_dummy, tau_tj_dummy, weights_cos_tf_w_to_t_dummy)
665 :
666 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
667 : INTENT(INOUT) :: tj_dummy, tau_tj_dummy
668 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
669 : INTENT(INOUT) :: weights_cos_tf_w_to_t_dummy
670 :
671 : CHARACTER(LEN=*), PARAMETER :: routineN = 'release_dummys'
672 :
673 : INTEGER :: handle
674 :
675 0 : CALL timeset(routineN, handle)
676 :
677 0 : DEALLOCATE (weights_cos_tf_w_to_t_dummy)
678 0 : DEALLOCATE (tj_dummy)
679 0 : DEALLOCATE (tau_tj_dummy)
680 :
681 0 : CALL timestop(handle)
682 :
683 0 : END SUBROUTINE release_dummys
684 :
685 : ! **************************************************************************************************
686 : !> \brief ...
687 : !> \param mat_P_omega ...
688 : !> \param qs_env ...
689 : !> \param kpoints ...
690 : !> \param jquad ...
691 : !> \param unit_nr ...
692 : ! **************************************************************************************************
693 440 : SUBROUTINE get_mat_cell_T_from_mat_gamma(mat_P_omega, qs_env, kpoints, jquad, unit_nr)
694 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: mat_P_omega
695 : TYPE(qs_environment_type), POINTER :: qs_env
696 : TYPE(kpoint_type), POINTER :: kpoints
697 : INTEGER, INTENT(IN) :: jquad, unit_nr
698 :
699 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_mat_cell_T_from_mat_gamma'
700 :
701 : INTEGER :: col, handle, i_cell, i_dim, j_cell, &
702 : num_cells_P, num_integ_points, row
703 : INTEGER, DIMENSION(3) :: cell_grid_P, periodic
704 440 : INTEGER, DIMENSION(:, :), POINTER :: index_to_cell_P
705 : LOGICAL :: i_cell_is_the_minimum_image_cell
706 : REAL(KIND=dp) :: abs_rab_cell_i, abs_rab_cell_j
707 : REAL(KIND=dp), DIMENSION(3) :: cell_vector, cell_vector_j, rab_cell_i, &
708 : rab_cell_j
709 : REAL(KIND=dp), DIMENSION(3, 3) :: hmat
710 440 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: data_block
711 : TYPE(cell_type), POINTER :: cell
712 : TYPE(dbcsr_iterator_type) :: iter
713 440 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
714 :
715 440 : CALL timeset(routineN, handle)
716 :
717 440 : NULLIFY (cell, particle_set)
718 : CALL get_qs_env(qs_env, cell=cell, &
719 440 : particle_set=particle_set)
720 440 : CALL get_cell(cell=cell, h=hmat, periodic=periodic)
721 :
722 1760 : DO i_dim = 1, 3
723 : ! we have at most 3 neigboring cells per dimension and at least one because
724 : ! the density response at Gamma is only divided to neighboring
725 1760 : IF (periodic(i_dim) == 1) THEN
726 880 : cell_grid_P(i_dim) = MAX(MIN((kpoints%nkp_grid(i_dim)/2)*2 - 1, 1), 3)
727 : ELSE
728 440 : cell_grid_P(i_dim) = 1
729 : END IF
730 : END DO
731 :
732 : ! overwrite the cell indices in kpoints
733 440 : CALL init_cell_index_rpa(cell_grid_P, kpoints%cell_to_index, kpoints%index_to_cell, cell)
734 :
735 440 : index_to_cell_P => kpoints%index_to_cell
736 :
737 440 : num_cells_P = SIZE(index_to_cell_P, 2)
738 :
739 440 : num_integ_points = SIZE(mat_P_omega, 1)
740 :
741 : ! first, copy the Gamma-only result from mat_P_omega(1) into all other matrices and
742 : ! remove the blocks later which do not belong to the cell index
743 3960 : DO i_cell = 2, num_cells_P
744 : CALL dbcsr_copy(mat_P_omega(i_cell)%matrix, &
745 3960 : mat_P_omega(1)%matrix)
746 : END DO
747 :
748 440 : IF (jquad == 1 .AND. unit_nr > 0) THEN
749 8 : WRITE (unit_nr, '(T3,A,T66,ES15.2)') 'GW_INFO| RI regularization parameter: ', &
750 16 : qs_env%mp2_env%ri_rpa_im_time%regularization_RI
751 8 : WRITE (unit_nr, '(T3,A,T66,ES15.2)') 'GW_INFO| eps_eigval_S: ', &
752 16 : qs_env%mp2_env%ri_rpa_im_time%eps_eigval_S
753 8 : IF (qs_env%mp2_env%ri_rpa_im_time%make_chi_pos_definite) THEN
754 : WRITE (unit_nr, '(T3,A,T81)') &
755 8 : 'GW_INFO| Make chi(iw,k) positive definite? TRUE'
756 : ELSE
757 : WRITE (unit_nr, '(T3,A,T81)') &
758 0 : 'GW_INFO| Make chi(iw,k) positive definite? FALSE'
759 : END IF
760 :
761 : END IF
762 :
763 4400 : DO i_cell = 1, num_cells_P
764 :
765 3960 : CALL dbcsr_iterator_start(iter, mat_P_omega(i_cell)%matrix)
766 20385 : DO WHILE (dbcsr_iterator_blocks_left(iter))
767 16425 : CALL dbcsr_iterator_next_block(iter, row, col, data_block)
768 :
769 262800 : cell_vector(1:3) = MATMUL(hmat, REAL(index_to_cell_P(1:3, i_cell), dp))
770 : rab_cell_i(1:3) = pbc(particle_set(row)%r(1:3), cell) - &
771 65700 : (pbc(particle_set(col)%r(1:3), cell) + cell_vector(1:3))
772 16425 : abs_rab_cell_i = SQRT(rab_cell_i(1)**2 + rab_cell_i(2)**2 + rab_cell_i(3)**2)
773 :
774 : ! minimum image convention
775 16425 : i_cell_is_the_minimum_image_cell = .TRUE.
776 164250 : DO j_cell = 1, num_cells_P
777 2365200 : cell_vector_j(1:3) = MATMUL(hmat, REAL(index_to_cell_P(1:3, j_cell), dp))
778 : rab_cell_j(1:3) = pbc(particle_set(row)%r(1:3), cell) - &
779 591300 : (pbc(particle_set(col)%r(1:3), cell) + cell_vector_j(1:3))
780 147825 : abs_rab_cell_j = SQRT(rab_cell_j(1)**2 + rab_cell_j(2)**2 + rab_cell_j(3)**2)
781 :
782 164250 : IF (abs_rab_cell_i > abs_rab_cell_j + 1.0E-6_dp) THEN
783 53748 : i_cell_is_the_minimum_image_cell = .FALSE.
784 : END IF
785 : END DO
786 :
787 32850 : IF (.NOT. i_cell_is_the_minimum_image_cell) THEN
788 2809552 : data_block(:, :) = data_block(:, :)*0.0_dp
789 : END IF
790 :
791 : END DO
792 8360 : CALL dbcsr_iterator_stop(iter)
793 :
794 : END DO
795 :
796 440 : CALL timestop(handle)
797 :
798 440 : END SUBROUTINE get_mat_cell_T_from_mat_gamma
799 :
800 : ! **************************************************************************************************
801 : !> \brief ...
802 : !> \param mat_P_omega ...
803 : !> \param mat_P_omega_kp ...
804 : !> \param kpoints ...
805 : !> \param eps_filter_im_time ...
806 : !> \param jquad ...
807 : ! **************************************************************************************************
808 120 : SUBROUTINE transform_P_from_real_space_to_kpoints(mat_P_omega, mat_P_omega_kp, &
809 : kpoints, eps_filter_im_time, jquad)
810 :
811 : TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(INOUT) :: mat_P_omega, mat_P_omega_kp
812 : TYPE(kpoint_type), POINTER :: kpoints
813 : REAL(kind=dp), INTENT(IN) :: eps_filter_im_time
814 : INTEGER, INTENT(IN) :: jquad
815 :
816 : CHARACTER(LEN=*), PARAMETER :: routineN = 'transform_P_from_real_space_to_kpoints'
817 :
818 : INTEGER :: handle, icell, nkp, num_integ_points
819 :
820 120 : CALL timeset(routineN, handle)
821 :
822 120 : num_integ_points = SIZE(mat_P_omega, 1)
823 120 : nkp = SIZE(mat_P_omega, 2)
824 :
825 : CALL real_space_to_kpoint_transform_rpa(mat_P_omega_kp(1, :), mat_P_omega_kp(2, :), mat_P_omega(jquad, :), &
826 120 : kpoints, eps_filter_im_time)
827 :
828 2664 : DO icell = 1, SIZE(mat_P_omega, 2)
829 2544 : CALL dbcsr_set(mat_P_omega(jquad, icell)%matrix, 0.0_dp)
830 2664 : CALL dbcsr_filter(mat_P_omega(jquad, icell)%matrix, 1.0_dp)
831 : END DO
832 :
833 120 : CALL timestop(handle)
834 :
835 120 : END SUBROUTINE transform_P_from_real_space_to_kpoints
836 :
837 : ! **************************************************************************************************
838 : !> \brief ...
839 : !> \param real_mat_kp ...
840 : !> \param imag_mat_kp ...
841 : !> \param mat_real_space ...
842 : !> \param kpoints ...
843 : !> \param eps_filter_im_time ...
844 : !> \param real_mat_real_space ...
845 : ! **************************************************************************************************
846 464 : SUBROUTINE real_space_to_kpoint_transform_rpa(real_mat_kp, imag_mat_kp, mat_real_space, &
847 : kpoints, eps_filter_im_time, real_mat_real_space)
848 :
849 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT) :: real_mat_kp, imag_mat_kp, mat_real_space
850 : TYPE(kpoint_type), POINTER :: kpoints
851 : REAL(KIND=dp), INTENT(IN) :: eps_filter_im_time
852 : LOGICAL, INTENT(IN), OPTIONAL :: real_mat_real_space
853 :
854 : CHARACTER(LEN=*), PARAMETER :: routineN = 'real_space_to_kpoint_transform_rpa'
855 :
856 : INTEGER :: handle, i_cell, ik, nkp, num_cells
857 : INTEGER, DIMENSION(3) :: cell
858 464 : INTEGER, DIMENSION(:, :), POINTER :: index_to_cell
859 : LOGICAL :: my_real_mat_real_space
860 : REAL(KIND=dp) :: arg, coskl, sinkl
861 464 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
862 : TYPE(dbcsr_type) :: mat_work
863 :
864 464 : CALL timeset(routineN, handle)
865 :
866 464 : my_real_mat_real_space = .TRUE.
867 464 : IF (PRESENT(real_mat_real_space)) my_real_mat_real_space = real_mat_real_space
868 :
869 : CALL dbcsr_create(matrix=mat_work, &
870 : template=real_mat_kp(1)%matrix, &
871 464 : matrix_type=dbcsr_type_no_symmetry)
872 464 : CALL dbcsr_reserve_all_blocks(mat_work)
873 464 : CALL dbcsr_set(mat_work, 0.0_dp)
874 :
875 : ! this kpoint environme t should be the kpoints for D(it) and X(it) created in init_cell_index_rpa
876 464 : CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp)
877 :
878 464 : NULLIFY (index_to_cell)
879 464 : index_to_cell => kpoints%index_to_cell
880 :
881 464 : num_cells = SIZE(index_to_cell, 2)
882 :
883 464 : CPASSERT(SIZE(mat_real_space) >= num_cells/2 + 1)
884 :
885 5338 : DO ik = 1, nkp
886 :
887 4874 : CALL dbcsr_reserve_all_blocks(real_mat_kp(ik)%matrix)
888 4874 : CALL dbcsr_reserve_all_blocks(imag_mat_kp(ik)%matrix)
889 :
890 4874 : CALL dbcsr_set(real_mat_kp(ik)%matrix, 0.0_dp)
891 4874 : CALL dbcsr_set(imag_mat_kp(ik)%matrix, 0.0_dp)
892 :
893 29100 : DO i_cell = 1, num_cells/2 + 1
894 :
895 96904 : cell(:) = index_to_cell(:, i_cell)
896 :
897 24226 : arg = REAL(cell(1), dp)*xkp(1, ik) + REAL(cell(2), dp)*xkp(2, ik) + REAL(cell(3), dp)*xkp(3, ik)
898 24226 : coskl = COS(twopi*arg)
899 24226 : sinkl = SIN(twopi*arg)
900 :
901 24226 : IF (my_real_mat_real_space) THEN
902 23986 : CALL dbcsr_add_local(real_mat_kp(ik)%matrix, mat_real_space(i_cell)%matrix, 1.0_dp, coskl)
903 23986 : CALL dbcsr_add_local(imag_mat_kp(ik)%matrix, mat_real_space(i_cell)%matrix, 1.0_dp, sinkl)
904 : ELSE
905 240 : CALL dbcsr_add_local(real_mat_kp(ik)%matrix, mat_real_space(i_cell)%matrix, 1.0_dp, -sinkl)
906 240 : CALL dbcsr_add_local(imag_mat_kp(ik)%matrix, mat_real_space(i_cell)%matrix, 1.0_dp, coskl)
907 : END IF
908 :
909 29100 : IF (.NOT. (cell(1) == 0 .AND. cell(2) == 0 .AND. cell(3) == 0)) THEN
910 :
911 19352 : CALL dbcsr_transposed(mat_work, mat_real_space(i_cell)%matrix)
912 :
913 19352 : IF (my_real_mat_real_space) THEN
914 19160 : CALL dbcsr_add_local(real_mat_kp(ik)%matrix, mat_work, 1.0_dp, coskl)
915 19160 : CALL dbcsr_add_local(imag_mat_kp(ik)%matrix, mat_work, 1.0_dp, -sinkl)
916 : ELSE
917 : ! for an imaginary real-space matrix, we need to consider the imaginary unit
918 : ! and we need to take into account that the transposed gives an extra "-" sign
919 : ! because the transposed is actually Hermitian conjugate
920 192 : CALL dbcsr_add_local(real_mat_kp(ik)%matrix, mat_work, 1.0_dp, -sinkl)
921 192 : CALL dbcsr_add_local(imag_mat_kp(ik)%matrix, mat_work, 1.0_dp, -coskl)
922 : END IF
923 :
924 19352 : CALL dbcsr_set(mat_work, 0.0_dp)
925 :
926 : END IF
927 :
928 : END DO
929 :
930 4874 : CALL dbcsr_filter(real_mat_kp(ik)%matrix, eps_filter_im_time)
931 5338 : CALL dbcsr_filter(imag_mat_kp(ik)%matrix, eps_filter_im_time)
932 :
933 : END DO
934 :
935 464 : CALL dbcsr_release(mat_work)
936 :
937 464 : CALL timestop(handle)
938 :
939 464 : END SUBROUTINE real_space_to_kpoint_transform_rpa
940 :
941 : ! **************************************************************************************************
942 : !> \brief ...
943 : !> \param mat_a ...
944 : !> \param mat_b ...
945 : !> \param alpha ...
946 : !> \param beta ...
947 : ! **************************************************************************************************
948 87156 : SUBROUTINE dbcsr_add_local(mat_a, mat_b, alpha, beta)
949 : TYPE(dbcsr_type), INTENT(INOUT) :: mat_a, mat_b
950 : REAL(kind=dp), INTENT(IN) :: alpha, beta
951 :
952 : INTEGER :: col, row
953 : LOGICAL :: found
954 87156 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: block_to_compute, data_block
955 : TYPE(dbcsr_iterator_type) :: iter
956 :
957 87156 : CALL dbcsr_iterator_start(iter, mat_b)
958 455994 : DO WHILE (dbcsr_iterator_blocks_left(iter))
959 368838 : CALL dbcsr_iterator_next_block(iter, row, col, data_block)
960 :
961 368838 : NULLIFY (block_to_compute)
962 : CALL dbcsr_get_block_p(matrix=mat_a, &
963 368838 : row=row, col=col, block=block_to_compute, found=found)
964 :
965 368838 : CPASSERT(found)
966 :
967 275001360 : block_to_compute(:, :) = alpha*block_to_compute(:, :) + beta*data_block(:, :)
968 :
969 : END DO
970 87156 : CALL dbcsr_iterator_stop(iter)
971 :
972 87156 : END SUBROUTINE dbcsr_add_local
973 :
974 : ! **************************************************************************************************
975 : !> \brief ...
976 : !> \param fm_mat_W_tau ...
977 : !> \param cfm_mat_Q ...
978 : !> \param fm_mat_L_re ...
979 : !> \param fm_mat_L_im ...
980 : !> \param dimen_RI ...
981 : !> \param num_integ_points ...
982 : !> \param jquad ...
983 : !> \param ikp ...
984 : !> \param tj ...
985 : !> \param tau_tj ...
986 : !> \param weights_cos_tf_w_to_t ...
987 : !> \param ikp_local ...
988 : !> \param para_env ...
989 : !> \param kpoints ...
990 : !> \param qs_env ...
991 : !> \param wkp_W ...
992 : ! **************************************************************************************************
993 2496 : SUBROUTINE compute_Wc_real_space_tau_GW(fm_mat_W_tau, cfm_mat_Q, fm_mat_L_re, fm_mat_L_im, &
994 : dimen_RI, num_integ_points, jquad, &
995 2496 : ikp, tj, tau_tj, weights_cos_tf_w_to_t, ikp_local, &
996 2496 : para_env, kpoints, qs_env, wkp_W)
997 :
998 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_W_tau
999 : TYPE(cp_cfm_type), INTENT(IN) :: cfm_mat_Q
1000 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_L_re, fm_mat_L_im
1001 : INTEGER, INTENT(IN) :: dimen_RI, num_integ_points, jquad, ikp
1002 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: tj
1003 : REAL(KIND=dp), DIMENSION(num_integ_points), &
1004 : INTENT(IN) :: tau_tj
1005 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: weights_cos_tf_w_to_t
1006 : INTEGER, INTENT(IN) :: ikp_local
1007 : TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env
1008 : TYPE(kpoint_type), INTENT(IN), POINTER :: kpoints
1009 : TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1010 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: wkp_W
1011 :
1012 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_Wc_real_space_tau_GW'
1013 :
1014 : INTEGER :: handle, handle2, i_global, iatom, iatom_old, iiB, iquad, irow, j_global, jatom, &
1015 : jatom_old, jcol, jjB, jkp, ncol_local, nkp, nrow_local, num_cells
1016 2496 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_from_RI_index
1017 2496 : INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1018 2496 : INTEGER, DIMENSION(:, :), POINTER :: index_to_cell
1019 : REAL(KIND=dp) :: contribution, omega, tau, weight, &
1020 : weight_im, weight_re
1021 : REAL(KIND=dp), DIMENSION(3, 3) :: hmat
1022 2496 : REAL(KIND=dp), DIMENSION(:), POINTER :: wkp
1023 2496 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
1024 : TYPE(cell_type), POINTER :: cell
1025 : TYPE(cp_cfm_type) :: cfm_mat_L, cfm_mat_work, cfm_mat_work_2
1026 : TYPE(cp_fm_type) :: fm_dummy, fm_mat_work_global, &
1027 : fm_mat_work_local
1028 2496 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1029 :
1030 2496 : CALL timeset(routineN, handle)
1031 :
1032 2496 : CALL timeset(routineN//"_1", handle2)
1033 :
1034 2496 : CALL cp_cfm_create(cfm_mat_work, cfm_mat_Q%matrix_struct)
1035 2496 : CALL cp_cfm_set_all(cfm_mat_work, z_zero)
1036 :
1037 2496 : CALL cp_cfm_create(cfm_mat_work_2, cfm_mat_Q%matrix_struct)
1038 2496 : CALL cp_cfm_set_all(cfm_mat_work_2, z_zero)
1039 :
1040 2496 : CALL cp_cfm_create(cfm_mat_L, cfm_mat_Q%matrix_struct)
1041 2496 : CALL cp_cfm_set_all(cfm_mat_L, z_zero)
1042 :
1043 : ! Copy fm_mat_L_re and fm_mat_L_re to cfm_mat_L
1044 2496 : CALL cp_cfm_scale_and_add_fm(z_zero, cfm_mat_L, z_one, fm_mat_L_re)
1045 2496 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_L, gaussi, fm_mat_L_im)
1046 :
1047 2496 : CALL cp_fm_create(fm_mat_work_global, fm_mat_W_tau(1)%matrix_struct)
1048 2496 : CALL cp_fm_set_all(fm_mat_work_global, 0.0_dp)
1049 :
1050 2496 : CALL cp_fm_create(fm_mat_work_local, cfm_mat_Q%matrix_struct)
1051 2496 : CALL cp_fm_set_all(fm_mat_work_local, 0.0_dp)
1052 :
1053 2496 : CALL timestop(handle2)
1054 :
1055 2496 : CALL timeset(routineN//"_2", handle2)
1056 :
1057 : ! calculate [1+Q(iw')]^-1
1058 2496 : CALL cp_cfm_cholesky_invert(cfm_mat_Q)
1059 :
1060 : ! symmetrize the result
1061 2496 : CALL cp_cfm_uplo_to_full(cfm_mat_Q)
1062 :
1063 : ! subtract exchange part by subtracing identity matrix from epsilon
1064 : CALL cp_cfm_get_info(matrix=cfm_mat_Q, &
1065 : nrow_local=nrow_local, &
1066 : ncol_local=ncol_local, &
1067 : row_indices=row_indices, &
1068 2496 : col_indices=col_indices)
1069 :
1070 176592 : DO jjB = 1, ncol_local
1071 174096 : j_global = col_indices(jjB)
1072 6950424 : DO iiB = 1, nrow_local
1073 6773832 : i_global = row_indices(iiB)
1074 6947928 : IF (j_global == i_global .AND. i_global <= dimen_RI) THEN
1075 87048 : cfm_mat_Q%local_data(iiB, jjB) = cfm_mat_Q%local_data(iiB, jjB) - z_one
1076 : END IF
1077 : END DO
1078 : END DO
1079 :
1080 2496 : CALL timestop(handle2)
1081 :
1082 2496 : CALL timeset(routineN//"_3", handle2)
1083 :
1084 : ! work = epsilon(iw,k)*V^1/2(k)
1085 : CALL parallel_gemm('N', 'N', dimen_RI, dimen_RI, dimen_RI, z_one, cfm_mat_Q, cfm_mat_L, &
1086 2496 : z_zero, cfm_mat_work)
1087 :
1088 : ! W(iw,k) = V^1/2(k)*work
1089 : CALL parallel_gemm('N', 'N', dimen_RI, dimen_RI, dimen_RI, z_one, cfm_mat_L, cfm_mat_work, &
1090 2496 : z_zero, cfm_mat_work_2)
1091 :
1092 2496 : CALL timestop(handle2)
1093 :
1094 2496 : CALL timeset(routineN//"_4", handle2)
1095 :
1096 2496 : CALL get_kpoint_info(kpoints, xkp=xkp, wkp=wkp, nkp=nkp)
1097 2496 : index_to_cell => kpoints%index_to_cell
1098 2496 : num_cells = SIZE(index_to_cell, 2)
1099 :
1100 2496 : CALL cp_cfm_set_all(cfm_mat_work, z_zero)
1101 :
1102 7488 : ALLOCATE (atom_from_RI_index(dimen_RI))
1103 :
1104 2496 : CALL get_atom_index_from_basis_function_index(qs_env, atom_from_RI_index, dimen_RI, "RI_AUX")
1105 :
1106 2496 : NULLIFY (cell, particle_set)
1107 2496 : CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
1108 2496 : CALL get_cell(cell=cell, h=hmat)
1109 2496 : iatom_old = 0
1110 2496 : jatom_old = 0
1111 :
1112 : CALL cp_cfm_get_info(matrix=cfm_mat_Q, &
1113 : nrow_local=nrow_local, &
1114 : ncol_local=ncol_local, &
1115 : row_indices=row_indices, &
1116 2496 : col_indices=col_indices)
1117 :
1118 89544 : DO irow = 1, nrow_local
1119 6863376 : DO jcol = 1, ncol_local
1120 :
1121 6773832 : iatom = atom_from_RI_index(row_indices(irow))
1122 6773832 : jatom = atom_from_RI_index(col_indices(jcol))
1123 :
1124 6773832 : IF (iatom /= iatom_old .OR. jatom /= jatom_old) THEN
1125 :
1126 : ! symmetrize=.FALSE. necessary since we already have a symmetrized index_to_cell
1127 : CALL compute_weight_re_im(weight_re, weight_im, &
1128 : num_cells, iatom, jatom, xkp(1:3, ikp), wkp_W(ikp), &
1129 258336 : cell, index_to_cell, hmat, particle_set)
1130 :
1131 258336 : iatom_old = iatom
1132 258336 : jatom_old = jatom
1133 :
1134 : END IF
1135 :
1136 : contribution = weight_re*REAL(cfm_mat_work_2%local_data(irow, jcol)) + &
1137 6773832 : weight_im*AIMAG(cfm_mat_work_2%local_data(irow, jcol))
1138 :
1139 6860880 : fm_mat_work_local%local_data(irow, jcol) = fm_mat_work_local%local_data(irow, jcol) + contribution
1140 :
1141 : END DO
1142 : END DO
1143 :
1144 2496 : CALL timestop(handle2)
1145 :
1146 2496 : CALL timeset(routineN//"_5", handle2)
1147 :
1148 2496 : IF (ikp_local == -1) THEN
1149 :
1150 2496 : CALL cp_fm_copy_general(fm_mat_work_local, fm_mat_work_global, para_env)
1151 :
1152 17472 : DO iquad = 1, num_integ_points
1153 :
1154 14976 : omega = tj(jquad)
1155 14976 : tau = tau_tj(iquad)
1156 14976 : weight = weights_cos_tf_w_to_t(iquad, jquad)*COS(tau*omega)
1157 :
1158 14976 : IF (jquad == 1 .AND. ikp == 1) THEN
1159 96 : CALL cp_fm_set_all(matrix=fm_mat_W_tau(iquad), alpha=0.0_dp)
1160 : END IF
1161 :
1162 17472 : CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_W_tau(iquad), beta=weight, matrix_b=fm_mat_work_global)
1163 :
1164 : END DO
1165 :
1166 : ELSE
1167 :
1168 0 : DO jkp = 1, nkp
1169 :
1170 0 : CALL para_env%sync()
1171 :
1172 0 : IF (ikp_local == jkp) THEN
1173 0 : CALL cp_fm_copy_general(fm_mat_work_local, fm_mat_work_global, para_env)
1174 : ELSE
1175 0 : CALL cp_fm_copy_general(fm_dummy, fm_mat_work_global, para_env)
1176 : END IF
1177 :
1178 0 : CALL para_env%sync()
1179 :
1180 0 : DO iquad = 1, num_integ_points
1181 :
1182 0 : omega = tj(jquad)
1183 0 : tau = tau_tj(iquad)
1184 0 : weight = weights_cos_tf_w_to_t(iquad, jquad)*COS(tau*omega)
1185 :
1186 0 : IF (jquad == 1 .AND. jkp == 1) THEN
1187 0 : CALL cp_fm_set_all(matrix=fm_mat_W_tau(iquad), alpha=0.0_dp)
1188 : END IF
1189 :
1190 : CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_W_tau(iquad), beta=weight, &
1191 0 : matrix_b=fm_mat_work_global)
1192 :
1193 : END DO
1194 :
1195 : END DO
1196 :
1197 : END IF
1198 :
1199 2496 : CALL cp_cfm_release(cfm_mat_work)
1200 2496 : CALL cp_cfm_release(cfm_mat_work_2)
1201 2496 : CALL cp_cfm_release(cfm_mat_L)
1202 2496 : CALL cp_fm_release(fm_mat_work_global)
1203 2496 : CALL cp_fm_release(fm_mat_work_local)
1204 :
1205 2496 : DEALLOCATE (atom_from_RI_index)
1206 :
1207 2496 : CALL timestop(handle2)
1208 :
1209 2496 : CALL timestop(handle)
1210 :
1211 27456 : END SUBROUTINE compute_Wc_real_space_tau_GW
1212 :
1213 : ! **************************************************************************************************
1214 : !> \brief ...
1215 : !> \param fm_mat_W ...
1216 : !> \param fm_matrix_Minv ...
1217 : !> \param para_env ...
1218 : !> \param dimen_RI ...
1219 : !> \param num_integ_points ...
1220 : ! **************************************************************************************************
1221 16 : SUBROUTINE Wc_to_Minv_Wc_Minv(fm_mat_W, fm_matrix_Minv, para_env, dimen_RI, num_integ_points)
1222 : TYPE(cp_fm_type), DIMENSION(:) :: fm_mat_W
1223 : TYPE(cp_fm_type), DIMENSION(:, :) :: fm_matrix_Minv
1224 : TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env
1225 : INTEGER :: dimen_RI, num_integ_points
1226 :
1227 : CHARACTER(LEN=*), PARAMETER :: routineN = 'Wc_to_Minv_Wc_Minv'
1228 :
1229 : INTEGER :: handle, jquad
1230 : TYPE(cp_fm_type) :: fm_work_Minv, fm_work_Minv_W
1231 :
1232 16 : CALL timeset(routineN, handle)
1233 :
1234 16 : CALL cp_fm_create(fm_work_Minv, fm_mat_W(1)%matrix_struct)
1235 16 : CALL cp_fm_copy_general(fm_matrix_Minv(1, 1), fm_work_Minv, para_env)
1236 :
1237 16 : CALL cp_fm_create(fm_work_Minv_W, fm_mat_W(1)%matrix_struct)
1238 :
1239 112 : DO jquad = 1, num_integ_points
1240 :
1241 : CALL parallel_gemm('N', 'N', dimen_RI, dimen_RI, dimen_RI, 1.0_dp, fm_work_Minv, fm_mat_W(jquad), &
1242 96 : 0.0_dp, fm_work_Minv_W)
1243 : CALL parallel_gemm('N', 'N', dimen_RI, dimen_RI, dimen_RI, 1.0_dp, fm_work_Minv_W, fm_work_Minv, &
1244 112 : 0.0_dp, fm_mat_W(jquad))
1245 :
1246 : END DO
1247 :
1248 16 : CALL cp_fm_release(fm_work_Minv)
1249 :
1250 16 : CALL cp_fm_release(fm_work_Minv_W)
1251 :
1252 16 : CALL timestop(handle)
1253 :
1254 16 : END SUBROUTINE Wc_to_Minv_Wc_Minv
1255 :
1256 : ! **************************************************************************************************
1257 : !> \brief ...
1258 : !> \param qs_env ...
1259 : !> \param wkp_W ...
1260 : !> \param wkp_V ...
1261 : !> \param kpoints ...
1262 : !> \param h_inv ...
1263 : !> \param periodic ...
1264 : ! **************************************************************************************************
1265 20 : SUBROUTINE compute_wkp_W(qs_env, wkp_W, wkp_V, kpoints, h_inv, periodic)
1266 :
1267 : TYPE(qs_environment_type), POINTER :: qs_env
1268 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
1269 : INTENT(OUT) :: wkp_W, wkp_V
1270 : TYPE(kpoint_type), POINTER :: kpoints
1271 : REAL(KIND=dp), DIMENSION(3, 3) :: h_inv
1272 : INTEGER, DIMENSION(3) :: periodic
1273 :
1274 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_wkp_W'
1275 :
1276 : INTEGER :: handle, i_x, ikp, info, j_y, k_z, &
1277 : kpoint_weights_W_method, n_x, n_y, &
1278 : n_z, nkp, nsuperfine, num_lin_eqs
1279 : REAL(KIND=dp) :: exp_kpoints, integral, k_sq, weight
1280 : REAL(KIND=dp), DIMENSION(3) :: k_vec, x_vec
1281 20 : REAL(KIND=dp), DIMENSION(:), POINTER :: right_side, wkp, wkp_tmp
1282 20 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: matrix_lin_eqs, xkp
1283 :
1284 20 : CALL timeset(routineN, handle)
1285 :
1286 20 : kpoint_weights_W_method = qs_env%mp2_env%ri_rpa_im_time%kpoint_weights_W_method
1287 :
1288 20 : CALL get_kpoint_info(kpoints, xkp=xkp, wkp=wkp, nkp=nkp)
1289 :
1290 : ! we determine the kpoint weights of the Monkhors Pack mesh new
1291 : ! such that the functions 1/k^2, 1/k and const are integrated exactly
1292 : ! in the Brillouin zone
1293 : ! this is done by minimizing sum_i |w_i|^2 where w_i are the weights of
1294 : ! the i-th kpoint under the following constraints:
1295 : ! 1) 1/k^2, 1/k and const are integrated exactly
1296 : ! 2) the kpoint weights of kpoints with identical absolute value are
1297 : ! the same, of e.g. (1/8,3/8,3/8) same weight as for (3/8,1/8,3/8)
1298 : ! for 1d and 2d materials: we use ordinary Monkhorst-Pack weights, checked
1299 : ! by SUM(periodic) == 3
1300 80 : ALLOCATE (wkp_V(nkp), wkp_W(nkp))
1301 :
1302 : ! for exchange part of self-energy, we use truncated Coulomb operator that should be fine
1303 : ! with uniform weights (without k-point extrapolation)
1304 20 : IF (ALLOCATED(qs_env%mp2_env%ri_rpa_im_time%wkp_V)) THEN
1305 432 : wkp_V(:) = qs_env%mp2_env%ri_rpa_im_time%wkp_V(:)
1306 : ELSE
1307 12 : wkp_V(:) = wkp(:)
1308 : END IF
1309 :
1310 20 : IF (kpoint_weights_W_method == kp_weights_W_uniform) THEN
1311 :
1312 : ! in the k-point weights wkp, there might be k-point extrapolation included
1313 444 : wkp_W(:) = wkp(:)
1314 :
1315 0 : ELSE IF (kpoint_weights_W_method == kp_weights_W_tailored .OR. &
1316 : kpoint_weights_W_method == kp_weights_W_auto) THEN
1317 :
1318 0 : IF (kpoint_weights_W_method == kp_weights_W_tailored) &
1319 0 : exp_kpoints = qs_env%mp2_env%ri_rpa_im_time%exp_tailored_weights
1320 :
1321 0 : IF (kpoint_weights_W_method == kp_weights_W_auto) THEN
1322 0 : IF (SUM(periodic) == 2) exp_kpoints = -1.0_dp
1323 : END IF
1324 :
1325 : ! first, compute the integral of f(k)=1/k^2 and 1/k on super fine grid
1326 0 : nsuperfine = 500
1327 0 : integral = 0.0_dp
1328 :
1329 0 : IF (periodic(1) == 1) THEN
1330 : n_x = nsuperfine
1331 : ELSE
1332 0 : n_x = 1
1333 : END IF
1334 0 : IF (periodic(2) == 1) THEN
1335 : n_y = nsuperfine
1336 : ELSE
1337 0 : n_y = 1
1338 : END IF
1339 0 : IF (periodic(3) == 1) THEN
1340 : n_z = nsuperfine
1341 : ELSE
1342 0 : n_z = 1
1343 : END IF
1344 :
1345 : ! actually, there is the factor *det_3x3(h_inv) missing to account for the
1346 : ! integration volume but for wkp det_3x3(h_inv) is needed
1347 0 : weight = 1.0_dp/(REAL(n_x, dp)*REAL(n_y, dp)*REAL(n_z, dp))
1348 0 : DO i_x = 1, n_x
1349 0 : DO j_y = 1, n_y
1350 0 : DO k_z = 1, n_z
1351 :
1352 0 : IF (periodic(1) == 1) THEN
1353 0 : x_vec(1) = (REAL(i_x - nsuperfine/2, dp) - 0.5_dp)/REAL(nsuperfine, dp)
1354 : ELSE
1355 0 : x_vec(1) = 0.0_dp
1356 : END IF
1357 0 : IF (periodic(2) == 1) THEN
1358 0 : x_vec(2) = (REAL(j_y - nsuperfine/2, dp) - 0.5_dp)/REAL(nsuperfine, dp)
1359 : ELSE
1360 0 : x_vec(2) = 0.0_dp
1361 : END IF
1362 0 : IF (periodic(3) == 1) THEN
1363 0 : x_vec(3) = (REAL(k_z - nsuperfine/2, dp) - 0.5_dp)/REAL(nsuperfine, dp)
1364 : ELSE
1365 0 : x_vec(3) = 0.0_dp
1366 : END IF
1367 :
1368 0 : k_vec = MATMUL(h_inv(1:3, 1:3), x_vec)
1369 0 : k_sq = k_vec(1)**2 + k_vec(2)**2 + k_vec(3)**2
1370 0 : integral = integral + weight*k_sq**(exp_kpoints*0.5_dp)
1371 :
1372 : END DO
1373 : END DO
1374 : END DO
1375 :
1376 0 : num_lin_eqs = nkp + 2
1377 :
1378 0 : ALLOCATE (matrix_lin_eqs(num_lin_eqs, num_lin_eqs))
1379 0 : matrix_lin_eqs(:, :) = 0.0_dp
1380 :
1381 0 : DO ikp = 1, nkp
1382 :
1383 0 : k_vec = MATMUL(h_inv(1:3, 1:3), xkp(1:3, ikp))
1384 0 : k_sq = k_vec(1)**2 + k_vec(2)**2 + k_vec(3)**2
1385 :
1386 0 : matrix_lin_eqs(ikp, ikp) = 2.0_dp
1387 0 : matrix_lin_eqs(ikp, nkp + 1) = 1.0_dp
1388 0 : matrix_lin_eqs(nkp + 1, ikp) = 1.0_dp
1389 :
1390 0 : matrix_lin_eqs(ikp, nkp + 2) = k_sq**(exp_kpoints*0.5_dp)
1391 0 : matrix_lin_eqs(nkp + 2, ikp) = k_sq**(exp_kpoints*0.5_dp)
1392 :
1393 : END DO
1394 :
1395 0 : CALL invmat(matrix_lin_eqs, info)
1396 : ! check whether inversion was successful
1397 0 : CPASSERT(info == 0)
1398 :
1399 0 : ALLOCATE (right_side(num_lin_eqs))
1400 0 : right_side = 0.0_dp
1401 0 : right_side(nkp + 1) = 1.0_dp
1402 : ! divide integral by two because CP2K k-mesh already considers symmetry k <-> -k
1403 0 : right_side(nkp + 2) = integral
1404 :
1405 0 : ALLOCATE (wkp_tmp(num_lin_eqs))
1406 :
1407 0 : wkp_tmp(1:num_lin_eqs) = MATMUL(matrix_lin_eqs, right_side)
1408 :
1409 0 : wkp_W(1:nkp) = wkp_tmp(1:nkp)
1410 :
1411 0 : DEALLOCATE (matrix_lin_eqs, right_side, wkp_tmp)
1412 :
1413 : END IF
1414 :
1415 20 : CALL timestop(handle)
1416 :
1417 20 : END SUBROUTINE compute_wkp_W
1418 :
1419 : ! **************************************************************************************************
1420 : !> \brief ...
1421 : !> \param qs_env ...
1422 : !> \param Eigenval_kp ...
1423 : ! **************************************************************************************************
1424 16 : SUBROUTINE get_bandstruc_and_k_dependent_MOs(qs_env, Eigenval_kp)
1425 : TYPE(qs_environment_type), POINTER :: qs_env
1426 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: Eigenval_kp
1427 :
1428 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_bandstruc_and_k_dependent_MOs'
1429 :
1430 : INTEGER :: handle, ikp, ispin, nmo, nspins
1431 : INTEGER, DIMENSION(3) :: nkp_grid_G
1432 16 : REAL(KIND=dp), DIMENSION(:), POINTER :: ev
1433 16 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: kpgeneral
1434 : TYPE(kpoint_type), POINTER :: kpoints_Sigma
1435 : TYPE(mp_para_env_type), POINTER :: para_env
1436 :
1437 16 : CALL timeset(routineN, handle)
1438 :
1439 : NULLIFY (qs_env%mp2_env%ri_rpa_im_time%kpoints_G, &
1440 16 : qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma, &
1441 16 : qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma_no_xc, &
1442 16 : para_env)
1443 :
1444 16 : nkp_grid_G(1:3) = [1, 1, 1]
1445 :
1446 16 : CALL get_qs_env(qs_env=qs_env, para_env=para_env)
1447 :
1448 : CALL create_kp_and_calc_kp_orbitals(qs_env, qs_env%mp2_env%ri_rpa_im_time%kpoints_G, &
1449 : "MONKHORST-PACK", para_env%num_pe, &
1450 16 : mp_grid=nkp_grid_G(1:3))
1451 :
1452 16 : IF (qs_env%mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
1453 :
1454 : ! set up k-points for GW band structure calculation, will be completed later
1455 16 : CALL get_kpgeneral_for_Sigma_kpoints(qs_env, kpgeneral)
1456 :
1457 : CALL create_kp_and_calc_kp_orbitals(qs_env, qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma, &
1458 : "GENERAL", para_env%num_pe, &
1459 16 : kpgeneral=kpgeneral)
1460 :
1461 : CALL create_kp_and_calc_kp_orbitals(qs_env, qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma_no_xc, &
1462 : "GENERAL", para_env%num_pe, &
1463 16 : kpgeneral=kpgeneral, with_xc_terms=.FALSE.)
1464 :
1465 16 : kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
1466 16 : nmo = SIZE(Eigenval_kp, 1)
1467 16 : nspins = SIZE(Eigenval_kp, 3)
1468 :
1469 48 : ALLOCATE (qs_env%mp2_env%ri_rpa_im_time%Eigenval_Gamma(nmo))
1470 340 : qs_env%mp2_env%ri_rpa_im_time%Eigenval_Gamma(:) = Eigenval_kp(:, 1, 1)
1471 :
1472 16 : DEALLOCATE (Eigenval_kp)
1473 :
1474 80 : ALLOCATE (Eigenval_kp(nmo, kpoints_Sigma%nkp, nspins))
1475 :
1476 136 : DO ikp = 1, kpoints_Sigma%nkp
1477 :
1478 272 : DO ispin = 1, nspins
1479 :
1480 136 : ev => kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(1, ispin)%eigenvalues
1481 :
1482 3016 : Eigenval_kp(:, ikp, ispin) = ev(:)
1483 :
1484 : END DO
1485 :
1486 : END DO
1487 :
1488 16 : DEALLOCATE (kpgeneral)
1489 :
1490 : END IF
1491 :
1492 16 : CALL release_hfx_stuff(qs_env)
1493 :
1494 16 : CALL timestop(handle)
1495 :
1496 16 : END SUBROUTINE get_bandstruc_and_k_dependent_MOs
1497 :
1498 : ! **************************************************************************************************
1499 : !> \brief releases part of the given qs_env in order to save memory
1500 : !> \param qs_env the object to release
1501 : ! **************************************************************************************************
1502 16 : SUBROUTINE release_hfx_stuff(qs_env)
1503 : TYPE(qs_environment_type), POINTER :: qs_env
1504 :
1505 16 : IF (ASSOCIATED(qs_env%x_data) .AND. .NOT. qs_env%mp2_env%ri_g0w0%do_ri_Sigma_x) THEN
1506 2 : CALL hfx_release(qs_env%x_data)
1507 : END IF
1508 :
1509 16 : END SUBROUTINE release_hfx_stuff
1510 :
1511 : ! **************************************************************************************************
1512 : !> \brief ...
1513 : !> \param qs_env ...
1514 : !> \param kpoints ...
1515 : !> \param scheme ...
1516 : !> \param group_size_ext ...
1517 : !> \param mp_grid ...
1518 : !> \param kpgeneral ...
1519 : !> \param with_xc_terms ...
1520 : ! **************************************************************************************************
1521 336 : SUBROUTINE create_kp_and_calc_kp_orbitals(qs_env, kpoints, scheme, &
1522 48 : group_size_ext, mp_grid, kpgeneral, with_xc_terms)
1523 :
1524 : TYPE(qs_environment_type), POINTER :: qs_env
1525 : TYPE(kpoint_type), POINTER :: kpoints
1526 : CHARACTER(LEN=*), INTENT(IN) :: scheme
1527 : INTEGER :: group_size_ext
1528 : INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL :: mp_grid
1529 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
1530 : OPTIONAL :: kpgeneral
1531 : LOGICAL, OPTIONAL :: with_xc_terms
1532 :
1533 : CHARACTER(LEN=*), PARAMETER :: routineN = 'create_kp_and_calc_kp_orbitals'
1534 :
1535 : INTEGER :: handle, i_dim, i_re_im, ikp, ispin, nkp, &
1536 : nspins
1537 : INTEGER, DIMENSION(3) :: cell_grid, periodic
1538 : LOGICAL :: my_with_xc_terms
1539 48 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
1540 : TYPE(cell_type), POINTER :: cell
1541 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
1542 : TYPE(cp_cfm_type) :: cksmat, cmos, csmat, cwork
1543 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1544 : TYPE(cp_fm_type) :: fm_work
1545 : TYPE(cp_fm_type), POINTER :: imos, rmos
1546 48 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, matrix_s_desymm
1547 48 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_ks_kp, mat_s_kp
1548 : TYPE(dft_control_type), POINTER :: dft_control
1549 : TYPE(kpoint_env_type), POINTER :: kp
1550 : TYPE(mp_para_env_type), POINTER :: para_env
1551 : TYPE(qs_scf_env_type), POINTER :: scf_env
1552 : TYPE(scf_control_type), POINTER :: scf_control
1553 :
1554 48 : CALL timeset(routineN, handle)
1555 :
1556 48 : my_with_xc_terms = .TRUE.
1557 48 : IF (PRESENT(with_xc_terms)) my_with_xc_terms = with_xc_terms
1558 :
1559 : CALL get_qs_env(qs_env, &
1560 : para_env=para_env, &
1561 : blacs_env=blacs_env, &
1562 : matrix_s=matrix_s, &
1563 : scf_env=scf_env, &
1564 : scf_control=scf_control, &
1565 48 : cell=cell)
1566 :
1567 : ! get kpoints
1568 : CALL calculate_kpoints_for_bs(kpoints, scheme, kpgeneral=kpgeneral, mp_grid=mp_grid, &
1569 64 : group_size_ext=group_size_ext)
1570 :
1571 48 : CALL kpoint_env_initialize(kpoints, para_env, blacs_env)
1572 :
1573 : ! calculate all MOs that are accessible in the given
1574 : ! Gaussian AO basis, therefore nadd=1E10
1575 48 : CALL kpoint_initialize_mos(kpoints, qs_env%mos, 2000000000)
1576 48 : CALL kpoint_initialize_mo_set(kpoints)
1577 :
1578 48 : CALL get_cell(cell=cell, periodic=periodic)
1579 :
1580 192 : DO i_dim = 1, 3
1581 : ! we have at most 3 neigboring cells per dimension and at least one because
1582 : ! the density response at Gamma is only divided to neighboring
1583 192 : IF (periodic(i_dim) == 1) THEN
1584 96 : cell_grid(i_dim) = MAX(MIN((kpoints%nkp_grid(i_dim)/2)*2 - 1, 1), 3)
1585 : ELSE
1586 48 : cell_grid(i_dim) = 1
1587 : END IF
1588 : END DO
1589 48 : CALL init_cell_index_rpa(cell_grid, kpoints%cell_to_index, kpoints%index_to_cell, cell)
1590 :
1591 : ! get S(k)
1592 48 : CALL get_qs_env(qs_env, matrix_s=matrix_s, scf_env=scf_env, scf_control=scf_control, dft_control=dft_control)
1593 :
1594 48 : NULLIFY (matrix_s_desymm)
1595 48 : CALL dbcsr_allocate_matrix_set(matrix_s_desymm, 1)
1596 48 : ALLOCATE (matrix_s_desymm(1)%matrix)
1597 : CALL dbcsr_create(matrix=matrix_s_desymm(1)%matrix, template=matrix_s(1)%matrix, &
1598 48 : matrix_type=dbcsr_type_no_symmetry)
1599 48 : CALL dbcsr_desymmetrize(matrix_s(1)%matrix, matrix_s_desymm(1)%matrix)
1600 :
1601 48 : CALL mat_kp_from_mat_gamma(qs_env, mat_s_kp, matrix_s_desymm(1)%matrix, kpoints, 1)
1602 :
1603 48 : CALL get_kpoint_info(kpoints, nkp=nkp)
1604 :
1605 48 : matrix_struct => kpoints%kp_env(1)%kpoint_env%wmat(1, 1)%matrix_struct
1606 :
1607 48 : CALL cp_cfm_create(cksmat, matrix_struct)
1608 48 : CALL cp_cfm_create(csmat, matrix_struct)
1609 48 : CALL cp_cfm_create(cmos, matrix_struct)
1610 48 : CALL cp_cfm_create(cwork, matrix_struct)
1611 48 : CALL cp_fm_create(fm_work, matrix_struct)
1612 :
1613 48 : nspins = dft_control%nspins
1614 :
1615 102 : DO ispin = 1, nspins
1616 :
1617 : ! get H(k)
1618 54 : IF (my_with_xc_terms) THEN
1619 36 : CALL mat_kp_from_mat_gamma(qs_env, mat_ks_kp, qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix, kpoints, ispin)
1620 : ELSE
1621 : CALL mat_kp_from_mat_gamma(qs_env, mat_ks_kp, qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix, &
1622 18 : kpoints, ispin)
1623 : END IF
1624 :
1625 392 : DO ikp = 1, nkp
1626 :
1627 290 : CALL copy_dbcsr_to_fm(mat_ks_kp(ikp, 1)%matrix, kpoints%kp_env(ikp)%kpoint_env%wmat(1, ispin))
1628 290 : CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, kpoints%kp_env(ikp)%kpoint_env%wmat(1, ispin))
1629 :
1630 290 : CALL copy_dbcsr_to_fm(mat_ks_kp(ikp, 2)%matrix, kpoints%kp_env(ikp)%kpoint_env%wmat(2, ispin))
1631 290 : CALL cp_cfm_scale_and_add_fm(z_one, cksmat, gaussi, kpoints%kp_env(ikp)%kpoint_env%wmat(2, ispin))
1632 :
1633 290 : CALL copy_dbcsr_to_fm(mat_s_kp(ikp, 1)%matrix, fm_work)
1634 290 : CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fm_work)
1635 :
1636 290 : CALL copy_dbcsr_to_fm(mat_s_kp(ikp, 2)%matrix, fm_work)
1637 290 : CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fm_work)
1638 :
1639 290 : kp => kpoints%kp_env(ikp)%kpoint_env
1640 :
1641 290 : CALL get_mo_set(kp%mos(1, ispin), mo_coeff=rmos, eigenvalues=eigenvalues)
1642 290 : CALL get_mo_set(kp%mos(2, ispin), mo_coeff=imos)
1643 :
1644 290 : IF (scf_env%cholesky_method == cholesky_off .OR. &
1645 : qs_env%mp2_env%ri_rpa_im_time%make_overlap_mat_ao_pos_definite) THEN
1646 0 : CALL cp_cfm_geeig_canon(cksmat, csmat, cmos, eigenvalues, cwork, scf_control%eps_eigval)
1647 : ELSE
1648 290 : CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
1649 : END IF
1650 :
1651 290 : CALL cp_cfm_to_fm(cmos, rmos, imos)
1652 :
1653 12382 : kp%mos(2, ispin)%eigenvalues = eigenvalues
1654 :
1655 : END DO
1656 :
1657 : END DO
1658 :
1659 304 : DO ikp = 1, nkp
1660 816 : DO i_re_im = 1, 2
1661 768 : CALL dbcsr_deallocate_matrix(mat_ks_kp(ikp, i_re_im)%matrix)
1662 : END DO
1663 : END DO
1664 48 : DEALLOCATE (mat_ks_kp)
1665 :
1666 304 : DO ikp = 1, nkp
1667 816 : DO i_re_im = 1, 2
1668 768 : CALL dbcsr_deallocate_matrix(mat_s_kp(ikp, i_re_im)%matrix)
1669 : END DO
1670 : END DO
1671 48 : DEALLOCATE (mat_s_kp)
1672 :
1673 48 : CALL dbcsr_deallocate_matrix(matrix_s_desymm(1)%matrix)
1674 48 : DEALLOCATE (matrix_s_desymm)
1675 :
1676 48 : CALL cp_cfm_release(cksmat)
1677 48 : CALL cp_cfm_release(csmat)
1678 48 : CALL cp_cfm_release(cwork)
1679 48 : CALL cp_cfm_release(cmos)
1680 48 : CALL cp_fm_release(fm_work)
1681 :
1682 48 : CALL timestop(handle)
1683 :
1684 48 : END SUBROUTINE create_kp_and_calc_kp_orbitals
1685 :
1686 : ! **************************************************************************************************
1687 : !> \brief ...
1688 : !> \param qs_env ...
1689 : !> \param mat_kp ...
1690 : !> \param mat_gamma ...
1691 : !> \param kpoints ...
1692 : !> \param ispin ...
1693 : !> \param real_mat_real_space ...
1694 : ! **************************************************************************************************
1695 114 : SUBROUTINE mat_kp_from_mat_gamma(qs_env, mat_kp, mat_gamma, kpoints, ispin, real_mat_real_space)
1696 :
1697 : TYPE(qs_environment_type), POINTER :: qs_env
1698 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_kp
1699 : TYPE(dbcsr_type) :: mat_gamma
1700 : TYPE(kpoint_type), POINTER :: kpoints
1701 : INTEGER :: ispin
1702 : LOGICAL, INTENT(IN), OPTIONAL :: real_mat_real_space
1703 :
1704 : CHARACTER(LEN=*), PARAMETER :: routineN = 'mat_kp_from_mat_gamma'
1705 :
1706 : INTEGER :: handle, i_cell, i_re_im, ikp, nkp, &
1707 : num_cells
1708 : INTEGER, DIMENSION(3) :: periodic
1709 114 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1710 114 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
1711 : TYPE(cell_type), POINTER :: cell
1712 114 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_real_space
1713 :
1714 114 : CALL timeset(routineN, handle)
1715 :
1716 114 : CALL get_qs_env(qs_env, cell=cell)
1717 114 : CALL get_cell(cell=cell, periodic=periodic)
1718 114 : num_cells = 3**(periodic(1) + periodic(2) + periodic(3))
1719 :
1720 114 : NULLIFY (mat_real_space)
1721 114 : CALL dbcsr_allocate_matrix_set(mat_real_space, num_cells)
1722 1140 : DO i_cell = 1, num_cells
1723 1026 : ALLOCATE (mat_real_space(i_cell)%matrix)
1724 : CALL dbcsr_create(matrix=mat_real_space(i_cell)%matrix, &
1725 1026 : template=mat_gamma)
1726 1026 : CALL dbcsr_reserve_all_blocks(mat_real_space(i_cell)%matrix)
1727 1140 : CALL dbcsr_set(mat_real_space(i_cell)%matrix, 0.0_dp)
1728 : END DO
1729 :
1730 114 : CALL dbcsr_copy(mat_real_space(1)%matrix, mat_gamma)
1731 :
1732 114 : CALL get_mat_cell_T_from_mat_gamma(mat_real_space, qs_env, kpoints, 2, 0)
1733 :
1734 114 : NULLIFY (xkp, cell_to_index)
1735 114 : CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, cell_to_index=cell_to_index)
1736 :
1737 114 : IF (ispin == 1) THEN
1738 108 : NULLIFY (mat_kp)
1739 108 : CALL dbcsr_allocate_matrix_set(mat_kp, nkp, 2)
1740 668 : DO ikp = 1, nkp
1741 1788 : DO i_re_im = 1, 2
1742 1120 : ALLOCATE (mat_kp(ikp, i_re_im)%matrix)
1743 1120 : CALL dbcsr_create(matrix=mat_kp(ikp, i_re_im)%matrix, template=mat_gamma)
1744 1120 : CALL dbcsr_reserve_all_blocks(mat_kp(ikp, i_re_im)%matrix)
1745 1680 : CALL dbcsr_set(mat_kp(ikp, i_re_im)%matrix, 0.0_dp)
1746 : END DO
1747 : END DO
1748 : END IF
1749 :
1750 114 : IF (PRESENT(real_mat_real_space)) THEN
1751 : CALL real_space_to_kpoint_transform_rpa(mat_kp(:, 1), mat_kp(:, 2), mat_real_space, kpoints, 0.0_dp, &
1752 12 : real_mat_real_space)
1753 : ELSE
1754 102 : CALL real_space_to_kpoint_transform_rpa(mat_kp(:, 1), mat_kp(:, 2), mat_real_space, kpoints, 0.0_dp)
1755 : END IF
1756 :
1757 1140 : DO i_cell = 1, num_cells
1758 1140 : CALL dbcsr_deallocate_matrix(mat_real_space(i_cell)%matrix)
1759 : END DO
1760 114 : DEALLOCATE (mat_real_space)
1761 :
1762 114 : CALL timestop(handle)
1763 :
1764 114 : END SUBROUTINE mat_kp_from_mat_gamma
1765 :
1766 : ! **************************************************************************************************
1767 : !> \brief ...
1768 : !> \param qs_env ...
1769 : !> \param kpgeneral ...
1770 : ! **************************************************************************************************
1771 16 : SUBROUTINE get_kpgeneral_for_Sigma_kpoints(qs_env, kpgeneral)
1772 : TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1773 : REAL(kind=dp), DIMENSION(:, :), POINTER :: kpgeneral
1774 :
1775 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_kpgeneral_for_Sigma_kpoints'
1776 :
1777 : INTEGER :: handle, i_kp_in_kp_line, i_special_kp, &
1778 : i_x, ikk, j_y, k_z, n_kp_in_kp_line, &
1779 : n_special_kp
1780 16 : INTEGER, DIMENSION(:), POINTER :: nkp_grid
1781 :
1782 16 : CALL timeset(routineN, handle)
1783 :
1784 16 : n_special_kp = qs_env%mp2_env%ri_g0w0%n_special_kp
1785 16 : n_kp_in_kp_line = qs_env%mp2_env%ri_g0w0%n_kp_in_kp_line
1786 16 : IF (n_special_kp > 0) THEN
1787 14 : qs_env%mp2_env%ri_g0w0%nkp_self_energy_special_kp = n_kp_in_kp_line*(n_special_kp - 1) + 1
1788 : ELSE
1789 2 : qs_env%mp2_env%ri_g0w0%nkp_self_energy_special_kp = 0
1790 : END IF
1791 :
1792 : qs_env%mp2_env%ri_g0w0%nkp_self_energy_monkh_pack = qs_env%mp2_env%ri_g0w0%kp_grid_Sigma(1)* &
1793 : qs_env%mp2_env%ri_g0w0%kp_grid_Sigma(2)* &
1794 16 : qs_env%mp2_env%ri_g0w0%kp_grid_Sigma(3)
1795 :
1796 : qs_env%mp2_env%ri_g0w0%nkp_self_energy = qs_env%mp2_env%ri_g0w0%nkp_self_energy_special_kp + &
1797 16 : qs_env%mp2_env%ri_g0w0%nkp_self_energy_monkh_pack
1798 :
1799 48 : ALLOCATE (kpgeneral(3, qs_env%mp2_env%ri_g0w0%nkp_self_energy))
1800 :
1801 16 : IF (n_special_kp > 0) THEN
1802 :
1803 112 : kpgeneral(1:3, 1) = qs_env%mp2_env%ri_g0w0%xkp_special_kp(1:3, 1)
1804 :
1805 14 : ikk = 1
1806 :
1807 28 : DO i_special_kp = 2, n_special_kp
1808 70 : DO i_kp_in_kp_line = 1, n_kp_in_kp_line
1809 :
1810 42 : ikk = ikk + 1
1811 : kpgeneral(1:3, ikk) = qs_env%mp2_env%ri_g0w0%xkp_special_kp(1:3, i_special_kp - 1) + &
1812 : REAL(i_kp_in_kp_line, KIND=dp)/REAL(n_kp_in_kp_line, KIND=dp)* &
1813 : (qs_env%mp2_env%ri_g0w0%xkp_special_kp(1:3, i_special_kp) - &
1814 350 : qs_env%mp2_env%ri_g0w0%xkp_special_kp(1:3, i_special_kp - 1))
1815 :
1816 : END DO
1817 : END DO
1818 :
1819 : ELSE
1820 :
1821 : ikk = 0
1822 :
1823 : END IF
1824 :
1825 16 : nkp_grid => qs_env%mp2_env%ri_g0w0%kp_grid_Sigma
1826 :
1827 48 : DO i_x = 1, nkp_grid(1)
1828 112 : DO j_y = 1, nkp_grid(2)
1829 160 : DO k_z = 1, nkp_grid(3)
1830 64 : ikk = ikk + 1
1831 64 : kpgeneral(1, ikk) = REAL(2*i_x - nkp_grid(1) - 1, KIND=dp)/(2._dp*REAL(nkp_grid(1), KIND=dp))
1832 64 : kpgeneral(2, ikk) = REAL(2*j_y - nkp_grid(2) - 1, KIND=dp)/(2._dp*REAL(nkp_grid(2), KIND=dp))
1833 128 : kpgeneral(3, ikk) = REAL(2*k_z - nkp_grid(3) - 1, KIND=dp)/(2._dp*REAL(nkp_grid(3), KIND=dp))
1834 : END DO
1835 : END DO
1836 : END DO
1837 :
1838 16 : CALL timestop(handle)
1839 :
1840 16 : END SUBROUTINE get_kpgeneral_for_Sigma_kpoints
1841 :
1842 0 : END MODULE rpa_gw_kpoints_util
|