(git:ed6f26b)
Loading...
Searching...
No Matches
mp2_ri_2c.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 Framework for 2c-integrals for RI
10!> \par History
11!> 06.2012 created [Mauro Del Ben]
12!> 03.2019 separated from mp2_ri_gpw [Frederick Stein]
13! **************************************************************************************************
19 USE cell_types, ONLY: cell_type,&
20 get_cell,&
27 USE cp_cfm_types, ONLY: cp_cfm_create,&
32 USE cp_dbcsr_api, ONLY: &
35 dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
36 dbcsr_type_symmetric
65 USE input_constants, ONLY: do_eri_gpw,&
67 do_eri_os,&
72 USE kinds, ONLY: dp
76 USE kpoint_types, ONLY: get_kpoint_info,&
80 USE machine, ONLY: m_flush
81 USE message_passing, ONLY: mp_comm_type,&
95 USE qs_kind_types, ONLY: get_qs_kind,&
97 USE qs_ks_types, ONLY: get_ks_env,&
101 USE qs_tensors, ONLY: build_2c_integrals,&
105
106!$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num
107#include "./base/base_uses.f90"
108
109 IMPLICIT NONE
110
111 PRIVATE
112
113 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mp2_ri_2c'
114
117
118CONTAINS
119
120! **************************************************************************************************
121!> \brief ...
122!> \param qs_env ...
123!> \param eri_method ...
124!> \param eri_param ...
125!> \param para_env ...
126!> \param para_env_sub ...
127!> \param mp2_memory ...
128!> \param my_Lrows ...
129!> \param my_Vrows ...
130!> \param fm_matrix_PQ ...
131!> \param ngroup ...
132!> \param color_sub ...
133!> \param dimen_RI ...
134!> \param dimen_RI_red reduced RI dimension, needed if we perform SVD instead of Cholesky
135!> \param kpoints ...
136!> \param my_group_L_size ...
137!> \param my_group_L_start ...
138!> \param my_group_L_end ...
139!> \param gd_array ...
140!> \param calc_PQ_cond_num ...
141!> \param do_svd ...
142!> \param eps_svd ...
143!> \param potential ...
144!> \param ri_metric ...
145!> \param fm_matrix_L_kpoints ...
146!> \param fm_matrix_Minv_L_kpoints ...
147!> \param fm_matrix_Minv ...
148!> \param fm_matrix_Minv_Vtrunc_Minv ...
149!> \param do_im_time ...
150!> \param do_kpoints ...
151!> \param mp2_eps_pgf_orb_S ...
152!> \param qs_kind_set ...
153!> \param sab_orb_sub ...
154!> \param calc_forces ...
155!> \param unit_nr ...
156! **************************************************************************************************
157 SUBROUTINE get_2c_integrals(qs_env, eri_method, eri_param, para_env, para_env_sub, mp2_memory, &
158 my_Lrows, my_Vrows, fm_matrix_PQ, ngroup, color_sub, dimen_RI, dimen_RI_red, &
159 kpoints, my_group_L_size, my_group_L_start, my_group_L_end, &
160 gd_array, calc_PQ_cond_num, do_svd, eps_svd, potential, ri_metric, &
161 fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, &
162 fm_matrix_Minv, fm_matrix_Minv_Vtrunc_Minv, &
163 do_im_time, do_kpoints, mp2_eps_pgf_orb_S, qs_kind_set, sab_orb_sub, calc_forces, unit_nr)
164
165 TYPE(qs_environment_type), POINTER :: qs_env
166 INTEGER, INTENT(IN) :: eri_method
167 TYPE(cp_eri_mme_param), POINTER :: eri_param
168 TYPE(mp_para_env_type), POINTER :: para_env, para_env_sub
169 REAL(kind=dp), INTENT(IN) :: mp2_memory
170 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
171 INTENT(OUT) :: my_lrows, my_vrows
172 TYPE(cp_fm_type), INTENT(OUT) :: fm_matrix_pq
173 INTEGER, INTENT(IN) :: ngroup, color_sub
174 INTEGER, INTENT(OUT) :: dimen_ri, dimen_ri_red
175 TYPE(kpoint_type), POINTER :: kpoints
176 INTEGER, INTENT(OUT) :: my_group_l_size, my_group_l_start, &
177 my_group_l_end
178 TYPE(group_dist_d1_type), INTENT(OUT) :: gd_array
179 LOGICAL, INTENT(IN) :: calc_pq_cond_num, do_svd
180 REAL(kind=dp), INTENT(IN) :: eps_svd
181 TYPE(libint_potential_type) :: potential, ri_metric
182 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_l_kpoints, &
183 fm_matrix_minv_l_kpoints, &
184 fm_matrix_minv, &
185 fm_matrix_minv_vtrunc_minv
186 LOGICAL, INTENT(IN) :: do_im_time, do_kpoints
187 REAL(kind=dp), INTENT(IN) :: mp2_eps_pgf_orb_s
188 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
189 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
190 POINTER :: sab_orb_sub
191 LOGICAL, INTENT(IN) :: calc_forces
192 INTEGER, INTENT(IN) :: unit_nr
193
194 CHARACTER(LEN=*), PARAMETER :: routinen = 'get_2c_integrals'
195
196 INTEGER :: handle, num_small_eigen
197 REAL(kind=dp) :: cond_num, eps_pgf_orb_old
198 TYPE(cp_fm_type) :: fm_matrix_l_work, fm_matrix_m_inv_work, &
199 fm_matrix_v
200 TYPE(dft_control_type), POINTER :: dft_control
201 TYPE(libint_potential_type) :: trunc_coulomb
202 TYPE(mp_para_env_type), POINTER :: para_env_l
203
204 CALL timeset(routinen, handle)
205
206 ! calculate V and store it in fm_matrix_L_work
207 CALL compute_2c_integrals(qs_env, eri_method, eri_param, para_env, para_env_sub, para_env_l, mp2_memory, &
208 fm_matrix_l_work, ngroup, color_sub, dimen_ri, &
209 my_group_l_size, my_group_l_start, my_group_l_end, &
210 gd_array, calc_pq_cond_num, cond_num, &
211 num_small_eigen, potential, sab_orb_sub, do_im_time=do_im_time)
212
213 IF (do_im_time .AND. calc_forces) THEN
214 !need a copy of the (P|Q) integrals
215 CALL cp_fm_create(fm_matrix_pq, fm_matrix_l_work%matrix_struct)
216 CALL cp_fm_to_fm(fm_matrix_l_work, fm_matrix_pq)
217 END IF
218
219 dimen_ri_red = dimen_ri
220
221 IF (compare_potential_types(ri_metric, potential) .AND. .NOT. do_im_time) THEN
222 CALL decomp_mat_l(fm_matrix_l_work, do_svd, eps_svd, num_small_eigen, cond_num, .true., gd_array, ngroup, &
223 dimen_ri, dimen_ri_red, para_env)
224 ELSE
225
226 ! RI-metric matrix (depending on RI metric: Coulomb, overlap or truncated Coulomb)
227 IF (do_im_time) THEN
228 CALL get_qs_env(qs_env, dft_control=dft_control)
229
230 ! re-init the radii to be able to generate pair lists with appropriate screening for overlap matrix
231 eps_pgf_orb_old = dft_control%qs_control%eps_pgf_orb
232 dft_control%qs_control%eps_pgf_orb = mp2_eps_pgf_orb_s
233 CALL init_interaction_radii(dft_control%qs_control, qs_kind_set)
234
235 CALL ri_2c_integral_mat(qs_env, fm_matrix_minv_l_kpoints, fm_matrix_l_work, dimen_ri, ri_metric, &
236 do_kpoints, kpoints, put_mat_ks_env=.true., &
237 regularization_ri=qs_env%mp2_env%ri_rpa_im_time%regularization_RI)
238
239 ! re-init the radii to previous values
240 dft_control%qs_control%eps_pgf_orb = eps_pgf_orb_old
241 CALL init_interaction_radii(dft_control%qs_control, qs_kind_set)
242
243 ! GPW overlap matrix
244 ELSE
245
246 CALL mp_para_env_release(para_env_l)
247 CALL release_group_dist(gd_array)
248
249 ALLOCATE (fm_matrix_minv_l_kpoints(1, 1))
250
251 ! Calculate matrix of RI operator (for overlap metric: S), store it in fm_matrix_Minv_L_kpoints
252 CALL compute_2c_integrals(qs_env, eri_method, eri_param, para_env, para_env_sub, para_env_l, mp2_memory, &
253 fm_matrix_minv_l_kpoints(1, 1), ngroup, color_sub, dimen_ri, &
254 my_group_l_size, my_group_l_start, my_group_l_end, &
255 gd_array, calc_pq_cond_num, cond_num, &
256 num_small_eigen, ri_metric, sab_orb_sub, &
257 fm_matrix_l_extern=fm_matrix_l_work)
258
259 END IF
260
261 IF (do_kpoints) THEN
262
263 ! k-dependent 1/r Coulomb matrix V_PQ(k)
264 CALL compute_v_by_lattice_sum(qs_env, fm_matrix_l_kpoints, fm_matrix_minv_l_kpoints, kpoints)
265
266 CALL inversion_of_m_and_mult_with_chol_dec_of_v(fm_matrix_minv_l_kpoints, fm_matrix_l_kpoints, dimen_ri, &
267 kpoints, qs_env%mp2_env%ri_rpa_im_time%eps_eigval_S)
268
269 CALL trunc_coulomb_for_exchange(qs_env, trunc_coulomb)
270
271 ! Gamma-only truncated Coulomb matrix V^tr with cutoff radius = half the unit cell size; for exchange self-energy
272 CALL ri_2c_integral_mat(qs_env, fm_matrix_minv_vtrunc_minv, fm_matrix_l_work, dimen_ri, trunc_coulomb, &
273 do_kpoints=.false., kpoints=kpoints, put_mat_ks_env=.false., regularization_ri=0.0_dp)
274
275 ! Gamma-only RI-metric matrix; for computing Gamma-only/MIC self-energy
276 CALL ri_2c_integral_mat(qs_env, fm_matrix_minv, fm_matrix_l_work, dimen_ri, ri_metric, &
277 do_kpoints=.false., kpoints=kpoints, put_mat_ks_env=.false., regularization_ri=0.0_dp)
278
279 CALL gamma_only_inversion_of_m_and_mult_with_chol_dec_of_vtrunc(fm_matrix_minv_vtrunc_minv, &
280 fm_matrix_minv, qs_env)
281 ELSE
282 IF (calc_forces .AND. (.NOT. do_im_time)) THEN
283 ! For the gradients, we make a copy of the inverse root of L
284 CALL cp_fm_create(fm_matrix_v, fm_matrix_l_work%matrix_struct)
285 CALL cp_fm_to_fm(fm_matrix_l_work, fm_matrix_v)
286
287 CALL decomp_mat_l(fm_matrix_v, do_svd, eps_svd, num_small_eigen, cond_num, .true., gd_array, ngroup, &
288 dimen_ri, dimen_ri_red, para_env)
289 END IF
290
291 CALL decomp_mat_l(fm_matrix_l_work, do_svd, eps_svd, num_small_eigen, cond_num, .false., gd_array, ngroup, &
292 dimen_ri, dimen_ri_red, para_env)
293
294 CALL decomp_mat_l(fm_matrix_minv_l_kpoints(1, 1), .false., 0.0_dp, num_small_eigen, cond_num, .true., &
295 gd_array, ngroup, dimen_ri, dimen_ri_red, para_env)
296
297 CALL cp_fm_create(fm_matrix_m_inv_work, fm_matrix_minv_l_kpoints(1, 1)%matrix_struct)
298 CALL cp_fm_set_all(fm_matrix_m_inv_work, 0.0_dp)
299
300 CALL parallel_gemm('N', 'T', dimen_ri, dimen_ri, dimen_ri, 1.0_dp, fm_matrix_minv_l_kpoints(1, 1), &
301 fm_matrix_minv_l_kpoints(1, 1), 0.0_dp, fm_matrix_m_inv_work)
302
303 IF (do_svd) THEN
304 ! We have to reset the size of fm_matrix_Minv_L_kpoints
305 CALL reset_size_matrix(fm_matrix_minv_l_kpoints(1, 1), dimen_ri_red, fm_matrix_l_work%matrix_struct)
306
307 ! L (=fm_matrix_Minv_L_kpoints) = S^(-1)*chol_dec(V)
308 CALL parallel_gemm('T', 'N', dimen_ri, dimen_ri_red, dimen_ri, 1.0_dp, fm_matrix_m_inv_work, &
309 fm_matrix_l_work, 0.0_dp, fm_matrix_minv_l_kpoints(1, 1))
310 ELSE
311 ! L (=fm_matrix_Minv_L_kpoints) = S^(-1)*chol_dec(V)
312 CALL parallel_gemm('T', 'T', dimen_ri, dimen_ri, dimen_ri, 1.0_dp, fm_matrix_m_inv_work, &
313 fm_matrix_l_work, 0.0_dp, fm_matrix_minv_l_kpoints(1, 1))
314 END IF
315
316 ! clean the S_inv matrix
317 CALL cp_fm_release(fm_matrix_m_inv_work)
318 END IF
319
320 IF (.NOT. do_im_time) THEN
321
322 CALL cp_fm_to_fm(fm_matrix_minv_l_kpoints(1, 1), fm_matrix_l_work)
323 CALL cp_fm_release(fm_matrix_minv_l_kpoints)
324
325 END IF
326
327 END IF
328
329 ! If the group distribution changed because of an SVD, we get the new values here
330 CALL get_group_dist(gd_array, color_sub, my_group_l_start, my_group_l_end, my_group_l_size)
331
332 IF (.NOT. do_im_time) THEN
333 IF (unit_nr > 0) THEN
334 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") "RI_INFO| Cholesky decomposition group size:", para_env_l%num_pe
335 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") "RI_INFO| Number of groups for auxiliary basis functions", ngroup
336 IF (calc_pq_cond_num .OR. do_svd) THEN
337 WRITE (unit=unit_nr, fmt="(T3,A,T67,ES14.5)") &
338 "RI_INFO| Condition number of the (P|Q):", cond_num
339 WRITE (unit=unit_nr, fmt="(T3,A,T75,i6)") &
340 "RI_INFO| Number of non-positive Eigenvalues of (P|Q):", num_small_eigen
341 END IF
342 CALL m_flush(unit_nr)
343 END IF
344
345 ! replicate the necessary row of the L^{-1} matrix on each proc
346 CALL grep_lcols(fm_matrix_l_work, my_group_l_start, my_group_l_end, my_group_l_size, my_lrows)
347 IF (calc_forces .AND. .NOT. compare_potential_types(qs_env%mp2_env%ri_metric, &
348 qs_env%mp2_env%potential_parameter)) THEN
349 CALL grep_lcols(fm_matrix_v, my_group_l_start, my_group_l_end, my_group_l_size, my_vrows)
350 END IF
351 END IF
352 CALL cp_fm_release(fm_matrix_l_work)
353 IF (calc_forces .AND. .NOT. (do_im_time .OR. compare_potential_types(qs_env%mp2_env%ri_metric, &
354 qs_env%mp2_env%potential_parameter))) CALL cp_fm_release(fm_matrix_v)
355 CALL mp_para_env_release(para_env_l)
356
357 CALL timestop(handle)
358
359 END SUBROUTINE get_2c_integrals
360
361! **************************************************************************************************
362!> \brief ...
363!> \param fm_matrix_L ...
364!> \param do_svd ...
365!> \param eps_svd ...
366!> \param num_small_eigen ...
367!> \param cond_num ...
368!> \param do_inversion ...
369!> \param gd_array ...
370!> \param ngroup ...
371!> \param dimen_RI ...
372!> \param dimen_RI_red ...
373!> \param para_env ...
374! **************************************************************************************************
375 SUBROUTINE decomp_mat_l(fm_matrix_L, do_svd, eps_svd, num_small_eigen, cond_num, do_inversion, gd_array, ngroup, &
376 dimen_RI, dimen_RI_red, para_env)
377
378 TYPE(cp_fm_type), INTENT(INOUT) :: fm_matrix_l
379 LOGICAL, INTENT(IN) :: do_svd
380 REAL(kind=dp), INTENT(IN) :: eps_svd
381 INTEGER, INTENT(INOUT) :: num_small_eigen
382 REAL(kind=dp), INTENT(INOUT) :: cond_num
383 LOGICAL, INTENT(IN) :: do_inversion
384 TYPE(group_dist_d1_type), INTENT(INOUT) :: gd_array
385 INTEGER, INTENT(IN) :: ngroup, dimen_ri
386 INTEGER, INTENT(INOUT) :: dimen_ri_red
387 TYPE(mp_para_env_type), INTENT(IN) :: para_env
388
389 IF (do_svd) THEN
390 CALL matrix_root_with_svd(fm_matrix_l, num_small_eigen, cond_num, eps_svd, do_inversion, para_env)
391
392 dimen_ri_red = dimen_ri - num_small_eigen
393
394 ! We changed the size of fm_matrix_L in matrix_root_with_svd.
395 ! So, we have to get new group sizes
396 CALL release_group_dist(gd_array)
397
398 CALL create_group_dist(gd_array, ngroup, dimen_ri_red)
399 ELSE
400
401 ! calculate Cholesky decomposition L (V=LL^T)
402 CALL cholesky_decomp(fm_matrix_l, dimen_ri, do_inversion=do_inversion)
403
404 IF (do_inversion) CALL invert_mat(fm_matrix_l)
405 END IF
406
407 END SUBROUTINE decomp_mat_l
408
409! **************************************************************************************************
410!> \brief ...
411!> \param qs_env ...
412!> \param fm_matrix_L_kpoints ...
413!> \param fm_matrix_Minv_L_kpoints ...
414!> \param kpoints ...
415! **************************************************************************************************
416 SUBROUTINE compute_v_by_lattice_sum(qs_env, fm_matrix_L_kpoints, fm_matrix_Minv_L_kpoints, kpoints)
417 TYPE(qs_environment_type), POINTER :: qs_env
418 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_l_kpoints, &
419 fm_matrix_minv_l_kpoints
420 TYPE(kpoint_type), POINTER :: kpoints
421
422 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_V_by_lattice_sum'
423
424 INTEGER :: handle, i_dim, i_real_imag, ikp, nkp, &
425 nkp_extra, nkp_orig
426 INTEGER, DIMENSION(3) :: nkp_grid_orig, periodic
427 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
428 TYPE(cell_type), POINTER :: cell
429 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s_ri_aux_transl, matrix_v_ri_kp
430 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
431 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
432
433 CALL timeset(routinen, handle)
434
435 NULLIFY (matrix_s_ri_aux_transl, particle_set, cell, qs_kind_set)
436
437 CALL get_qs_env(qs_env=qs_env, &
438 matrix_s_ri_aux_kp=matrix_s_ri_aux_transl, &
439 particle_set=particle_set, &
440 cell=cell, &
441 qs_kind_set=qs_kind_set, &
442 atomic_kind_set=atomic_kind_set)
443
444 ! check that we have a 2n x 2m x 2k mesh to guarantee good convergence
445 CALL get_cell(cell=cell, periodic=periodic)
446 DO i_dim = 1, 3
447 IF (periodic(i_dim) == 1) THEN
448 cpassert(modulo(kpoints%nkp_grid(i_dim), 2) == 0)
449 END IF
450 END DO
451
452 nkp = kpoints%nkp
453
454 ALLOCATE (fm_matrix_l_kpoints(nkp, 2))
455 DO ikp = 1, nkp
456 DO i_real_imag = 1, 2
457 CALL cp_fm_create(fm_matrix_l_kpoints(ikp, i_real_imag), &
458 fm_matrix_minv_l_kpoints(1, i_real_imag)%matrix_struct)
459 CALL cp_fm_set_all(fm_matrix_l_kpoints(ikp, i_real_imag), 0.0_dp)
460 END DO
461 END DO
462
463 CALL allocate_matrix_v_ri_kp(matrix_v_ri_kp, matrix_s_ri_aux_transl, nkp)
464
465 IF (qs_env%mp2_env%ri_rpa_im_time%do_extrapolate_kpoints) THEN
466
467 nkp_orig = qs_env%mp2_env%ri_rpa_im_time%nkp_orig
468 nkp_extra = qs_env%mp2_env%ri_rpa_im_time%nkp_extra
469
470 CALL build_2c_coulomb_matrix_kp(matrix_v_ri_kp, kpoints, basis_type="RI_AUX", &
471 cell=cell, particle_set=particle_set, qs_kind_set=qs_kind_set, &
472 atomic_kind_set=atomic_kind_set, &
473 size_lattice_sum=qs_env%mp2_env%mp2_gpw%size_lattice_sum, &
474 operator_type=operator_coulomb, ikp_start=1, ikp_end=nkp_orig)
475
476 nkp_grid_orig = kpoints%nkp_grid
477 kpoints%nkp_grid(1:3) = qs_env%mp2_env%ri_rpa_im_time%kp_grid_extra(1:3)
478
479 CALL build_2c_coulomb_matrix_kp(matrix_v_ri_kp, kpoints, basis_type="RI_AUX", &
480 cell=cell, particle_set=particle_set, qs_kind_set=qs_kind_set, &
481 atomic_kind_set=atomic_kind_set, &
482 size_lattice_sum=qs_env%mp2_env%mp2_gpw%size_lattice_sum, &
483 operator_type=operator_coulomb, ikp_start=nkp_orig + 1, ikp_end=nkp)
484
485 kpoints%nkp_grid = nkp_grid_orig
486
487 ELSE
488
489 CALL build_2c_coulomb_matrix_kp(matrix_v_ri_kp, kpoints, basis_type="RI_AUX", &
490 cell=cell, particle_set=particle_set, qs_kind_set=qs_kind_set, &
491 atomic_kind_set=atomic_kind_set, &
492 size_lattice_sum=qs_env%mp2_env%mp2_gpw%size_lattice_sum, &
493 operator_type=operator_coulomb, ikp_start=1, ikp_end=nkp)
494
495 END IF
496
497 DO ikp = 1, nkp
498
499 CALL copy_dbcsr_to_fm(matrix_v_ri_kp(ikp, 1)%matrix, fm_matrix_l_kpoints(ikp, 1))
500 CALL copy_dbcsr_to_fm(matrix_v_ri_kp(ikp, 2)%matrix, fm_matrix_l_kpoints(ikp, 2))
501
502 END DO
503
504 CALL dbcsr_deallocate_matrix_set(matrix_v_ri_kp)
505
506 CALL timestop(handle)
507
508 END SUBROUTINE compute_v_by_lattice_sum
509
510! **************************************************************************************************
511!> \brief ...
512!> \param matrix_v_RI_kp ...
513!> \param matrix_s_RI_aux_transl ...
514!> \param nkp ...
515! **************************************************************************************************
516 SUBROUTINE allocate_matrix_v_ri_kp(matrix_v_RI_kp, matrix_s_RI_aux_transl, nkp)
517
518 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_v_ri_kp, matrix_s_ri_aux_transl
519 INTEGER :: nkp
520
521 INTEGER :: ikp
522
523 NULLIFY (matrix_v_ri_kp)
524 CALL dbcsr_allocate_matrix_set(matrix_v_ri_kp, nkp, 2)
525
526 DO ikp = 1, nkp
527
528 ALLOCATE (matrix_v_ri_kp(ikp, 1)%matrix)
529 CALL dbcsr_create(matrix_v_ri_kp(ikp, 1)%matrix, template=matrix_s_ri_aux_transl(1, 1)%matrix, &
530 matrix_type=dbcsr_type_no_symmetry)
531 CALL dbcsr_reserve_all_blocks(matrix_v_ri_kp(ikp, 1)%matrix)
532 CALL dbcsr_set(matrix_v_ri_kp(ikp, 1)%matrix, 0.0_dp)
533
534 ALLOCATE (matrix_v_ri_kp(ikp, 2)%matrix)
535 CALL dbcsr_create(matrix_v_ri_kp(ikp, 2)%matrix, template=matrix_s_ri_aux_transl(1, 1)%matrix, &
536 matrix_type=dbcsr_type_no_symmetry)
537 CALL dbcsr_reserve_all_blocks(matrix_v_ri_kp(ikp, 2)%matrix)
538 CALL dbcsr_set(matrix_v_ri_kp(ikp, 2)%matrix, 0.0_dp)
539
540 END DO
541
542 END SUBROUTINE allocate_matrix_v_ri_kp
543
544! **************************************************************************************************
545!> \brief ...
546!> \param qs_env ...
547!> \param fm_matrix_Minv_L_kpoints ...
548!> \param fm_matrix_L ...
549!> \param dimen_RI ...
550!> \param ri_metric ...
551!> \param do_kpoints ...
552!> \param kpoints ...
553!> \param put_mat_KS_env ...
554!> \param regularization_RI ...
555!> \param ikp_ext ...
556!> \param do_build_cell_index ...
557! **************************************************************************************************
558 SUBROUTINE ri_2c_integral_mat(qs_env, fm_matrix_Minv_L_kpoints, fm_matrix_L, dimen_RI, ri_metric, &
559 do_kpoints, kpoints, put_mat_KS_env, regularization_RI, ikp_ext, &
560 do_build_cell_index)
561
562 TYPE(qs_environment_type), POINTER :: qs_env
563 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: fm_matrix_minv_l_kpoints
564 TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_l
565 INTEGER, INTENT(IN) :: dimen_ri
566 TYPE(libint_potential_type) :: ri_metric
567 LOGICAL, INTENT(IN) :: do_kpoints
568 TYPE(kpoint_type), OPTIONAL, POINTER :: kpoints
569 LOGICAL, OPTIONAL :: put_mat_ks_env
570 REAL(kind=dp), OPTIONAL :: regularization_ri
571 INTEGER, OPTIONAL :: ikp_ext
572 LOGICAL, OPTIONAL :: do_build_cell_index
573
574 CHARACTER(LEN=*), PARAMETER :: routinen = 'RI_2c_integral_mat'
575
576 INTEGER :: handle, i_real_imag, i_size, ikp, &
577 ikp_for_xkp, img, n_real_imag, natom, &
578 nimg, nkind, nkp
579 INTEGER, ALLOCATABLE, DIMENSION(:) :: sizes_ri
580 INTEGER, DIMENSION(:), POINTER :: col_bsize, row_bsize
581 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
582 LOGICAL :: my_do_build_cell_index, my_put_mat_ks_env
583 REAL(kind=dp) :: my_regularization_ri
584 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
585 TYPE(cp_blacs_env_type), POINTER :: blacs_env
586 TYPE(cp_fm_struct_type), POINTER :: fm_struct
587 TYPE(cp_fm_type) :: fm_matrix_s_global
588 TYPE(dbcsr_distribution_type) :: dbcsr_dist
589 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s_ri_aux_transl
590 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: mat_2c
591 TYPE(dbcsr_type), POINTER :: cmatrix, matrix_s_ri_aux_desymm, &
592 rmatrix, tmpmat
593 TYPE(dft_control_type), POINTER :: dft_control
594 TYPE(distribution_2d_type), POINTER :: dist_2d
595 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_ri
596 TYPE(mp_para_env_type), POINTER :: para_env
597 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
598 POINTER :: sab_ri
599 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
600 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
601
602 CALL timeset(routinen, handle)
603
604 NULLIFY (sab_ri, matrix_s_ri_aux_transl, dist_2d)
605
606 IF (PRESENT(regularization_ri)) THEN
607 my_regularization_ri = regularization_ri
608 ELSE
609 my_regularization_ri = 0.0_dp
610 END IF
611
612 IF (PRESENT(put_mat_ks_env)) THEN
613 my_put_mat_ks_env = put_mat_ks_env
614 ELSE
615 my_put_mat_ks_env = .false.
616 END IF
617
618 IF (PRESENT(do_build_cell_index)) THEN
619 my_do_build_cell_index = do_build_cell_index
620 ELSE
621 my_do_build_cell_index = .false.
622 END IF
623
624 CALL get_qs_env(qs_env=qs_env, &
625 para_env=para_env, &
626 blacs_env=blacs_env, &
627 nkind=nkind, &
628 distribution_2d=dist_2d, &
629 qs_kind_set=qs_kind_set, &
630 particle_set=particle_set, &
631 dft_control=dft_control, &
632 natom=natom)
633
634 ALLOCATE (sizes_ri(natom))
635 ALLOCATE (basis_set_ri(nkind))
636
637 CALL basis_set_list_setup(basis_set_ri, 'RI_AUX', qs_kind_set)
638 CALL get_particle_set(particle_set, qs_kind_set, nsgf=sizes_ri, basis=basis_set_ri)
639
640 CALL build_2c_neighbor_lists(sab_ri, basis_set_ri, basis_set_ri, ri_metric, "RPA_2c_nl_RI", qs_env, &
641 sym_ij=.true., dist_2d=dist_2d)
642
643 CALL cp_dbcsr_dist2d_to_dist(dist_2d, dbcsr_dist)
644 ALLOCATE (row_bsize(SIZE(sizes_ri)))
645 ALLOCATE (col_bsize(SIZE(sizes_ri)))
646 row_bsize(:) = sizes_ri
647 col_bsize(:) = sizes_ri
648
649 IF (do_kpoints) THEN
650 cpassert(PRESENT(kpoints))
651 IF (my_do_build_cell_index) THEN
652 CALL kpoint_init_cell_index(kpoints, sab_ri, para_env, dft_control)
653 END IF
654 CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, &
655 cell_to_index=cell_to_index)
656 n_real_imag = 2
657 nimg = dft_control%nimages
658 ELSE
659 nkp = 1
660 n_real_imag = 1
661 nimg = 1
662 END IF
663
664 ALLOCATE (mat_2c(nimg))
665 CALL dbcsr_create(mat_2c(1), "(RI|RI)", dbcsr_dist, dbcsr_type_symmetric, &
666 row_bsize, col_bsize)
667 DEALLOCATE (row_bsize, col_bsize)
668
669 DO img = 2, nimg
670 CALL dbcsr_create(mat_2c(img), template=mat_2c(1))
671 END DO
672
673 CALL build_2c_integrals(mat_2c, 0.0_dp, qs_env, sab_ri, basis_set_ri, basis_set_ri, &
674 ri_metric, do_kpoints=do_kpoints, ext_kpoints=kpoints, &
675 regularization_ri=my_regularization_ri)
676
677 CALL dbcsr_distribution_release(dbcsr_dist)
678 DEALLOCATE (basis_set_ri)
679
680 IF (my_put_mat_ks_env) THEN
681 CALL get_ks_env(qs_env%ks_env, matrix_s_ri_aux_kp=matrix_s_ri_aux_transl)
682 IF (ASSOCIATED(matrix_s_ri_aux_transl)) CALL dbcsr_deallocate_matrix_set(matrix_s_ri_aux_transl)
683 END IF
684 CALL dbcsr_allocate_matrix_set(matrix_s_ri_aux_transl, 1, nimg)
685 DO img = 1, nimg
686 ALLOCATE (matrix_s_ri_aux_transl(1, img)%matrix)
687 CALL dbcsr_copy(matrix_s_ri_aux_transl(1, img)%matrix, mat_2c(img))
688 CALL dbcsr_release(mat_2c(img))
689 END DO
690
691 IF (my_put_mat_ks_env) THEN
692 CALL set_ks_env(qs_env%ks_env, matrix_s_ri_aux_kp=matrix_s_ri_aux_transl)
693 END IF
694
695 IF (PRESENT(ikp_ext)) nkp = 1
696
697 ALLOCATE (fm_matrix_minv_l_kpoints(nkp, n_real_imag))
698 DO i_size = 1, nkp
699 DO i_real_imag = 1, n_real_imag
700 CALL cp_fm_create(fm_matrix_minv_l_kpoints(i_size, i_real_imag), fm_matrix_l%matrix_struct)
701 CALL cp_fm_set_all(fm_matrix_minv_l_kpoints(i_size, i_real_imag), 0.0_dp)
702 END DO
703 END DO
704
705 NULLIFY (fm_struct)
706 CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=dimen_ri, &
707 ncol_global=dimen_ri, para_env=para_env)
708
709 CALL cp_fm_create(fm_matrix_s_global, fm_struct)
710 CALL cp_fm_set_all(fm_matrix_s_global, 0.0_dp)
711
712 IF (do_kpoints) THEN
713
714 ALLOCATE (rmatrix, cmatrix, tmpmat)
715 CALL dbcsr_create(rmatrix, template=matrix_s_ri_aux_transl(1, 1)%matrix, &
716 matrix_type=dbcsr_type_symmetric)
717 CALL dbcsr_create(cmatrix, template=matrix_s_ri_aux_transl(1, 1)%matrix, &
718 matrix_type=dbcsr_type_antisymmetric)
719 CALL dbcsr_create(tmpmat, template=matrix_s_ri_aux_transl(1, 1)%matrix, &
720 matrix_type=dbcsr_type_no_symmetry)
721 CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_ri)
722 CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_ri)
723
724 DO ikp = 1, nkp
725
726 ! s matrix is not spin dependent, double the work
727 CALL dbcsr_set(rmatrix, 0.0_dp)
728 CALL dbcsr_set(cmatrix, 0.0_dp)
729
730 IF (PRESENT(ikp_ext)) THEN
731 ikp_for_xkp = ikp_ext
732 ELSE
733 ikp_for_xkp = ikp
734 END IF
735
736 CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_s_ri_aux_transl, ispin=1, &
737 xkp=xkp(1:3, ikp_for_xkp), cell_to_index=cell_to_index, sab_nl=sab_ri)
738
739 CALL dbcsr_set(tmpmat, 0.0_dp)
740 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
741
742 CALL cp_fm_set_all(fm_matrix_s_global, 0.0_dp)
743 CALL copy_dbcsr_to_fm(tmpmat, fm_matrix_s_global)
744 CALL cp_fm_copy_general(fm_matrix_s_global, fm_matrix_minv_l_kpoints(ikp, 1), para_env)
745
746 CALL dbcsr_set(tmpmat, 0.0_dp)
747 CALL dbcsr_desymmetrize(cmatrix, tmpmat)
748
749 CALL cp_fm_set_all(fm_matrix_s_global, 0.0_dp)
750 CALL copy_dbcsr_to_fm(tmpmat, fm_matrix_s_global)
751 CALL cp_fm_copy_general(fm_matrix_s_global, fm_matrix_minv_l_kpoints(ikp, 2), para_env)
752
753 END DO
754
755 CALL dbcsr_deallocate_matrix(rmatrix)
756 CALL dbcsr_deallocate_matrix(cmatrix)
757 CALL dbcsr_deallocate_matrix(tmpmat)
758
759 ELSE
760
761 NULLIFY (matrix_s_ri_aux_desymm)
762 ALLOCATE (matrix_s_ri_aux_desymm)
763 CALL dbcsr_create(matrix_s_ri_aux_desymm, template=matrix_s_ri_aux_transl(1, 1)%matrix, &
764 name='S_RI non_symm', matrix_type=dbcsr_type_no_symmetry)
765
766 CALL dbcsr_desymmetrize(matrix_s_ri_aux_transl(1, 1)%matrix, matrix_s_ri_aux_desymm)
767
768 CALL copy_dbcsr_to_fm(matrix_s_ri_aux_desymm, fm_matrix_s_global)
769
770 CALL cp_fm_copy_general(fm_matrix_s_global, fm_matrix_minv_l_kpoints(1, 1), para_env)
771
772 CALL dbcsr_deallocate_matrix(matrix_s_ri_aux_desymm)
773
774 END IF
775
776 CALL release_neighbor_list_sets(sab_ri)
777
778 CALL cp_fm_struct_release(fm_struct)
779
780 CALL cp_fm_release(fm_matrix_s_global)
781
782 IF (.NOT. my_put_mat_ks_env) THEN
783 CALL dbcsr_deallocate_matrix_set(matrix_s_ri_aux_transl)
784 END IF
785
786 CALL timestop(handle)
787
788 END SUBROUTINE ri_2c_integral_mat
789
790! **************************************************************************************************
791!> \brief ...
792!> \param qs_env ...
793!> \param eri_method ...
794!> \param eri_param ...
795!> \param para_env ...
796!> \param para_env_sub ...
797!> \param para_env_L ...
798!> \param mp2_memory ...
799!> \param fm_matrix_L ...
800!> \param ngroup ...
801!> \param color_sub ...
802!> \param dimen_RI ...
803!> \param my_group_L_size ...
804!> \param my_group_L_start ...
805!> \param my_group_L_end ...
806!> \param gd_array ...
807!> \param calc_PQ_cond_num ...
808!> \param cond_num ...
809!> \param num_small_eigen ...
810!> \param potential ...
811!> \param sab_orb_sub ...
812!> \param do_im_time ...
813!> \param fm_matrix_L_extern ...
814! **************************************************************************************************
815 SUBROUTINE compute_2c_integrals(qs_env, eri_method, eri_param, para_env, para_env_sub, para_env_L, mp2_memory, &
816 fm_matrix_L, ngroup, color_sub, dimen_RI, &
817 my_group_L_size, my_group_L_start, my_group_L_end, &
818 gd_array, calc_PQ_cond_num, cond_num, num_small_eigen, potential, &
819 sab_orb_sub, do_im_time, fm_matrix_L_extern)
820
821 TYPE(qs_environment_type), POINTER :: qs_env
822 INTEGER, INTENT(IN) :: eri_method
823 TYPE(cp_eri_mme_param), POINTER :: eri_param
824 TYPE(mp_para_env_type), INTENT(IN) :: para_env
825 TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env_sub
826 TYPE(mp_para_env_type), INTENT(OUT), POINTER :: para_env_l
827 REAL(kind=dp), INTENT(IN) :: mp2_memory
828 TYPE(cp_fm_type), INTENT(OUT) :: fm_matrix_l
829 INTEGER, INTENT(IN) :: ngroup, color_sub
830 INTEGER, INTENT(OUT) :: dimen_ri, my_group_l_size, &
831 my_group_l_start, my_group_l_end
832 TYPE(group_dist_d1_type), INTENT(OUT) :: gd_array
833 LOGICAL, INTENT(IN) :: calc_pq_cond_num
834 REAL(kind=dp), INTENT(OUT) :: cond_num
835 INTEGER, INTENT(OUT) :: num_small_eigen
836 TYPE(libint_potential_type), INTENT(IN) :: potential
837 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
838 POINTER :: sab_orb_sub
839 LOGICAL, INTENT(IN), OPTIONAL :: do_im_time
840 TYPE(cp_fm_type), INTENT(IN), OPTIONAL :: fm_matrix_l_extern
841
842 CHARACTER(LEN=*), PARAMETER :: routinen = 'compute_2c_integrals'
843
844 INTEGER :: best_group_size, color_l, group_size, handle, handle2, i_global, iatom, iib, &
845 ikind, iproc, j_global, jjb, natom, ncol_local, nkind, nrow_local, nsgf, potential_type, &
846 proc_receive, proc_receive_static, proc_send_static, proc_shift, rec_l_end, rec_l_size, &
847 rec_l_start, strat_group_size
848 INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
849 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
850 LOGICAL :: my_do_im_time
851 REAL(kind=dp) :: min_mem_for_qk
852 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: egen_l
853 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: l_external_col, l_local_col
854 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
855 TYPE(cp_blacs_env_type), POINTER :: blacs_env_l
856 TYPE(cp_fm_type) :: fm_matrix_l_diag
857 TYPE(group_dist_d1_type) :: gd_sub_array
858 TYPE(gto_basis_set_type), POINTER :: basis_set_a
859 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
860 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
861
862 CALL timeset(routinen, handle)
863
864 my_do_im_time = .false.
865 IF (PRESENT(do_im_time)) THEN
866 my_do_im_time = do_im_time
867 END IF
868
869 ! get stuff
870 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
871 particle_set=particle_set)
872
873 nkind = SIZE(qs_kind_set)
874 natom = SIZE(particle_set)
875
876 CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of)
877
878 DO ikind = 1, nkind
879 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, basis_type="RI_AUX")
880 cpassert(ASSOCIATED(basis_set_a))
881 END DO
882
883 dimen_ri = 0
884 DO iatom = 1, natom
885 ikind = kind_of(iatom)
886 CALL get_qs_kind(qs_kind=qs_kind_set(ikind), nsgf=nsgf, basis_type="RI_AUX")
887 dimen_ri = dimen_ri + nsgf
888 END DO
889
890 ! check that very small systems are not running on too many processes
891 IF (dimen_ri < ngroup) THEN
892 CALL cp_abort(__location__, "Product of block size and number "// &
893 "of RI functions should not exceed total number of processes")
894 END IF
895
896 CALL create_group_dist(gd_array, ngroup, dimen_ri)
897
898 CALL get_group_dist(gd_array, color_sub, my_group_l_start, my_group_l_end, my_group_l_size)
899
900 CALL timeset(routinen//"_loop_lm", handle2)
901
902 ALLOCATE (l_local_col(dimen_ri, my_group_l_size))
903 l_local_col = 0.0_dp
904
905 potential_type = potential%potential_type
906
907 IF ((eri_method .EQ. do_eri_mme .OR. eri_method .EQ. do_eri_os) &
908 .AND. potential_type .EQ. do_potential_coulomb .OR. &
909 (eri_method .EQ. do_eri_mme .AND. potential_type .EQ. do_potential_long)) THEN
910
911 CALL mp2_eri_2c_integrate(eri_param, potential, para_env_sub, qs_env, &
912 basis_type_a="RI_AUX", basis_type_b="RI_AUX", &
913 hab=l_local_col, first_b=my_group_l_start, last_b=my_group_l_end, &
914 eri_method=eri_method)
915
916 ELSEIF (eri_method .EQ. do_eri_gpw .OR. &
917 (potential_type == do_potential_long .AND. qs_env%mp2_env%eri_method == do_eri_os) &
918 .OR. (potential_type == do_potential_id .AND. qs_env%mp2_env%eri_method == do_eri_mme)) THEN
919
920 CALL mp2_eri_2c_integrate_gpw(qs_env, para_env_sub, my_group_l_start, my_group_l_end, &
921 natom, potential, sab_orb_sub, l_local_col, kind_of)
922
923 ELSE
924 cpabort("unknown ERI method")
925 END IF
926
927 CALL timestop(handle2)
928
929 ! split the total number of proc in a subgroup of the size of ~1/10 of the
930 ! total num of proc
931 best_group_size = para_env%num_pe
932
933 strat_group_size = max(1, para_env%num_pe/10)
934
935 min_mem_for_qk = real(dimen_ri, kind=dp)*dimen_ri*3.0_dp*8.0_dp/1024_dp/1024_dp
936
937 group_size = strat_group_size - 1
938 DO iproc = strat_group_size, para_env%num_pe
939 group_size = group_size + 1
940 ! check that group_size is a multiple of sub_group_size and a divisor of
941 ! the total num of proc
942 IF (mod(para_env%num_pe, group_size) /= 0 .OR. mod(group_size, para_env_sub%num_pe) /= 0) cycle
943
944 ! check for memory
945 IF (real(group_size, kind=dp)*mp2_memory < min_mem_for_qk) cycle
946
947 best_group_size = group_size
948 EXIT
949 END DO
950
951 IF (my_do_im_time) THEN
952 ! para_env_L is the para_env for im. time to avoid bug
953 best_group_size = para_env%num_pe
954 END IF
955
956 ! create the L group
957 color_l = para_env%mepos/best_group_size
958 ALLOCATE (para_env_l)
959 CALL para_env_l%from_split(para_env, color_l)
960
961 ! create the blacs_L
962 NULLIFY (blacs_env_l)
963 CALL cp_blacs_env_create(blacs_env=blacs_env_l, para_env=para_env_l)
964
965 ! create the full matrix L defined in the L group
966 CALL create_matrix_l(fm_matrix_l, blacs_env_l, dimen_ri, para_env_l, "fm_matrix_L", fm_matrix_l_extern)
967
968 IF (my_do_im_time .AND. para_env%num_pe > 1) THEN
969
970 CALL fill_fm_l_from_l_loc_non_blocking(fm_matrix_l, l_local_col, para_env, &
971 my_group_l_start, my_group_l_end, &
972 dimen_ri)
973
974 ELSE
975 block
976 TYPE(mp_comm_type) :: comm_exchange
977
978 CALL comm_exchange%from_split(para_env_l, para_env_sub%mepos)
979
980 CALL create_group_dist(gd_sub_array, my_group_l_start, &
981 my_group_l_end, my_group_l_size, comm_exchange)
982
983 CALL cp_fm_get_info(matrix=fm_matrix_l, &
984 nrow_local=nrow_local, &
985 ncol_local=ncol_local, &
986 row_indices=row_indices, &
987 col_indices=col_indices)
988
989 DO jjb = 1, ncol_local
990 j_global = col_indices(jjb)
991 IF (j_global >= my_group_l_start .AND. j_global <= my_group_l_end) THEN
992 DO iib = 1, nrow_local
993 i_global = row_indices(iib)
994 fm_matrix_l%local_data(iib, jjb) = l_local_col(i_global, j_global - my_group_l_start + 1)
995 END DO
996 END IF
997 END DO
998
999 proc_send_static = modulo(comm_exchange%mepos + 1, comm_exchange%num_pe)
1000 proc_receive_static = modulo(comm_exchange%mepos - 1, comm_exchange%num_pe)
1001
1002 DO proc_shift = 1, comm_exchange%num_pe - 1
1003 proc_receive = modulo(comm_exchange%mepos - proc_shift, comm_exchange%num_pe)
1004
1005 CALL get_group_dist(gd_sub_array, proc_receive, rec_l_start, rec_l_end, rec_l_size)
1006
1007 ALLOCATE (l_external_col(dimen_ri, rec_l_size))
1008 l_external_col = 0.0_dp
1009
1010 CALL comm_exchange%sendrecv(l_local_col, proc_send_static, l_external_col, proc_receive_static)
1011
1012 DO jjb = 1, ncol_local
1013 j_global = col_indices(jjb)
1014 IF (j_global >= rec_l_start .AND. j_global <= rec_l_end) THEN
1015 DO iib = 1, nrow_local
1016 i_global = row_indices(iib)
1017 fm_matrix_l%local_data(iib, jjb) = l_external_col(i_global, j_global - rec_l_start + 1)
1018 END DO
1019 END IF
1020 END DO
1021
1022 CALL move_alloc(l_external_col, l_local_col)
1023 END DO
1024
1025 CALL release_group_dist(gd_sub_array)
1026 CALL comm_exchange%free()
1027 END block
1028 END IF
1029
1030 DEALLOCATE (l_local_col)
1031
1032 ! create the new group for the sum of the local data over all processes
1033 block
1034 TYPE(mp_comm_type) :: comm_exchange
1035 comm_exchange = fm_matrix_l%matrix_struct%context%interconnect(para_env)
1036 CALL comm_exchange%sum(fm_matrix_l%local_data)
1037 CALL comm_exchange%free()
1038 END block
1039
1040 cond_num = 1.0_dp
1041 num_small_eigen = 0
1042 IF (calc_pq_cond_num) THEN
1043 ! calculate the condition number of the (P|Q) matrix
1044 ! create a copy of the matrix
1045
1046 CALL create_matrix_l(fm_matrix_l_diag, blacs_env_l, dimen_ri, para_env_l, "fm_matrix_L_diag", fm_matrix_l_extern)
1047
1048 CALL cp_fm_to_fm(source=fm_matrix_l, destination=fm_matrix_l_diag)
1049
1050 ALLOCATE (egen_l(dimen_ri))
1051
1052 egen_l = 0.0_dp
1053 CALL cp_fm_syevx(matrix=fm_matrix_l_diag, eigenvalues=egen_l)
1054
1055 num_small_eigen = 0
1056 DO iib = 1, dimen_ri
1057 IF (abs(egen_l(iib)) < 0.001_dp) num_small_eigen = num_small_eigen + 1
1058 END DO
1059
1060 cond_num = maxval(abs(egen_l))/minval(abs(egen_l))
1061
1062 CALL cp_fm_release(fm_matrix_l_diag)
1063
1064 DEALLOCATE (egen_l)
1065 END IF
1066
1067 ! release blacs_env
1068 CALL cp_blacs_env_release(blacs_env_l)
1069
1070 CALL timestop(handle)
1071
1072 END SUBROUTINE compute_2c_integrals
1073
1074! **************************************************************************************************
1075!> \brief ...
1076!> \param matrix ...
1077!> \param num_small_evals ...
1078!> \param cond_num ...
1079!> \param eps_svd ...
1080!> \param do_inversion ...
1081!> \param para_env ...
1082! **************************************************************************************************
1083 SUBROUTINE matrix_root_with_svd(matrix, num_small_evals, cond_num, eps_svd, do_inversion, para_env)
1084 TYPE(cp_fm_type), INTENT(INOUT) :: matrix
1085 INTEGER, INTENT(OUT) :: num_small_evals
1086 REAL(kind=dp), INTENT(OUT) :: cond_num
1087 REAL(kind=dp), INTENT(IN) :: eps_svd
1088 LOGICAL, INTENT(IN) :: do_inversion
1089 TYPE(mp_para_env_type), INTENT(IN) :: para_env
1090
1091 CHARACTER(LEN=*), PARAMETER :: routinen = 'matrix_root_with_svd'
1092
1093 INTEGER :: group_size_l, handle, ii, needed_evals, &
1094 nrow, pos_max(1)
1095 INTEGER, ALLOCATABLE, DIMENSION(:) :: num_eval
1096 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: evals
1097 TYPE(cp_fm_type) :: evecs
1098 TYPE(mp_comm_type) :: comm_exchange
1099
1100 CALL timeset(routinen, handle)
1101
1102 ! Create arrays carrying eigenvalues and eigenvectors later
1103 CALL cp_fm_get_info(matrix=matrix, nrow_global=nrow)
1104
1105 ALLOCATE (evals(nrow))
1106 evals = 0
1107
1108 CALL cp_fm_create(evecs, matrix%matrix_struct)
1109
1110 ! Perform the EVD (=SVD of a positive semidefinite matrix)
1111 CALL choose_eigv_solver(matrix, evecs, evals)
1112
1113 ! Determine the number of neglectable eigenvalues assuming that the eigenvalues are in ascending order
1114 num_small_evals = 0
1115 DO ii = 1, nrow
1116 IF (evals(ii) > eps_svd) THEN
1117 num_small_evals = ii - 1
1118 EXIT
1119 END IF
1120 END DO
1121 needed_evals = nrow - num_small_evals
1122
1123 ! Get the condition number w.r.t. considered eigenvalues
1124 cond_num = evals(nrow)/evals(num_small_evals + 1)
1125
1126 ! Determine the eigenvalues of the request matrix root or its inverse
1127 evals(1:num_small_evals) = 0.0_dp
1128 IF (do_inversion) THEN
1129 evals(num_small_evals + 1:nrow) = 1.0_dp/sqrt(evals(num_small_evals + 1:nrow))
1130 ELSE
1131 evals(num_small_evals + 1:nrow) = sqrt(evals(num_small_evals + 1:nrow))
1132 END IF
1133
1134 CALL cp_fm_column_scale(evecs, evals)
1135
1136 ! As it turns out, the results in the subgroups differ.
1137 ! Thus, we have to equilibrate the results.
1138 ! Step 1: Get a communicator connecting processes with same id within subgroups
1139 ! use that group_size_L is divisible by the total number of processes (see above)
1140 group_size_l = para_env%num_pe/matrix%matrix_struct%para_env%num_pe
1141 comm_exchange = matrix%matrix_struct%context%interconnect(para_env)
1142
1143 ALLOCATE (num_eval(0:group_size_l - 1))
1144 CALL comm_exchange%allgather(num_small_evals, num_eval)
1145
1146 num_small_evals = minval(num_eval)
1147
1148 IF (num_small_evals /= maxval(num_eval)) THEN
1149 ! Step 2: Get position of maximum value
1150 pos_max = maxloc(num_eval)
1151 num_small_evals = num_eval(pos_max(1))
1152 needed_evals = nrow - num_small_evals
1153
1154 ! Step 3: Broadcast your local data to all other processes
1155 CALL comm_exchange%bcast(evecs%local_data, pos_max(1))
1156 CALL comm_exchange%bcast(cond_num, pos_max(1))
1157 END IF
1158
1159 DEALLOCATE (num_eval)
1160
1161 CALL comm_exchange%free()
1162
1163 CALL reset_size_matrix(matrix, needed_evals, matrix%matrix_struct)
1164
1165 ! Copy the needed eigenvectors
1166 CALL cp_fm_to_fm(evecs, matrix, needed_evals, num_small_evals + 1)
1167
1168 CALL cp_fm_release(evecs)
1169
1170 CALL timestop(handle)
1171
1172 END SUBROUTINE matrix_root_with_svd
1173
1174! **************************************************************************************************
1175!> \brief ...
1176!> \param matrix ...
1177!> \param new_size ...
1178!> \param fm_struct_template ...
1179! **************************************************************************************************
1180 SUBROUTINE reset_size_matrix(matrix, new_size, fm_struct_template)
1181 TYPE(cp_fm_type), INTENT(INOUT) :: matrix
1182 INTEGER, INTENT(IN) :: new_size
1183 TYPE(cp_fm_struct_type), POINTER :: fm_struct_template
1184
1185 CHARACTER(LEN=*), PARAMETER :: routinen = 'reset_size_matrix'
1186
1187 INTEGER :: handle
1188 TYPE(cp_fm_struct_type), POINTER :: fm_struct
1189
1190 CALL timeset(routinen, handle)
1191
1192 ! Choose the block sizes as large as in the template for the later steps
1193 NULLIFY (fm_struct)
1194 CALL cp_fm_struct_create(fm_struct, ncol_global=new_size, template_fmstruct=fm_struct_template, force_block=.true.)
1195
1196 CALL cp_fm_release(matrix)
1197
1198 CALL cp_fm_create(matrix, fm_struct)
1199 CALL cp_fm_set_all(matrix, 0.0_dp)
1200
1201 CALL cp_fm_struct_release(fm_struct)
1202
1203 CALL timestop(handle)
1204
1205 END SUBROUTINE reset_size_matrix
1206
1207! **************************************************************************************************
1208!> \brief ...
1209!> \param fm_matrix_L ...
1210!> \param L_local_col ...
1211!> \param para_env ...
1212!> \param my_group_L_start ...
1213!> \param my_group_L_end ...
1214!> \param dimen_RI ...
1215! **************************************************************************************************
1216 SUBROUTINE fill_fm_l_from_l_loc_non_blocking(fm_matrix_L, L_local_col, para_env, my_group_L_start, &
1217 my_group_L_end, dimen_RI)
1218 TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_l
1219 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
1220 INTENT(IN) :: l_local_col
1221 TYPE(mp_para_env_type), INTENT(IN) :: para_env
1222 INTEGER, INTENT(IN) :: my_group_l_start, my_group_l_end, &
1223 dimen_ri
1224
1225 CHARACTER(LEN=*), PARAMETER :: routinen = 'fill_fm_L_from_L_loc_non_blocking'
1226
1227 INTEGER :: dummy_proc, handle, handle2, i_entry_rec, i_row, i_row_global, iproc, j_col, &
1228 j_col_global, lll, mmm, ncol_local, nrow_local, proc_send, send_pcol, send_prow
1229 INTEGER, ALLOCATABLE, DIMENSION(:) :: entry_counter, num_entries_rec, &
1230 num_entries_send
1231 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1232 TYPE(integ_mat_buffer_type), ALLOCATABLE, &
1233 DIMENSION(:) :: buffer_rec, buffer_send
1234 TYPE(mp_request_type), DIMENSION(:, :), POINTER :: req_array
1235
1236 CALL timeset(routinen, handle)
1237
1238 CALL timeset(routinen//"_1", handle2)
1239
1240 ! get info for the dest
1241 CALL cp_fm_get_info(matrix=fm_matrix_l, &
1242 nrow_local=nrow_local, &
1243 ncol_local=ncol_local, &
1244 row_indices=row_indices, &
1245 col_indices=col_indices)
1246
1247 ALLOCATE (num_entries_rec(0:para_env%num_pe - 1))
1248 ALLOCATE (num_entries_send(0:para_env%num_pe - 1))
1249
1250 num_entries_rec(:) = 0
1251 num_entries_send(:) = 0
1252
1253 dummy_proc = 0
1254
1255 ! get the process, where the elements from L_local_col have to be sent
1256 DO lll = 1, dimen_ri
1257
1258 send_prow = fm_matrix_l%matrix_struct%g2p_row(lll)
1259
1260 DO mmm = my_group_l_start, my_group_l_end
1261
1262 send_pcol = fm_matrix_l%matrix_struct%g2p_col(mmm)
1263
1264 proc_send = fm_matrix_l%matrix_struct%context%blacs2mpi(send_prow, send_pcol)
1265
1266 num_entries_send(proc_send) = num_entries_send(proc_send) + 1
1267
1268 END DO
1269
1270 END DO
1271
1272 CALL timestop(handle2)
1273
1274 CALL timeset(routinen//"_2", handle2)
1275
1276 CALL para_env%alltoall(num_entries_send, num_entries_rec, 1)
1277
1278 CALL timestop(handle2)
1279
1280 CALL timeset(routinen//"_3", handle2)
1281
1282 ! allocate buffers to send the entries and the information of the entries
1283 ALLOCATE (buffer_rec(0:para_env%num_pe - 1))
1284 ALLOCATE (buffer_send(0:para_env%num_pe - 1))
1285
1286 ! allocate data message and corresponding indices
1287 DO iproc = 0, para_env%num_pe - 1
1288
1289 ALLOCATE (buffer_rec(iproc)%msg(num_entries_rec(iproc)))
1290 buffer_rec(iproc)%msg = 0.0_dp
1291
1292 END DO
1293
1294 CALL timestop(handle2)
1295
1296 CALL timeset(routinen//"_4", handle2)
1297
1298 DO iproc = 0, para_env%num_pe - 1
1299
1300 ALLOCATE (buffer_send(iproc)%msg(num_entries_send(iproc)))
1301 buffer_send(iproc)%msg = 0.0_dp
1302
1303 END DO
1304
1305 CALL timestop(handle2)
1306
1307 CALL timeset(routinen//"_5", handle2)
1308
1309 DO iproc = 0, para_env%num_pe - 1
1310
1311 ALLOCATE (buffer_rec(iproc)%indx(num_entries_rec(iproc), 2))
1312 buffer_rec(iproc)%indx = 0
1313
1314 END DO
1315
1316 CALL timestop(handle2)
1317
1318 CALL timeset(routinen//"_6", handle2)
1319
1320 DO iproc = 0, para_env%num_pe - 1
1321
1322 ALLOCATE (buffer_send(iproc)%indx(num_entries_send(iproc), 2))
1323 buffer_send(iproc)%indx = 0
1324
1325 END DO
1326
1327 CALL timestop(handle2)
1328
1329 CALL timeset(routinen//"_7", handle2)
1330
1331 ALLOCATE (entry_counter(0:para_env%num_pe - 1))
1332 entry_counter(:) = 0
1333
1334 ! get the process, where the elements from L_local_col have to be sent and
1335 ! write the data and the info to buffer_send
1336 DO lll = 1, dimen_ri
1337
1338 send_prow = fm_matrix_l%matrix_struct%g2p_row(lll)
1339
1340 DO mmm = my_group_l_start, my_group_l_end
1341
1342 send_pcol = fm_matrix_l%matrix_struct%g2p_col(mmm)
1343
1344 proc_send = fm_matrix_l%matrix_struct%context%blacs2mpi(send_prow, send_pcol)
1345
1346 entry_counter(proc_send) = entry_counter(proc_send) + 1
1347
1348 buffer_send(proc_send)%msg(entry_counter(proc_send)) = &
1349 l_local_col(lll, mmm - my_group_l_start + 1)
1350
1351 buffer_send(proc_send)%indx(entry_counter(proc_send), 1) = lll
1352 buffer_send(proc_send)%indx(entry_counter(proc_send), 2) = mmm
1353
1354 END DO
1355
1356 END DO
1357
1358 ALLOCATE (req_array(1:para_env%num_pe, 4))
1359
1360 CALL timestop(handle2)
1361
1362 CALL timeset(routinen//"_8", handle2)
1363
1364 ! communicate the buffer
1365 CALL communicate_buffer(para_env, num_entries_rec, num_entries_send, buffer_rec, &
1366 buffer_send, req_array)
1367
1368 fm_matrix_l%local_data = 0.0_dp
1369
1370 CALL timestop(handle2)
1371
1372 CALL timeset(routinen//"_9", handle2)
1373
1374 ! fill fm_matrix_L with the entries from buffer_rec
1375 DO iproc = 0, para_env%num_pe - 1
1376
1377 DO i_entry_rec = 1, num_entries_rec(iproc)
1378
1379 DO i_row = 1, nrow_local
1380
1381 i_row_global = row_indices(i_row)
1382
1383 DO j_col = 1, ncol_local
1384
1385 j_col_global = col_indices(j_col)
1386
1387 IF (i_row_global == buffer_rec(iproc)%indx(i_entry_rec, 1) .AND. &
1388 j_col_global == buffer_rec(iproc)%indx(i_entry_rec, 2)) THEN
1389
1390 fm_matrix_l%local_data(i_row, j_col) = buffer_rec(iproc)%msg(i_entry_rec)
1391
1392 END IF
1393
1394 END DO
1395
1396 END DO
1397
1398 END DO
1399
1400 END DO
1401
1402 CALL timestop(handle2)
1403
1404 CALL timeset(routinen//"_10", handle2)
1405
1406 DO iproc = 0, para_env%num_pe - 1
1407 DEALLOCATE (buffer_rec(iproc)%msg)
1408 DEALLOCATE (buffer_rec(iproc)%indx)
1409 DEALLOCATE (buffer_send(iproc)%msg)
1410 DEALLOCATE (buffer_send(iproc)%indx)
1411 END DO
1412
1413 DEALLOCATE (buffer_rec, buffer_send)
1414 DEALLOCATE (req_array)
1415 DEALLOCATE (entry_counter)
1416 DEALLOCATE (num_entries_rec, num_entries_send)
1417
1418 CALL timestop(handle2)
1419
1420 CALL timestop(handle)
1421
1422 END SUBROUTINE fill_fm_l_from_l_loc_non_blocking
1423
1424! **************************************************************************************************
1425!> \brief ...
1426!> \param fm_matrix_L ...
1427!> \param dimen_RI ...
1428!> \param do_inversion ...
1429! **************************************************************************************************
1430 SUBROUTINE cholesky_decomp(fm_matrix_L, dimen_RI, do_inversion)
1431
1432 TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_l
1433 INTEGER, INTENT(IN) :: dimen_ri
1434 LOGICAL, INTENT(IN) :: do_inversion
1435
1436 CHARACTER(LEN=*), PARAMETER :: routinen = 'cholesky_decomp'
1437
1438 INTEGER :: handle, i_global, iib, info_chol, &
1439 j_global, jjb, ncol_local, nrow_local
1440 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1441
1442 CALL timeset(routinen, handle)
1443
1444 ! do cholesky decomposition
1445 CALL cp_fm_cholesky_decompose(matrix=fm_matrix_l, n=dimen_ri, info_out=info_chol)
1446 cpassert(info_chol == 0)
1447
1448 IF (.NOT. do_inversion) THEN
1449 ! clean the lower part of the L^{-1} matrix (just to not have surprises afterwards)
1450 CALL cp_fm_get_info(matrix=fm_matrix_l, &
1451 nrow_local=nrow_local, &
1452 ncol_local=ncol_local, &
1453 row_indices=row_indices, &
1454 col_indices=col_indices)
1455 DO iib = 1, nrow_local
1456 i_global = row_indices(iib)
1457 DO jjb = 1, ncol_local
1458 j_global = col_indices(jjb)
1459 IF (j_global < i_global) fm_matrix_l%local_data(iib, jjb) = 0.0_dp
1460 END DO
1461 END DO
1462
1463 END IF
1464
1465 CALL timestop(handle)
1466
1467 END SUBROUTINE cholesky_decomp
1468
1469! **************************************************************************************************
1470!> \brief ...
1471!> \param fm_matrix_Minv_L_kpoints ...
1472!> \param fm_matrix_L_kpoints ...
1473!> \param dimen_RI ...
1474!> \param kpoints ...
1475!> \param eps_eigval_S ...
1476! **************************************************************************************************
1477 SUBROUTINE inversion_of_m_and_mult_with_chol_dec_of_v(fm_matrix_Minv_L_kpoints, fm_matrix_L_kpoints, &
1478 dimen_RI, kpoints, eps_eigval_S)
1479
1480 TYPE(cp_fm_type), DIMENSION(:, :), INTENT(IN) :: fm_matrix_minv_l_kpoints, &
1481 fm_matrix_l_kpoints
1482 INTEGER, INTENT(IN) :: dimen_ri
1483 TYPE(kpoint_type), POINTER :: kpoints
1484 REAL(kind=dp), INTENT(IN) :: eps_eigval_s
1485
1486 CHARACTER(LEN=*), PARAMETER :: routinen = 'inversion_of_M_and_mult_with_chol_dec_of_V'
1487 COMPLEX(KIND=dp), PARAMETER :: cone = cmplx(1.0_dp, 0.0_dp, kind=dp), &
1488 czero = cmplx(0.0_dp, 0.0_dp, kind=dp), ione = cmplx(0.0_dp, 1.0_dp, kind=dp)
1489
1490 INTEGER :: handle, ikp, nkp
1491 TYPE(cp_cfm_type) :: cfm_matrix_k_tmp, cfm_matrix_m_tmp, &
1492 cfm_matrix_v_tmp, cfm_matrix_vtrunc_tmp
1493 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
1494
1495 CALL timeset(routinen, handle)
1496
1497 CALL cp_fm_get_info(fm_matrix_minv_l_kpoints(1, 1), matrix_struct=matrix_struct)
1498
1499 CALL cp_cfm_create(cfm_matrix_m_tmp, matrix_struct)
1500 CALL cp_cfm_create(cfm_matrix_v_tmp, matrix_struct)
1501 CALL cp_cfm_create(cfm_matrix_k_tmp, matrix_struct)
1502 CALL cp_cfm_create(cfm_matrix_vtrunc_tmp, matrix_struct)
1503
1504 CALL get_kpoint_info(kpoints, nkp=nkp)
1505
1506 DO ikp = 1, nkp
1507
1508 CALL cp_cfm_scale_and_add_fm(czero, cfm_matrix_m_tmp, cone, fm_matrix_minv_l_kpoints(ikp, 1))
1509 CALL cp_cfm_scale_and_add_fm(cone, cfm_matrix_m_tmp, ione, fm_matrix_minv_l_kpoints(ikp, 2))
1510
1511 CALL cp_cfm_scale_and_add_fm(czero, cfm_matrix_v_tmp, cone, fm_matrix_l_kpoints(ikp, 1))
1512 CALL cp_cfm_scale_and_add_fm(cone, cfm_matrix_v_tmp, ione, fm_matrix_l_kpoints(ikp, 2))
1513
1514 CALL cp_cfm_power(cfm_matrix_m_tmp, threshold=eps_eigval_s, exponent=-1.0_dp)
1515
1516 CALL cp_cfm_power(cfm_matrix_v_tmp, threshold=0.0_dp, exponent=0.5_dp)
1517
1518 ! save L(k) = SQRT(V(k))
1519 CALL cp_cfm_to_fm(cfm_matrix_v_tmp, fm_matrix_l_kpoints(ikp, 1), fm_matrix_l_kpoints(ikp, 2))
1520
1521 ! get K = M^(-1)*L, where L is the Cholesky decomposition of V = L^T*L
1522 CALL parallel_gemm("N", "C", dimen_ri, dimen_ri, dimen_ri, cone, cfm_matrix_m_tmp, cfm_matrix_v_tmp, &
1523 czero, cfm_matrix_k_tmp)
1524
1525 ! move
1526 CALL cp_cfm_to_fm(cfm_matrix_k_tmp, fm_matrix_minv_l_kpoints(ikp, 1), fm_matrix_minv_l_kpoints(ikp, 2))
1527
1528 END DO
1529
1530 CALL cp_cfm_release(cfm_matrix_m_tmp)
1531 CALL cp_cfm_release(cfm_matrix_v_tmp)
1532 CALL cp_cfm_release(cfm_matrix_k_tmp)
1533 CALL cp_cfm_release(cfm_matrix_vtrunc_tmp)
1534
1535 CALL timestop(handle)
1536
1538
1539! **************************************************************************************************
1540!> \brief ...
1541!> \param fm_matrix_Minv_Vtrunc_Minv ...
1542!> \param fm_matrix_Minv ...
1543!> \param qs_env ...
1544! **************************************************************************************************
1545 SUBROUTINE gamma_only_inversion_of_m_and_mult_with_chol_dec_of_vtrunc(fm_matrix_Minv_Vtrunc_Minv, &
1546 fm_matrix_Minv, qs_env)
1547
1548 TYPE(cp_fm_type), DIMENSION(:, :) :: fm_matrix_minv_vtrunc_minv, &
1549 fm_matrix_minv
1550 TYPE(qs_environment_type), POINTER :: qs_env
1551
1552 CHARACTER(LEN=*), PARAMETER :: &
1553 routinen = 'Gamma_only_inversion_of_M_and_mult_with_chol_dec_of_Vtrunc'
1554
1555 INTEGER :: dimen_ri, handle, ndep
1556 REAL(kind=dp) :: eps_eigval_s_gamma
1557 TYPE(cp_fm_type) :: fm_matrix_ri_metric_inv_work, fm_work
1558
1559 CALL timeset(routinen, handle)
1560
1561 CALL cp_fm_create(fm_work, fm_matrix_minv(1, 1)%matrix_struct)
1562 CALL cp_fm_set_all(fm_work, 0.0_dp)
1563
1564 CALL cp_fm_create(fm_matrix_ri_metric_inv_work, fm_matrix_minv(1, 1)%matrix_struct)
1565 CALL cp_fm_set_all(fm_matrix_ri_metric_inv_work, 0.0_dp)
1566
1567 CALL cp_fm_get_info(matrix=fm_matrix_minv(1, 1), nrow_global=dimen_ri)
1568
1569 eps_eigval_s_gamma = qs_env%mp2_env%ri_rpa_im_time%eps_eigval_S_Gamma
1570
1571 IF (eps_eigval_s_gamma > 1.0e-18) THEN
1572
1573 ! remove small eigenvalues
1574 CALL cp_fm_power(fm_matrix_minv(1, 1), fm_matrix_ri_metric_inv_work, -0.5_dp, &
1575 eps_eigval_s_gamma, ndep)
1576
1577 ELSE
1578
1579 CALL cholesky_decomp(fm_matrix_minv(1, 1), dimen_ri, do_inversion=.true.)
1580
1581 CALL invert_mat(fm_matrix_minv(1, 1))
1582
1583 END IF
1584
1585 CALL parallel_gemm('N', 'T', dimen_ri, dimen_ri, dimen_ri, 1.0_dp, fm_matrix_minv(1, 1), &
1586 fm_matrix_minv(1, 1), 0.0_dp, fm_matrix_ri_metric_inv_work)
1587
1588 CALL cp_fm_to_fm(fm_matrix_ri_metric_inv_work, fm_matrix_minv(1, 1))
1589
1590 CALL parallel_gemm('N', 'N', dimen_ri, dimen_ri, dimen_ri, 1.0_dp, fm_matrix_ri_metric_inv_work, &
1591 fm_matrix_minv_vtrunc_minv(1, 1), 0.0_dp, fm_work)
1592
1593 CALL parallel_gemm('N', 'N', dimen_ri, dimen_ri, dimen_ri, 1.0_dp, fm_work, &
1594 fm_matrix_ri_metric_inv_work, 0.0_dp, fm_matrix_minv_vtrunc_minv(1, 1))
1595
1596 CALL cp_fm_release(fm_work)
1597 CALL cp_fm_release(fm_matrix_ri_metric_inv_work)
1598
1599 CALL timestop(handle)
1600
1601 END SUBROUTINE gamma_only_inversion_of_m_and_mult_with_chol_dec_of_vtrunc
1602
1603! **************************************************************************************************
1604!> \brief ...
1605!> \param qs_env ...
1606!> \param trunc_coulomb ...
1607!> \param rel_cutoff_trunc_coulomb_ri_x ...
1608!> \param cell_grid ...
1609!> \param do_BvK_cell ...
1610! **************************************************************************************************
1611 SUBROUTINE trunc_coulomb_for_exchange(qs_env, trunc_coulomb, rel_cutoff_trunc_coulomb_ri_x, &
1612 cell_grid, do_BvK_cell)
1613 TYPE(qs_environment_type), POINTER :: qs_env
1614 TYPE(libint_potential_type), OPTIONAL :: trunc_coulomb
1615 REAL(kind=dp), OPTIONAL :: rel_cutoff_trunc_coulomb_ri_x
1616 INTEGER, DIMENSION(3), OPTIONAL :: cell_grid
1617 LOGICAL, OPTIONAL :: do_bvk_cell
1618
1619 CHARACTER(LEN=*), PARAMETER :: routinen = 'trunc_coulomb_for_exchange'
1620
1621 INTEGER :: handle, i_dim
1622 INTEGER, DIMENSION(3) :: periodic
1623 LOGICAL :: my_do_bvk_cell
1624 REAL(kind=dp) :: kp_fac, kp_fac_idim, my_rel_cutoff_trunc_coulomb_ri_x, &
1625 shortest_dist_cell_planes
1626 TYPE(cell_type), POINTER :: cell
1627 TYPE(kpoint_type), POINTER :: kpoints_scf
1628
1629 CALL timeset(routinen, handle)
1630
1631 NULLIFY (cell)
1632 CALL get_qs_env(qs_env, cell=cell, kpoints=kpoints_scf)
1633 CALL get_cell(cell=cell, periodic=periodic)
1634
1635 my_do_bvk_cell = .false.
1636 IF (PRESENT(do_bvk_cell)) my_do_bvk_cell = do_bvk_cell
1637 IF (my_do_bvk_cell) THEN
1638 kp_fac = 1.0e10_dp
1639 DO i_dim = 1, 3
1640 ! look for smallest k-point mesh in periodic direction
1641 IF (periodic(i_dim) == 1) THEN
1642 IF (PRESENT(cell_grid)) THEN
1643 kp_fac_idim = real(cell_grid(i_dim), kind=dp)
1644 ELSE
1645 kp_fac_idim = real(kpoints_scf%nkp_grid(i_dim), kind=dp)
1646 END IF
1647 IF (kp_fac > kp_fac_idim) kp_fac = kp_fac_idim
1648 END IF
1649 END DO
1650 ELSE
1651 kp_fac = 1.0_dp
1652 END IF
1653
1654 shortest_dist_cell_planes = 1.0e4_dp
1655 IF (periodic(1) == 1) THEN
1656 IF (shortest_dist_cell_planes > plane_distance(1, 0, 0, cell)) THEN
1657 shortest_dist_cell_planes = plane_distance(1, 0, 0, cell)
1658 END IF
1659 END IF
1660 IF (periodic(2) == 1) THEN
1661 IF (shortest_dist_cell_planes > plane_distance(0, 1, 0, cell)) THEN
1662 shortest_dist_cell_planes = plane_distance(0, 1, 0, cell)
1663 END IF
1664 END IF
1665 IF (periodic(3) == 1) THEN
1666 IF (shortest_dist_cell_planes > plane_distance(0, 0, 1, cell)) THEN
1667 shortest_dist_cell_planes = plane_distance(0, 0, 1, cell)
1668 END IF
1669 END IF
1670
1671 IF (PRESENT(rel_cutoff_trunc_coulomb_ri_x)) THEN
1672 my_rel_cutoff_trunc_coulomb_ri_x = rel_cutoff_trunc_coulomb_ri_x
1673 ELSE
1674 my_rel_cutoff_trunc_coulomb_ri_x = qs_env%mp2_env%ri_rpa_im_time%rel_cutoff_trunc_coulomb_ri_x
1675 END IF
1676
1677 IF (PRESENT(trunc_coulomb)) THEN
1678 trunc_coulomb%potential_type = do_potential_truncated
1679 trunc_coulomb%cutoff_radius = shortest_dist_cell_planes* &
1680 my_rel_cutoff_trunc_coulomb_ri_x* &
1681 kp_fac
1682 trunc_coulomb%filename = "t_c_g.dat"
1683 ! dummy
1684 trunc_coulomb%omega = 0.0_dp
1685 END IF
1686
1687 CALL timestop(handle)
1688
1689 END SUBROUTINE trunc_coulomb_for_exchange
1690
1691! **************************************************************************************************
1692!> \brief ...
1693!> \param fm_matrix_L ...
1694! **************************************************************************************************
1695 SUBROUTINE invert_mat(fm_matrix_L)
1696
1697 TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_l
1698
1699 CHARACTER(LEN=*), PARAMETER :: routinen = 'invert_mat'
1700
1701 INTEGER :: handle, i_global, iib, j_global, jjb, &
1702 ncol_local, nrow_local
1703 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1704
1705 CALL timeset(routinen, handle)
1706
1707 CALL cp_fm_triangular_invert(matrix_a=fm_matrix_l, uplo_tr='U')
1708
1709 ! clear the lower part of the L^{-1} matrix (just to have no surprises afterwards)
1710 CALL cp_fm_get_info(matrix=fm_matrix_l, &
1711 nrow_local=nrow_local, &
1712 ncol_local=ncol_local, &
1713 row_indices=row_indices, &
1714 col_indices=col_indices)
1715 ! assume upper triangular format
1716 DO jjb = 1, ncol_local
1717 j_global = col_indices(jjb)
1718 DO iib = 1, nrow_local
1719 i_global = row_indices(iib)
1720 IF (j_global < i_global) fm_matrix_l%local_data(iib, jjb) = 0.0_dp
1721 END DO
1722 END DO
1723
1724 CALL timestop(handle)
1725
1726 END SUBROUTINE invert_mat
1727
1728! **************************************************************************************************
1729!> \brief ...
1730!> \param fm_matrix_L ...
1731!> \param blacs_env_L ...
1732!> \param dimen_RI ...
1733!> \param para_env_L ...
1734!> \param name ...
1735!> \param fm_matrix_L_extern ...
1736! **************************************************************************************************
1737 SUBROUTINE create_matrix_l(fm_matrix_L, blacs_env_L, dimen_RI, para_env_L, name, fm_matrix_L_extern)
1738 TYPE(cp_fm_type), INTENT(OUT) :: fm_matrix_l
1739 TYPE(cp_blacs_env_type), POINTER :: blacs_env_l
1740 INTEGER, INTENT(IN) :: dimen_ri
1741 TYPE(mp_para_env_type), POINTER :: para_env_l
1742 CHARACTER(LEN=*), INTENT(IN) :: name
1743 TYPE(cp_fm_type), INTENT(IN), OPTIONAL :: fm_matrix_l_extern
1744
1745 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_matrix_L'
1746
1747 INTEGER :: handle
1748 TYPE(cp_fm_struct_type), POINTER :: fm_struct
1749
1750 CALL timeset(routinen, handle)
1751
1752 ! create the full matrix L defined in the L group
1753 IF (PRESENT(fm_matrix_l_extern)) THEN
1754 CALL cp_fm_create(fm_matrix_l, fm_matrix_l_extern%matrix_struct, name=name)
1755 ELSE
1756 NULLIFY (fm_struct)
1757 CALL cp_fm_struct_create(fm_struct, context=blacs_env_l, nrow_global=dimen_ri, &
1758 ncol_global=dimen_ri, para_env=para_env_l)
1759
1760 CALL cp_fm_create(fm_matrix_l, fm_struct, name=name)
1761
1762 CALL cp_fm_struct_release(fm_struct)
1763 END IF
1764
1765 CALL cp_fm_set_all(matrix=fm_matrix_l, alpha=0.0_dp)
1766
1767 CALL timestop(handle)
1768
1769 END SUBROUTINE create_matrix_l
1770
1771! **************************************************************************************************
1772!> \brief ...
1773!> \param fm_matrix_L ...
1774!> \param my_group_L_start ...
1775!> \param my_group_L_end ...
1776!> \param my_group_L_size ...
1777!> \param my_Lrows ...
1778! **************************************************************************************************
1779 SUBROUTINE grep_lcols(fm_matrix_L, &
1780 my_group_L_start, my_group_L_end, my_group_L_size, my_Lrows)
1781 TYPE(cp_fm_type), INTENT(IN) :: fm_matrix_l
1782 INTEGER, INTENT(IN) :: my_group_l_start, my_group_l_end, &
1783 my_group_l_size
1784 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
1785 INTENT(OUT) :: my_lrows
1786
1787 CHARACTER(LEN=*), PARAMETER :: routinen = 'grep_Lcols'
1788
1789 INTEGER :: dimen_ri, handle, handle2, i_global, iib, j_global, jjb, max_row_col_local, &
1790 ncol_local, ncol_rec, nrow_local, nrow_rec, proc_receive_static, proc_send_static, &
1791 proc_shift
1792 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: local_col_row_info, rec_col_row_info
1793 INTEGER, DIMENSION(:), POINTER :: col_indices, col_indices_rec, &
1794 row_indices, row_indices_rec
1795 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: local_l, rec_l
1796 REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :), &
1797 POINTER :: local_l_internal
1798 TYPE(mp_para_env_type), POINTER :: para_env
1799
1800 CALL timeset(routinen, handle)
1801
1802 CALL cp_fm_get_info(matrix=fm_matrix_l, &
1803 nrow_local=nrow_local, &
1804 ncol_local=ncol_local, &
1805 row_indices=row_indices, &
1806 col_indices=col_indices, &
1807 nrow_global=dimen_ri, &
1808 local_data=local_l_internal, &
1809 para_env=para_env)
1810
1811 ALLOCATE (my_lrows(dimen_ri, my_group_l_size))
1812 my_lrows = 0.0_dp
1813
1814 ALLOCATE (local_l(nrow_local, ncol_local))
1815 local_l(:, :) = local_l_internal(1:nrow_local, 1:ncol_local)
1816
1817 max_row_col_local = max(nrow_local, ncol_local)
1818 CALL para_env%max(max_row_col_local)
1819
1820 ALLOCATE (local_col_row_info(0:max_row_col_local, 2))
1821 local_col_row_info = 0
1822 ! 0,1 nrows
1823 local_col_row_info(0, 1) = nrow_local
1824 local_col_row_info(1:nrow_local, 1) = row_indices(1:nrow_local)
1825 ! 0,2 ncols
1826 local_col_row_info(0, 2) = ncol_local
1827 local_col_row_info(1:ncol_local, 2) = col_indices(1:ncol_local)
1828
1829 ALLOCATE (rec_col_row_info(0:max_row_col_local, 2))
1830
1831 ! accumulate data on my_Lrows starting from myself
1832 DO jjb = 1, ncol_local
1833 j_global = col_indices(jjb)
1834 IF (j_global >= my_group_l_start .AND. j_global <= my_group_l_end) THEN
1835 DO iib = 1, nrow_local
1836 i_global = row_indices(iib)
1837 my_lrows(i_global, j_global - my_group_l_start + 1) = local_l(iib, jjb)
1838 END DO
1839 END IF
1840 END DO
1841
1842 proc_send_static = modulo(para_env%mepos + 1, para_env%num_pe)
1843 proc_receive_static = modulo(para_env%mepos - 1, para_env%num_pe)
1844
1845 CALL timeset(routinen//"_comm", handle2)
1846
1847 DO proc_shift = 1, para_env%num_pe - 1
1848 ! first exchange information on the local data
1849 rec_col_row_info = 0
1850 CALL para_env%sendrecv(local_col_row_info, proc_send_static, rec_col_row_info, proc_receive_static)
1851 nrow_rec = rec_col_row_info(0, 1)
1852 ncol_rec = rec_col_row_info(0, 2)
1853
1854 ALLOCATE (row_indices_rec(nrow_rec))
1855 row_indices_rec = rec_col_row_info(1:nrow_rec, 1)
1856
1857 ALLOCATE (col_indices_rec(ncol_rec))
1858 col_indices_rec = rec_col_row_info(1:ncol_rec, 2)
1859
1860 ALLOCATE (rec_l(nrow_rec, ncol_rec))
1861 rec_l = 0.0_dp
1862
1863 ! then send and receive the real data
1864 CALL para_env%sendrecv(local_l, proc_send_static, rec_l, proc_receive_static)
1865
1866 ! accumulate the received data on my_Lrows
1867 DO jjb = 1, ncol_rec
1868 j_global = col_indices_rec(jjb)
1869 IF (j_global >= my_group_l_start .AND. j_global <= my_group_l_end) THEN
1870 DO iib = 1, nrow_rec
1871 i_global = row_indices_rec(iib)
1872 my_lrows(i_global, j_global - my_group_l_start + 1) = rec_l(iib, jjb)
1873 END DO
1874 END IF
1875 END DO
1876
1877 local_col_row_info(:, :) = rec_col_row_info
1878 CALL move_alloc(rec_l, local_l)
1879
1880 DEALLOCATE (col_indices_rec)
1881 DEALLOCATE (row_indices_rec)
1882 END DO
1883 CALL timestop(handle2)
1884
1885 DEALLOCATE (local_col_row_info)
1886 DEALLOCATE (rec_col_row_info)
1887 DEALLOCATE (local_l)
1888
1889 CALL timestop(handle)
1890
1891 END SUBROUTINE grep_lcols
1892
1893END MODULE mp2_ri_2c
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.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
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
real(kind=dp) function, public plane_distance(h, k, l, cell)
Calculate the distance between two lattice planes as defined by a triple of Miller indices (hkl).
Definition cell_types.F:252
constants for the different operators of the 2c-integrals
integer, parameter, public operator_coulomb
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add_fm(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b). where b is a real matrix (adapted from cp_cf...
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_distribution_release(dist)
...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_dist2d_to_dist(dist2d, dist)
Creates a DBCSR distribution from a distribution_2d.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
Interface to Minimax-Ewald method for periodic ERI's to be used in CP2K.
basic linear algebra operations for full matrices
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
subroutine, public cp_fm_triangular_invert(matrix_a, uplo_tr)
inverts a triangular matrix
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_decompose(matrix, n, info_out)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
Definition cp_fm_diag.F:17
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
Definition cp_fm_diag.F:229
subroutine, public cp_fm_syevx(matrix, eigenvectors, eigenvalues, neig, work_syevx)
compute eigenvalues and optionally eigenvectors of a real symmetric matrix using scalapack....
Definition cp_fm_diag.F:678
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_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
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_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
Types to describe group distributions.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_eri_os
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_long
integer, parameter, public do_eri_gpw
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Routines to compute the Coulomb integral V_(alpha beta)(k) for a k-point k using lattice summation in...
subroutine, public build_2c_coulomb_matrix_kp(matrix_v_kp, kpoints, basis_type, cell, particle_set, qs_kind_set, atomic_kind_set, size_lattice_sum, operator_type, ikp_start, ikp_end)
...
Routines needed for kpoint calculation.
subroutine, public rskp_transform(rmatrix, cmatrix, rsmat, ispin, xkp, cell_to_index, sab_nl, is_complex, rs_sign)
Transformation of real space matrices to a kpoint.
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.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym)
Retrieve information from a kpoint environment.
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.
subroutine, public mp_para_env_release(para_env)
releases the para object (to be called when you don't want anymore the shared copy of this object)
Routines to calculate 2c- and 3c-integrals for RI with GPW.
Definition mp2_eri_gpw.F:13
subroutine, public mp2_eri_2c_integrate_gpw(qs_env, para_env_sub, my_group_l_start, my_group_l_end, natom, potential_parameter, sab_orb_sub, l_local_col, kind_of)
Integrates the potential of an RI function.
Interface to direct methods for electron repulsion integrals for MP2.
Definition mp2_eri.F:12
subroutine, public mp2_eri_2c_integrate(param, potential_parameter, para_env, qs_env, basis_type_a, basis_type_b, hab, first_b, last_b, eri_method, pab, force_a, force_b, hdab, hadb, reflection_z_a, reflection_z_b, do_reflection_a, do_reflection_b)
high-level integration routine for 2c integrals over CP2K basis sets. Contiguous column-wise distribu...
Definition mp2_eri.F:115
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
subroutine, public trunc_coulomb_for_exchange(qs_env, trunc_coulomb, rel_cutoff_trunc_coulomb_ri_x, cell_grid, do_bvk_cell)
...
Definition mp2_ri_2c.F:1613
subroutine, public inversion_of_m_and_mult_with_chol_dec_of_v(fm_matrix_minv_l_kpoints, fm_matrix_l_kpoints, dimen_ri, kpoints, eps_eigval_s)
...
Definition mp2_ri_2c.F:1479
subroutine, public ri_2c_integral_mat(qs_env, fm_matrix_minv_l_kpoints, fm_matrix_l, dimen_ri, ri_metric, do_kpoints, kpoints, put_mat_ks_env, regularization_ri, ikp_ext, do_build_cell_index)
...
Definition mp2_ri_2c.F:561
Types needed for MP2 calculations.
Definition mp2_types.F:14
basic linear algebra operations for full matrixes
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.
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.
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(qs_control, qs_kind_set)
Initialize all the atomic kind radii for a given threshold value.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public set_ks_env(ks_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, complex_ks, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, kinetic, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_ks_im_kp, vppl, rho_core, rho_nlcc, rho_nlcc_g, vee, neighbor_list_id, kpoints, sab_orb, sab_all, sac_ae, sac_ppl, sac_lri, sap_ppnl, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_vdw, sab_scp, sab_almo, sab_kp, sab_kp_nosym, task_list, task_list_soft, subsys, dft_control, dbcsr_dist, distribution_2d, pw_env, para_env, blacs_env)
...
subroutine, public get_ks_env(ks_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, complex_ks, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, kinetic, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_ks_im_kp, rho, rho_xc, vppl, rho_core, rho_nlcc, rho_nlcc_g, vee, neighbor_list_id, sab_orb, sab_all, sac_ae, sac_ppl, sac_lri, sap_ppnl, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_vdw, sab_scp, sab_almo, sab_kp, sab_kp_nosym, task_list, task_list_soft, kpoints, do_kpoints, atomic_kind_set, qs_kind_set, cell, cell_ref, use_ref_cell, particle_set, energy, force, local_particles, local_molecules, molecule_kind_set, molecule_set, subsys, cp_subsys, virial, results, atprop, nkind, natom, dft_control, dbcsr_dist, distribution_2d, pw_env, para_env, blacs_env, nelectron_total, nelectron_spin)
...
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
Utility methods to build 3-center integral tensors of various types.
Definition qs_tensors.F:11
subroutine, public build_2c_integrals(t2c, filter_eps, qs_env, nl_2c, basis_i, basis_j, potential_parameter, do_kpoints, do_hfx_kpoints, ext_kpoints, regularization_ri)
...
subroutine, public build_2c_neighbor_lists(ij_list, basis_i, basis_j, potential_parameter, name, qs_env, sym_ij, molecular, dist_2d, pot_to_rad)
Build 2-center neighborlists adapted to different operators This mainly wraps build_neighbor_lists fo...
Definition qs_tensors.F:143
Auxiliary routines necessary to redistribute an fm_matrix from a given blacs_env to another.
subroutine, public communicate_buffer(para_env, num_entries_rec, num_entries_send, buffer_rec, buffer_send, req_array, do_indx, do_msg)
...
Routines treating GW and RPA calculations with kpoints.
subroutine, public cp_cfm_power(matrix, threshold, exponent, min_eigval)
...
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.
keeps the information about the structure of a full matrix
represent a full matrix
distributes pairs on a 2d grid of processors
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.