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 to calculate RI-RPA energy
10 : !> \par History
11 : !> 06.2012 created [Mauro Del Ben]
12 : !> 04.2015 GW routines added [Jan Wilhelm]
13 : !> 10.2015 Cubic-scaling RPA routines added [Jan Wilhelm]
14 : !> 10.2018 Cubic-scaling SOS-MP2 added [Frederick Stein]
15 : !> 03.2019 Refactoring [Frederick Stein]
16 : ! **************************************************************************************************
17 : MODULE rpa_main
18 : USE bibliography, ONLY: &
19 : Bates2013, DelBen2013, DelBen2015, Freeman1977, Gruneis2009, Ren2011, Ren2013, &
20 : Wilhelm2016a, Wilhelm2016b, Wilhelm2017, Wilhelm2018, cite_reference
21 : USE bse_main, ONLY: start_bse_calculation
22 : USE cp_blacs_env, ONLY: cp_blacs_env_create, &
23 : cp_blacs_env_release, &
24 : cp_blacs_env_type
25 : USE cp_cfm_types, ONLY: cp_cfm_type
26 : USE cp_dbcsr_api, ONLY: dbcsr_add, &
27 : dbcsr_clear, &
28 : dbcsr_get_info, &
29 : dbcsr_p_type, &
30 : dbcsr_type
31 : USE cp_fm_basic_linalg, ONLY: cp_fm_scale_and_add
32 : USE cp_fm_struct, ONLY: cp_fm_struct_create, &
33 : cp_fm_struct_release, &
34 : cp_fm_struct_type
35 : USE cp_fm_types, ONLY: cp_fm_create, &
36 : cp_fm_release, &
37 : cp_fm_set_all, &
38 : cp_fm_to_fm, &
39 : cp_fm_type
40 : USE dbt_api, ONLY: dbt_type
41 : USE dgemm_counter_types, ONLY: dgemm_counter_init, &
42 : dgemm_counter_type, &
43 : dgemm_counter_write
44 : USE group_dist_types, ONLY: create_group_dist, &
45 : get_group_dist, &
46 : group_dist_d1_type, &
47 : maxsize, &
48 : release_group_dist
49 : USE hfx_types, ONLY: block_ind_type, &
50 : hfx_compression_type
51 : USE input_constants, ONLY: rpa_exchange_axk, &
52 : rpa_exchange_none, &
53 : rpa_exchange_sosex, &
54 : sigma_none, &
55 : wfc_mm_style_gemm
56 : USE kinds, ONLY: dp, &
57 : int_8
58 : USE kpoint_types, ONLY: kpoint_type
59 : USE machine, ONLY: m_flush, &
60 : m_memory
61 : USE mathconstants, ONLY: pi, &
62 : z_zero
63 : USE message_passing, ONLY: mp_comm_type, &
64 : mp_para_env_release, &
65 : mp_para_env_type
66 : USE minimax_exp, ONLY: check_exp_minimax_range
67 : USE mp2_grids, ONLY: get_clenshaw_grid, &
68 : get_minimax_grid, &
69 : init_greenx_grids
70 : USE mp2_laplace, ONLY: SOS_MP2_postprocessing
71 : USE mp2_ri_grad_util, ONLY: array2fm
72 : USE mp2_types, ONLY: mp2_type, &
73 : three_dim_real_array, &
74 : two_dim_int_array, &
75 : two_dim_real_array
76 : USE qs_environment_types, ONLY: get_qs_env, &
77 : qs_environment_type
78 : USE rpa_exchange, ONLY: rpa_exchange_needed_mem, &
79 : rpa_exchange_work_type
80 : USE rpa_grad, ONLY: rpa_grad_copy_Q, &
81 : rpa_grad_create, &
82 : rpa_grad_finalize, &
83 : rpa_grad_matrix_operations, &
84 : rpa_grad_needed_mem, &
85 : rpa_grad_type
86 : USE rpa_gw, ONLY: allocate_matrices_gw, &
87 : allocate_matrices_gw_im_time, &
88 : compute_GW_self_energy, &
89 : compute_QP_energies, &
90 : compute_W_cubic_GW, &
91 : deallocate_matrices_gw, &
92 : deallocate_matrices_gw_im_time, &
93 : get_fermi_level_offset
94 : USE rpa_gw_ic, ONLY: calculate_ic_correction
95 : USE rpa_gw_kpoints_util, ONLY: get_bandstruc_and_k_dependent_MOs, &
96 : invert_eps_compute_W_and_Erpa_kp
97 : USE rpa_im_time, ONLY: compute_mat_P_omega, &
98 : zero_mat_P_omega
99 : USE rpa_im_time_force_methods, ONLY: calc_laplace_loop_forces, &
100 : calc_post_loop_forces, &
101 : calc_rpa_loop_forces, &
102 : init_im_time_forces, &
103 : keep_initial_quad
104 : USE rpa_im_time_force_types, ONLY: im_time_force_release, &
105 : im_time_force_type
106 : USE rpa_sigma_functional, ONLY: finalize_rpa_sigma, &
107 : rpa_sigma_create, &
108 : rpa_sigma_matrix_spectral, &
109 : rpa_sigma_type
110 : USE rpa_util, ONLY: Q_trace_and_add_unit_matrix, &
111 : alloc_im_time, &
112 : calc_mat_Q, &
113 : compute_Erpa_by_freq_int, &
114 : contract_P_omega_with_mat_L, &
115 : dealloc_im_time, &
116 : remove_scaling_factor_rpa
117 : USE util, ONLY: get_limit
118 : #if defined (__GREENX)
119 : USE gx_minimax, ONLY: gx_minimax_grid
120 : #endif
121 :
122 : #include "./base/base_uses.f90"
123 :
124 : IMPLICIT NONE
125 :
126 : PRIVATE
127 :
128 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rpa_main'
129 :
130 : PUBLIC :: rpa_ri_compute_en
131 :
132 : CONTAINS
133 :
134 : ! **************************************************************************************************
135 : !> \brief ...
136 : !> \param qs_env ...
137 : !> \param Erpa ...
138 : !> \param mp2_env ...
139 : !> \param BIb_C ...
140 : !> \param BIb_C_gw ...
141 : !> \param BIb_C_bse_ij ...
142 : !> \param BIb_C_bse_ab ...
143 : !> \param para_env ...
144 : !> \param para_env_sub ...
145 : !> \param color_sub ...
146 : !> \param gd_array ...
147 : !> \param gd_B_virtual ...
148 : !> \param gd_B_all ...
149 : !> \param gd_B_occ_bse ...
150 : !> \param gd_B_virt_bse ...
151 : !> \param mo_coeff ...
152 : !> \param fm_matrix_PQ ...
153 : !> \param fm_matrix_L_kpoints ...
154 : !> \param fm_matrix_Minv_L_kpoints ...
155 : !> \param fm_matrix_Minv ...
156 : !> \param fm_matrix_Minv_Vtrunc_Minv ...
157 : !> \param kpoints ...
158 : !> \param Eigenval ...
159 : !> \param nmo ...
160 : !> \param homo ...
161 : !> \param dimen_RI ...
162 : !> \param dimen_RI_red ...
163 : !> \param gw_corr_lev_occ ...
164 : !> \param gw_corr_lev_virt ...
165 : !> \param bse_lev_virt ...
166 : !> \param unit_nr ...
167 : !> \param do_ri_sos_laplace_mp2 ...
168 : !> \param my_do_gw ...
169 : !> \param do_im_time ...
170 : !> \param do_bse ...
171 : !> \param matrix_s ...
172 : !> \param mat_munu ...
173 : !> \param mat_P_global ...
174 : !> \param t_3c_M ...
175 : !> \param t_3c_O ...
176 : !> \param t_3c_O_compressed ...
177 : !> \param t_3c_O_ind ...
178 : !> \param starts_array_mc ...
179 : !> \param ends_array_mc ...
180 : !> \param starts_array_mc_block ...
181 : !> \param ends_array_mc_block ...
182 : !> \param calc_forces ...
183 : ! **************************************************************************************************
184 1470 : SUBROUTINE rpa_ri_compute_en(qs_env, Erpa, mp2_env, BIb_C, BIb_C_gw, BIb_C_bse_ij, BIb_C_bse_ab, &
185 : para_env, para_env_sub, color_sub, &
186 294 : gd_array, gd_B_virtual, gd_B_all, gd_B_occ_bse, gd_B_virt_bse, &
187 294 : mo_coeff, fm_matrix_PQ, fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
188 : fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, kpoints, &
189 588 : Eigenval, nmo, homo, dimen_RI, dimen_RI_red, gw_corr_lev_occ, gw_corr_lev_virt, &
190 : bse_lev_virt, &
191 : unit_nr, do_ri_sos_laplace_mp2, my_do_gw, do_im_time, do_bse, matrix_s, &
192 : mat_munu, mat_P_global, t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
193 : starts_array_mc, ends_array_mc, &
194 : starts_array_mc_block, ends_array_mc_block, calc_forces)
195 :
196 : TYPE(qs_environment_type), POINTER :: qs_env
197 : REAL(KIND=dp), INTENT(OUT) :: Erpa
198 : TYPE(mp2_type), INTENT(INOUT) :: mp2_env
199 : TYPE(three_dim_real_array), DIMENSION(:), &
200 : INTENT(INOUT) :: BIb_C, BIb_C_gw
201 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
202 : INTENT(INOUT) :: BIb_C_bse_ij, BIb_C_bse_ab
203 : TYPE(mp_para_env_type), POINTER :: para_env, para_env_sub
204 : INTEGER, INTENT(INOUT) :: color_sub
205 : TYPE(group_dist_d1_type), INTENT(INOUT) :: gd_array
206 : TYPE(group_dist_d1_type), DIMENSION(:), &
207 : INTENT(INOUT) :: gd_B_virtual
208 : TYPE(group_dist_d1_type), INTENT(INOUT) :: gd_B_all, gd_B_occ_bse, gd_B_virt_bse
209 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
210 : TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_PQ
211 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_L_kpoints, &
212 : fm_matrix_Minv_L_kpoints, &
213 : fm_matrix_Minv, &
214 : fm_matrix_Minv_Vtrunc_Minv
215 : TYPE(kpoint_type), POINTER :: kpoints
216 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
217 : INTENT(INOUT) :: Eigenval
218 : INTEGER, INTENT(IN) :: nmo
219 : INTEGER, DIMENSION(:), INTENT(IN) :: homo
220 : INTEGER, INTENT(IN) :: dimen_RI, dimen_RI_red
221 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt
222 : INTEGER, INTENT(IN) :: bse_lev_virt, unit_nr
223 : LOGICAL, INTENT(IN) :: do_ri_sos_laplace_mp2, my_do_gw, &
224 : do_im_time, do_bse
225 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
226 : TYPE(dbcsr_p_type), INTENT(IN) :: mat_munu
227 : TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_P_global
228 : TYPE(dbt_type) :: t_3c_M
229 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_O
230 : TYPE(hfx_compression_type), ALLOCATABLE, &
231 : DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_O_compressed
232 : TYPE(block_ind_type), ALLOCATABLE, &
233 : DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_O_ind
234 : INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(IN) :: starts_array_mc, ends_array_mc, &
235 : starts_array_mc_block, &
236 : ends_array_mc_block
237 : LOGICAL, INTENT(IN) :: calc_forces
238 :
239 : CHARACTER(LEN=*), PARAMETER :: routineN = 'rpa_ri_compute_en'
240 :
241 : INTEGER :: best_integ_group_size, best_num_integ_point, color_rpa_group, dimen_homo_square, &
242 : dimen_nm_gw, dimen_virt_square, handle, handle2, handle3, ierr, iiB, &
243 : input_num_integ_groups, integ_group_size, ispin, jjB, min_integ_group_size, &
244 : my_ab_comb_bse_end, my_ab_comb_bse_size, my_ab_comb_bse_start, my_group_L_end, &
245 : my_group_L_size, my_group_L_start, my_ij_comb_bse_end, my_ij_comb_bse_size, &
246 : my_ij_comb_bse_start, my_nm_gw_end, my_nm_gw_size, my_nm_gw_start, ncol_block_mat, &
247 : ngroup, nrow_block_mat, nspins, num_integ_group, num_integ_points, pos_integ_group
248 : INTEGER(KIND=int_8) :: mem
249 588 : INTEGER, ALLOCATABLE, DIMENSION(:) :: dimen_ia, my_ia_end, my_ia_size, &
250 294 : my_ia_start, virtual
251 : LOGICAL :: do_kpoints_from_Gamma, do_minimax_quad, &
252 : my_open_shell, skip_integ_group_opt
253 : REAL(KIND=dp) :: allowed_memory, avail_mem, E_Range, Emax, Emin, mem_for_iaK, mem_for_QK, &
254 : mem_min, mem_per_group, mem_per_rank, mem_per_repl, mem_real
255 294 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: Eigenval_kp
256 588 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_mat_Q, fm_mat_Q_gemm, fm_mat_S, &
257 294 : fm_mat_S_gw
258 882 : TYPE(cp_fm_type), DIMENSION(1) :: fm_mat_R_gw, fm_mat_S_ab_bse, &
259 588 : fm_mat_S_ij_bse
260 : TYPE(mp_para_env_type), POINTER :: para_env_RPA
261 : TYPE(two_dim_real_array), ALLOCATABLE, &
262 588 : DIMENSION(:) :: BIb_C_2D, BIb_C_2D_gw
263 2940 : TYPE(two_dim_real_array), DIMENSION(1) :: BIb_C_2D_bse_ab, BIb_C_2D_bse_ij
264 :
265 294 : CALL timeset(routineN, handle)
266 :
267 294 : CALL cite_reference(DelBen2013)
268 294 : CALL cite_reference(DelBen2015)
269 :
270 294 : IF (mp2_env%ri_rpa%exchange_correction == rpa_exchange_axk) THEN
271 10 : CALL cite_reference(Bates2013)
272 284 : ELSE IF (mp2_env%ri_rpa%exchange_correction == rpa_exchange_sosex) THEN
273 2 : CALL cite_reference(Freeman1977)
274 2 : CALL cite_reference(Gruneis2009)
275 : END IF
276 294 : IF (mp2_env%ri_rpa%do_rse) THEN
277 4 : CALL cite_reference(Ren2011)
278 4 : CALL cite_reference(Ren2013)
279 : END IF
280 :
281 294 : IF (my_do_gw) THEN
282 104 : CALL cite_reference(Wilhelm2016a)
283 104 : CALL cite_reference(Wilhelm2017)
284 104 : CALL cite_reference(Wilhelm2018)
285 : END IF
286 :
287 294 : IF (do_im_time) THEN
288 134 : CALL cite_reference(Wilhelm2016b)
289 : END IF
290 :
291 294 : nspins = SIZE(homo)
292 294 : my_open_shell = (nspins == 2)
293 2058 : ALLOCATE (virtual(nspins), dimen_ia(nspins), my_ia_end(nspins), my_ia_start(nspins), my_ia_size(nspins))
294 644 : virtual(:) = nmo - homo(:)
295 644 : dimen_ia(:) = virtual(:)*homo(:)
296 :
297 1176 : ALLOCATE (Eigenval_kp(nmo, 1, nspins))
298 8842 : Eigenval_kp(:, 1, :) = Eigenval(:, :)
299 :
300 294 : IF (do_im_time) mp2_env%ri_rpa%minimax_quad = .TRUE.
301 294 : do_minimax_quad = mp2_env%ri_rpa%minimax_quad
302 :
303 294 : IF (do_ri_sos_laplace_mp2) THEN
304 58 : num_integ_points = mp2_env%ri_laplace%n_quadrature
305 58 : input_num_integ_groups = mp2_env%ri_laplace%num_integ_groups
306 :
307 : ! check the range for the minimax approximation
308 58 : E_Range = mp2_env%e_range
309 58 : IF (mp2_env%e_range <= 1.0_dp .OR. mp2_env%e_gap <= 0.0_dp) THEN
310 : Emin = HUGE(dp)
311 : Emax = 0.0_dp
312 88 : DO ispin = 1, nspins
313 88 : IF (homo(ispin) > 0) THEN
314 50 : Emin = MIN(Emin, 2.0_dp*(Eigenval(homo(ispin) + 1, ispin) - Eigenval(homo(ispin), ispin)))
315 2740 : Emax = MAX(Emax, 2.0_dp*(MAXVAL(Eigenval(:, ispin)) - MINVAL(Eigenval(:, ispin))))
316 : END IF
317 : END DO
318 38 : E_Range = Emax/Emin
319 : END IF
320 58 : IF (E_Range < 2.0_dp) E_Range = 2.0_dp
321 : ierr = 0
322 58 : CALL check_exp_minimax_range(num_integ_points, E_Range, ierr)
323 58 : IF (ierr /= 0) THEN
324 : jjB = num_integ_points - 1
325 0 : DO iiB = 1, jjB
326 0 : num_integ_points = num_integ_points - 1
327 : ierr = 0
328 0 : CALL check_exp_minimax_range(num_integ_points, E_Range, ierr)
329 0 : IF (ierr == 0) EXIT
330 : END DO
331 : END IF
332 58 : CPASSERT(num_integ_points >= 1)
333 : ELSE
334 236 : num_integ_points = mp2_env%ri_rpa%rpa_num_quad_points
335 236 : input_num_integ_groups = mp2_env%ri_rpa%rpa_num_integ_groups
336 236 : IF (my_do_gw .AND. do_minimax_quad) THEN
337 46 : IF (num_integ_points > 34) THEN
338 0 : IF (unit_nr > 0) &
339 : CALL cp_warn(__LOCATION__, &
340 : "The required number of quadrature point exceeds the maximum possible in the "// &
341 0 : "Minimax quadrature scheme. The number of quadrature point has been reset to 30.")
342 0 : num_integ_points = 30
343 : END IF
344 : ELSE
345 190 : IF (do_minimax_quad .AND. num_integ_points > 20) THEN
346 0 : IF (unit_nr > 0) &
347 : CALL cp_warn(__LOCATION__, &
348 : "The required number of quadrature point exceeds the maximum possible in the "// &
349 0 : "Minimax quadrature scheme. The number of quadrature point has been reset to 20.")
350 0 : num_integ_points = 20
351 : END IF
352 : END IF
353 : END IF
354 294 : allowed_memory = mp2_env%mp2_memory
355 :
356 294 : CALL get_group_dist(gd_array, color_sub, my_group_L_start, my_group_L_end, my_group_L_size)
357 :
358 294 : ngroup = para_env%num_pe/para_env_sub%num_pe
359 :
360 : ! for imaginary time or periodic GW or BSE, we use all processors for a single frequency/time point
361 294 : IF (do_im_time .OR. mp2_env%ri_g0w0%do_periodic .OR. do_bse) THEN
362 :
363 166 : integ_group_size = ngroup
364 166 : best_num_integ_point = num_integ_points
365 :
366 : ELSE
367 :
368 : ! Calculate available memory and create integral group according to that
369 : ! mem_for_iaK is the memory needed for storing the 3 centre integrals
370 284 : mem_for_iaK = REAL(SUM(dimen_ia), KIND=dp)*dimen_RI_red*8.0_dp/(1024_dp**2)
371 128 : mem_for_QK = REAL(dimen_RI_red, KIND=dp)*nspins*dimen_RI_red*8.0_dp/(1024_dp**2)
372 :
373 128 : CALL m_memory(mem)
374 128 : mem_real = (mem + 1024*1024 - 1)/(1024*1024)
375 128 : CALL para_env%min(mem_real)
376 :
377 128 : mem_per_rank = 0.0_dp
378 :
379 : ! B_ia_P
380 : mem_per_repl = mem_for_iaK
381 : ! Q (regular and for dgemm)
382 128 : mem_per_repl = mem_per_repl + 2.0_dp*mem_for_QK
383 :
384 128 : IF (calc_forces) CALL rpa_grad_needed_mem(homo, virtual, dimen_RI_red, mem_per_rank, mem_per_repl, do_ri_sos_laplace_mp2)
385 128 : CALL rpa_exchange_needed_mem(mp2_env, homo, virtual, dimen_RI_red, para_env, mem_per_rank, mem_per_repl)
386 :
387 128 : mem_min = mem_per_repl/para_env%num_pe + mem_per_rank
388 :
389 128 : IF (unit_nr > 0) THEN
390 64 : WRITE (unit_nr, '(T3,A,T68,F9.2,A4)') 'RI_INFO| Minimum required memory per MPI process:', mem_min, ' MiB'
391 64 : WRITE (unit_nr, '(T3,A,T68,F9.2,A4)') 'RI_INFO| Available memory per MPI process:', mem_real, ' MiB'
392 : END IF
393 :
394 : ! Use only the allowed amount of memory
395 128 : mem_real = MIN(mem_real, allowed_memory)
396 : ! For the memory estimate, we require the amount of required memory per replication group and the available memory
397 128 : mem_real = mem_real - mem_per_rank
398 :
399 128 : mem_per_group = mem_real*para_env_sub%num_pe
400 :
401 : ! here we try to find the best rpa/laplace group size
402 128 : skip_integ_group_opt = .FALSE.
403 :
404 : ! Check the input number of integration groups
405 128 : IF (input_num_integ_groups > 0) THEN
406 2 : IF (MOD(num_integ_points, input_num_integ_groups) == 0) THEN
407 0 : IF (MOD(ngroup, input_num_integ_groups) == 0) THEN
408 0 : best_integ_group_size = ngroup/input_num_integ_groups
409 0 : best_num_integ_point = num_integ_points/input_num_integ_groups
410 0 : skip_integ_group_opt = .TRUE.
411 : ELSE
412 0 : IF (unit_nr > 0) WRITE (unit_nr, '(T3,A)') 'Total number of groups not multiple of NUM_INTEG_GROUPS'
413 : END IF
414 : ELSE
415 2 : IF (unit_nr > 0) WRITE (unit_nr, '(T3,A)') 'NUM_QUAD_POINTS not multiple of NUM_INTEG_GROUPS'
416 : END IF
417 : END IF
418 :
419 128 : IF (.NOT. skip_integ_group_opt) THEN
420 128 : best_integ_group_size = ngroup
421 128 : best_num_integ_point = num_integ_points
422 :
423 128 : min_integ_group_size = MAX(1, ngroup/num_integ_points)
424 :
425 128 : integ_group_size = min_integ_group_size - 1
426 142 : DO iiB = min_integ_group_size + 1, ngroup
427 106 : integ_group_size = integ_group_size + 1
428 :
429 : ! check that the ngroup is a multiple of integ_group_size
430 106 : IF (MOD(ngroup, integ_group_size) /= 0) CYCLE
431 :
432 : ! check for memory
433 106 : avail_mem = integ_group_size*mem_per_group
434 106 : IF (avail_mem < mem_per_repl) CYCLE
435 :
436 : ! check that the integration groups have the same size
437 106 : num_integ_group = ngroup/integ_group_size
438 106 : IF (MOD(num_integ_points, num_integ_group) /= 0) CYCLE
439 :
440 92 : best_num_integ_point = num_integ_points/num_integ_group
441 92 : best_integ_group_size = integ_group_size
442 :
443 142 : EXIT
444 :
445 : END DO
446 : END IF
447 :
448 128 : integ_group_size = best_integ_group_size
449 :
450 : END IF
451 :
452 294 : IF (unit_nr > 0 .AND. .NOT. do_im_time) THEN
453 80 : IF (do_ri_sos_laplace_mp2) THEN
454 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
455 14 : "RI_INFO| Group size for laplace numerical integration:", integ_group_size*para_env_sub%num_pe
456 : WRITE (UNIT=unit_nr, FMT="(T3,A)") &
457 14 : "INTEG_INFO| MINIMAX approximation"
458 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
459 14 : "INTEG_INFO| Number of integration points:", num_integ_points
460 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
461 14 : "INTEG_INFO| Number of integration points per Laplace group:", best_num_integ_point
462 : ELSE
463 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
464 66 : "RI_INFO| Group size for frequency integration:", integ_group_size*para_env_sub%num_pe
465 66 : IF (do_minimax_quad) THEN
466 : WRITE (UNIT=unit_nr, FMT="(T3,A)") &
467 19 : "INTEG_INFO| MINIMAX quadrature"
468 : ELSE
469 : WRITE (UNIT=unit_nr, FMT="(T3,A)") &
470 47 : "INTEG_INFO| Clenshaw-Curtius quadrature"
471 : END IF
472 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
473 66 : "INTEG_INFO| Number of integration points:", num_integ_points
474 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
475 66 : "INTEG_INFO| Number of integration points per RPA group:", best_num_integ_point
476 : END IF
477 80 : CALL m_flush(unit_nr)
478 : END IF
479 :
480 294 : num_integ_group = ngroup/integ_group_size
481 :
482 294 : pos_integ_group = MOD(color_sub, integ_group_size)
483 294 : color_rpa_group = color_sub/integ_group_size
484 :
485 294 : CALL timeset(routineN//"_reorder", handle2)
486 :
487 : ! not necessary for imaginary time
488 :
489 1232 : ALLOCATE (BIb_C_2D(nspins))
490 :
491 294 : IF (.NOT. do_im_time) THEN
492 :
493 : ! reorder the local data in such a way to help the next stage of matrix creation
494 : ! now the data inside the group are divided into a ia x K matrix
495 348 : DO ispin = 1, nspins
496 : CALL calculate_BIb_C_2D(BIb_C_2D(ispin)%array, BIb_C(ispin)%array, para_env_sub, dimen_ia(ispin), &
497 : homo(ispin), virtual(ispin), gd_B_virtual(ispin), &
498 188 : my_ia_size(ispin), my_ia_start(ispin), my_ia_end(ispin), my_group_L_size)
499 :
500 188 : DEALLOCATE (BIb_C(ispin)%array)
501 536 : CALL release_group_dist(gd_B_virtual(ispin))
502 :
503 : END DO
504 :
505 : ! in the GW case, BIb_C_2D_gw is an nm x K matrix, with n: number of corr GW levels, m=nmo
506 160 : IF (my_do_gw) THEN
507 178 : ALLOCATE (BIb_C_2D_gw(nspins))
508 :
509 58 : CALL timeset(routineN//"_reorder_gw", handle3)
510 :
511 58 : dimen_nm_gw = nmo*(gw_corr_lev_occ(1) + gw_corr_lev_virt(1))
512 :
513 : ! The same for open shell
514 120 : DO ispin = 1, nspins
515 : CALL calculate_BIb_C_2D(BIb_C_2D_gw(ispin)%array, BIb_C_gw(ispin)%array, para_env_sub, dimen_nm_gw, &
516 : gw_corr_lev_occ(ispin) + gw_corr_lev_virt(ispin), nmo, gd_B_all, &
517 62 : my_nm_gw_size, my_nm_gw_start, my_nm_gw_end, my_group_L_size)
518 120 : DEALLOCATE (BIb_C_gw(ispin)%array)
519 : END DO
520 :
521 58 : CALL release_group_dist(gd_B_all)
522 :
523 116 : CALL timestop(handle3)
524 :
525 : END IF
526 : END IF
527 :
528 354 : IF (do_bse) THEN
529 :
530 30 : CALL timeset(routineN//"_reorder_bse1", handle3)
531 :
532 30 : dimen_homo_square = homo(1)**2
533 : ! We do not implement an explicit bse_lev_occ different to homo here, because the small number of occupied levels
534 : ! does not critically influence the memory
535 : CALL calculate_BIb_C_2D(BIb_C_2D_bse_ij(1)%array, BIb_C_bse_ij, para_env_sub, dimen_homo_square, &
536 : homo(1), homo(1), gd_B_occ_bse, &
537 30 : my_ij_comb_bse_size, my_ij_comb_bse_start, my_ij_comb_bse_end, my_group_L_size)
538 :
539 30 : DEALLOCATE (BIb_C_bse_ij)
540 30 : CALL release_group_dist(gd_B_occ_bse)
541 :
542 30 : CALL timestop(handle3)
543 :
544 30 : CALL timeset(routineN//"_reorder_bse2", handle3)
545 :
546 30 : dimen_virt_square = bse_lev_virt**2
547 :
548 : CALL calculate_BIb_C_2D(BIb_C_2D_bse_ab(1)%array, BIb_C_bse_ab, para_env_sub, dimen_virt_square, &
549 : bse_lev_virt, bse_lev_virt, gd_B_virt_bse, &
550 30 : my_ab_comb_bse_size, my_ab_comb_bse_start, my_ab_comb_bse_end, my_group_L_size)
551 :
552 30 : DEALLOCATE (BIb_C_bse_ab)
553 30 : CALL release_group_dist(gd_B_virt_bse)
554 :
555 30 : CALL timestop(handle3)
556 :
557 : END IF
558 :
559 294 : CALL timestop(handle2)
560 :
561 294 : IF (num_integ_group > 1) THEN
562 92 : ALLOCATE (para_env_RPA)
563 92 : CALL para_env_RPA%from_split(para_env, color_rpa_group)
564 : ELSE
565 202 : para_env_RPA => para_env
566 : END IF
567 :
568 : ! now create the matrices needed for the calculation, Q, S and G
569 : ! Q and G will have omega dependence
570 :
571 294 : IF (do_im_time) THEN
572 832 : ALLOCATE (fm_mat_Q(nspins), fm_mat_Q_gemm(1), fm_mat_S(1))
573 : ELSE
574 1364 : ALLOCATE (fm_mat_Q(nspins), fm_mat_Q_gemm(nspins), fm_mat_S(nspins))
575 : END IF
576 :
577 : CALL create_integ_mat(BIb_C_2D, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
578 : dimen_RI_red, dimen_ia, color_rpa_group, &
579 : mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
580 : my_ia_size, my_ia_start, my_ia_end, &
581 : my_group_L_size, my_group_L_start, my_group_L_end, &
582 : para_env_RPA, fm_mat_S, nrow_block_mat, ncol_block_mat, &
583 : dimen_ia_for_block_size=dimen_ia(1), &
584 294 : do_im_time=do_im_time, fm_mat_Q_gemm=fm_mat_Q_gemm, fm_mat_Q=fm_mat_Q, qs_env=qs_env)
585 :
586 644 : DEALLOCATE (BIb_C_2D, my_ia_end, my_ia_size, my_ia_start)
587 :
588 : ! for GW, we need other matrix fm_mat_S, always allocate the container to prevent crying compilers
589 1232 : ALLOCATE (fm_mat_S_gw(nspins))
590 294 : IF (my_do_gw .AND. .NOT. do_im_time) THEN
591 :
592 : CALL create_integ_mat(BIb_C_2D_gw, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
593 : dimen_RI_red, [dimen_nm_gw, dimen_nm_gw], color_rpa_group, &
594 : mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
595 : [my_nm_gw_size, my_nm_gw_size], [my_nm_gw_start, my_nm_gw_start], [my_nm_gw_end, my_nm_gw_end], &
596 : my_group_L_size, my_group_L_start, my_group_L_end, &
597 : para_env_RPA, fm_mat_S_gw, nrow_block_mat, ncol_block_mat, &
598 : fm_mat_Q(1)%matrix_struct%context, fm_mat_Q(1)%matrix_struct%context, &
599 522 : fm_mat_Q=fm_mat_R_gw)
600 120 : DEALLOCATE (BIb_C_2D_gw)
601 :
602 : END IF
603 :
604 : ! for Bethe-Salpeter, we need other matrix fm_mat_S
605 294 : IF (do_bse) THEN
606 : CALL create_integ_mat(BIb_C_2D_bse_ij, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
607 : dimen_RI_red, [dimen_homo_square], color_rpa_group, &
608 : mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
609 : [my_ij_comb_bse_size], [my_ij_comb_bse_start], [my_ij_comb_bse_end], &
610 : my_group_L_size, my_group_L_start, my_group_L_end, &
611 : para_env_RPA, fm_mat_S_ij_bse, nrow_block_mat, ncol_block_mat, &
612 150 : fm_mat_Q(1)%matrix_struct%context, fm_mat_Q(1)%matrix_struct%context)
613 :
614 : CALL create_integ_mat(BIb_C_2D_bse_ab, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
615 : dimen_RI_red, [dimen_virt_square], color_rpa_group, &
616 : mp2_env%block_size_row, mp2_env%block_size_col, unit_nr, &
617 : [my_ab_comb_bse_size], [my_ab_comb_bse_start], [my_ab_comb_bse_end], &
618 : my_group_L_size, my_group_L_start, my_group_L_end, &
619 : para_env_RPA, fm_mat_S_ab_bse, nrow_block_mat, ncol_block_mat, &
620 150 : fm_mat_Q(1)%matrix_struct%context, fm_mat_Q(1)%matrix_struct%context)
621 :
622 : END IF
623 :
624 294 : do_kpoints_from_Gamma = qs_env%mp2_env%ri_rpa_im_time%do_kpoints_from_Gamma
625 294 : IF (do_kpoints_from_Gamma) THEN
626 16 : CALL get_bandstruc_and_k_dependent_MOs(qs_env, Eigenval_kp)
627 : END IF
628 :
629 : ! Now start the RPA calculation
630 : ! fm_mo_coeff_occ, fm_mo_coeff_virt will be deallocated here
631 : CALL rpa_num_int(qs_env, Erpa, mp2_env, para_env, para_env_RPA, para_env_sub, unit_nr, &
632 : homo, virtual, dimen_RI, dimen_RI_red, dimen_ia, dimen_nm_gw, &
633 : Eigenval_kp, num_integ_points, num_integ_group, color_rpa_group, &
634 : fm_matrix_PQ, fm_mat_S, fm_mat_Q_gemm, fm_mat_Q, fm_mat_S_gw, fm_mat_R_gw(1), &
635 : fm_mat_S_ij_bse(1), fm_mat_S_ab_bse(1), &
636 : my_do_gw, do_bse, gw_corr_lev_occ, gw_corr_lev_virt, &
637 : bse_lev_virt, &
638 : do_minimax_quad, &
639 : do_im_time, mo_coeff, &
640 : fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
641 : fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, mat_munu, mat_P_global, &
642 : t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
643 : starts_array_mc, ends_array_mc, &
644 : starts_array_mc_block, ends_array_mc_block, &
645 : matrix_s, do_kpoints_from_Gamma, kpoints, gd_array, color_sub, &
646 294 : do_ri_sos_laplace_mp2=do_ri_sos_laplace_mp2, calc_forces=calc_forces)
647 :
648 294 : CALL release_group_dist(gd_array)
649 :
650 294 : IF (num_integ_group > 1) CALL mp_para_env_release(para_env_RPA)
651 :
652 294 : IF (.NOT. do_im_time) THEN
653 160 : CALL cp_fm_release(fm_mat_Q_gemm)
654 160 : CALL cp_fm_release(fm_mat_S)
655 : END IF
656 294 : CALL cp_fm_release(fm_mat_Q)
657 :
658 294 : IF (my_do_gw .AND. .NOT. do_im_time) THEN
659 58 : CALL cp_fm_release(fm_mat_S_gw)
660 58 : CALL cp_fm_release(fm_mat_R_gw(1))
661 : END IF
662 :
663 294 : IF (do_bse) THEN
664 30 : CALL cp_fm_release(fm_mat_S_ij_bse(1))
665 30 : CALL cp_fm_release(fm_mat_S_ab_bse(1))
666 : END IF
667 :
668 294 : CALL timestop(handle)
669 :
670 1176 : END SUBROUTINE rpa_ri_compute_en
671 :
672 : ! **************************************************************************************************
673 : !> \brief reorder the local data in such a way to help the next stage of matrix creation;
674 : !> now the data inside the group are divided into a ia x K matrix (BIb_C_2D);
675 : !> Subroutine created to avoid massive double coding
676 : !> \param BIb_C_2D ...
677 : !> \param BIb_C ...
678 : !> \param para_env_sub ...
679 : !> \param dimen_ia ...
680 : !> \param homo ...
681 : !> \param virtual ...
682 : !> \param gd_B_virtual ...
683 : !> \param my_ia_size ...
684 : !> \param my_ia_start ...
685 : !> \param my_ia_end ...
686 : !> \param my_group_L_size ...
687 : !> \author Jan Wilhelm, 03/2015
688 : ! **************************************************************************************************
689 310 : SUBROUTINE calculate_BIb_C_2D(BIb_C_2D, BIb_C, para_env_sub, dimen_ia, homo, virtual, &
690 : gd_B_virtual, &
691 : my_ia_size, my_ia_start, my_ia_end, my_group_L_size)
692 :
693 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
694 : INTENT(OUT) :: BIb_C_2D
695 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
696 : INTENT(IN) :: BIb_C
697 : TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
698 : INTEGER, INTENT(IN) :: dimen_ia, homo, virtual
699 : TYPE(group_dist_d1_type), INTENT(INOUT) :: gd_B_virtual
700 : INTEGER :: my_ia_size, my_ia_start, my_ia_end, &
701 : my_group_L_size
702 :
703 : INTEGER, PARAMETER :: occ_chunk = 128
704 :
705 : INTEGER :: ia_global, iiB, itmp(2), jjB, my_B_size, my_B_virtual_start, occ_high, occ_low, &
706 : proc_receive, proc_send, proc_shift, rec_B_size, rec_B_virtual_end, rec_B_virtual_start
707 310 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), TARGET :: BIb_C_rec_1D
708 310 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: BIb_C_rec
709 :
710 310 : itmp = get_limit(dimen_ia, para_env_sub%num_pe, para_env_sub%mepos)
711 310 : my_ia_start = itmp(1)
712 310 : my_ia_end = itmp(2)
713 310 : my_ia_size = my_ia_end - my_ia_start + 1
714 :
715 310 : CALL get_group_dist(gd_B_virtual, para_env_sub%mepos, sizes=my_B_size, starts=my_B_virtual_start)
716 :
717 : ! reorder data
718 1234 : ALLOCATE (BIb_C_2D(my_group_L_size, my_ia_size))
719 :
720 : !$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,ia_global) &
721 : !$OMP SHARED(homo,my_B_size,virtual,my_B_virtual_start,my_ia_start,my_ia_end,BIb_C,BIb_C_2D,&
722 310 : !$OMP my_group_L_size)
723 : DO iiB = 1, homo
724 : DO jjB = 1, my_B_size
725 : ia_global = (iiB - 1)*virtual + my_B_virtual_start + jjB - 1
726 : IF (ia_global >= my_ia_start .AND. ia_global <= my_ia_end) THEN
727 : BIb_C_2D(1:my_group_L_size, ia_global - my_ia_start + 1) = BIb_C(1:my_group_L_size, jjB, iiB)
728 : END IF
729 : END DO
730 : END DO
731 :
732 310 : IF (para_env_sub%num_pe > 1) THEN
733 30 : ALLOCATE (BIb_C_rec_1D(INT(my_group_L_size, int_8)*maxsize(gd_B_virtual)*MIN(homo, occ_chunk)))
734 20 : DO proc_shift = 1, para_env_sub%num_pe - 1
735 10 : proc_send = MODULO(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
736 10 : proc_receive = MODULO(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
737 :
738 10 : CALL get_group_dist(gd_B_virtual, proc_receive, rec_B_virtual_start, rec_B_virtual_end, rec_B_size)
739 :
740 : ! do this in chunks to avoid high memory overhead
741 20 : DO occ_low = 1, homo, occ_chunk
742 10 : occ_high = MIN(homo, occ_low + occ_chunk - 1)
743 : BIb_C_rec(1:my_group_L_size, 1:rec_B_size, 1:occ_high - occ_low + 1) => &
744 10 : BIb_C_rec_1D(1:INT(my_group_L_size, int_8)*rec_B_size*(occ_high - occ_low + 1))
745 : CALL para_env_sub%sendrecv(BIb_C(:, :, occ_low:occ_high), proc_send, &
746 31970 : BIb_C_rec(:, :, 1:occ_high - occ_low + 1), proc_receive)
747 : !$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(jjB,ia_global) &
748 : !$OMP SHARED(occ_low,occ_high,rec_B_size,virtual,rec_B_virtual_start,my_ia_start,my_ia_end,BIb_C_rec,BIb_C_2D,&
749 10 : !$OMP my_group_L_size)
750 : DO iiB = occ_low, occ_high
751 : DO jjB = 1, rec_B_size
752 : ia_global = (iiB - 1)*virtual + rec_B_virtual_start + jjB - 1
753 : IF (ia_global >= my_ia_start .AND. ia_global <= my_ia_end) THEN
754 : BIb_C_2D(1:my_group_L_size, ia_global - my_ia_start + 1) = BIb_C_rec(1:my_group_L_size, jjB, iiB - occ_low + 1)
755 : END IF
756 : END DO
757 : END DO
758 : END DO
759 :
760 : END DO
761 10 : DEALLOCATE (BIb_C_rec_1D)
762 : END IF
763 :
764 310 : END SUBROUTINE calculate_BIb_C_2D
765 :
766 : ! **************************************************************************************************
767 : !> \brief ...
768 : !> \param BIb_C_2D ...
769 : !> \param para_env ...
770 : !> \param para_env_sub ...
771 : !> \param color_sub ...
772 : !> \param ngroup ...
773 : !> \param integ_group_size ...
774 : !> \param dimen_RI ...
775 : !> \param dimen_ia ...
776 : !> \param color_rpa_group ...
777 : !> \param ext_row_block_size ...
778 : !> \param ext_col_block_size ...
779 : !> \param unit_nr ...
780 : !> \param my_ia_size ...
781 : !> \param my_ia_start ...
782 : !> \param my_ia_end ...
783 : !> \param my_group_L_size ...
784 : !> \param my_group_L_start ...
785 : !> \param my_group_L_end ...
786 : !> \param para_env_RPA ...
787 : !> \param fm_mat_S ...
788 : !> \param nrow_block_mat ...
789 : !> \param ncol_block_mat ...
790 : !> \param blacs_env_ext ...
791 : !> \param blacs_env_ext_S ...
792 : !> \param dimen_ia_for_block_size ...
793 : !> \param do_im_time ...
794 : !> \param fm_mat_Q_gemm ...
795 : !> \param fm_mat_Q ...
796 : !> \param qs_env ...
797 : ! **************************************************************************************************
798 412 : SUBROUTINE create_integ_mat(BIb_C_2D, para_env, para_env_sub, color_sub, ngroup, integ_group_size, &
799 412 : dimen_RI, dimen_ia, color_rpa_group, &
800 : ext_row_block_size, ext_col_block_size, unit_nr, &
801 412 : my_ia_size, my_ia_start, my_ia_end, &
802 : my_group_L_size, my_group_L_start, my_group_L_end, &
803 412 : para_env_RPA, fm_mat_S, nrow_block_mat, ncol_block_mat, &
804 : blacs_env_ext, blacs_env_ext_S, dimen_ia_for_block_size, &
805 412 : do_im_time, fm_mat_Q_gemm, fm_mat_Q, qs_env)
806 :
807 : TYPE(two_dim_real_array), DIMENSION(:), &
808 : INTENT(INOUT) :: BIb_C_2D
809 : TYPE(mp_para_env_type), INTENT(IN) :: para_env, para_env_sub
810 : INTEGER, INTENT(IN) :: color_sub, ngroup, integ_group_size, &
811 : dimen_RI
812 : INTEGER, DIMENSION(:), INTENT(IN) :: dimen_ia
813 : INTEGER, INTENT(IN) :: color_rpa_group, ext_row_block_size, &
814 : ext_col_block_size, unit_nr
815 : INTEGER, DIMENSION(:), INTENT(IN) :: my_ia_size, my_ia_start, my_ia_end
816 : INTEGER, INTENT(IN) :: my_group_L_size, my_group_L_start, &
817 : my_group_L_end
818 : TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env_RPA
819 : TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: fm_mat_S
820 : INTEGER, INTENT(INOUT) :: nrow_block_mat, ncol_block_mat
821 : TYPE(cp_blacs_env_type), OPTIONAL, POINTER :: blacs_env_ext, blacs_env_ext_S
822 : INTEGER, INTENT(IN), OPTIONAL :: dimen_ia_for_block_size
823 : LOGICAL, INTENT(IN), OPTIONAL :: do_im_time
824 : TYPE(cp_fm_type), DIMENSION(:), OPTIONAL :: fm_mat_Q_gemm, fm_mat_Q
825 : TYPE(qs_environment_type), INTENT(IN), OPTIONAL, &
826 : POINTER :: qs_env
827 :
828 : CHARACTER(LEN=*), PARAMETER :: routineN = 'create_integ_mat'
829 :
830 : INTEGER :: col_row_proc_ratio, grid_2D(2), handle, &
831 : iproc, iproc_col, iproc_row, ispin, &
832 : mepos_in_RPA_group
833 412 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: group_grid_2_mepos
834 : LOGICAL :: my_blacs_ext, my_blacs_S_ext, &
835 : my_do_im_time
836 : TYPE(cp_blacs_env_type), POINTER :: blacs_env, blacs_env_Q
837 : TYPE(cp_fm_struct_type), POINTER :: fm_struct
838 412 : TYPE(group_dist_d1_type) :: gd_ia, gd_L
839 :
840 412 : CALL timeset(routineN, handle)
841 :
842 412 : CPASSERT(PRESENT(blacs_env_ext) .OR. PRESENT(dimen_ia_for_block_size))
843 :
844 412 : my_blacs_ext = .FALSE.
845 412 : IF (PRESENT(blacs_env_ext)) my_blacs_ext = .TRUE.
846 :
847 412 : my_blacs_S_ext = .FALSE.
848 412 : IF (PRESENT(blacs_env_ext_S)) my_blacs_S_ext = .TRUE.
849 :
850 412 : my_do_im_time = .FALSE.
851 412 : IF (PRESENT(do_im_time)) my_do_im_time = do_im_time
852 :
853 412 : NULLIFY (blacs_env)
854 : ! create the RPA blacs env
855 412 : IF (my_blacs_S_ext) THEN
856 118 : blacs_env => blacs_env_ext_S
857 : ELSE
858 294 : IF (para_env_RPA%num_pe > 1) THEN
859 202 : col_row_proc_ratio = MAX(1, dimen_ia_for_block_size/dimen_RI)
860 :
861 202 : iproc_col = MIN(MAX(INT(SQRT(REAL(para_env_RPA%num_pe*col_row_proc_ratio, KIND=dp))), 1), para_env_RPA%num_pe) + 1
862 202 : DO iproc = 1, para_env_RPA%num_pe
863 202 : iproc_col = iproc_col - 1
864 202 : IF (MOD(para_env_RPA%num_pe, iproc_col) == 0) EXIT
865 : END DO
866 :
867 202 : iproc_row = para_env_RPA%num_pe/iproc_col
868 202 : grid_2D(1) = iproc_row
869 202 : grid_2D(2) = iproc_col
870 : ELSE
871 276 : grid_2D = 1
872 : END IF
873 294 : CALL cp_blacs_env_create(blacs_env=blacs_env, para_env=para_env_RPA, grid_2d=grid_2D)
874 :
875 294 : IF (unit_nr > 0 .AND. .NOT. my_do_im_time) THEN
876 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
877 80 : "MATRIX_INFO| Number row processes:", grid_2D(1)
878 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
879 80 : "MATRIX_INFO| Number column processes:", grid_2D(2)
880 : END IF
881 :
882 : ! define the block_size for the row
883 294 : IF (ext_row_block_size > 0) THEN
884 0 : nrow_block_mat = ext_row_block_size
885 : ELSE
886 294 : nrow_block_mat = MAX(1, dimen_RI/grid_2D(1)/2)
887 : END IF
888 :
889 : ! define the block_size for the column
890 294 : IF (ext_col_block_size > 0) THEN
891 0 : ncol_block_mat = ext_col_block_size
892 : ELSE
893 294 : ncol_block_mat = MAX(1, dimen_ia_for_block_size/grid_2D(2)/2)
894 : END IF
895 :
896 294 : IF (unit_nr > 0 .AND. .NOT. my_do_im_time) THEN
897 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
898 80 : "MATRIX_INFO| Row block size:", nrow_block_mat
899 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
900 80 : "MATRIX_INFO| Column block size:", ncol_block_mat
901 : END IF
902 : END IF
903 :
904 345 : IF (.NOT. my_do_im_time) THEN
905 588 : DO ispin = 1, SIZE(BIb_C_2D)
906 310 : NULLIFY (fm_struct)
907 310 : IF (my_blacs_ext) THEN
908 : CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_RI, &
909 122 : ncol_global=dimen_ia(ispin), para_env=para_env_RPA)
910 : ELSE
911 : CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_RI, &
912 : ncol_global=dimen_ia(ispin), para_env=para_env_RPA, &
913 188 : nrow_block=nrow_block_mat, ncol_block=ncol_block_mat, force_block=.TRUE.)
914 :
915 : END IF ! external blacs_env
916 :
917 310 : CALL create_group_dist(gd_ia, my_ia_start(ispin), my_ia_end(ispin), my_ia_size(ispin), para_env_RPA)
918 310 : CALL create_group_dist(gd_L, my_group_L_start, my_group_L_end, my_group_L_size, para_env_RPA)
919 :
920 : ! create the info array
921 :
922 310 : mepos_in_RPA_group = MOD(color_sub, integ_group_size)
923 1240 : ALLOCATE (group_grid_2_mepos(0:integ_group_size - 1, 0:para_env_sub%num_pe - 1))
924 1106 : group_grid_2_mepos = 0
925 310 : group_grid_2_mepos(mepos_in_RPA_group, para_env_sub%mepos) = para_env_RPA%mepos
926 310 : CALL para_env_RPA%sum(group_grid_2_mepos)
927 :
928 : CALL array2fm(BIb_C_2D(ispin)%array, fm_struct, my_group_L_start, my_group_L_end, &
929 : my_ia_start(ispin), my_ia_end(ispin), gd_L, gd_ia, &
930 : group_grid_2_mepos, ngroup, para_env_sub%num_pe, fm_mat_S(ispin), &
931 310 : integ_group_size, color_rpa_group)
932 :
933 310 : DEALLOCATE (group_grid_2_mepos)
934 310 : CALL cp_fm_struct_release(fm_struct)
935 :
936 : ! deallocate the info array
937 310 : CALL release_group_dist(gd_L)
938 310 : CALL release_group_dist(gd_ia)
939 :
940 : ! sum the local data across processes belonging to different RPA group.
941 588 : IF (para_env_RPA%num_pe /= para_env%num_pe) THEN
942 : BLOCK
943 : TYPE(mp_comm_type) :: comm_exchange
944 144 : comm_exchange = fm_mat_S(ispin)%matrix_struct%context%interconnect(para_env)
945 144 : CALL comm_exchange%sum(fm_mat_S(ispin)%local_data)
946 288 : CALL comm_exchange%free()
947 : END BLOCK
948 : END IF
949 : END DO
950 : END IF
951 :
952 412 : IF (PRESENT(fm_mat_Q_gemm) .AND. .NOT. my_do_im_time) THEN
953 : ! create the Q matrix dimen_RIxdimen_RI where the result of the mat-mat-mult will be stored
954 160 : NULLIFY (fm_struct)
955 : CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_RI, &
956 : ncol_global=dimen_RI, para_env=para_env_RPA, &
957 160 : nrow_block=nrow_block_mat, ncol_block=ncol_block_mat, force_block=.TRUE.)
958 348 : DO ispin = 1, SIZE(fm_mat_Q_gemm)
959 348 : CALL cp_fm_create(fm_mat_Q_gemm(ispin), fm_struct, name="fm_mat_Q_gemm")
960 : END DO
961 160 : CALL cp_fm_struct_release(fm_struct)
962 : END IF
963 :
964 412 : IF (PRESENT(fm_mat_Q)) THEN
965 352 : NULLIFY (blacs_env_Q)
966 352 : IF (my_blacs_ext) THEN
967 58 : blacs_env_Q => blacs_env_ext
968 294 : ELSE IF (para_env_RPA%num_pe == para_env%num_pe .AND. PRESENT(qs_env)) THEN
969 202 : CALL get_qs_env(qs_env, blacs_env=blacs_env_Q)
970 : ELSE
971 92 : CALL cp_blacs_env_create(blacs_env=blacs_env_Q, para_env=para_env_RPA)
972 : END IF
973 352 : NULLIFY (fm_struct)
974 : CALL cp_fm_struct_create(fm_struct, context=blacs_env_Q, nrow_global=dimen_RI, &
975 352 : ncol_global=dimen_RI, para_env=para_env_RPA)
976 760 : DO ispin = 1, SIZE(fm_mat_Q)
977 760 : CALL cp_fm_create(fm_mat_Q(ispin), fm_struct, name="fm_mat_Q")
978 : END DO
979 :
980 352 : CALL cp_fm_struct_release(fm_struct)
981 :
982 352 : IF (.NOT. (my_blacs_ext .OR. (para_env_RPA%num_pe == para_env%num_pe .AND. PRESENT(qs_env)))) &
983 92 : CALL cp_blacs_env_release(blacs_env_Q)
984 : END IF
985 :
986 : ! release blacs_env
987 412 : IF (.NOT. my_blacs_S_ext) THEN
988 294 : CALL cp_blacs_env_release(blacs_env)
989 : ELSE
990 118 : NULLIFY (blacs_env)
991 : END IF
992 :
993 412 : CALL timestop(handle)
994 :
995 412 : END SUBROUTINE create_integ_mat
996 :
997 : ! **************************************************************************************************
998 : !> \brief ...
999 : !> \param qs_env ...
1000 : !> \param Erpa ...
1001 : !> \param mp2_env ...
1002 : !> \param para_env ...
1003 : !> \param para_env_RPA ...
1004 : !> \param para_env_sub ...
1005 : !> \param unit_nr ...
1006 : !> \param homo ...
1007 : !> \param virtual ...
1008 : !> \param dimen_RI ...
1009 : !> \param dimen_RI_red ...
1010 : !> \param dimen_ia ...
1011 : !> \param dimen_nm_gw ...
1012 : !> \param Eigenval ...
1013 : !> \param num_integ_points ...
1014 : !> \param num_integ_group ...
1015 : !> \param color_rpa_group ...
1016 : !> \param fm_matrix_PQ ...
1017 : !> \param fm_mat_S ...
1018 : !> \param fm_mat_Q_gemm ...
1019 : !> \param fm_mat_Q ...
1020 : !> \param fm_mat_S_gw ...
1021 : !> \param fm_mat_R_gw ...
1022 : !> \param fm_mat_S_ij_bse ...
1023 : !> \param fm_mat_S_ab_bse ...
1024 : !> \param my_do_gw ...
1025 : !> \param do_bse ...
1026 : !> \param gw_corr_lev_occ ...
1027 : !> \param gw_corr_lev_virt ...
1028 : !> \param bse_lev_virt ...
1029 : !> \param do_minimax_quad ...
1030 : !> \param do_im_time ...
1031 : !> \param mo_coeff ...
1032 : !> \param fm_matrix_L_kpoints ...
1033 : !> \param fm_matrix_Minv_L_kpoints ...
1034 : !> \param fm_matrix_Minv ...
1035 : !> \param fm_matrix_Minv_Vtrunc_Minv ...
1036 : !> \param mat_munu ...
1037 : !> \param mat_P_global ...
1038 : !> \param t_3c_M ...
1039 : !> \param t_3c_O ...
1040 : !> \param t_3c_O_compressed ...
1041 : !> \param t_3c_O_ind ...
1042 : !> \param starts_array_mc ...
1043 : !> \param ends_array_mc ...
1044 : !> \param starts_array_mc_block ...
1045 : !> \param ends_array_mc_block ...
1046 : !> \param matrix_s ...
1047 : !> \param do_kpoints_from_Gamma ...
1048 : !> \param kpoints ...
1049 : !> \param gd_array ...
1050 : !> \param color_sub ...
1051 : !> \param do_ri_sos_laplace_mp2 ...
1052 : !> \param calc_forces ...
1053 : ! **************************************************************************************************
1054 294 : SUBROUTINE rpa_num_int(qs_env, Erpa, mp2_env, para_env, para_env_RPA, para_env_sub, unit_nr, &
1055 294 : homo, virtual, dimen_RI, dimen_RI_red, dimen_ia, dimen_nm_gw, &
1056 : Eigenval, num_integ_points, num_integ_group, color_rpa_group, &
1057 588 : fm_matrix_PQ, fm_mat_S, fm_mat_Q_gemm, fm_mat_Q, fm_mat_S_gw, fm_mat_R_gw, &
1058 : fm_mat_S_ij_bse, fm_mat_S_ab_bse, &
1059 294 : my_do_gw, do_bse, gw_corr_lev_occ, gw_corr_lev_virt, &
1060 : bse_lev_virt, &
1061 294 : do_minimax_quad, do_im_time, mo_coeff, &
1062 : fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
1063 : fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, mat_munu, mat_P_global, &
1064 : t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
1065 : starts_array_mc, ends_array_mc, &
1066 : starts_array_mc_block, ends_array_mc_block, &
1067 : matrix_s, do_kpoints_from_Gamma, kpoints, gd_array, color_sub, &
1068 : do_ri_sos_laplace_mp2, calc_forces)
1069 :
1070 : TYPE(qs_environment_type), POINTER :: qs_env
1071 : REAL(KIND=dp), INTENT(OUT) :: Erpa
1072 : TYPE(mp2_type) :: mp2_env
1073 : TYPE(mp_para_env_type), POINTER :: para_env, para_env_RPA, para_env_sub
1074 : INTEGER, INTENT(IN) :: unit_nr
1075 : INTEGER, DIMENSION(:), INTENT(IN) :: homo, virtual
1076 : INTEGER, INTENT(IN) :: dimen_RI, dimen_RI_red
1077 : INTEGER, DIMENSION(:), INTENT(IN) :: dimen_ia
1078 : INTEGER, INTENT(IN) :: dimen_nm_gw
1079 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
1080 : INTENT(INOUT) :: Eigenval
1081 : INTEGER, INTENT(IN) :: num_integ_points, num_integ_group, &
1082 : color_rpa_group
1083 : TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_PQ
1084 : TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: fm_mat_S
1085 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_Q_gemm, fm_mat_Q, fm_mat_S_gw
1086 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_R_gw, fm_mat_S_ij_bse, &
1087 : fm_mat_S_ab_bse
1088 : LOGICAL, INTENT(IN) :: my_do_gw, do_bse
1089 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt
1090 : INTEGER, INTENT(IN) :: bse_lev_virt
1091 : LOGICAL, INTENT(IN) :: do_minimax_quad, do_im_time
1092 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
1093 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_L_kpoints, &
1094 : fm_matrix_Minv_L_kpoints, &
1095 : fm_matrix_Minv, &
1096 : fm_matrix_Minv_Vtrunc_Minv
1097 : TYPE(dbcsr_p_type), INTENT(IN) :: mat_munu
1098 : TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_P_global
1099 : TYPE(dbt_type), INTENT(INOUT) :: t_3c_M
1100 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :), &
1101 : INTENT(INOUT) :: t_3c_O
1102 : TYPE(hfx_compression_type), ALLOCATABLE, &
1103 : DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_O_compressed
1104 : TYPE(block_ind_type), ALLOCATABLE, &
1105 : DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_O_ind
1106 : INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(IN) :: starts_array_mc, ends_array_mc, &
1107 : starts_array_mc_block, &
1108 : ends_array_mc_block
1109 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1110 : LOGICAL :: do_kpoints_from_Gamma
1111 : TYPE(kpoint_type), POINTER :: kpoints
1112 : TYPE(group_dist_d1_type), INTENT(IN) :: gd_array
1113 : INTEGER, INTENT(IN) :: color_sub
1114 : LOGICAL, INTENT(IN) :: do_ri_sos_laplace_mp2, calc_forces
1115 :
1116 : CHARACTER(LEN=*), PARAMETER :: routineN = 'rpa_num_int'
1117 :
1118 : COMPLEX(KIND=dp), ALLOCATABLE, &
1119 294 : DIMENSION(:, :, :, :) :: vec_Sigma_c_gw
1120 : INTEGER :: count_ev_sc_GW, cut_memory, group_size_P, gw_corr_lev_tot, handle, handle3, &
1121 : i, ikp_local, ispin, iter_evGW, iter_sc_GW0, j, jquad, min_bsize, mm_style, nkp, &
1122 : nkp_self_energy, nmo, nspins, num_3c_repl, num_cells_dm, num_fit_points, Pspin, Qspin, &
1123 : size_P
1124 : #if defined (__GREENX)
1125 : INTEGER :: gi, ierr
1126 : #endif
1127 : INTEGER(int_8) :: dbcsr_nflop
1128 294 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: index_to_cell_3c
1129 294 : INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: cell_to_index_3c
1130 588 : INTEGER, DIMENSION(:), POINTER :: col_blk_size, prim_blk_sizes, &
1131 294 : RI_blk_sizes
1132 : LOGICAL :: do_apply_ic_corr_to_gw, do_gw_im_time, do_ic_model, do_kpoints_cubic_RPA, &
1133 : do_periodic, do_print, do_ri_Sigma_x, exit_ev_gw, first_cycle, &
1134 : first_cycle_periodic_correction, my_open_shell, print_ic_values
1135 294 : LOGICAL, ALLOCATABLE, DIMENSION(:, :, :, :, :) :: has_mat_P_blocks
1136 : REAL(KIND=dp) :: a_scaling, alpha, dbcsr_time, e_exchange, e_exchange_corr, &
1137 : eps_filter, eps_filter_im_time, ext_scaling, fermi_level_offset, fermi_level_offset_input, &
1138 : my_flop_rate, omega, omega_max_fit, omega_old, tau, tau_old
1139 : #if defined (__GREENX)
1140 : REAL(KIND=dp) :: cosft_duality_error_greenx, Emax, Emin, &
1141 : max_errors_greenx(3)
1142 : #endif
1143 588 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: delta_corr, e_fermi, tau_tj, tau_wj, tj, &
1144 294 : trace_Qomega, vec_omega_fit_gw, wj, &
1145 294 : wkp_W
1146 294 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: vec_W_gw, weights_cos_tf_t_to_w, &
1147 294 : weights_cos_tf_w_to_t, &
1148 294 : weights_sin_tf_t_to_w
1149 294 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: Eigenval_last, Eigenval_scf, &
1150 294 : vec_Sigma_x_gw
1151 : TYPE(cp_cfm_type) :: cfm_mat_Q
1152 : TYPE(cp_fm_type) :: fm_mat_Q_static_bse_gemm, fm_mat_RI_global_work, fm_mat_S_ia_bse, &
1153 : fm_mat_work, fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, fm_scaled_dm_occ_tau, &
1154 : fm_scaled_dm_virt_tau
1155 294 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_mat_S_gw_work, fm_mat_W, &
1156 294 : fm_mo_coeff_occ, fm_mo_coeff_virt
1157 294 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_mat_L_kpoints, fm_mat_Minv_L_kpoints
1158 : TYPE(dbcsr_p_type) :: mat_dm, mat_L, mat_M_P_munu_occ, &
1159 : mat_M_P_munu_virt, mat_MinvVMinv
1160 : TYPE(dbcsr_p_type), ALLOCATABLE, &
1161 294 : DIMENSION(:, :, :) :: mat_P_omega
1162 294 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_im_mo_mo, &
1163 294 : matrix_berry_re_mo_mo
1164 294 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_P_omega_kp
1165 : TYPE(dbcsr_type), POINTER :: mat_W, mat_work
1166 2058 : TYPE(dbt_type) :: t_3c_overl_int_ao_mo
1167 294 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:) :: t_3c_overl_int_gw_AO, &
1168 294 : t_3c_overl_int_gw_RI, &
1169 294 : t_3c_overl_nnP_ic, &
1170 294 : t_3c_overl_nnP_ic_reflected
1171 : TYPE(dgemm_counter_type) :: dgemm_counter
1172 : TYPE(hfx_compression_type), ALLOCATABLE, &
1173 294 : DIMENSION(:) :: t_3c_O_mo_compressed
1174 21756 : TYPE(im_time_force_type) :: force_data
1175 294 : TYPE(rpa_exchange_work_type) :: exchange_work
1176 1470 : TYPE(rpa_grad_type) :: rpa_grad
1177 294 : TYPE(rpa_sigma_type) :: rpa_sigma
1178 294 : TYPE(two_dim_int_array), ALLOCATABLE, DIMENSION(:) :: t_3c_O_mo_ind
1179 :
1180 294 : CALL timeset(routineN, handle)
1181 :
1182 294 : nspins = SIZE(homo)
1183 294 : nmo = homo(1) + virtual(1)
1184 :
1185 294 : my_open_shell = (nspins == 2)
1186 :
1187 294 : do_gw_im_time = my_do_gw .AND. do_im_time
1188 294 : do_ri_Sigma_x = mp2_env%ri_g0w0%do_ri_Sigma_x
1189 294 : do_ic_model = mp2_env%ri_g0w0%do_ic_model
1190 294 : print_ic_values = mp2_env%ri_g0w0%print_ic_values
1191 294 : do_periodic = mp2_env%ri_g0w0%do_periodic
1192 294 : do_kpoints_cubic_RPA = mp2_env%ri_rpa_im_time%do_im_time_kpoints
1193 :
1194 : ! For SOS-MP2 only gemm is implemented
1195 294 : mm_style = wfc_mm_style_gemm
1196 294 : IF (.NOT. do_ri_sos_laplace_mp2) mm_style = mp2_env%ri_rpa%mm_style
1197 :
1198 294 : IF (my_do_gw) THEN
1199 104 : ext_scaling = 0.2_dp
1200 104 : omega_max_fit = mp2_env%ri_g0w0%omega_max_fit
1201 104 : fermi_level_offset_input = mp2_env%ri_g0w0%fermi_level_offset
1202 104 : iter_evGW = mp2_env%ri_g0w0%iter_evGW
1203 104 : iter_sc_GW0 = mp2_env%ri_g0w0%iter_sc_GW0
1204 104 : IF ((.NOT. do_im_time)) THEN
1205 58 : IF (iter_sc_GW0 .NE. 1 .AND. iter_evGW .NE. 1) CPABORT("Mixed scGW0/evGW not implemented.")
1206 : ! in case of scGW0 with the N^4 algorithm, we use the evGW code but use the DFT eigenvalues for W
1207 58 : IF (iter_sc_GW0 .NE. 1) iter_evGW = iter_sc_GW0
1208 : END IF
1209 : ELSE
1210 190 : ext_scaling = 0.0_dp
1211 190 : iter_evGW = 1
1212 190 : iter_sc_GW0 = 1
1213 : END IF
1214 :
1215 294 : IF (do_kpoints_cubic_RPA .AND. do_ri_sos_laplace_mp2) THEN
1216 0 : CPABORT("RI-SOS-Laplace-MP2 with k-point-sampling is not implemented.")
1217 : END IF
1218 :
1219 294 : do_apply_ic_corr_to_gw = .FALSE.
1220 294 : IF (mp2_env%ri_g0w0%ic_corr_list(1)%array(1) > 0.0_dp) do_apply_ic_corr_to_gw = .TRUE.
1221 :
1222 294 : IF (do_im_time) THEN
1223 134 : CPASSERT(do_minimax_quad .OR. do_ri_sos_laplace_mp2)
1224 :
1225 134 : group_size_P = mp2_env%ri_rpa_im_time%group_size_P
1226 134 : cut_memory = mp2_env%ri_rpa_im_time%cut_memory
1227 134 : eps_filter = mp2_env%ri_rpa_im_time%eps_filter
1228 : eps_filter_im_time = mp2_env%ri_rpa_im_time%eps_filter* &
1229 134 : mp2_env%ri_rpa_im_time%eps_filter_factor
1230 :
1231 134 : min_bsize = mp2_env%ri_rpa_im_time%min_bsize
1232 :
1233 : CALL alloc_im_time(qs_env, para_env, dimen_RI, dimen_RI_red, &
1234 : num_integ_points, nspins, fm_mat_Q(1), fm_mo_coeff_occ, fm_mo_coeff_virt, &
1235 : fm_matrix_Minv_L_kpoints, fm_matrix_L_kpoints, mat_P_global, &
1236 : t_3c_O, matrix_s, kpoints, eps_filter_im_time, &
1237 : cut_memory, nkp, num_cells_dm, num_3c_repl, &
1238 : size_P, ikp_local, &
1239 : index_to_cell_3c, &
1240 : cell_to_index_3c, &
1241 : col_blk_size, &
1242 : do_ic_model, do_kpoints_cubic_RPA, &
1243 : do_kpoints_from_Gamma, do_ri_Sigma_x, my_open_shell, &
1244 : has_mat_P_blocks, wkp_W, &
1245 : cfm_mat_Q, fm_mat_Minv_L_kpoints, fm_mat_L_kpoints, &
1246 : fm_mat_RI_global_work, fm_mat_work, fm_mo_coeff_occ_scaled, &
1247 : fm_mo_coeff_virt_scaled, mat_dm, mat_L, mat_M_P_munu_occ, mat_M_P_munu_virt, &
1248 : mat_MinvVMinv, mat_P_omega, mat_P_omega_kp, mat_work, mo_coeff, &
1249 134 : fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, homo, nmo)
1250 :
1251 134 : IF (calc_forces) CALL init_im_time_forces(force_data, fm_matrix_PQ, t_3c_M, unit_nr, mp2_env, qs_env)
1252 :
1253 134 : IF (my_do_gw) THEN
1254 :
1255 : CALL dbcsr_get_info(mat_P_global%matrix, &
1256 46 : row_blk_size=RI_blk_sizes)
1257 :
1258 : CALL dbcsr_get_info(matrix_s(1)%matrix, &
1259 46 : row_blk_size=prim_blk_sizes)
1260 :
1261 46 : gw_corr_lev_tot = gw_corr_lev_occ(1) + gw_corr_lev_virt(1)
1262 :
1263 46 : IF (.NOT. do_kpoints_cubic_RPA) THEN
1264 : CALL allocate_matrices_gw_im_time(gw_corr_lev_occ, gw_corr_lev_virt, homo, nmo, &
1265 : num_integ_points, unit_nr, &
1266 : RI_blk_sizes, do_ic_model, &
1267 : para_env, fm_mat_W, fm_mat_Q(1), &
1268 : mo_coeff, &
1269 : t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
1270 : t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
1271 : starts_array_mc, ends_array_mc, &
1272 : t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, &
1273 : matrix_s, mat_W, t_3c_O, &
1274 : t_3c_O_compressed, t_3c_O_ind, &
1275 46 : qs_env)
1276 :
1277 : END IF
1278 : END IF
1279 :
1280 : END IF
1281 294 : IF (do_ic_model) THEN
1282 : ! image charge model only implemented for cubic scaling GW
1283 2 : CPASSERT(do_gw_im_time)
1284 2 : CPASSERT(.NOT. do_periodic)
1285 2 : IF (cut_memory .NE. 1) CPABORT("For IC, use MEMORY_CUT 1 in the LOW_SCALING section.")
1286 : END IF
1287 :
1288 882 : ALLOCATE (e_fermi(nspins))
1289 294 : IF (do_minimax_quad .OR. do_ri_sos_laplace_mp2) THEN
1290 200 : do_print = .NOT. do_ic_model
1291 : #if defined (__GREENX)
1292 : CALL init_greenx_grids(qs_env, para_env, homo, Eigenval, do_ri_sos_laplace_mp2, &
1293 200 : do_kpoints_cubic_RPA, Emin, Emax, e_fermi(1))
1294 : CALL gx_minimax_grid(num_integ_points, Emin, Emax, tau_tj, tau_wj, tj, wj, &
1295 : weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, &
1296 : max_errors_greenx, cosft_duality_error_greenx, ierr, &
1297 : bare_cos_sin_weights=.TRUE., &
1298 200 : regularization=qs_env%mp2_env%ri_g0w0%regularization_minimax)
1299 : ! Factor 4 is hard-coded in the RPA weights in the internal CP2K minimax routines
1300 1464 : wj(:) = wj(:)*4.0_dp
1301 200 : IF (ierr == 0) THEN
1302 74 : IF (unit_nr > 0) THEN
1303 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75,i6)") &
1304 37 : "GREENX MINIMAX_INFO| Number of integration points:", num_integ_points
1305 : WRITE (UNIT=unit_nr, FMT="(T3,A,T61,3F20.7)") &
1306 37 : "GREENX MINIMAX_INFO| Gap (Emin):", Emin
1307 : WRITE (UNIT=unit_nr, FMT="(T3,A,T61,3F20.7)") &
1308 37 : "GREENX MINIMAX_INFO| Maximum eigenvalue difference (Emax):", Emax
1309 : WRITE (UNIT=unit_nr, FMT="(T3,A,T61,3F20.4)") &
1310 37 : "GREENX MINIMAX_INFO| Energy range (Emax/Emin):", Emax/Emin
1311 : WRITE (UNIT=unit_nr, FMT="(T3,A,T54,A,T72,A)") &
1312 37 : "GREENX MINIMAX_INFO| Frequency grid (scaled):", "Weights", "Abscissas"
1313 425 : DO gi = 1, num_integ_points
1314 425 : WRITE (UNIT=unit_nr, FMT="(T41,F20.10,F20.10)") wj(gi), tj(gi)
1315 : END DO
1316 : WRITE (UNIT=unit_nr, FMT="(T3,A,T54,A,T72,A)") &
1317 37 : "GREENX MINIMAX_INFO| Time grid (scaled):", "Weights", "Abscissas"
1318 425 : DO gi = 1, num_integ_points
1319 425 : WRITE (UNIT=unit_nr, FMT="(T41,F20.10,F20.10)") tau_wj(gi), tau_tj(gi)
1320 : END DO
1321 37 : CALL m_flush(unit_nr)
1322 : END IF
1323 : ELSE
1324 126 : IF (unit_nr > 0) THEN
1325 : WRITE (UNIT=unit_nr, FMT="(T3,A,T75)") &
1326 63 : "GREENX MINIMAX_INFO| Grid not available, use internal CP2K grids"
1327 63 : CALL m_flush(unit_nr)
1328 : END IF
1329 126 : IF (ALLOCATED(tau_tj)) THEN
1330 126 : DEALLOCATE (tau_tj)
1331 : END IF
1332 126 : IF (ALLOCATED(tau_wj)) THEN
1333 126 : DEALLOCATE (tau_wj)
1334 : END IF
1335 126 : IF (ALLOCATED(tj)) THEN
1336 126 : DEALLOCATE (tj)
1337 : END IF
1338 126 : IF (ALLOCATED(wj)) THEN
1339 126 : DEALLOCATE (wj)
1340 : END IF
1341 126 : IF (ALLOCATED(weights_cos_tf_t_to_w)) THEN
1342 0 : DEALLOCATE (weights_cos_tf_t_to_w)
1343 : END IF
1344 126 : IF (ALLOCATED(weights_cos_tf_w_to_t)) THEN
1345 0 : DEALLOCATE (weights_cos_tf_w_to_t)
1346 : END IF
1347 126 : IF (ALLOCATED(weights_sin_tf_t_to_w)) THEN
1348 0 : DEALLOCATE (weights_sin_tf_t_to_w)
1349 : END IF
1350 : CALL get_minimax_grid(para_env, unit_nr, homo, Eigenval, num_integ_points, do_im_time, &
1351 : do_ri_sos_laplace_mp2, do_print, &
1352 : tau_tj, tau_wj, qs_env, do_gw_im_time, &
1353 : do_kpoints_cubic_RPA, e_fermi(1), tj, wj, &
1354 : weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, &
1355 126 : qs_env%mp2_env%ri_g0w0%regularization_minimax)
1356 : END IF
1357 : #else
1358 : CALL get_minimax_grid(para_env, unit_nr, homo, Eigenval, num_integ_points, do_im_time, &
1359 : do_ri_sos_laplace_mp2, do_print, &
1360 : tau_tj, tau_wj, qs_env, do_gw_im_time, &
1361 : do_kpoints_cubic_RPA, e_fermi(1), tj, wj, &
1362 : weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, &
1363 : qs_env%mp2_env%ri_g0w0%regularization_minimax)
1364 : #endif
1365 :
1366 : !For sos_laplace_mp2 and low-scaling RPA, potentially need to store/retrieve the initial weights
1367 200 : IF (qs_env%mp2_env%ri_rpa_im_time%keep_quad) THEN
1368 : CALL keep_initial_quad(tj, wj, tau_tj, tau_wj, weights_cos_tf_t_to_w, &
1369 : weights_cos_tf_w_to_t, do_ri_sos_laplace_mp2, do_im_time, &
1370 200 : num_integ_points, unit_nr, qs_env)
1371 : END IF
1372 : ELSE
1373 94 : IF (calc_forces) CPABORT("Forces with Clenshaw-Curtis grid not implemented.")
1374 : CALL get_clenshaw_grid(para_env, para_env_RPA, unit_nr, homo, virtual, Eigenval, num_integ_points, &
1375 : num_integ_group, color_rpa_group, fm_mat_S, my_do_gw, &
1376 94 : ext_scaling, a_scaling, tj, wj)
1377 : END IF
1378 :
1379 : ! This array is needed for RPA
1380 294 : IF (.NOT. do_ri_sos_laplace_mp2) THEN
1381 708 : ALLOCATE (trace_Qomega(dimen_RI_red))
1382 : END IF
1383 :
1384 294 : IF (do_ri_sos_laplace_mp2 .AND. .NOT. do_im_time) THEN
1385 28 : alpha = 1.0_dp
1386 266 : ELSE IF (my_open_shell .OR. do_ri_sos_laplace_mp2) THEN
1387 70 : alpha = 2.0_dp
1388 : ELSE
1389 196 : alpha = 4.0_dp
1390 : END IF
1391 294 : IF (my_do_gw) THEN
1392 : CALL allocate_matrices_gw(vec_Sigma_c_gw, color_rpa_group, dimen_nm_gw, &
1393 : gw_corr_lev_occ, gw_corr_lev_virt, homo, &
1394 : nmo, num_integ_group, num_integ_points, unit_nr, &
1395 : gw_corr_lev_tot, num_fit_points, omega_max_fit, &
1396 : do_minimax_quad, do_periodic, do_ri_Sigma_x,.NOT. do_im_time, &
1397 : first_cycle_periodic_correction, &
1398 : a_scaling, Eigenval, tj, vec_omega_fit_gw, vec_Sigma_x_gw, &
1399 : delta_corr, Eigenval_last, Eigenval_scf, vec_W_gw, &
1400 : fm_mat_S_gw, fm_mat_S_gw_work, &
1401 : para_env, mp2_env, kpoints, nkp, nkp_self_energy, &
1402 104 : do_kpoints_cubic_RPA, do_kpoints_from_Gamma)
1403 :
1404 104 : IF (do_bse) THEN
1405 :
1406 30 : CALL cp_fm_create(fm_mat_Q_static_bse_gemm, fm_mat_Q_gemm(1)%matrix_struct)
1407 30 : CALL cp_fm_to_fm(fm_mat_Q_gemm(1), fm_mat_Q_static_bse_gemm)
1408 30 : CALL cp_fm_set_all(fm_mat_Q_static_bse_gemm, 0.0_dp)
1409 :
1410 : END IF
1411 :
1412 : END IF
1413 :
1414 294 : IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_create(rpa_grad, fm_mat_Q(1), &
1415 : fm_mat_S, homo, virtual, mp2_env, Eigenval(:, 1, :), &
1416 40 : unit_nr, do_ri_sos_laplace_mp2)
1417 : !doubtful
1418 294 : IF (.NOT. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) &
1419 : CALL exchange_work%create(qs_env, para_env_sub, mat_munu, dimen_RI_red, &
1420 132 : fm_mat_S, fm_mat_Q(1), fm_mat_Q_gemm(1), homo, virtual)
1421 294 : Erpa = 0.0_dp
1422 294 : IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) e_exchange = 0.0_dp
1423 294 : first_cycle = .TRUE.
1424 294 : omega_old = 0.0_dp
1425 294 : CALL dgemm_counter_init(dgemm_counter, unit_nr, mp2_env%ri_rpa%print_dgemm_info)
1426 :
1427 698 : DO count_ev_sc_GW = 1, iter_evGW
1428 424 : dbcsr_time = 0.0_dp
1429 424 : dbcsr_nflop = 0
1430 :
1431 424 : IF (do_ic_model) CYCLE
1432 :
1433 : ! reset some values, important when doing eigenvalue self-consistent GW
1434 422 : IF (my_do_gw) THEN
1435 232 : Erpa = 0.0_dp
1436 156488 : vec_Sigma_c_gw = z_zero
1437 232 : first_cycle = .TRUE.
1438 : END IF
1439 :
1440 : ! calculate Q_PQ(it)
1441 422 : IF (do_im_time) THEN ! not using Imaginary time
1442 :
1443 146 : IF (.NOT. do_kpoints_cubic_RPA) THEN
1444 312 : DO ispin = 1, nspins
1445 312 : e_fermi(ispin) = (Eigenval(homo(ispin), 1, ispin) + Eigenval(homo(ispin) + 1, 1, ispin))*0.5_dp
1446 : END DO
1447 : END IF
1448 :
1449 146 : tau = 0.0_dp
1450 146 : tau_old = 0.0_dp
1451 :
1452 146 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(/T3,A,T66,i15)") &
1453 73 : "MEMORY_INFO| Memory cut:", cut_memory
1454 146 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,ES15.2)") &
1455 73 : "SPARSITY_INFO| Eps filter for M virt/occ tensors:", eps_filter
1456 146 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,ES15.2)") &
1457 73 : "SPARSITY_INFO| Eps filter for P matrix:", eps_filter_im_time
1458 146 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,i15)") &
1459 73 : "SPARSITY_INFO| Minimum tensor block size:", min_bsize
1460 :
1461 : ! for evGW, we have to ensure that mat_P_omega is zero
1462 146 : CALL zero_mat_P_omega(mat_P_omega(:, :, 1))
1463 :
1464 : ! compute the matrix Q(it) and Fourier transform it directly to mat_P_omega(iw)
1465 : CALL compute_mat_P_omega(mat_P_omega(:, :, 1), fm_scaled_dm_occ_tau, &
1466 : fm_scaled_dm_virt_tau, fm_mo_coeff_occ(1), fm_mo_coeff_virt(1), &
1467 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
1468 : mat_P_global, matrix_s, 1, &
1469 : t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
1470 : starts_array_mc, ends_array_mc, &
1471 : starts_array_mc_block, ends_array_mc_block, &
1472 : weights_cos_tf_t_to_w, tj, tau_tj, e_fermi(1), eps_filter, alpha, &
1473 : eps_filter_im_time, Eigenval(:, 1, 1), nmo, &
1474 : num_integ_points, cut_memory, &
1475 : unit_nr, mp2_env, para_env, &
1476 : qs_env, do_kpoints_from_Gamma, &
1477 : index_to_cell_3c, cell_to_index_3c, &
1478 : has_mat_P_blocks, do_ri_sos_laplace_mp2, &
1479 146 : dbcsr_time, dbcsr_nflop)
1480 :
1481 : ! the same for open shell, use fm_mo_coeff_occ_beta and fm_mo_coeff_virt_beta
1482 146 : IF (my_open_shell) THEN
1483 28 : CALL zero_mat_P_omega(mat_P_omega(:, :, 2))
1484 : CALL compute_mat_P_omega(mat_P_omega(:, :, 2), fm_scaled_dm_occ_tau, &
1485 : fm_scaled_dm_virt_tau, fm_mo_coeff_occ(2), &
1486 : fm_mo_coeff_virt(2), &
1487 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
1488 : mat_P_global, matrix_s, 2, &
1489 : t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
1490 : starts_array_mc, ends_array_mc, &
1491 : starts_array_mc_block, ends_array_mc_block, &
1492 : weights_cos_tf_t_to_w, tj, tau_tj, e_fermi(2), eps_filter, alpha, &
1493 : eps_filter_im_time, Eigenval(:, 1, 2), nmo, &
1494 : num_integ_points, cut_memory, &
1495 : unit_nr, mp2_env, para_env, &
1496 : qs_env, do_kpoints_from_Gamma, &
1497 : index_to_cell_3c, cell_to_index_3c, &
1498 : has_mat_P_blocks, do_ri_sos_laplace_mp2, &
1499 28 : dbcsr_time, dbcsr_nflop)
1500 :
1501 : !For RPA, we sum up the P matrices. If no force needed, can clean-up the beta spin one
1502 28 : IF (.NOT. do_ri_sos_laplace_mp2) THEN
1503 90 : DO j = 1, SIZE(mat_P_omega, 2)
1504 598 : DO i = 1, SIZE(mat_P_omega, 1)
1505 508 : CALL dbcsr_add(mat_P_omega(i, j, 1)%matrix, mat_P_omega(i, j, 2)%matrix, 1.0_dp, 1.0_dp)
1506 578 : IF (.NOT. calc_forces) CALL dbcsr_clear(mat_P_omega(i, j, 2)%matrix)
1507 : END DO
1508 : END DO
1509 : END IF
1510 : END IF ! my_open_shell
1511 :
1512 : END IF ! do im time
1513 :
1514 422 : IF (mp2_env%ri_rpa%sigma_param /= sigma_none) THEN
1515 10 : CALL rpa_sigma_create(rpa_sigma, mp2_env%ri_rpa%sigma_param, fm_mat_Q(1), unit_nr, para_env)
1516 : END IF
1517 :
1518 12544 : DO jquad = 1, num_integ_points
1519 12122 : IF (MODULO(jquad, num_integ_group) /= color_rpa_group) CYCLE
1520 :
1521 11482 : CALL timeset(routineN//"_RPA_matrix_operations", handle3)
1522 :
1523 11482 : IF (do_ri_sos_laplace_mp2) THEN
1524 206 : omega = tau_tj(jquad)
1525 : ELSE
1526 11276 : IF (do_minimax_quad) THEN
1527 1186 : omega = tj(jquad)
1528 : ELSE
1529 10090 : omega = a_scaling/TAN(tj(jquad))
1530 : END IF
1531 : END IF ! do_ri_sos_laplace_mp2
1532 :
1533 11482 : IF (do_im_time) THEN
1534 : ! in case we do imag time, we already calculated fm_mat_Q by a Fourier transform from im. time
1535 :
1536 1168 : IF (.NOT. (do_kpoints_cubic_RPA .OR. do_kpoints_from_Gamma)) THEN
1537 :
1538 2324 : DO ispin = 1, SIZE(mat_P_omega, 3)
1539 : CALL contract_P_omega_with_mat_L(mat_P_omega(jquad, 1, ispin)%matrix, mat_L%matrix, mat_work, &
1540 : eps_filter_im_time, fm_mat_work, dimen_RI, dimen_RI_red, &
1541 2324 : fm_mat_Minv_L_kpoints(1, 1), fm_mat_Q(ispin))
1542 : END DO
1543 : END IF
1544 :
1545 : ELSE
1546 10314 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3, A, 1X, I3, 1X, A, 1X, I3)") &
1547 5157 : "INTEG_INFO| Started with Integration point", jquad, "of", num_integ_points
1548 :
1549 10314 : IF (first_cycle .AND. count_ev_sc_gw > 1) THEN
1550 116 : IF (iter_sc_gw0 == 1) THEN
1551 124 : DO ispin = 1, nspins
1552 : CALL remove_scaling_factor_rpa(fm_mat_S(ispin), virtual(ispin), &
1553 124 : Eigenval_last(:, 1, ispin), homo(ispin), omega_old)
1554 : END DO
1555 : ELSE
1556 116 : DO ispin = 1, nspins
1557 : CALL remove_scaling_factor_rpa(fm_mat_S(ispin), virtual(ispin), &
1558 116 : Eigenval_scf(:, 1, ispin), homo(ispin), omega_old)
1559 : END DO
1560 : END IF
1561 : END IF
1562 :
1563 10314 : IF (iter_sc_GW0 > 1) THEN
1564 12140 : DO ispin = 1, nspins
1565 : CALL calc_mat_Q(fm_mat_S(ispin), do_ri_sos_laplace_mp2, first_cycle, virtual(ispin), &
1566 : Eigenval_scf(:, 1, ispin), homo(ispin), omega, omega_old, jquad, mm_style, &
1567 : dimen_RI_red, dimen_ia(ispin), alpha, fm_mat_Q(ispin), &
1568 : fm_mat_Q_gemm(ispin), do_bse, fm_mat_Q_static_bse_gemm, dgemm_counter, &
1569 12140 : num_integ_points, count_ev_sc_GW)
1570 : END DO
1571 :
1572 : ! For SOS-MP2 we need both matrices separately
1573 6070 : IF (.NOT. do_ri_sos_laplace_mp2) THEN
1574 6070 : DO ispin = 2, nspins
1575 6070 : CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_Q(1), beta=1.0_dp, matrix_b=fm_mat_Q(ispin))
1576 : END DO
1577 : END IF
1578 : ELSE
1579 8652 : DO ispin = 1, nspins
1580 : CALL calc_mat_Q(fm_mat_S(ispin), do_ri_sos_laplace_mp2, first_cycle, virtual(ispin), &
1581 : Eigenval(:, 1, ispin), homo(ispin), omega, omega_old, jquad, mm_style, &
1582 : dimen_RI_red, dimen_ia(ispin), alpha, fm_mat_Q(ispin), &
1583 : fm_mat_Q_gemm(ispin), do_bse, fm_mat_Q_static_bse_gemm, dgemm_counter, &
1584 8652 : num_integ_points, count_ev_sc_GW)
1585 : END DO
1586 :
1587 : ! For SOS-MP2 we need both matrices separately
1588 4244 : IF (.NOT. do_ri_sos_laplace_mp2) THEN
1589 4280 : DO ispin = 2, nspins
1590 4280 : CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_Q(1), beta=1.0_dp, matrix_b=fm_mat_Q(ispin))
1591 : END DO
1592 : END IF
1593 :
1594 : END IF
1595 :
1596 : END IF ! im time
1597 :
1598 : ! Calculate RPA exchange energy correction
1599 11482 : IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) THEN
1600 12 : e_exchange_corr = 0.0_dp
1601 12 : CALL exchange_work%compute(fm_mat_Q(1), Eigenval(:, 1, :), fm_mat_S, omega, e_exchange_corr, mp2_env)
1602 :
1603 : ! Evaluate the final exchange energy correction
1604 12 : e_exchange = e_exchange + e_exchange_corr*wj(jquad)
1605 : END IF
1606 :
1607 : ! for developing Sigma functional closed and open shell are taken cared for
1608 11482 : IF (mp2_env%ri_rpa%sigma_param /= sigma_none) THEN
1609 30 : CALL rpa_sigma_matrix_spectral(rpa_sigma, fm_mat_Q(1), wj(jquad), para_env_RPA)
1610 : END IF
1611 :
1612 11482 : IF (do_ri_sos_laplace_mp2) THEN
1613 :
1614 206 : CALL SOS_MP2_postprocessing(fm_mat_Q, Erpa, tau_wj(jquad))
1615 :
1616 206 : IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_matrix_operations(mp2_env, rpa_grad, do_ri_sos_laplace_mp2, &
1617 : fm_mat_Q, fm_mat_Q_gemm, dgemm_counter, fm_mat_S, omega, homo, virtual, &
1618 60 : Eigenval(:, 1, :), tau_wj(jquad), unit_nr)
1619 : ELSE
1620 11276 : IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_copy_Q(fm_mat_Q(1), rpa_grad)
1621 :
1622 11276 : CALL Q_trace_and_add_unit_matrix(dimen_RI_red, trace_Qomega, fm_mat_Q(1))
1623 :
1624 11276 : IF (do_kpoints_cubic_RPA .OR. do_kpoints_from_Gamma) THEN
1625 : CALL invert_eps_compute_W_and_Erpa_kp(dimen_RI, num_integ_points, jquad, nkp, count_ev_sc_GW, para_env, &
1626 : Erpa, tau_tj, tj, wj, weights_cos_tf_w_to_t, &
1627 : wkp_W, do_gw_im_time, do_ri_Sigma_x, do_kpoints_from_Gamma, &
1628 : cfm_mat_Q, ikp_local, &
1629 : mat_P_omega(:, :, 1), mat_P_omega_kp, qs_env, eps_filter_im_time, unit_nr, &
1630 : kpoints, fm_mat_Minv_L_kpoints, fm_mat_L_kpoints, &
1631 : fm_mat_W, fm_mat_RI_global_work, mat_MinvVMinv, &
1632 120 : fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv)
1633 : ELSE
1634 11156 : CALL compute_Erpa_by_freq_int(dimen_RI_red, trace_Qomega, fm_mat_Q(1), para_env_RPA, Erpa, wj(jquad))
1635 : END IF
1636 :
1637 11276 : IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_matrix_operations(mp2_env, rpa_grad, do_ri_sos_laplace_mp2, &
1638 : fm_mat_Q, fm_mat_Q_gemm, dgemm_counter, fm_mat_S, omega, homo, virtual, &
1639 48 : Eigenval(:, 1, :), wj(jquad), unit_nr)
1640 : END IF ! do_ri_sos_laplace_mp2
1641 :
1642 : ! save omega and reset the first_cycle flag
1643 11482 : first_cycle = .FALSE.
1644 11482 : omega_old = omega
1645 :
1646 11482 : CALL timestop(handle3)
1647 :
1648 11482 : IF (my_do_gw) THEN
1649 :
1650 10708 : CALL get_fermi_level_offset(fermi_level_offset, fermi_level_offset_input, Eigenval(:, 1, :), homo)
1651 :
1652 : ! do_im_time = TRUE means low-scaling calculation
1653 10708 : IF (do_im_time) THEN
1654 : ! only for molecules
1655 818 : IF (.NOT. (do_kpoints_cubic_RPA .OR. do_kpoints_from_Gamma)) THEN
1656 : CALL compute_W_cubic_GW(fm_mat_W, fm_mat_Q(1), fm_mat_work, dimen_RI, fm_mat_Minv_L_kpoints, num_integ_points, &
1657 722 : tj, tau_tj, weights_cos_tf_w_to_t, jquad, omega)
1658 : END IF
1659 : ELSE
1660 : CALL compute_GW_self_energy(vec_Sigma_c_gw, dimen_nm_gw, dimen_RI_red, gw_corr_lev_occ, &
1661 : gw_corr_lev_virt, homo, jquad, nmo, num_fit_points, &
1662 : do_im_time, do_periodic, first_cycle_periodic_correction, &
1663 : fermi_level_offset, &
1664 : omega, Eigenval(:, 1, :), delta_corr, vec_omega_fit_gw, vec_W_gw, wj, &
1665 : fm_mat_Q(1), fm_mat_R_gw, fm_mat_S_gw, &
1666 : fm_mat_S_gw_work, mo_coeff(1), para_env, &
1667 : para_env_RPA, matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, &
1668 9890 : kpoints, qs_env, mp2_env)
1669 : END IF
1670 : END IF
1671 :
1672 11482 : IF (unit_nr > 0) CALL m_flush(unit_nr)
1673 24026 : CALL para_env%sync() ! sync to see output
1674 :
1675 : END DO ! jquad
1676 :
1677 422 : IF (mp2_env%ri_rpa%sigma_param /= sigma_none) THEN
1678 10 : CALL finalize_rpa_sigma(rpa_sigma, unit_nr, mp2_env%ri_rpa%e_sigma_corr, para_env, do_minimax_quad)
1679 10 : IF (do_minimax_quad) mp2_env%ri_rpa%e_sigma_corr = mp2_env%ri_rpa%e_sigma_corr/2.0_dp
1680 10 : CALL para_env%sum(mp2_env%ri_rpa%e_sigma_corr)
1681 : END IF
1682 :
1683 422 : CALL para_env%sum(Erpa)
1684 :
1685 422 : IF (.NOT. (do_ri_sos_laplace_mp2)) THEN
1686 364 : Erpa = Erpa/(pi*2.0_dp)
1687 364 : IF (do_minimax_quad) Erpa = Erpa/2.0_dp
1688 : END IF
1689 :
1690 422 : IF (mp2_env%ri_rpa%exchange_correction /= rpa_exchange_none) THEN
1691 12 : CALL para_env%sum(E_exchange)
1692 12 : E_exchange = E_exchange/(pi*2.0_dp)
1693 12 : IF (do_minimax_quad) E_exchange = E_exchange/2.0_dp
1694 12 : mp2_env%ri_rpa%ener_exchange = E_exchange
1695 : END IF
1696 :
1697 422 : IF (calc_forces .AND. do_ri_sos_laplace_mp2 .AND. do_im_time) THEN
1698 22 : IF (my_open_shell) THEN
1699 4 : Pspin = 1
1700 4 : Qspin = 2
1701 : CALL calc_laplace_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
1702 : t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
1703 : fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
1704 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
1705 : starts_array_mc, ends_array_mc, starts_array_mc_block, &
1706 : ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
1707 : tau_tj, tau_wj, cut_memory, Pspin, Qspin, my_open_shell, &
1708 4 : unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
1709 4 : Pspin = 2
1710 4 : Qspin = 1
1711 : CALL calc_laplace_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
1712 : t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
1713 : fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
1714 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
1715 : starts_array_mc, ends_array_mc, starts_array_mc_block, &
1716 : ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
1717 : tau_tj, tau_wj, cut_memory, Pspin, Qspin, my_open_shell, &
1718 4 : unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
1719 :
1720 : ELSE
1721 18 : Pspin = 1
1722 18 : Qspin = 1
1723 : CALL calc_laplace_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
1724 : t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
1725 : fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
1726 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
1727 : starts_array_mc, ends_array_mc, starts_array_mc_block, &
1728 : ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
1729 : tau_tj, tau_wj, cut_memory, Pspin, Qspin, my_open_shell, &
1730 18 : unit_nr, dbcsr_time, dbcsr_nflop, mp2_env, qs_env)
1731 : END IF
1732 22 : CALL calc_post_loop_forces(force_data, unit_nr, qs_env)
1733 : END IF !laplace SOS-MP2
1734 :
1735 422 : IF (calc_forces .AND. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) THEN
1736 64 : DO ispin = 1, nspins
1737 : CALL calc_rpa_loop_forces(force_data, mat_P_omega(:, 1, :), t_3c_M, t_3c_O(1, 1), &
1738 : t_3c_O_compressed(1, 1, :), t_3c_O_ind(1, 1, :), fm_scaled_dm_occ_tau, &
1739 : fm_scaled_dm_virt_tau, fm_mo_coeff_occ, fm_mo_coeff_virt, &
1740 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, &
1741 : starts_array_mc, ends_array_mc, starts_array_mc_block, &
1742 : ends_array_mc_block, num_integ_points, nmo, Eigenval(:, 1, :), &
1743 : e_fermi(ispin), weights_cos_tf_t_to_w, weights_cos_tf_w_to_t, tj, &
1744 : wj, tau_tj, cut_memory, ispin, my_open_shell, unit_nr, dbcsr_time, &
1745 64 : dbcsr_nflop, mp2_env, qs_env)
1746 : END DO
1747 28 : CALL calc_post_loop_forces(force_data, unit_nr, qs_env)
1748 : END IF
1749 :
1750 422 : IF (do_im_time) THEN
1751 :
1752 146 : my_flop_rate = REAL(dbcsr_nflop, dp)/(1.0E09_dp*dbcsr_time)
1753 146 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(/T3,A,T73,ES8.2)") &
1754 73 : "PERFORMANCE| DBCSR total number of flops:", REAL(dbcsr_nflop*para_env%num_pe, dp)
1755 146 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,F15.2)") &
1756 73 : "PERFORMANCE| DBCSR total execution time:", dbcsr_time
1757 146 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T66,F15.2)") &
1758 73 : "PERFORMANCE| DBCSR flop rate (Gflops / MPI rank):", my_flop_rate
1759 :
1760 : ELSE
1761 :
1762 276 : CALL dgemm_counter_write(dgemm_counter, para_env)
1763 :
1764 : END IF
1765 :
1766 : ! GW: for low-scaling calculation: Compute self-energy Sigma(i*tau), Sigma(i*omega)
1767 : ! for low-scaling and ordinary-scaling: analytic continuation from Sigma(iw) -> Sigma(w)
1768 : ! and correction of quasiparticle energies e_n^GW
1769 716 : IF (my_do_gw) THEN
1770 :
1771 : CALL compute_QP_energies(vec_Sigma_c_gw, count_ev_sc_GW, gw_corr_lev_occ, &
1772 : gw_corr_lev_tot, gw_corr_lev_virt, homo, &
1773 : nmo, num_fit_points, num_integ_points, &
1774 : unit_nr, do_apply_ic_corr_to_gw, do_im_time, &
1775 : do_periodic, do_ri_Sigma_x, first_cycle_periodic_correction, &
1776 : e_fermi, eps_filter, fermi_level_offset, &
1777 : delta_corr, Eigenval, &
1778 : Eigenval_last, Eigenval_scf, iter_sc_GW0, exit_ev_gw, tau_tj, tj, &
1779 : vec_omega_fit_gw, vec_Sigma_x_gw, mp2_env%ri_g0w0%ic_corr_list, &
1780 : weights_cos_tf_t_to_w, weights_sin_tf_t_to_w, &
1781 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, fm_mo_coeff_occ, &
1782 : fm_mo_coeff_virt, fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, &
1783 : mo_coeff(1), fm_mat_W, para_env, para_env_RPA, mat_dm, mat_MinvVMinv, &
1784 : t_3c_O, t_3c_M, t_3c_overl_int_ao_mo, t_3c_O_compressed, t_3c_O_mo_compressed, &
1785 : t_3c_O_ind, t_3c_O_mo_ind, &
1786 : t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
1787 : matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, mat_W, matrix_s, &
1788 : kpoints, mp2_env, qs_env, nkp_self_energy, do_kpoints_cubic_RPA, &
1789 232 : starts_array_mc, ends_array_mc)
1790 :
1791 : ! if HOMO-LUMO gap differs by less than mp2_env%ri_g0w0%eps_ev_sc_iter, exit ev sc GW loop
1792 232 : IF (exit_ev_gw) EXIT
1793 :
1794 : END IF ! my_do_gw if
1795 :
1796 : END DO ! evGW loop
1797 :
1798 294 : IF (do_ic_model) THEN
1799 :
1800 2 : IF (my_open_shell) THEN
1801 :
1802 : CALL calculate_ic_correction(Eigenval(:, 1, 1), mat_MinvVMinv%matrix, &
1803 : t_3c_overl_nnP_ic(1), t_3c_overl_nnP_ic_reflected(1), &
1804 : gw_corr_lev_tot, &
1805 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), unit_nr, &
1806 0 : print_ic_values, para_env, do_alpha=.TRUE.)
1807 :
1808 : CALL calculate_ic_correction(Eigenval(:, 1, 2), mat_MinvVMinv%matrix, &
1809 : t_3c_overl_nnP_ic(2), t_3c_overl_nnP_ic_reflected(2), &
1810 : gw_corr_lev_tot, &
1811 : gw_corr_lev_occ(2), gw_corr_lev_virt(2), homo(2), unit_nr, &
1812 0 : print_ic_values, para_env, do_beta=.TRUE.)
1813 :
1814 : ELSE
1815 :
1816 : CALL calculate_ic_correction(Eigenval(:, 1, 1), mat_MinvVMinv%matrix, &
1817 : t_3c_overl_nnP_ic(1), t_3c_overl_nnP_ic_reflected(1), &
1818 : gw_corr_lev_tot, &
1819 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), unit_nr, &
1820 2 : print_ic_values, para_env)
1821 :
1822 : END IF
1823 :
1824 : END IF
1825 :
1826 : ! postprocessing after GW for Bethe-Salpeter
1827 294 : IF (do_bse) THEN
1828 : ! Check used GW flavor; in Case of evGW we use W0 for BSE
1829 : ! Use environment variable, since local iter_evGW is overwritten if evGW0 is invoked
1830 30 : IF (mp2_env%ri_g0w0%iter_evGW > 1) THEN
1831 4 : IF (unit_nr > 0) THEN
1832 : CALL cp_warn(__LOCATION__, &
1833 2 : "BSE@evGW applies W0, i.e. screening with DFT energies to the BSE!")
1834 : END IF
1835 : END IF
1836 : ! Create a copy of fm_mat_S for usage in BSE
1837 30 : CALL cp_fm_create(fm_mat_S_ia_bse, fm_mat_S(1)%matrix_struct)
1838 30 : CALL cp_fm_to_fm(fm_mat_S(1), fm_mat_S_ia_bse)
1839 : ! Remove energy/frequency factor from 3c-Integral for BSE
1840 30 : IF (iter_sc_gw0 == 1) THEN
1841 : CALL remove_scaling_factor_rpa(fm_mat_S_ia_bse, virtual(1), &
1842 18 : Eigenval_last(:, 1, 1), homo(1), omega)
1843 : ELSE
1844 : CALL remove_scaling_factor_rpa(fm_mat_S_ia_bse, virtual(1), &
1845 12 : Eigenval_scf(:, 1, 1), homo(1), omega)
1846 : END IF
1847 : ! Main routine for all BSE postprocessing
1848 : CALL start_bse_calculation(fm_mat_S_ia_bse, fm_mat_S_ij_bse, fm_mat_S_ab_bse, &
1849 : fm_mat_Q_static_bse_gemm, &
1850 : Eigenval, Eigenval_scf, &
1851 : homo, virtual, dimen_RI, dimen_RI_red, bse_lev_virt, &
1852 30 : gd_array, color_sub, mp2_env, qs_env, mo_coeff, unit_nr)
1853 : ! Release BSE-copy of fm_mat_S
1854 30 : CALL cp_fm_release(fm_mat_S_ia_bse)
1855 : END IF
1856 :
1857 294 : IF (my_do_gw) THEN
1858 : CALL deallocate_matrices_gw(fm_mat_S_gw_work, vec_W_gw, vec_Sigma_c_gw, vec_omega_fit_gw, &
1859 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw, &
1860 : Eigenval_last, Eigenval_scf, do_periodic, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
1861 104 : kpoints, vec_Sigma_x_gw,.NOT. do_im_time)
1862 : END IF
1863 :
1864 294 : IF (do_im_time) THEN
1865 :
1866 : CALL dealloc_im_time(fm_mo_coeff_occ, fm_mo_coeff_virt, &
1867 : fm_scaled_dm_occ_tau, fm_scaled_dm_virt_tau, index_to_cell_3c, &
1868 : cell_to_index_3c, do_ic_model, &
1869 : do_kpoints_cubic_RPA, do_kpoints_from_Gamma, do_ri_Sigma_x, &
1870 : has_mat_P_blocks, &
1871 : wkp_W, cfm_mat_Q, fm_mat_Minv_L_kpoints, fm_mat_L_kpoints, &
1872 : fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, fm_mat_RI_global_work, fm_mat_work, &
1873 : fm_mo_coeff_occ_scaled, fm_mo_coeff_virt_scaled, mat_dm, mat_L, &
1874 : mat_MinvVMinv, mat_P_omega, mat_P_omega_kp, &
1875 134 : t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, mat_work, qs_env)
1876 :
1877 134 : IF (my_do_gw) THEN
1878 : CALL deallocate_matrices_gw_im_time(weights_cos_tf_w_to_t, weights_sin_tf_t_to_w, do_ic_model, &
1879 : do_kpoints_cubic_RPA, fm_mat_W, &
1880 : t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
1881 : t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
1882 : t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, &
1883 46 : mat_W, qs_env)
1884 : END IF
1885 :
1886 : END IF
1887 :
1888 294 : IF (.NOT. do_im_time .AND. .NOT. do_ri_sos_laplace_mp2) CALL exchange_work%release()
1889 :
1890 294 : IF (.NOT. do_ri_sos_laplace_mp2) THEN
1891 236 : DEALLOCATE (tj)
1892 236 : DEALLOCATE (wj)
1893 236 : DEALLOCATE (trace_Qomega)
1894 : END IF
1895 :
1896 294 : IF (do_im_time .OR. do_ri_sos_laplace_mp2) THEN
1897 162 : DEALLOCATE (tau_tj)
1898 162 : DEALLOCATE (tau_wj)
1899 : END IF
1900 :
1901 294 : IF (do_im_time .AND. calc_forces) THEN
1902 50 : CALL im_time_force_release(force_data)
1903 : END IF
1904 :
1905 294 : IF (calc_forces .AND. .NOT. do_im_time) CALL rpa_grad_finalize(rpa_grad, mp2_env, para_env_sub, para_env, &
1906 : qs_env, gd_array, color_sub, do_ri_sos_laplace_mp2, &
1907 40 : homo, virtual)
1908 :
1909 294 : CALL timestop(handle)
1910 :
1911 6002 : END SUBROUTINE rpa_num_int
1912 :
1913 : END MODULE rpa_main
|