(git:ed6f26b)
Loading...
Searching...
No Matches
mp2_integrals.F
Go to the documentation of this file.
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 and distribute 2c- and 3c- integrals for RI
10!> \par History
11!> 06.2012 created [Mauro Del Ben]
12!> 03.2019 separated from mp2_ri_gpw [Frederick Stein]
13! **************************************************************************************************
15 USE omp_lib, ONLY: omp_get_num_threads,&
16 omp_get_thread_num
20 USE bibliography, ONLY: delben2013,&
21 cite_reference
22 USE cell_types, ONLY: cell_type,&
26 USE cp_dbcsr_api, ONLY: &
28 dbcsr_release_p, dbcsr_set, dbcsr_type, dbcsr_type_no_symmetry
36 USE cp_fm_types, ONLY: cp_fm_create,&
42 USE dbt_api, ONLY: &
43 dbt_clear, dbt_contract, dbt_copy, dbt_create, dbt_destroy, dbt_distribution_destroy, &
44 dbt_distribution_new, dbt_distribution_type, dbt_filter, dbt_get_block, dbt_get_info, &
45 dbt_get_stored_coordinates, dbt_mp_environ_pgrid, dbt_pgrid_create, dbt_pgrid_destroy, &
46 dbt_pgrid_type, dbt_put_block, dbt_reserve_blocks, dbt_scale, dbt_split_blocks, dbt_type
50 USE hfx_types, ONLY: alloc_containers,&
53 USE input_constants, ONLY: &
60 USE kinds, ONLY: default_string_length,&
61 dp,&
62 int_8
64 USE kpoint_types, ONLY: kpoint_type
67 USE machine, ONLY: m_flush
68 USE message_passing, ONLY: mp_cart_type,&
72 USE mp2_eri_gpw, ONLY: cleanup_gpw,&
79 USE pw_env_types, ONLY: pw_env_type
82 USE pw_types, ONLY: pw_c1d_gs_type,&
103 USE util, ONLY: get_limit
104#include "./base/base_uses.f90"
105
106 IMPLICIT NONE
107
108 PRIVATE
109
110 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mp2_integrals'
111
113
114 TYPE intermediate_matrix_type
115 TYPE(dbcsr_type) :: matrix_ia_jnu, matrix_ia_jb
116 INTEGER :: max_row_col_local = 0
117 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: local_col_row_info
118 TYPE(cp_fm_type) :: fm_BIb_jb = cp_fm_type()
119 CHARACTER(LEN=default_string_length) :: descr = ""
120 END TYPE intermediate_matrix_type
121
122CONTAINS
123
124! **************************************************************************************************
125!> \brief with ri mp2 gpw
126!> \param BIb_C ...
127!> \param BIb_C_gw ...
128!> \param BIb_C_bse_ij ...
129!> \param BIb_C_bse_ab ...
130!> \param gd_array ...
131!> \param gd_B_virtual ...
132!> \param dimen_RI ...
133!> \param dimen_RI_red ...
134!> \param qs_env ...
135!> \param para_env ...
136!> \param para_env_sub ...
137!> \param color_sub ...
138!> \param cell ...
139!> \param particle_set ...
140!> \param atomic_kind_set ...
141!> \param qs_kind_set ...
142!> \param fm_matrix_PQ ...
143!> \param fm_matrix_L_kpoints ...
144!> \param fm_matrix_Minv_L_kpoints ...
145!> \param fm_matrix_Minv ...
146!> \param fm_matrix_Minv_Vtrunc_Minv ...
147!> \param nmo ...
148!> \param homo ...
149!> \param mat_munu ...
150!> \param sab_orb_sub ...
151!> \param mo_coeff_o ...
152!> \param mo_coeff_v ...
153!> \param mo_coeff_all ...
154!> \param mo_coeff_gw ...
155!> \param mo_coeff_o_bse ...
156!> \param mo_coeff_v_bse ...
157!> \param eps_filter ...
158!> \param unit_nr ...
159!> \param mp2_memory ...
160!> \param calc_PQ_cond_num ...
161!> \param calc_forces ...
162!> \param blacs_env_sub ...
163!> \param my_do_gw ...
164!> \param do_bse ...
165!> \param gd_B_all ...
166!> \param starts_array_mc ...
167!> \param ends_array_mc ...
168!> \param starts_array_mc_block ...
169!> \param ends_array_mc_block ...
170!> \param gw_corr_lev_occ ...
171!> \param gw_corr_lev_virt ...
172!> \param bse_lev_virt ...
173!> \param do_im_time ...
174!> \param do_kpoints_cubic_RPA ...
175!> \param kpoints ...
176!> \param t_3c_M ...
177!> \param t_3c_O ...
178!> \param t_3c_O_compressed ...
179!> \param t_3c_O_ind ...
180!> \param ri_metric ...
181!> \param gd_B_occ_bse ...
182!> \param gd_B_virt_bse ...
183!> \author Mauro Del Ben
184! **************************************************************************************************
185 SUBROUTINE mp2_ri_gpw_compute_in(BIb_C, BIb_C_gw, BIb_C_bse_ij, BIb_C_bse_ab, gd_array, gd_B_virtual, &
186 dimen_RI, dimen_RI_red, qs_env, para_env, para_env_sub, color_sub, &
187 cell, particle_set, atomic_kind_set, qs_kind_set, &
188 fm_matrix_PQ, fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
189 fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, &
190 nmo, homo, mat_munu, &
191 sab_orb_sub, mo_coeff_o, mo_coeff_v, mo_coeff_all, &
192 mo_coeff_gw, mo_coeff_o_bse, mo_coeff_v_bse, eps_filter, unit_nr, &
193 mp2_memory, calc_PQ_cond_num, calc_forces, blacs_env_sub, my_do_gw, do_bse, &
194 gd_B_all, starts_array_mc, ends_array_mc, &
195 starts_array_mc_block, ends_array_mc_block, &
196 gw_corr_lev_occ, gw_corr_lev_virt, &
197 bse_lev_virt, &
198 do_im_time, do_kpoints_cubic_RPA, kpoints, &
199 t_3c_M, t_3c_O, t_3c_O_compressed, t_3c_O_ind, &
200 ri_metric, gd_B_occ_bse, gd_B_virt_bse)
201
202 TYPE(three_dim_real_array), ALLOCATABLE, &
203 DIMENSION(:), INTENT(OUT) :: bib_c, bib_c_gw
204 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :), &
205 INTENT(OUT) :: bib_c_bse_ij, bib_c_bse_ab
206 TYPE(group_dist_d1_type), INTENT(OUT) :: gd_array
207 TYPE(group_dist_d1_type), ALLOCATABLE, &
208 DIMENSION(:), INTENT(OUT) :: gd_b_virtual
209 INTEGER, INTENT(OUT) :: dimen_ri, dimen_ri_red
210 TYPE(qs_environment_type), POINTER :: qs_env
211 TYPE(mp_para_env_type), POINTER :: para_env, para_env_sub
212 INTEGER, INTENT(IN) :: color_sub
213 TYPE(cell_type), POINTER :: cell
214 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
215 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
216 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
217 TYPE(cp_fm_type), INTENT(OUT) :: fm_matrix_pq
218 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_l_kpoints, &
219 fm_matrix_minv_l_kpoints, &
220 fm_matrix_minv, &
221 fm_matrix_minv_vtrunc_minv
222 INTEGER, INTENT(IN) :: nmo
223 INTEGER, DIMENSION(:), INTENT(IN) :: homo
224 TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_munu
225 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
226 INTENT(IN), POINTER :: sab_orb_sub
227 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: mo_coeff_o, mo_coeff_v, mo_coeff_all, &
228 mo_coeff_gw, mo_coeff_o_bse, &
229 mo_coeff_v_bse
230 REAL(kind=dp), INTENT(IN) :: eps_filter
231 INTEGER, INTENT(IN) :: unit_nr
232 REAL(kind=dp), INTENT(IN) :: mp2_memory
233 LOGICAL, INTENT(IN) :: calc_pq_cond_num, calc_forces
234 TYPE(cp_blacs_env_type), POINTER :: blacs_env_sub
235 LOGICAL, INTENT(IN) :: my_do_gw, do_bse
236 TYPE(group_dist_d1_type), INTENT(OUT) :: gd_b_all
237 INTEGER, ALLOCATABLE, DIMENSION(:), INTENT(OUT) :: starts_array_mc, ends_array_mc, &
238 starts_array_mc_block, &
239 ends_array_mc_block
240 INTEGER, INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, &
241 bse_lev_virt
242 LOGICAL, INTENT(IN) :: do_im_time, do_kpoints_cubic_rpa
243 TYPE(kpoint_type), POINTER :: kpoints
244 TYPE(dbt_type), INTENT(OUT) :: t_3c_m
245 TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :), &
246 INTENT(OUT) :: t_3c_o
247 TYPE(hfx_compression_type), ALLOCATABLE, &
248 DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_o_compressed
249 TYPE(block_ind_type), ALLOCATABLE, &
250 DIMENSION(:, :, :) :: t_3c_o_ind
251 TYPE(libint_potential_type), INTENT(IN) :: ri_metric
252 TYPE(group_dist_d1_type), INTENT(OUT) :: gd_b_occ_bse, gd_b_virt_bse
253
254 CHARACTER(LEN=*), PARAMETER :: routinen = 'mp2_ri_gpw_compute_in'
255
256 INTEGER :: cm, cut_memory, cut_memory_int, eri_method, gw_corr_lev_total, handle, handle2, &
257 handle4, i, i_counter, i_mem, ibasis, ispin, itmp(2), j, jcell, kcell, lll, min_bsize, &
258 my_b_all_end, my_b_all_size, my_b_all_start, my_b_occ_bse_end, my_b_occ_bse_size, &
259 my_b_occ_bse_start, my_b_virt_bse_end, my_b_virt_bse_size, my_b_virt_bse_start, &
260 my_group_l_end, my_group_l_size, my_group_l_start, n_rep, natom, ngroup, nimg, nkind, &
261 nspins, potential_type, ri_metric_type
262 INTEGER(int_8) :: nze
263 INTEGER, ALLOCATABLE, DIMENSION(:) :: dist_ao_1, dist_ao_2, dist_ri, &
264 ends_array_mc_block_int, ends_array_mc_int, my_b_size, my_b_virtual_end, &
265 my_b_virtual_start, sizes_ao, sizes_ao_split, sizes_ri, sizes_ri_split, &
266 starts_array_mc_block_int, starts_array_mc_int, virtual
267 INTEGER, DIMENSION(2, 3) :: bounds
268 INTEGER, DIMENSION(3) :: bounds_3c, pcoord, pdims, pdims_t3c, &
269 periodic
270 LOGICAL :: do_gpw, do_kpoints_from_gamma, do_svd, &
271 memory_info
272 REAL(kind=dp) :: compression_factor, cutoff_old, eps_pgf_orb, eps_pgf_orb_old, eps_svd, &
273 mem_for_abk, mem_for_iak, mem_for_ijk, memory_3c, occ, omega_pot, rc_ang, &
274 relative_cutoff_old
275 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: e_cutoff_old
276 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: my_lrows, my_vrows
277 TYPE(cp_eri_mme_param), POINTER :: eri_param
278 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_munu_local_l
279 TYPE(dbt_pgrid_type) :: pgrid_t3c_m, pgrid_t3c_overl
280 TYPE(dbt_type) :: t_3c_overl_int_template, t_3c_tmp
281 TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_overl_int
282 TYPE(dft_control_type), POINTER :: dft_control
283 TYPE(distribution_3d_type) :: dist_3d
284 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_ao, basis_set_ri_aux
285 TYPE(gto_basis_set_type), POINTER :: orb_basis, ri_basis
286 TYPE(intermediate_matrix_type) :: intermed_mat_bse_ab, intermed_mat_bse_ij
287 TYPE(intermediate_matrix_type), ALLOCATABLE, &
288 DIMENSION(:) :: intermed_mat, intermed_mat_gw
289 TYPE(mp_cart_type) :: mp_comm_t3c_2
290 TYPE(neighbor_list_3c_type) :: nl_3c
291 TYPE(pw_c1d_gs_type) :: pot_g, rho_g
292 TYPE(pw_env_type), POINTER :: pw_env_sub
293 TYPE(pw_poisson_type), POINTER :: poisson_env
294 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
295 TYPE(pw_r3d_rs_type) :: psi_l, rho_r
296 TYPE(section_vals_type), POINTER :: qs_section
297 TYPE(task_list_type), POINTER :: task_list_sub
298
299 CALL timeset(routinen, handle)
300
301 CALL cite_reference(delben2013)
302
303 nspins = SIZE(homo)
304
305 ALLOCATE (virtual(nspins))
306 virtual(:) = nmo - homo(:)
307 gw_corr_lev_total = gw_corr_lev_virt + gw_corr_lev_occ
308
309 eri_method = qs_env%mp2_env%eri_method
310 eri_param => qs_env%mp2_env%eri_mme_param
311 do_svd = qs_env%mp2_env%do_svd
312 eps_svd = qs_env%mp2_env%eps_svd
313 potential_type = qs_env%mp2_env%potential_parameter%potential_type
314 ri_metric_type = ri_metric%potential_type
315 omega_pot = qs_env%mp2_env%potential_parameter%omega
316
317 ! whether we need gpw integrals (plus pw stuff)
318 do_gpw = (eri_method == do_eri_gpw) .OR. &
319 ((potential_type == do_potential_long .OR. ri_metric_type == do_potential_long) &
320 .AND. qs_env%mp2_env%eri_method == do_eri_os) &
321 .OR. (ri_metric_type == do_potential_id .AND. qs_env%mp2_env%eri_method == do_eri_mme)
322
323 IF (do_svd .AND. calc_forces) THEN
324 cpabort("SVD not implemented for forces.!")
325 END IF
326
327 do_kpoints_from_gamma = qs_env%mp2_env%ri_rpa_im_time%do_kpoints_from_Gamma
328 IF (do_kpoints_cubic_rpa .OR. do_kpoints_from_gamma) THEN
329 CALL get_qs_env(qs_env=qs_env, &
330 kpoints=kpoints)
331 END IF
332 IF (do_kpoints_from_gamma) THEN
333 CALL compute_kpoints(qs_env, kpoints, unit_nr)
334 END IF
335
336 IF (do_bse) THEN
337 IF (.NOT. my_do_gw) THEN
338 CALL cp_abort(__location__, "BSE calculations require prior GW calculations.")
339 END IF
340 IF (do_im_time) THEN
341 CALL cp_abort(__location__, "BSE calculations are not implemented for low-scaling GW.")
342 END IF
343 ! GPW integrals have to be implemented later
344 IF (eri_method == do_eri_gpw) THEN
345 CALL cp_abort(__location__, &
346 "BSE calculations are not implemented for GPW integrals. "// &
347 "This is probably caused by invoking a periodic calculation. "// &
348 "Use PERIODIC NONE for BSE calculations.")
349 END IF
350 END IF
351
352 ngroup = para_env%num_pe/para_env_sub%num_pe
353
354 ! Preparations for MME method to compute ERIs
355 IF (qs_env%mp2_env%eri_method .EQ. do_eri_mme) THEN
356 ! cell might have changed, so we need to reset parameters
357 CALL cp_eri_mme_set_params(eri_param, cell, qs_kind_set, basis_type_1="ORB", basis_type_2="RI_AUX", para_env=para_env)
358 END IF
359
360 CALL get_cell(cell=cell, periodic=periodic)
361 ! for minimax Ewald summation, full periodicity is required
362 IF (eri_method == do_eri_mme) THEN
363 cpassert(periodic(1) == 1 .AND. periodic(2) == 1 .AND. periodic(3) == 1)
364 END IF
365
366 IF (do_svd .AND. (do_kpoints_from_gamma .OR. do_kpoints_cubic_rpa)) THEN
367 cpabort("SVD with kpoints not implemented yet!")
368 END IF
369
370 CALL get_2c_integrals(qs_env, eri_method, eri_param, para_env, para_env_sub, mp2_memory, &
371 my_lrows, my_vrows, fm_matrix_pq, ngroup, color_sub, dimen_ri, dimen_ri_red, &
372 kpoints, my_group_l_size, my_group_l_start, my_group_l_end, &
373 gd_array, calc_pq_cond_num .AND. .NOT. do_svd, do_svd, eps_svd, &
374 qs_env%mp2_env%potential_parameter, ri_metric, &
375 fm_matrix_l_kpoints, fm_matrix_minv_l_kpoints, fm_matrix_minv, fm_matrix_minv_vtrunc_minv, &
376 do_im_time, do_kpoints_from_gamma .OR. do_kpoints_cubic_rpa, qs_env%mp2_env%mp2_gpw%eps_pgf_orb_S, &
377 qs_kind_set, sab_orb_sub, calc_forces, unit_nr)
378
379 IF (unit_nr > 0) THEN
380 associate(ri_metric => qs_env%mp2_env%ri_metric)
381 SELECT CASE (ri_metric%potential_type)
383 WRITE (unit_nr, fmt="(/T3,A,T74,A)") &
384 "RI_INFO| RI metric: ", "COULOMB"
385 CASE (do_potential_short)
386 WRITE (unit_nr, fmt="(T3,A,T71,A)") &
387 "RI_INFO| RI metric: ", "SHORTRANGE"
388 WRITE (unit_nr, '(T3,A,T61,F20.10)') &
389 "RI_INFO| Omega: ", ri_metric%omega
390 rc_ang = cp_unit_from_cp2k(ri_metric%cutoff_radius, "angstrom")
391 WRITE (unit_nr, '(T3,A,T61,F20.10)') &
392 "RI_INFO| Cutoff Radius [angstrom]: ", rc_ang
393 CASE (do_potential_long)
394 WRITE (unit_nr, fmt="(T3,A,T72,A)") &
395 "RI_INFO| RI metric: ", "LONGRANGE"
396 WRITE (unit_nr, '(T3,A,T61,F20.10)') &
397 "RI_INFO| Omega: ", ri_metric%omega
398 CASE (do_potential_id)
399 WRITE (unit_nr, fmt="(T3,A,T74,A)") &
400 "RI_INFO| RI metric: ", "OVERLAP"
402 WRITE (unit_nr, fmt="(T3,A,T64,A)") &
403 "RI_INFO| RI metric: ", "TRUNCATED COULOMB"
404 rc_ang = cp_unit_from_cp2k(ri_metric%cutoff_radius, "angstrom")
405 WRITE (unit_nr, '(T3,A,T61,F20.2)') &
406 "RI_INFO| Cutoff Radius [angstrom]: ", rc_ang
407 END SELECT
408 END associate
409 END IF
410
411 IF (calc_forces .AND. .NOT. do_im_time) THEN
412 ! we need (P|Q)^(-1/2) for future use, just save it
413 ! in a fully (home made) distributed way
414 itmp = get_limit(dimen_ri, para_env_sub%num_pe, para_env_sub%mepos)
415 lll = itmp(2) - itmp(1) + 1
416 ALLOCATE (qs_env%mp2_env%ri_grad%PQ_half(lll, my_group_l_size))
417 qs_env%mp2_env%ri_grad%PQ_half(:, :) = my_lrows(itmp(1):itmp(2), 1:my_group_l_size)
418 IF (.NOT. compare_potential_types(qs_env%mp2_env%ri_metric, qs_env%mp2_env%potential_parameter)) THEN
419 ALLOCATE (qs_env%mp2_env%ri_grad%operator_half(lll, my_group_l_size))
420 qs_env%mp2_env%ri_grad%operator_half(:, :) = my_vrows(itmp(1):itmp(2), 1:my_group_l_size)
421 DEALLOCATE (my_vrows)
422 END IF
423 END IF
424
425 IF (unit_nr > 0) THEN
426 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
427 "RI_INFO| Number of auxiliary basis functions:", dimen_ri, &
428 "GENERAL_INFO| Number of basis functions:", nmo, &
429 "GENERAL_INFO| Number of occupied orbitals:", homo(1), &
430 "GENERAL_INFO| Number of virtual orbitals:", virtual(1)
431 IF (do_svd) THEN
432 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
433 "RI_INFO| Reduced auxiliary basis set size:", dimen_ri_red
434 END IF
435
436 mem_for_iak = dimen_ri*real(sum(homo*virtual), kind=dp)*8.0_dp/(1024_dp**2)
437 mem_for_ijk = dimen_ri*real(sum([homo(1)]**2), kind=dp)*8.0_dp/(1024_dp**2)
438 mem_for_abk = dimen_ri*real(sum([bse_lev_virt]**2), kind=dp)*8.0_dp/(1024_dp**2)
439
440 IF (.NOT. do_im_time) THEN
441 WRITE (unit_nr, '(T3,A,T66,F11.2,A4)') 'RI_INFO| Total memory for (ia|K) integrals:', &
442 mem_for_iak, ' MiB'
443 IF (my_do_gw .AND. .NOT. do_im_time) THEN
444 mem_for_iak = dimen_ri*real(nmo, kind=dp)*gw_corr_lev_total*8.0_dp/(1024_dp**2)
445
446 WRITE (unit_nr, '(T3,A,T66,F11.2,A4)') 'RI_INFO| Total memory for G0W0-(nm|K) integrals:', &
447 mem_for_iak, ' MiB'
448 END IF
449 END IF
450 IF (do_bse) THEN
451 WRITE (unit_nr, '(T3,A,T66,F11.2,A4)') 'RI_INFO| Total memory for (ij|K) integrals:', &
452 mem_for_ijk, ' MiB'
453 WRITE (unit_nr, '(T3,A,T66,F11.2,A4)') 'RI_INFO| Total memory for (ab|K) integrals:', &
454 mem_for_abk, ' MiB'
455 END IF
456 CALL m_flush(unit_nr)
457 END IF
458
459 CALL para_env%sync() ! sync to see memory output
460
461 ! in case we do imaginary time, we need the overlap tensor (alpha beta P) or trunc. Coulomb tensor
462 IF (.NOT. do_im_time) THEN
463
464 ALLOCATE (gd_b_virtual(nspins), intermed_mat(nspins))
465 ALLOCATE (my_b_virtual_start(nspins), my_b_virtual_end(nspins), my_b_size(nspins))
466 DO ispin = 1, nspins
467
468 CALL create_intermediate_matrices(intermed_mat(ispin), mo_coeff_o(ispin)%matrix, virtual(ispin), homo(ispin), &
469 trim(adjustl(cp_to_string(ispin))), blacs_env_sub, para_env_sub)
470
471 CALL create_group_dist(gd_b_virtual(ispin), para_env_sub%num_pe, virtual(ispin))
472 CALL get_group_dist(gd_b_virtual(ispin), para_env_sub%mepos, my_b_virtual_start(ispin), my_b_virtual_end(ispin), &
473 my_b_size(ispin))
474
475 END DO
476
477 ! in the case of G0W0, we need (K|nm), n,m may be occ or virt (m restricted to corrected levels)
478 IF (my_do_gw) THEN
479
480 ALLOCATE (intermed_mat_gw(nspins))
481 DO ispin = 1, nspins
482 CALL create_intermediate_matrices(intermed_mat_gw(ispin), mo_coeff_gw(ispin)%matrix, &
483 nmo, gw_corr_lev_total, &
484 "gw_"//trim(adjustl(cp_to_string(ispin))), &
485 blacs_env_sub, para_env_sub)
486
487 END DO
488
489 CALL create_group_dist(gd_b_all, para_env_sub%num_pe, nmo)
490 CALL get_group_dist(gd_b_all, para_env_sub%mepos, my_b_all_start, my_b_all_end, my_b_all_size)
491
492 IF (do_bse) THEN
493 ! virt x virt matrices
494 CALL create_intermediate_matrices(intermed_mat_bse_ab, mo_coeff_v_bse(1)%matrix, bse_lev_virt, bse_lev_virt, &
495 "bse_ab", blacs_env_sub, para_env_sub)
496
497 CALL create_group_dist(gd_b_virt_bse, para_env_sub%num_pe, bse_lev_virt)
498 CALL get_group_dist(gd_b_virt_bse, para_env_sub%mepos, my_b_virt_bse_start, my_b_virt_bse_end, my_b_virt_bse_size)
499
500 ! occ x occ matrices
501 ! We do not implement bse_lev_occ here, because the small number of occupied levels
502 ! does not critically influence the memory
503 CALL create_intermediate_matrices(intermed_mat_bse_ij, mo_coeff_o_bse(1)%matrix, homo(1), homo(1), &
504 "bse_ij", blacs_env_sub, para_env_sub)
505
506 CALL create_group_dist(gd_b_occ_bse, para_env_sub%num_pe, homo(1))
507 CALL get_group_dist(gd_b_occ_bse, para_env_sub%mepos, my_b_occ_bse_start, my_b_occ_bse_end, my_b_occ_bse_size)
508
509 END IF
510 END IF
511
512 ! array that will store the (ia|K) integrals
513 ALLOCATE (bib_c(nspins))
514 DO ispin = 1, nspins
515 ALLOCATE (bib_c(ispin)%array(my_group_l_size, my_b_size(ispin), homo(ispin)))
516 bib_c(ispin)%array = 0.0_dp
517 END DO
518
519 ! in the case of GW, we also need (nm|K)
520 IF (my_do_gw) THEN
521
522 ALLOCATE (bib_c_gw(nspins))
523 DO ispin = 1, nspins
524 ALLOCATE (bib_c_gw(ispin)%array(my_group_l_size, my_b_all_size, gw_corr_lev_total))
525 bib_c_gw(ispin)%array = 0.0_dp
526 END DO
527
528 END IF
529
530 IF (do_bse) THEN
531
532 ALLOCATE (bib_c_bse_ij(my_group_l_size, my_b_occ_bse_size, homo(1)))
533 bib_c_bse_ij = 0.0_dp
534
535 ALLOCATE (bib_c_bse_ab(my_group_l_size, my_b_virt_bse_size, bse_lev_virt))
536 bib_c_bse_ab = 0.0_dp
537
538 END IF
539
540 CALL timeset(routinen//"_loop", handle2)
541
542 IF (eri_method == do_eri_mme .AND. &
543 (ri_metric%potential_type == do_potential_coulomb .OR. ri_metric%potential_type == do_potential_long) .OR. &
544 eri_method == do_eri_os .AND. ri_metric%potential_type == do_potential_coulomb) THEN
545
546 ! Add a warning for automatically generated RI_AUX basis sets
547 ! Tend to be not sufficiently converged
548 IF (qs_env%mp2_env%ri_aux_auto_generated) THEN
549 CALL cp_warn(__location__, &
550 "At least one RI_AUX basis set was not explicitly invoked in &KIND-section. "// &
551 "Automatically RI-basis sets and ERI_METHOD OS tend to be not converged. "// &
552 "Consider specifying BASIS_SET RI_AUX explicitly with a sufficiently large basis.")
553 END IF
554
555 NULLIFY (mat_munu_local_l)
556 ALLOCATE (mat_munu_local_l(my_group_l_size))
557 DO lll = 1, my_group_l_size
558 NULLIFY (mat_munu_local_l(lll)%matrix)
559 ALLOCATE (mat_munu_local_l(lll)%matrix)
560 CALL dbcsr_copy(mat_munu_local_l(lll)%matrix, mat_munu%matrix)
561 CALL dbcsr_set(mat_munu_local_l(lll)%matrix, 0.0_dp)
562 END DO
563 CALL mp2_eri_3c_integrate(eri_param, ri_metric, para_env_sub, qs_env, &
564 first_c=my_group_l_start, last_c=my_group_l_end, &
565 mat_ab=mat_munu_local_l, &
566 basis_type_a="ORB", basis_type_b="ORB", &
567 basis_type_c="RI_AUX", &
568 sab_nl=sab_orb_sub, eri_method=eri_method)
569
570 DO ispin = 1, nspins
571 DO lll = 1, my_group_l_size
572 CALL ao_to_mo_and_store_b(para_env_sub, mat_munu_local_l(lll), intermed_mat(ispin), &
573 bib_c(ispin)%array(lll, :, :), &
574 mo_coeff_o(ispin)%matrix, mo_coeff_v(ispin)%matrix, &
575 eps_filter, &
576 my_b_virtual_end(ispin), my_b_virtual_start(ispin))
577 END DO
578 CALL contract_b_l(bib_c(ispin)%array, my_lrows, gd_b_virtual(ispin)%sizes, &
579 gd_array%sizes, qs_env%mp2_env%eri_blksize, &
580 ngroup, color_sub, para_env, para_env_sub)
581 END DO
582
583 IF (my_do_gw) THEN
584
585 DO ispin = 1, nspins
586 DO lll = 1, my_group_l_size
587 CALL ao_to_mo_and_store_b(para_env_sub, mat_munu_local_l(lll), intermed_mat_gw(ispin), &
588 bib_c_gw(ispin)%array(lll, :, :), &
589 mo_coeff_gw(ispin)%matrix, mo_coeff_all(ispin)%matrix, eps_filter, &
590 my_b_all_end, my_b_all_start)
591 END DO
592 CALL contract_b_l(bib_c_gw(ispin)%array, my_lrows, gd_b_all%sizes, gd_array%sizes, qs_env%mp2_env%eri_blksize, &
593 ngroup, color_sub, para_env, para_env_sub)
594 END DO
595 END IF
596
597 IF (do_bse) THEN
598
599 ! B^ab_P matrix elements for BSE
600 DO lll = 1, my_group_l_size
601 CALL ao_to_mo_and_store_b(para_env_sub, mat_munu_local_l(lll), intermed_mat_bse_ab, &
602 bib_c_bse_ab(lll, :, :), &
603 mo_coeff_v_bse(1)%matrix, mo_coeff_v_bse(1)%matrix, eps_filter, &
604 my_b_all_end, my_b_all_start)
605 END DO
606 CALL contract_b_l(bib_c_bse_ab, my_lrows, gd_b_virt_bse%sizes, gd_array%sizes, qs_env%mp2_env%eri_blksize, &
607 ngroup, color_sub, para_env, para_env_sub)
608
609 ! B^ij_P matrix elements for BSE
610 DO lll = 1, my_group_l_size
611 CALL ao_to_mo_and_store_b(para_env_sub, mat_munu_local_l(lll), intermed_mat_bse_ij, &
612 bib_c_bse_ij(lll, :, :), &
613 mo_coeff_o(1)%matrix, mo_coeff_o(1)%matrix, eps_filter, &
614 my_b_occ_bse_end, my_b_occ_bse_start)
615 END DO
616 CALL contract_b_l(bib_c_bse_ij, my_lrows, gd_b_occ_bse%sizes, gd_array%sizes, qs_env%mp2_env%eri_blksize, &
617 ngroup, color_sub, para_env, para_env_sub)
618
619 END IF
620
621 DO lll = 1, my_group_l_size
622 CALL dbcsr_release_p(mat_munu_local_l(lll)%matrix)
623 END DO
624 DEALLOCATE (mat_munu_local_l)
625
626 ELSE IF (do_gpw) THEN
627
628 CALL prepare_gpw(qs_env, dft_control, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
629 auxbas_pw_pool, poisson_env, task_list_sub, rho_r, rho_g, pot_g, psi_l, sab_orb_sub)
630
631 DO i_counter = 1, my_group_l_size
632
633 CALL mp2_eri_3c_integrate_gpw(psi_l, rho_g, atomic_kind_set, qs_kind_set, cell, dft_control, &
634 particle_set, pw_env_sub, my_lrows(:, i_counter), poisson_env, rho_r, pot_g, &
635 ri_metric, mat_munu, qs_env, task_list_sub)
636
637 DO ispin = 1, nspins
638 CALL ao_to_mo_and_store_b(para_env_sub, mat_munu, intermed_mat(ispin), &
639 bib_c(ispin)%array(i_counter, :, :), &
640 mo_coeff_o(ispin)%matrix, mo_coeff_v(ispin)%matrix, eps_filter, &
641 my_b_virtual_end(ispin), my_b_virtual_start(ispin))
642
643 END DO
644
645 IF (my_do_gw) THEN
646 ! transform (K|mu nu) to (K|nm), n corresponds to corrected GW levels, m is in nmo
647 DO ispin = 1, nspins
648 CALL ao_to_mo_and_store_b(para_env_sub, mat_munu, intermed_mat_gw(ispin), &
649 bib_c_gw(ispin)%array(i_counter, :, :), &
650 mo_coeff_gw(ispin)%matrix, mo_coeff_all(ispin)%matrix, eps_filter, &
651 my_b_all_end, my_b_all_start)
652
653 END DO
654 END IF
655
656 END DO
657
658 CALL cleanup_gpw(qs_env, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
659 task_list_sub, auxbas_pw_pool, rho_r, rho_g, pot_g, psi_l)
660 ELSE
661 cpabort("Integration method not implemented!")
662 END IF
663
664 CALL timestop(handle2)
665
666 DEALLOCATE (my_lrows)
667
668 DO ispin = 1, nspins
669 CALL release_intermediate_matrices(intermed_mat(ispin))
670 END DO
671 DEALLOCATE (intermed_mat)
672
673 IF (my_do_gw) THEN
674 DO ispin = 1, nspins
675 CALL release_intermediate_matrices(intermed_mat_gw(ispin))
676 END DO
677 DEALLOCATE (intermed_mat_gw)
678 END IF
679
680 IF (do_bse) THEN
681 CALL release_intermediate_matrices(intermed_mat_bse_ab)
682 CALL release_intermediate_matrices(intermed_mat_bse_ij)
683 END IF
684
685 ! imag. time = low-scaling SOS-MP2, RPA, GW
686 ELSE
687
688 memory_info = qs_env%mp2_env%ri_rpa_im_time%memory_info
689
690 ! we need 3 tensors:
691 ! 1) t_3c_overl_int: 3c overlap integrals, optimized for easy access to integral blocks
692 ! (atomic blocks)
693 ! 2) t_3c_O: 3c overlap integrals, optimized for contraction (split blocks)
694 ! 3) t_3c_M: tensor M, optimized for contraction
695
696 CALL get_qs_env(qs_env, natom=natom, nkind=nkind, dft_control=dft_control)
697
698 pdims_t3c = 0
699 CALL dbt_pgrid_create(para_env, pdims_t3c, pgrid_t3c_overl)
700
701 ! set up basis
702 ALLOCATE (sizes_ri(natom), sizes_ao(natom))
703 ALLOCATE (basis_set_ri_aux(nkind), basis_set_ao(nkind))
704 CALL basis_set_list_setup(basis_set_ri_aux, "RI_AUX", qs_kind_set)
705 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ri, basis=basis_set_ri_aux)
706 CALL basis_set_list_setup(basis_set_ao, "ORB", qs_kind_set)
707 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ao, basis=basis_set_ao)
708
709 ! make sure we use the QS%EPS_PGF_ORB
710 qs_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS")
711 CALL section_vals_val_get(qs_section, "EPS_PGF_ORB", n_rep_val=n_rep)
712 IF (n_rep /= 0) THEN
713 CALL section_vals_val_get(qs_section, "EPS_PGF_ORB", r_val=eps_pgf_orb)
714 ELSE
715 CALL section_vals_val_get(qs_section, "EPS_DEFAULT", r_val=eps_pgf_orb)
716 eps_pgf_orb = sqrt(eps_pgf_orb)
717 END IF
718 eps_pgf_orb_old = dft_control%qs_control%eps_pgf_orb
719
720 DO ibasis = 1, SIZE(basis_set_ao)
721 orb_basis => basis_set_ao(ibasis)%gto_basis_set
722 CALL init_interaction_radii_orb_basis(orb_basis, eps_pgf_orb)
723 ri_basis => basis_set_ri_aux(ibasis)%gto_basis_set
724 CALL init_interaction_radii_orb_basis(ri_basis, eps_pgf_orb)
725 END DO
726
727 cut_memory_int = qs_env%mp2_env%ri_rpa_im_time%cut_memory
728 CALL create_tensor_batches(sizes_ri, cut_memory_int, starts_array_mc_int, ends_array_mc_int, &
729 starts_array_mc_block_int, ends_array_mc_block_int)
730
731 DEALLOCATE (starts_array_mc_int, ends_array_mc_int)
732
733 CALL create_3c_tensor(t_3c_overl_int_template, dist_ri, dist_ao_1, dist_ao_2, pgrid_t3c_overl, &
734 sizes_ri, sizes_ao, sizes_ao, map1=[1, 2], map2=[3], &
735 name="O (RI AO | AO)")
736
737 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set)
738 CALL dbt_mp_environ_pgrid(pgrid_t3c_overl, pdims, pcoord)
739 CALL mp_comm_t3c_2%create(pgrid_t3c_overl%mp_comm_2d, 3, pdims)
740 CALL distribution_3d_create(dist_3d, dist_ri, dist_ao_1, dist_ao_2, &
741 nkind, particle_set, mp_comm_t3c_2, own_comm=.true.)
742 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
743
744 CALL build_3c_neighbor_lists(nl_3c, basis_set_ri_aux, basis_set_ao, basis_set_ao, &
745 dist_3d, ri_metric, "RPA_3c_nl", qs_env, &
746 sym_jk=.NOT. do_kpoints_cubic_rpa, own_dist=.true.)
747
748 ! init k points
749 IF (do_kpoints_cubic_rpa) THEN
750 ! set up new kpoint type with periodic images according to eps_grid from MP2 section
751 ! instead of eps_pgf_orb from QS section
752 CALL kpoint_init_cell_index(kpoints, nl_3c%jk_list, para_env, dft_control)
753 IF (unit_nr > 0) WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
754 "3C_OVERLAP_INTEGRALS_INFO| Number of periodic images considered:", dft_control%nimages
755
756 nimg = dft_control%nimages
757 ELSE
758 nimg = 1
759 END IF
760
761 ALLOCATE (t_3c_overl_int(nimg, nimg))
762
763 DO i = 1, SIZE(t_3c_overl_int, 1)
764 DO j = 1, SIZE(t_3c_overl_int, 2)
765 CALL dbt_create(t_3c_overl_int_template, t_3c_overl_int(i, j))
766 END DO
767 END DO
768
769 CALL dbt_destroy(t_3c_overl_int_template)
770
771 ! split blocks to improve load balancing for tensor contraction
772 min_bsize = qs_env%mp2_env%ri_rpa_im_time%min_bsize
773
774 CALL pgf_block_sizes(atomic_kind_set, basis_set_ao, min_bsize, sizes_ao_split)
775 CALL pgf_block_sizes(atomic_kind_set, basis_set_ri_aux, min_bsize, sizes_ri_split)
776
777 pdims_t3c = 0
778 CALL dbt_pgrid_create(para_env, pdims_t3c, pgrid_t3c_m)
779
780 associate(cut_memory => qs_env%mp2_env%ri_rpa_im_time%cut_memory)
781 CALL create_tensor_batches(sizes_ao_split, cut_memory, starts_array_mc, ends_array_mc, &
782 starts_array_mc_block, ends_array_mc_block)
783 CALL create_tensor_batches(sizes_ri_split, cut_memory, &
784 qs_env%mp2_env%ri_rpa_im_time%starts_array_mc_RI, &
785 qs_env%mp2_env%ri_rpa_im_time%ends_array_mc_RI, &
786 qs_env%mp2_env%ri_rpa_im_time%starts_array_mc_block_RI, &
787 qs_env%mp2_env%ri_rpa_im_time%ends_array_mc_block_RI)
788
789 END associate
790 cut_memory = qs_env%mp2_env%ri_rpa_im_time%cut_memory
791
792 CALL create_3c_tensor(t_3c_m, dist_ri, dist_ao_1, dist_ao_2, pgrid_t3c_m, &
793 sizes_ri_split, sizes_ao_split, sizes_ao_split, &
794 map1=[1], map2=[2, 3], &
795 name="M (RI | AO AO)")
796 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
797 CALL dbt_pgrid_destroy(pgrid_t3c_m)
798
799 ALLOCATE (t_3c_o(SIZE(t_3c_overl_int, 1), SIZE(t_3c_overl_int, 2)))
800 ALLOCATE (t_3c_o_compressed(SIZE(t_3c_overl_int, 1), SIZE(t_3c_overl_int, 2), cut_memory))
801 ALLOCATE (t_3c_o_ind(SIZE(t_3c_overl_int, 1), SIZE(t_3c_overl_int, 2), cut_memory))
802 CALL create_3c_tensor(t_3c_o(1, 1), dist_ri, dist_ao_1, dist_ao_2, pgrid_t3c_overl, &
803 sizes_ri_split, sizes_ao_split, sizes_ao_split, &
804 map1=[1, 2], map2=[3], &
805 name="O (RI AO | AO)")
806 DEALLOCATE (dist_ri, dist_ao_1, dist_ao_2)
807 CALL dbt_pgrid_destroy(pgrid_t3c_overl)
808
809 DO i = 1, SIZE(t_3c_o, 1)
810 DO j = 1, SIZE(t_3c_o, 2)
811 IF (i > 1 .OR. j > 1) CALL dbt_create(t_3c_o(1, 1), t_3c_o(i, j))
812 END DO
813 END DO
814
815 ! build integrals in batches and copy to optimized format
816 ! note: integrals are stored in terms of atomic blocks. To avoid a memory bottleneck,
817 ! integrals are calculated in batches and copied to optimized format with subatomic blocks
818
819 DO cm = 1, cut_memory_int
820 CALL build_3c_integrals(t_3c_overl_int, &
821 qs_env%mp2_env%ri_rpa_im_time%eps_filter/2, &
822 qs_env, &
823 nl_3c, &
824 int_eps=qs_env%mp2_env%ri_rpa_im_time%eps_filter/2, &
825 basis_i=basis_set_ri_aux, &
826 basis_j=basis_set_ao, basis_k=basis_set_ao, &
827 potential_parameter=ri_metric, &
828 do_kpoints=do_kpoints_cubic_rpa, &
829 bounds_i=[starts_array_mc_block_int(cm), ends_array_mc_block_int(cm)], desymmetrize=.false.)
830 CALL timeset(routinen//"_copy_3c", handle4)
831 ! copy integral tensor t_3c_overl_int to t_3c_O tensor optimized for contraction
832 DO i = 1, SIZE(t_3c_overl_int, 1)
833 DO j = 1, SIZE(t_3c_overl_int, 2)
834
835 CALL dbt_copy(t_3c_overl_int(i, j), t_3c_o(i, j), order=[1, 3, 2], &
836 summation=.true., move_data=.true.)
837 CALL dbt_clear(t_3c_overl_int(i, j))
838 CALL dbt_filter(t_3c_o(i, j), qs_env%mp2_env%ri_rpa_im_time%eps_filter/2)
839 ! rescaling, probably because of neighbor list
840 IF (do_kpoints_cubic_rpa .AND. cm == cut_memory_int) THEN
841 CALL dbt_scale(t_3c_o(i, j), 0.5_dp)
842 END IF
843 END DO
844 END DO
845 CALL timestop(handle4)
846 END DO
847
848 DO i = 1, SIZE(t_3c_overl_int, 1)
849 DO j = 1, SIZE(t_3c_overl_int, 2)
850 CALL dbt_destroy(t_3c_overl_int(i, j))
851 END DO
852 END DO
853 DEALLOCATE (t_3c_overl_int)
854
855 CALL timeset(routinen//"_copy_3c", handle4)
856 ! desymmetrize
857 CALL dbt_create(t_3c_o(1, 1), t_3c_tmp)
858 DO jcell = 1, nimg
859 DO kcell = 1, jcell
860 CALL dbt_copy(t_3c_o(jcell, kcell), t_3c_tmp)
861 CALL dbt_copy(t_3c_tmp, t_3c_o(kcell, jcell), order=[1, 3, 2], summation=.true., move_data=.true.)
862 CALL dbt_filter(t_3c_o(kcell, jcell), qs_env%mp2_env%ri_rpa_im_time%eps_filter)
863 END DO
864 END DO
865 DO jcell = 1, nimg
866 DO kcell = jcell + 1, nimg
867 CALL dbt_copy(t_3c_o(jcell, kcell), t_3c_tmp)
868 CALL dbt_copy(t_3c_tmp, t_3c_o(kcell, jcell), order=[1, 3, 2], summation=.false., move_data=.true.)
869 CALL dbt_filter(t_3c_o(kcell, jcell), qs_env%mp2_env%ri_rpa_im_time%eps_filter)
870 END DO
871 END DO
872
873 CALL dbt_get_info(t_3c_o(1, 1), nfull_total=bounds_3c)
874 CALL get_tensor_occupancy(t_3c_o(1, 1), nze, occ)
875 memory_3c = 0.0_dp
876
877 bounds(:, 1) = [1, bounds_3c(1)]
878 bounds(:, 3) = [1, bounds_3c(3)]
879 DO i = 1, SIZE(t_3c_o, 1)
880 DO j = 1, SIZE(t_3c_o, 2)
881 DO i_mem = 1, cut_memory
882 bounds(:, 2) = [starts_array_mc(i_mem), ends_array_mc(i_mem)]
883 CALL dbt_copy(t_3c_o(i, j), t_3c_tmp, bounds=bounds)
884
885 CALL alloc_containers(t_3c_o_compressed(i, j, i_mem), 1)
886 CALL compress_tensor(t_3c_tmp, t_3c_o_ind(i, j, i_mem)%ind, &
887 t_3c_o_compressed(i, j, i_mem), &
888 qs_env%mp2_env%ri_rpa_im_time%eps_compress, memory_3c)
889 END DO
890 CALL dbt_clear(t_3c_o(i, j))
891 END DO
892 END DO
893
894 CALL para_env%sum(memory_3c)
895
896 compression_factor = real(nze, dp)*1.0e-06*8.0_dp/memory_3c
897
898 IF (unit_nr > 0) THEN
899 WRITE (unit=unit_nr, fmt="((T3,A,T66,F11.2,A4))") &
900 "MEMORY_INFO| Memory for 3-center integrals (compressed):", memory_3c, ' MiB'
901
902 WRITE (unit=unit_nr, fmt="((T3,A,T60,F21.2))") &
903 "MEMORY_INFO| Compression factor: ", compression_factor
904 END IF
905
906 CALL dbt_destroy(t_3c_tmp)
907
908 CALL timestop(handle4)
909
910 DO ibasis = 1, SIZE(basis_set_ao)
911 orb_basis => basis_set_ao(ibasis)%gto_basis_set
912 CALL init_interaction_radii_orb_basis(orb_basis, eps_pgf_orb_old)
913 ri_basis => basis_set_ri_aux(ibasis)%gto_basis_set
914 CALL init_interaction_radii_orb_basis(ri_basis, eps_pgf_orb_old)
915 END DO
916
917 DEALLOCATE (basis_set_ri_aux, basis_set_ao)
918
919 CALL neighbor_list_3c_destroy(nl_3c)
920
921 END IF
922
923 CALL timestop(handle)
924
925 END SUBROUTINE mp2_ri_gpw_compute_in
926
927! **************************************************************************************************
928!> \brief Contract (P|ai) = (R|P) x (R|ai)
929!> \param BIb_C (R|ai)
930!> \param my_Lrows (R|P)
931!> \param sizes_B number of a (virtual) indices per subgroup process
932!> \param sizes_L number of P / R (auxiliary) indices per subgroup
933!> \param blk_size ...
934!> \param ngroup how many subgroups (NG)
935!> \param igroup subgroup color
936!> \param mp_comm communicator
937!> \param para_env_sub ...
938! **************************************************************************************************
939 SUBROUTINE contract_b_l(BIb_C, my_Lrows, sizes_B, sizes_L, blk_size, ngroup, igroup, mp_comm, para_env_sub)
940 REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT) :: bib_c
941 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: my_lrows
942 INTEGER, DIMENSION(:), INTENT(IN) :: sizes_b, sizes_l
943 INTEGER, DIMENSION(2), INTENT(IN) :: blk_size
944 INTEGER, INTENT(IN) :: ngroup, igroup
945
946 CLASS(mp_comm_type), INTENT(IN) :: mp_comm
947 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
948
949 CHARACTER(LEN=*), PARAMETER :: routinen = 'contract_B_L'
950 LOGICAL, PARAMETER :: debug = .false.
951
952 INTEGER :: check_proc, handle, i, iend, ii, ioff, &
953 istart, loc_a, loc_p, nblk_per_thread
954 INTEGER, ALLOCATABLE, DIMENSION(:) :: block_ind_l_p, block_ind_l_r
955 INTEGER, DIMENSION(1) :: dist_b_i, map_b_1, map_l_1, map_l_2, &
956 sizes_i
957 INTEGER, DIMENSION(2) :: map_b_2, pdims_l
958 INTEGER, DIMENSION(3) :: pdims_b
959 LOGICAL :: found
960 INTEGER, DIMENSION(ngroup) :: dist_l_p, dist_l_r
961 INTEGER, DIMENSION(para_env_sub%num_pe) :: dist_b_a
962 TYPE(dbt_distribution_type) :: dist_b, dist_l
963 TYPE(dbt_pgrid_type) :: mp_comm_b, mp_comm_l
964 TYPE(dbt_type) :: tb_in, tb_in_split, tb_out, &
965 tb_out_split, tl, tl_split
966
967 CALL timeset(routinen, handle)
968
969 sizes_i(1) = SIZE(bib_c, 3)
970
971 associate(nproc => para_env_sub%num_pe, iproc => para_env_sub%mepos, iproc_glob => mp_comm%mepos)
972
973 ! local block index for R/P and a
974 loc_p = igroup + 1; loc_a = iproc + 1
975
976 cpassert(SIZE(sizes_l) .EQ. ngroup)
977 cpassert(SIZE(sizes_b) .EQ. nproc)
978 cpassert(sizes_l(loc_p) .EQ. SIZE(bib_c, 1))
979 cpassert(sizes_l(loc_p) .EQ. SIZE(my_lrows, 2))
980 cpassert(sizes_b(loc_a) .EQ. SIZE(bib_c, 2))
981
982 ! Tensor distributions as follows:
983 ! Process grid NG x Nw
984 ! Each process has coordinates (np, nw)
985 ! tB_in: (R|ai): R distributed (np), a distributed (nw)
986 ! tB_out: (P|ai): P distributed (np), a distributed (nw)
987 ! tL: (R|P): R distributed (nw), P distributed (np)
988
989 ! define mappings between tensor index and matrix index:
990 ! (R|ai) and (P|ai):
991 map_b_1 = [1] ! index 1 (R or P) maps to 1st matrix index (np distributed)
992 map_b_2 = [2, 3] ! indices 2, 3 (a, i) map to 2nd matrix index (nw distributed)
993 ! (R|P):
994 map_l_1 = [2] ! index 2 (P) maps to 1st matrix index (np distributed)
995 map_l_2 = [1] ! index 1 (R) maps to 2nd matrix index (nw distributed)
996
997 ! derive nd process grid that is compatible with distributions and 2d process grid
998 ! (R|ai) / (P|ai) on process grid NG x Nw x 1
999 ! (R|P) on process grid NG x Nw
1000 pdims_b = [ngroup, nproc, 1]
1001 pdims_l = [nproc, ngroup]
1002
1003 CALL dbt_pgrid_create(mp_comm, pdims_b, mp_comm_b)
1004 CALL dbt_pgrid_create(mp_comm, pdims_l, mp_comm_l)
1005
1006 ! setup distribution vectors such that distribution matches parallel data layout of BIb_C and my_Lrows
1007 dist_b_i = [0]
1008 dist_b_a = (/(i, i=0, nproc - 1)/)
1009 dist_l_r = (/(modulo(i, nproc), i=0, ngroup - 1)/) ! R index is replicated in my_Lrows, we impose a cyclic distribution
1010 dist_l_p = (/(i, i=0, ngroup - 1)/)
1011
1012 ! create distributions and tensors
1013 CALL dbt_distribution_new(dist_b, mp_comm_b, dist_l_p, dist_b_a, dist_b_i)
1014 CALL dbt_distribution_new(dist_l, mp_comm_l, dist_l_r, dist_l_p)
1015
1016 CALL dbt_create(tb_in, "(R|ai)", dist_b, map_b_1, map_b_2, sizes_l, sizes_b, sizes_i)
1017 CALL dbt_create(tb_out, "(P|ai)", dist_b, map_b_1, map_b_2, sizes_l, sizes_b, sizes_i)
1018 CALL dbt_create(tl, "(R|P)", dist_l, map_l_1, map_l_2, sizes_l, sizes_l)
1019
1020 IF (debug) THEN
1021 ! check that tensor distribution is correct
1022 CALL dbt_get_stored_coordinates(tb_in, [loc_p, loc_a, 1], check_proc)
1023 cpassert(check_proc .EQ. iproc_glob)
1024 END IF
1025
1026 ! reserve (R|ai) block
1027!$OMP PARALLEL DEFAULT(NONE) SHARED(tB_in,loc_P,loc_a)
1028 CALL dbt_reserve_blocks(tb_in, [loc_p], [loc_a], [1])
1029!$OMP END PARALLEL
1030
1031 ! reserve (R|P) blocks
1032 ! in my_Lrows, R index is replicated. For (R|P), we distribute quadratic blocks cyclically over
1033 ! the processes in a subgroup.
1034 ! There are NG blocks, so each process holds at most NG/Nw+1 blocks.
1035 ALLOCATE (block_ind_l_r(ngroup/nproc + 1))
1036 ALLOCATE (block_ind_l_p(ngroup/nproc + 1))
1037 block_ind_l_r(:) = 0; block_ind_l_p(:) = 0
1038 ii = 0
1039 DO i = 1, ngroup
1040 CALL dbt_get_stored_coordinates(tl, [i, loc_p], check_proc)
1041 IF (check_proc == iproc_glob) THEN
1042 ii = ii + 1
1043 block_ind_l_r(ii) = i
1044 block_ind_l_p(ii) = loc_p
1045 END IF
1046 END DO
1047
1048!TODO: Parallelize creation of block list.
1049!$OMP PARALLEL DEFAULT(NONE) SHARED(tL,block_ind_L_R,block_ind_L_P,ii) &
1050!$OMP PRIVATE(nblk_per_thread,istart,iend)
1051 nblk_per_thread = ii/omp_get_num_threads() + 1
1052 istart = omp_get_thread_num()*nblk_per_thread + 1
1053 iend = min(istart + nblk_per_thread, ii)
1054 CALL dbt_reserve_blocks(tl, block_ind_l_r(istart:iend), block_ind_l_p(istart:iend))
1055!$OMP END PARALLEL
1056
1057 ! insert (R|ai) block
1058 CALL dbt_put_block(tb_in, [loc_p, loc_a, 1], shape(bib_c), bib_c)
1059
1060 ! insert (R|P) blocks
1061 ioff = 0
1062 DO i = 1, ngroup
1063 istart = ioff + 1; iend = ioff + sizes_l(i)
1064 ioff = ioff + sizes_l(i)
1065 CALL dbt_get_stored_coordinates(tl, [i, loc_p], check_proc)
1066 IF (check_proc == iproc_glob) THEN
1067 CALL dbt_put_block(tl, [i, loc_p], [sizes_l(i), sizes_l(loc_p)], my_lrows(istart:iend, :))
1068 END IF
1069 END DO
1070 END associate
1071
1072 CALL dbt_split_blocks(tb_in, tb_in_split, [blk_size(2), blk_size(1), blk_size(1)])
1073 CALL dbt_split_blocks(tl, tl_split, [blk_size(2), blk_size(2)])
1074 CALL dbt_split_blocks(tb_out, tb_out_split, [blk_size(2), blk_size(1), blk_size(1)])
1075
1076 ! contract
1077 CALL dbt_contract(alpha=1.0_dp, tensor_1=tb_in_split, tensor_2=tl_split, &
1078 beta=0.0_dp, tensor_3=tb_out_split, &
1079 contract_1=[1], notcontract_1=[2, 3], &
1080 contract_2=[1], notcontract_2=[2], &
1081 map_1=[2, 3], map_2=[1], optimize_dist=.true.)
1082
1083 ! retrieve local block of contraction result (P|ai)
1084 CALL dbt_copy(tb_out_split, tb_out)
1085
1086 CALL dbt_get_block(tb_out, [loc_p, loc_a, 1], shape(bib_c), bib_c, found)
1087 cpassert(found)
1088
1089 ! cleanup
1090 CALL dbt_destroy(tb_in)
1091 CALL dbt_destroy(tb_in_split)
1092 CALL dbt_destroy(tb_out)
1093 CALL dbt_destroy(tb_out_split)
1094 CALL dbt_destroy(tl)
1095 CALL dbt_destroy(tl_split)
1096
1097 CALL dbt_distribution_destroy(dist_b)
1098 CALL dbt_distribution_destroy(dist_l)
1099
1100 CALL dbt_pgrid_destroy(mp_comm_b)
1101 CALL dbt_pgrid_destroy(mp_comm_l)
1102
1103 CALL timestop(handle)
1104
1105 END SUBROUTINE contract_b_l
1106
1107! **************************************************************************************************
1108!> \brief Encapsulate building of intermediate matrices matrix_ia_jnu(_beta
1109!> matrix_ia_jb(_beta),fm_BIb_jb(_beta),matrix_in_jnu(for G0W0) and
1110!> fm_BIb_all(for G0W0)
1111!> \param intermed_mat ...
1112!> \param mo_coeff_templ ...
1113!> \param size_1 ...
1114!> \param size_2 ...
1115!> \param matrix_name_2 ...
1116!> \param blacs_env_sub ...
1117!> \param para_env_sub ...
1118!> \author Jan Wilhelm
1119! **************************************************************************************************
1120 SUBROUTINE create_intermediate_matrices(intermed_mat, mo_coeff_templ, size_1, size_2, &
1121 matrix_name_2, blacs_env_sub, para_env_sub)
1122
1123 TYPE(intermediate_matrix_type), INTENT(OUT) :: intermed_mat
1124 TYPE(dbcsr_type), INTENT(INOUT) :: mo_coeff_templ
1125 INTEGER, INTENT(IN) :: size_1, size_2
1126 CHARACTER(LEN=*), INTENT(IN) :: matrix_name_2
1127 TYPE(cp_blacs_env_type), POINTER :: blacs_env_sub
1128 TYPE(mp_para_env_type), POINTER :: para_env_sub
1129
1130 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_intermediate_matrices'
1131
1132 INTEGER :: handle, ncol_local, nfullcols_total, &
1133 nfullrows_total, nrow_local
1134 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1135 TYPE(cp_fm_struct_type), POINTER :: fm_struct
1136
1137 CALL timeset(routinen, handle)
1138
1139 ! initialize and create the matrix (K|jnu)
1140 CALL dbcsr_create(intermed_mat%matrix_ia_jnu, template=mo_coeff_templ)
1141
1142 ! Allocate Sparse matrices: (K|jb)
1143 CALL cp_dbcsr_m_by_n_from_template(intermed_mat%matrix_ia_jb, template=mo_coeff_templ, m=size_2, n=size_1, &
1144 sym=dbcsr_type_no_symmetry)
1145
1146 ! set all to zero in such a way that the memory is actually allocated
1147 CALL dbcsr_set(intermed_mat%matrix_ia_jnu, 0.0_dp)
1148 CALL dbcsr_set(intermed_mat%matrix_ia_jb, 0.0_dp)
1149
1150 ! create the analogous of matrix_ia_jb in fm type
1151 NULLIFY (fm_struct)
1152 CALL dbcsr_get_info(intermed_mat%matrix_ia_jb, nfullrows_total=nfullrows_total, nfullcols_total=nfullcols_total)
1153 CALL cp_fm_struct_create(fm_struct, context=blacs_env_sub, nrow_global=nfullrows_total, &
1154 ncol_global=nfullcols_total, para_env=para_env_sub)
1155 CALL cp_fm_create(intermed_mat%fm_BIb_jb, fm_struct, name="fm_BIb_jb_"//matrix_name_2)
1156
1157 CALL copy_dbcsr_to_fm(intermed_mat%matrix_ia_jb, intermed_mat%fm_BIb_jb)
1158 CALL cp_fm_struct_release(fm_struct)
1159
1160 CALL cp_fm_get_info(matrix=intermed_mat%fm_BIb_jb, &
1161 nrow_local=nrow_local, &
1162 ncol_local=ncol_local, &
1163 row_indices=row_indices, &
1164 col_indices=col_indices)
1165
1166 intermed_mat%max_row_col_local = max(nrow_local, ncol_local)
1167 CALL para_env_sub%max(intermed_mat%max_row_col_local)
1168
1169 ALLOCATE (intermed_mat%local_col_row_info(0:intermed_mat%max_row_col_local, 2))
1170 intermed_mat%local_col_row_info = 0
1171 ! 0,1 nrows
1172 intermed_mat%local_col_row_info(0, 1) = nrow_local
1173 intermed_mat%local_col_row_info(1:nrow_local, 1) = row_indices(1:nrow_local)
1174 ! 0,2 ncols
1175 intermed_mat%local_col_row_info(0, 2) = ncol_local
1176 intermed_mat%local_col_row_info(1:ncol_local, 2) = col_indices(1:ncol_local)
1177
1178 intermed_mat%descr = matrix_name_2
1179
1180 CALL timestop(handle)
1181
1182 END SUBROUTINE create_intermediate_matrices
1183
1184! **************************************************************************************************
1185!> \brief Encapsulate ERI postprocessing: AO to MO transformation and store in B matrix.
1186!> \param para_env ...
1187!> \param mat_munu ...
1188!> \param intermed_mat ...
1189!> \param BIb_jb ...
1190!> \param mo_coeff_o ...
1191!> \param mo_coeff_v ...
1192!> \param eps_filter ...
1193!> \param my_B_end ...
1194!> \param my_B_start ...
1195! **************************************************************************************************
1196 SUBROUTINE ao_to_mo_and_store_b(para_env, mat_munu, intermed_mat, BIb_jb, &
1197 mo_coeff_o, mo_coeff_v, eps_filter, &
1198 my_B_end, my_B_start)
1199 TYPE(mp_para_env_type), INTENT(IN) :: para_env
1200 TYPE(dbcsr_p_type), INTENT(IN) :: mat_munu
1201 TYPE(intermediate_matrix_type), INTENT(INOUT) :: intermed_mat
1202 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: bib_jb
1203 TYPE(dbcsr_type), POINTER :: mo_coeff_o, mo_coeff_v
1204 REAL(kind=dp), INTENT(IN) :: eps_filter
1205 INTEGER, INTENT(IN) :: my_b_end, my_b_start
1206
1207 CHARACTER(LEN=*), PARAMETER :: routinen = 'ao_to_mo_and_store_B'
1208
1209 INTEGER :: handle
1210
1211 CALL timeset(routinen//"_mult_"//trim(intermed_mat%descr), handle)
1212
1213 CALL dbcsr_multiply("N", "N", 1.0_dp, mat_munu%matrix, mo_coeff_o, &
1214 0.0_dp, intermed_mat%matrix_ia_jnu, filter_eps=eps_filter)
1215 CALL dbcsr_multiply("T", "N", 1.0_dp, intermed_mat%matrix_ia_jnu, mo_coeff_v, &
1216 0.0_dp, intermed_mat%matrix_ia_jb, filter_eps=eps_filter)
1217 CALL timestop(handle)
1218
1219 CALL timeset(routinen//"_E_Ex_"//trim(intermed_mat%descr), handle)
1220 CALL copy_dbcsr_to_fm(intermed_mat%matrix_ia_jb, intermed_mat%fm_BIb_jb)
1221
1222 CALL grep_my_integrals(para_env, intermed_mat%fm_BIb_jb, bib_jb, intermed_mat%max_row_col_local, &
1223 intermed_mat%local_col_row_info, &
1224 my_b_end, my_b_start)
1225
1226 CALL timestop(handle)
1227 END SUBROUTINE ao_to_mo_and_store_b
1228
1229! **************************************************************************************************
1230!> \brief ...
1231!> \param intermed_mat ...
1232! **************************************************************************************************
1233 SUBROUTINE release_intermediate_matrices(intermed_mat)
1234 TYPE(intermediate_matrix_type), INTENT(INOUT) :: intermed_mat
1235
1236 CALL dbcsr_release(intermed_mat%matrix_ia_jnu)
1237 CALL dbcsr_release(intermed_mat%matrix_ia_jb)
1238 CALL cp_fm_release(intermed_mat%fm_BIb_jb)
1239 DEALLOCATE (intermed_mat%local_col_row_info)
1240
1241 END SUBROUTINE
1242
1243! **************************************************************************************************
1244!> \brief ...
1245!> \param qs_env ...
1246!> \param kpoints ...
1247!> \param unit_nr ...
1248! **************************************************************************************************
1249 SUBROUTINE compute_kpoints(qs_env, kpoints, unit_nr)
1250
1251 TYPE(qs_environment_type), POINTER :: qs_env
1252 TYPE(kpoint_type), POINTER :: kpoints
1253 INTEGER :: unit_nr
1254
1255 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_kpoints'
1256
1257 INTEGER :: handle, i, i_dim, ix, iy, iz, nkp, &
1258 nkp_extra, nkp_orig
1259 INTEGER, DIMENSION(3) :: nkp_grid, nkp_grid_extra, periodic
1260 LOGICAL :: do_extrapolate_kpoints
1261 TYPE(cell_type), POINTER :: cell
1262 TYPE(dft_control_type), POINTER :: dft_control
1263 TYPE(mp_para_env_type), POINTER :: para_env
1264 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1265 POINTER :: sab_orb
1266
1267 CALL timeset(routinen, handle)
1268
1269 NULLIFY (cell, dft_control, para_env)
1270 CALL get_qs_env(qs_env=qs_env, cell=cell, para_env=para_env, dft_control=dft_control, sab_orb=sab_orb)
1271 CALL get_cell(cell=cell, periodic=periodic)
1272
1273 ! general because we augment a Monkhorst-Pack mesh by additional points in the BZ
1274 kpoints%kp_scheme = "GENERAL"
1275 kpoints%symmetry = .false.
1276 kpoints%verbose = .false.
1277 kpoints%full_grid = .true.
1278 kpoints%use_real_wfn = .false.
1279 kpoints%eps_geo = 1.e-6_dp
1280 nkp_grid(1:3) = qs_env%mp2_env%ri_rpa_im_time%kp_grid(1:3)
1281 do_extrapolate_kpoints = qs_env%mp2_env%ri_rpa_im_time%do_extrapolate_kpoints
1282
1283 DO i_dim = 1, 3
1284 IF (periodic(i_dim) == 1) THEN
1285 cpassert(modulo(nkp_grid(i_dim), 2) == 0)
1286 END IF
1287 IF (periodic(i_dim) == 0) THEN
1288 cpassert(nkp_grid(i_dim) == 1)
1289 END IF
1290 END DO
1291
1292 nkp_orig = nkp_grid(1)*nkp_grid(2)*nkp_grid(3)/2
1293
1294 IF (do_extrapolate_kpoints) THEN
1295
1296 cpassert(qs_env%mp2_env%ri_rpa_im_time%kpoint_weights_W_method == kp_weights_w_uniform)
1297
1298 DO i_dim = 1, 3
1299 IF (periodic(i_dim) == 1) nkp_grid_extra(i_dim) = nkp_grid(i_dim) + 2
1300 IF (periodic(i_dim) == 0) nkp_grid_extra(i_dim) = 1
1301 END DO
1302
1303 qs_env%mp2_env%ri_rpa_im_time%kp_grid_extra(1:3) = nkp_grid_extra(1:3)
1304
1305 nkp_extra = nkp_grid_extra(1)*nkp_grid_extra(2)*nkp_grid_extra(3)/2
1306
1307 ELSE
1308
1309 nkp_grid_extra(1:3) = 0
1310 nkp_extra = 0
1311
1312 END IF
1313
1314 nkp = nkp_orig + nkp_extra
1315
1316 qs_env%mp2_env%ri_rpa_im_time%nkp_orig = nkp_orig
1317 qs_env%mp2_env%ri_rpa_im_time%nkp_extra = nkp_extra
1318
1319 ALLOCATE (kpoints%xkp(3, nkp), kpoints%wkp(nkp))
1320
1321 kpoints%nkp_grid(1:3) = nkp_grid(1:3)
1322 kpoints%nkp = nkp
1323
1324 ALLOCATE (qs_env%mp2_env%ri_rpa_im_time%wkp_V(nkp))
1325 IF (do_extrapolate_kpoints) THEN
1326 kpoints%wkp(1:nkp_orig) = 1.0_dp/real(nkp_orig, kind=dp) &
1327 /(1.0_dp - sqrt(real(nkp_extra, kind=dp)/real(nkp_orig, kind=dp)))
1328 kpoints%wkp(nkp_orig + 1:nkp) = 1.0_dp/real(nkp_extra, kind=dp) &
1329 /(1.0_dp - sqrt(real(nkp_orig, kind=dp)/real(nkp_extra, kind=dp)))
1330 qs_env%mp2_env%ri_rpa_im_time%wkp_V(1:nkp_orig) = 0.0_dp
1331 qs_env%mp2_env%ri_rpa_im_time%wkp_V(nkp_orig + 1:nkp) = 1.0_dp/real(nkp_extra, kind=dp)
1332 ELSE
1333 kpoints%wkp(:) = 1.0_dp/real(nkp, kind=dp)
1334 qs_env%mp2_env%ri_rpa_im_time%wkp_V(:) = kpoints%wkp(:)
1335 END IF
1336
1337 i = 0
1338 DO ix = 1, nkp_grid(1)
1339 DO iy = 1, nkp_grid(2)
1340 DO iz = 1, nkp_grid(3)
1341
1342 IF (i == nkp_orig) cycle
1343 i = i + 1
1344
1345 kpoints%xkp(1, i) = real(2*ix - nkp_grid(1) - 1, kind=dp)/(2._dp*real(nkp_grid(1), kind=dp))
1346 kpoints%xkp(2, i) = real(2*iy - nkp_grid(2) - 1, kind=dp)/(2._dp*real(nkp_grid(2), kind=dp))
1347 kpoints%xkp(3, i) = real(2*iz - nkp_grid(3) - 1, kind=dp)/(2._dp*real(nkp_grid(3), kind=dp))
1348
1349 END DO
1350 END DO
1351 END DO
1352
1353 DO ix = 1, nkp_grid_extra(1)
1354 DO iy = 1, nkp_grid_extra(2)
1355 DO iz = 1, nkp_grid_extra(3)
1356
1357 i = i + 1
1358 IF (i > nkp) cycle
1359
1360 kpoints%xkp(1, i) = real(2*ix - nkp_grid_extra(1) - 1, kind=dp)/(2._dp*real(nkp_grid_extra(1), kind=dp))
1361 kpoints%xkp(2, i) = real(2*iy - nkp_grid_extra(2) - 1, kind=dp)/(2._dp*real(nkp_grid_extra(2), kind=dp))
1362 kpoints%xkp(3, i) = real(2*iz - nkp_grid_extra(3) - 1, kind=dp)/(2._dp*real(nkp_grid_extra(3), kind=dp))
1363
1364 END DO
1365 END DO
1366 END DO
1367
1368 CALL kpoint_init_cell_index(kpoints, sab_orb, para_env, dft_control)
1369
1370 CALL set_qs_env(qs_env, kpoints=kpoints)
1371
1372 IF (unit_nr > 0) THEN
1373
1374 IF (do_extrapolate_kpoints) THEN
1375 WRITE (unit=unit_nr, fmt="(T3,A,T69,3I4)") "KPOINT_INFO| K-point mesh for V (leading to Sigma^x):", nkp_grid(1:3)
1376 WRITE (unit=unit_nr, fmt="(T3,A,T69)") "KPOINT_INFO| K-point extrapolation for W^c is used (W^c leads to Sigma^c):"
1377 WRITE (unit=unit_nr, fmt="(T3,A,T69,3I4)") "KPOINT_INFO| K-point mesh 1 for W^c:", nkp_grid(1:3)
1378 WRITE (unit=unit_nr, fmt="(T3,A,T69,3I4)") "KPOINT_INFO| K-point mesh 2 for W^c:", nkp_grid_extra(1:3)
1379 ELSE
1380 WRITE (unit=unit_nr, fmt="(T3,A,T69,3I4)") "KPOINT_INFO| K-point mesh for V and W:", nkp_grid(1:3)
1381 WRITE (unit=unit_nr, fmt="(T3,A,T75,I6)") "KPOINT_INFO| Number of kpoints for V and W:", nkp
1382 END IF
1383
1384 SELECT CASE (qs_env%mp2_env%ri_rpa_im_time%kpoint_weights_W_method)
1385 CASE (kp_weights_w_tailored)
1386 WRITE (unit=unit_nr, fmt="(T3,A,T81)") &
1387 "KPOINT_INFO| K-point weights for W: TAILORED"
1388 CASE (kp_weights_w_auto)
1389 WRITE (unit=unit_nr, fmt="(T3,A,T81)") &
1390 "KPOINT_INFO| K-point weights for W: AUTO"
1391 CASE (kp_weights_w_uniform)
1392 WRITE (unit=unit_nr, fmt="(T3,A,T81)") &
1393 "KPOINT_INFO| K-point weights for W: UNIFORM"
1394 END SELECT
1395
1396 END IF
1397
1398 CALL timestop(handle)
1399
1400 END SUBROUTINE compute_kpoints
1401
1402! **************************************************************************************************
1403!> \brief ...
1404!> \param para_env_sub ...
1405!> \param fm_BIb_jb ...
1406!> \param BIb_jb ...
1407!> \param max_row_col_local ...
1408!> \param local_col_row_info ...
1409!> \param my_B_virtual_end ...
1410!> \param my_B_virtual_start ...
1411! **************************************************************************************************
1412 SUBROUTINE grep_my_integrals(para_env_sub, fm_BIb_jb, BIb_jb, max_row_col_local, &
1413 local_col_row_info, &
1414 my_B_virtual_end, my_B_virtual_start)
1415 TYPE(mp_para_env_type), INTENT(IN) :: para_env_sub
1416 TYPE(cp_fm_type), INTENT(IN) :: fm_bib_jb
1417 REAL(kind=dp), DIMENSION(:, :), INTENT(OUT) :: bib_jb
1418 INTEGER, INTENT(IN) :: max_row_col_local
1419 INTEGER, ALLOCATABLE, DIMENSION(:, :), INTENT(IN) :: local_col_row_info
1420 INTEGER, INTENT(IN) :: my_b_virtual_end, my_b_virtual_start
1421
1422 INTEGER :: i_global, iib, j_global, jjb, ncol_rec, &
1423 nrow_rec, proc_receive, proc_send, &
1424 proc_shift
1425 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: rec_col_row_info
1426 INTEGER, DIMENSION(:), POINTER :: col_indices_rec, row_indices_rec
1427 REAL(kind=dp), DIMENSION(:, :), POINTER :: local_bi, rec_bi
1428
1429 ALLOCATE (rec_col_row_info(0:max_row_col_local, 2))
1430
1431 rec_col_row_info(:, :) = local_col_row_info
1432
1433 nrow_rec = rec_col_row_info(0, 1)
1434 ncol_rec = rec_col_row_info(0, 2)
1435
1436 ALLOCATE (row_indices_rec(nrow_rec))
1437 row_indices_rec = rec_col_row_info(1:nrow_rec, 1)
1438
1439 ALLOCATE (col_indices_rec(ncol_rec))
1440 col_indices_rec = rec_col_row_info(1:ncol_rec, 2)
1441
1442 ! accumulate data on BIb_jb buffer starting from myself
1443 DO jjb = 1, ncol_rec
1444 j_global = col_indices_rec(jjb)
1445 IF (j_global >= my_b_virtual_start .AND. j_global <= my_b_virtual_end) THEN
1446 DO iib = 1, nrow_rec
1447 i_global = row_indices_rec(iib)
1448 bib_jb(j_global - my_b_virtual_start + 1, i_global) = fm_bib_jb%local_data(iib, jjb)
1449 END DO
1450 END IF
1451 END DO
1452
1453 DEALLOCATE (row_indices_rec)
1454 DEALLOCATE (col_indices_rec)
1455
1456 IF (para_env_sub%num_pe > 1) THEN
1457 ALLOCATE (local_bi(nrow_rec, ncol_rec))
1458 local_bi(1:nrow_rec, 1:ncol_rec) = fm_bib_jb%local_data(1:nrow_rec, 1:ncol_rec)
1459
1460 DO proc_shift = 1, para_env_sub%num_pe - 1
1461 proc_send = modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
1462 proc_receive = modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
1463
1464 ! first exchange information on the local data
1465 rec_col_row_info = 0
1466 CALL para_env_sub%sendrecv(local_col_row_info, proc_send, rec_col_row_info, proc_receive)
1467 nrow_rec = rec_col_row_info(0, 1)
1468 ncol_rec = rec_col_row_info(0, 2)
1469
1470 ALLOCATE (row_indices_rec(nrow_rec))
1471 row_indices_rec = rec_col_row_info(1:nrow_rec, 1)
1472
1473 ALLOCATE (col_indices_rec(ncol_rec))
1474 col_indices_rec = rec_col_row_info(1:ncol_rec, 2)
1475
1476 ALLOCATE (rec_bi(nrow_rec, ncol_rec))
1477 rec_bi = 0.0_dp
1478
1479 ! then send and receive the real data
1480 CALL para_env_sub%sendrecv(local_bi, proc_send, rec_bi, proc_receive)
1481
1482 ! accumulate the received data on BIb_jb buffer
1483 DO jjb = 1, ncol_rec
1484 j_global = col_indices_rec(jjb)
1485 IF (j_global >= my_b_virtual_start .AND. j_global <= my_b_virtual_end) THEN
1486 DO iib = 1, nrow_rec
1487 i_global = row_indices_rec(iib)
1488 bib_jb(j_global - my_b_virtual_start + 1, i_global) = rec_bi(iib, jjb)
1489 END DO
1490 END IF
1491 END DO
1492
1493 DEALLOCATE (col_indices_rec)
1494 DEALLOCATE (row_indices_rec)
1495 DEALLOCATE (rec_bi)
1496 END DO
1497
1498 DEALLOCATE (local_bi)
1499 END IF
1500
1501 DEALLOCATE (rec_col_row_info)
1502
1503 END SUBROUTINE grep_my_integrals
1504
1505END MODULE mp2_integrals
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Define the atomic kind types and their sub types.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public delben2013
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
Definition cell_types.F:195
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_dbcsr_m_by_n_from_template(matrix, template, m, n, sym)
Utility function to create an arbitrary shaped dbcsr matrix with the same processor grid as the templ...
Interface to Minimax-Ewald method for periodic ERI's to be used in CP2K.
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
unit conversion facility
Definition cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition cp_units.F:1179
This is the start of a dbt_api, all publically needed functions are exported here....
Definition dbt_api.F:17
Types to describe group distributions.
Types and set/get functions for HFX.
Definition hfx_types.F:15
subroutine, public alloc_containers(data, bin_size)
...
Definition hfx_types.F:2905
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_eri_os
integer, parameter, public kp_weights_w_auto
integer, parameter, public kp_weights_w_uniform
integer, parameter, public do_eri_mme
integer, parameter, public do_potential_truncated
integer, parameter, public do_potential_id
integer, parameter, public do_potential_coulomb
integer, parameter, public do_potential_short
integer, parameter, public kp_weights_w_tailored
integer, parameter, public do_potential_long
integer, parameter, public do_eri_gpw
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
Routines needed for kpoint calculation.
subroutine, public kpoint_init_cell_index(kpoint, sab_nl, para_env, dft_control)
Generates the mapping of cell indices and linear RS index CELL (0,0,0) is always mapped to index 1.
Types and basic routines needed for a kpoint calculation.
2- and 3-center electron repulsion integral routines based on libint2 Currently available operators: ...
pure logical function, public compare_potential_types(potential1, potential2)
Helper function to compare libint_potential_types.
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:130
Interface to the message passing library MPI.
Routines to calculate 2c- and 3c-integrals for RI with GPW.
Definition mp2_eri_gpw.F:13
subroutine, public prepare_gpw(qs_env, dft_control, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, auxbas_pw_pool, poisson_env, task_list_sub, rho_r, rho_g, pot_g, psi_l, sab_orb_sub)
Prepares GPW calculation for RI-MP2/RI-RPA.
subroutine, public mp2_eri_3c_integrate_gpw(psi_l, rho_g, atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, pw_env_sub, external_vector, poisson_env, rho_r, pot_g, potential_parameter, mat_munu, qs_env, task_list_sub)
...
subroutine, public cleanup_gpw(qs_env, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, task_list_sub, auxbas_pw_pool, rho_r, rho_g, pot_g, psi_l)
Cleanup GPW integration for RI-MP2/RI-RPA.
Interface to direct methods for electron repulsion integrals for MP2.
Definition mp2_eri.F:12
subroutine, public mp2_eri_3c_integrate(param, potential_parameter, para_env, qs_env, first_c, last_c, mat_ab, basis_type_a, basis_type_b, basis_type_c, sab_nl, eri_method, pabc, force_a, force_b, force_c, mat_dabc, mat_adbc, mat_abdc)
high-level integration routine for 3c integrals (ab|c) over CP2K basis sets. For each local function ...
Definition mp2_eri.F:680
Routines to calculate and distribute 2c- and 3c- integrals for RI.
subroutine, public mp2_ri_gpw_compute_in(bib_c, bib_c_gw, bib_c_bse_ij, bib_c_bse_ab, gd_array, gd_b_virtual, dimen_ri, dimen_ri_red, qs_env, para_env, para_env_sub, color_sub, cell, particle_set, atomic_kind_set, qs_kind_set, fm_matrix_pq, fm_matrix_l_kpoints, fm_matrix_minv_l_kpoints, fm_matrix_minv, fm_matrix_minv_vtrunc_minv, nmo, homo, mat_munu, sab_orb_sub, mo_coeff_o, mo_coeff_v, mo_coeff_all, mo_coeff_gw, mo_coeff_o_bse, mo_coeff_v_bse, eps_filter, unit_nr, mp2_memory, calc_pq_cond_num, calc_forces, blacs_env_sub, my_do_gw, do_bse, gd_b_all, starts_array_mc, ends_array_mc, starts_array_mc_block, ends_array_mc_block, gw_corr_lev_occ, gw_corr_lev_virt, bse_lev_virt, do_im_time, do_kpoints_cubic_rpa, kpoints, t_3c_m, t_3c_o, t_3c_o_compressed, t_3c_o_ind, ri_metric, gd_b_occ_bse, gd_b_virt_bse)
with ri mp2 gpw
subroutine, public compute_kpoints(qs_env, kpoints, unit_nr)
...
Framework for 2c-integrals for RI.
Definition mp2_ri_2c.F:14
subroutine, public get_2c_integrals(qs_env, eri_method, eri_param, para_env, para_env_sub, mp2_memory, my_lrows, my_vrows, fm_matrix_pq, ngroup, color_sub, dimen_ri, dimen_ri_red, kpoints, my_group_l_size, my_group_l_start, my_group_l_end, gd_array, calc_pq_cond_num, do_svd, eps_svd, potential, ri_metric, fm_matrix_l_kpoints, fm_matrix_minv_l_kpoints, fm_matrix_minv, fm_matrix_minv_vtrunc_minv, do_im_time, do_kpoints, mp2_eps_pgf_orb_s, qs_kind_set, sab_orb_sub, calc_forces, unit_nr)
...
Definition mp2_ri_2c.F:164
Types needed for MP2 calculations.
Definition mp2_types.F:14
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis)
Get the components of a particle set.
Define the data structure for the particle information.
container for various plainwaves related things
functions related to the poisson solver on regular grids
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Get the QUICKSTEP environment.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Set the QUICKSTEP environment.
Some utility functions for the calculation of integrals.
subroutine, public basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
Set up an easy accessible list of the basis sets for all kinds.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii_orb_basis(orb_basis_set, eps_pgf_orb, eps_pgf_short)
...
Define the quickstep kind type and their sub types.
Define the neighbor list data types and the corresponding functionality.
Utility methods to build 3-center integral tensors of various types.
subroutine, public distribution_3d_create(dist_3d, dist1, dist2, dist3, nkind, particle_set, mp_comm_3d, own_comm)
Create a 3d distribution.
subroutine, public pgf_block_sizes(atomic_kind_set, basis, min_blk_size, pgf_blk_sizes)
...
subroutine, public create_tensor_batches(sizes, nbatches, starts_array, ends_array, starts_array_block, ends_array_block)
...
subroutine, public create_3c_tensor(t3c, dist_1, dist_2, dist_3, pgrid, sizes_1, sizes_2, sizes_3, map1, map2, name)
...
Utility methods to build 3-center integral tensors of various types.
Definition qs_tensors.F:11
subroutine, public build_3c_integrals(t3c, filter_eps, qs_env, nl_3c, basis_i, basis_j, basis_k, potential_parameter, int_eps, op_pos, do_kpoints, do_hfx_kpoints, desymmetrize, cell_sym, bounds_i, bounds_j, bounds_k, ri_range, img_to_ri_cell, cell_to_index_ext)
Build 3-center integral tensor.
subroutine, public compress_tensor(tensor, blk_indices, compressed, eps, memory)
...
subroutine, public neighbor_list_3c_destroy(ijk_list)
Destroy 3c neighborlist.
Definition qs_tensors.F:383
subroutine, public get_tensor_occupancy(tensor, nze, occ)
...
subroutine, public build_3c_neighbor_lists(ijk_list, basis_i, basis_j, basis_k, dist_3d, potential_parameter, name, qs_env, sym_ij, sym_jk, sym_ik, molecular, op_pos, own_dist)
Build a 3-center neighbor list.
Definition qs_tensors.F:282
types for task lists
All kind of helpful little routines.
Definition util.F:14
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
Definition util.F:333
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
Contains information about kpoints.
stores all the informations relevant to an mpi environment
contained for different pw related things
environment for the poisson solver
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.