(git:97501a3)
Loading...
Searching...
No Matches
mp2_ri_grad.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 gradients of RI-GPW-MP2 energy using pw
10!> \par History
11!> 10.2013 created [Mauro Del Ben]
12! **************************************************************************************************
16 USE cell_types, ONLY: cell_type
19 USE cp_dbcsr_api, ONLY: &
21 dbcsr_release, dbcsr_set, dbcsr_transposed, dbcsr_type, dbcsr_type_no_symmetry, &
22 dbcsr_type_symmetric
29 USE cp_fm_types, ONLY: cp_fm_create,&
35 USE input_constants, ONLY: do_eri_gpw,&
40 USE kinds, ONLY: dp
47 USE mp2_eri, ONLY: mp2_eri_2c_integrate,&
51 USE mp2_eri_gpw, ONLY: cleanup_gpw,&
61 USE pw_env_types, ONLY: pw_env_type
64 USE pw_types, ONLY: pw_c1d_gs_type,&
75 USE util, ONLY: get_limit
76 USE virial_types, ONLY: virial_type
77#include "./base/base_uses.f90"
78
79 IMPLICIT NONE
80
81 PRIVATE
82
83 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mp2_ri_grad'
84
85 PUBLIC :: calc_ri_mp2_nonsep
86
87CONTAINS
88
89! **************************************************************************************************
90!> \brief Calculate the non-separable part of the gradients and update the
91!> Lagrangian
92!> \param qs_env ...
93!> \param mp2_env ...
94!> \param para_env ...
95!> \param para_env_sub ...
96!> \param cell ...
97!> \param particle_set ...
98!> \param atomic_kind_set ...
99!> \param qs_kind_set ...
100!> \param mo_coeff ...
101!> \param dimen_RI ...
102!> \param Eigenval ...
103!> \param my_group_L_start ...
104!> \param my_group_L_end ...
105!> \param my_group_L_size ...
106!> \param sab_orb_sub ...
107!> \param mat_munu ...
108!> \param blacs_env_sub ...
109!> \author Mauro Del Ben
110! **************************************************************************************************
111 SUBROUTINE calc_ri_mp2_nonsep(qs_env, mp2_env, para_env, para_env_sub, cell, particle_set, &
112 atomic_kind_set, qs_kind_set, mo_coeff, dimen_RI, Eigenval, &
113 my_group_L_start, my_group_L_end, my_group_L_size, sab_orb_sub, mat_munu, &
114 blacs_env_sub)
115 TYPE(qs_environment_type), POINTER :: qs_env
116 TYPE(mp2_type) :: mp2_env
117 TYPE(mp_para_env_type), POINTER :: para_env, para_env_sub
118 TYPE(cell_type), POINTER :: cell
119 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
120 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
121 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
122 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
123 INTEGER, INTENT(IN) :: dimen_ri
124 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: eigenval
125 INTEGER, INTENT(IN) :: my_group_l_start, my_group_l_end, &
126 my_group_l_size
127 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
128 POINTER :: sab_orb_sub
129 TYPE(dbcsr_p_type), INTENT(INOUT) :: mat_munu
130 TYPE(cp_blacs_env_type), POINTER :: blacs_env_sub
131
132 CHARACTER(LEN=*), PARAMETER :: routinen = 'calc_ri_mp2_nonsep'
133
134 INTEGER :: eri_method, handle, handle2, i, ikind, &
135 ispin, itmp(2), l_counter, lll, &
136 my_p_end, my_p_size, my_p_start, nao, &
137 nspins
138 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, homo, kind_of, &
139 natom_of_kind, virtual
140 LOGICAL :: alpha_beta, use_virial
141 REAL(kind=dp) :: cutoff_old, eps_filter, factor, &
142 factor_2c, relative_cutoff_old
143 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: e_cutoff_old
144 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: g_pq_local, g_pq_local_2
145 REAL(kind=dp), DIMENSION(3, 3) :: h_stress, pv_virial
146 REAL(kind=dp), DIMENSION(:, :), POINTER :: i_tmp2
147 TYPE(cp_eri_mme_param), POINTER :: eri_param
148 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
149 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: l1_mu_i, l2_nu_a
150 TYPE(dbcsr_p_type) :: matrix_p_munu
151 TYPE(dbcsr_p_type), ALLOCATABLE, DIMENSION(:) :: mo_coeff_o, mo_coeff_v
152 TYPE(dbcsr_p_type), ALLOCATABLE, DIMENSION(:, :) :: g_p_ia
153 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_munu_local, matrix_p_munu_local
154 TYPE(dbcsr_type) :: matrix_p_munu_nosym
155 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: lag_mu_i_1, lag_nu_a_2, matrix_p_inu
156 TYPE(dft_control_type), POINTER :: dft_control
157 TYPE(mp2_eri_force), ALLOCATABLE, DIMENSION(:) :: force_2c, force_2c_ri, force_3c_aux, &
158 force_3c_orb_mu, force_3c_orb_nu
159 TYPE(pw_c1d_gs_type) :: dvg(3), pot_g, rho_g, rho_g_copy
160 TYPE(pw_env_type), POINTER :: pw_env_sub
161 TYPE(pw_poisson_type), POINTER :: poisson_env
162 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
163 TYPE(pw_r3d_rs_type) :: psi_l, rho_r
164 TYPE(qs_force_type), DIMENSION(:), POINTER :: force, mp2_force
165 TYPE(qs_ks_env_type), POINTER :: ks_env
166 TYPE(task_list_type), POINTER :: task_list_sub
167 TYPE(virial_type), POINTER :: virial
168
169 CALL timeset(routinen, handle)
170
171 eri_method = mp2_env%eri_method
172 eri_param => mp2_env%eri_mme_param
173
174 ! Find out whether we have a closed or open shell
175 nspins = SIZE(eigenval, 2)
176 alpha_beta = (nspins == 2)
177
178 ALLOCATE (virtual(nspins), homo(nspins))
179 eps_filter = mp2_env%mp2_gpw%eps_filter
180 ALLOCATE (mo_coeff_o(nspins), mo_coeff_v(nspins), g_p_ia(nspins, my_group_l_size))
181 DO ispin = 1, nspins
182 mo_coeff_o(ispin)%matrix => mp2_env%ri_grad%mo_coeff_o(ispin)%matrix
183 mo_coeff_v(ispin)%matrix => mp2_env%ri_grad%mo_coeff_v(ispin)%matrix
184 CALL dbcsr_get_info(mo_coeff_o(ispin)%matrix, &
185 nfullrows_total=nao, &
186 nfullcols_total=homo(ispin))
187 CALL dbcsr_get_info(mo_coeff_v(ispin)%matrix, &
188 nfullrows_total=nao, &
189 nfullcols_total=virtual(ispin))
190 DO lll = 1, my_group_l_size
191 g_p_ia(ispin, lll)%matrix => mp2_env%ri_grad%G_P_ia(lll, ispin)%matrix
192 END DO
193 END DO
194 DEALLOCATE (mp2_env%ri_grad%G_P_ia)
195
196 itmp = get_limit(dimen_ri, para_env_sub%num_pe, para_env_sub%mepos)
197 my_p_start = itmp(1)
198 my_p_end = itmp(2)
199 my_p_size = itmp(2) - itmp(1) + 1
200
201 ALLOCATE (g_pq_local(dimen_ri, my_group_l_size))
202 g_pq_local = 0.0_dp
203 g_pq_local(my_p_start:my_p_end, :) = mp2_env%ri_grad%Gamma_PQ
204 DEALLOCATE (mp2_env%ri_grad%Gamma_PQ)
205 g_pq_local(my_p_start:my_p_end, :) = g_pq_local(my_p_start:my_p_end, :)/real(nspins, dp)
206 CALL para_env_sub%sum(g_pq_local)
207 IF (.NOT. compare_potential_types(mp2_env%ri_metric, mp2_env%potential_parameter)) THEN
208 ALLOCATE (g_pq_local_2(dimen_ri, my_group_l_size))
209 g_pq_local_2 = 0.0_dp
210 g_pq_local_2(my_p_start:my_p_end, :) = mp2_env%ri_grad%Gamma_PQ_2
211 DEALLOCATE (mp2_env%ri_grad%Gamma_PQ_2)
212 g_pq_local_2(my_p_start:my_p_end, :) = g_pq_local_2(my_p_start:my_p_end, :)/real(nspins, dp)
213 CALL para_env_sub%sum(g_pq_local_2)
214 END IF
215
216 ! create matrix holding the back transformation (G_P_inu)
217 ALLOCATE (matrix_p_inu(nspins))
218 DO ispin = 1, nspins
219 CALL dbcsr_create(matrix_p_inu(ispin), template=mo_coeff_o(ispin)%matrix)
220 END DO
221
222 ! non symmetric matrix
223 CALL dbcsr_create(matrix_p_munu_nosym, template=mat_munu%matrix, &
224 matrix_type=dbcsr_type_no_symmetry)
225
226 ! create Lagrangian matrices in mixed AO/MO formalism
227 ALLOCATE (lag_mu_i_1(nspins))
228 DO ispin = 1, nspins
229 CALL dbcsr_create(lag_mu_i_1(ispin), template=mo_coeff_o(ispin)%matrix)
230 CALL dbcsr_set(lag_mu_i_1(ispin), 0.0_dp)
231 END DO
232
233 ALLOCATE (lag_nu_a_2(nspins))
234 DO ispin = 1, nspins
235 CALL dbcsr_create(lag_nu_a_2(ispin), template=mo_coeff_v(ispin)%matrix)
236 CALL dbcsr_set(lag_nu_a_2(ispin), 0.0_dp)
237 END DO
238
239 ! get forces
240 NULLIFY (force, virial)
241 CALL get_qs_env(qs_env=qs_env, force=force, virial=virial)
242
243 ! check if we want to calculate the virial
244 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
245
246 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom_of_kind=natom_of_kind)
247 NULLIFY (mp2_force)
248 CALL allocate_qs_force(mp2_force, natom_of_kind)
249 DEALLOCATE (natom_of_kind)
250 CALL zero_qs_force(mp2_force)
251 mp2_env%ri_grad%mp2_force => mp2_force
252
253 factor_2c = -4.0_dp
254 IF (mp2_env%method == ri_rpa_method_gpw) THEN
255 factor_2c = -1.0_dp
256 IF (alpha_beta) factor_2c = -2.0_dp
257 END IF
258
259 ! prepare integral derivatives with mme method
260 IF (eri_method .EQ. do_eri_mme) THEN
261 ALLOCATE (matrix_p_munu_local(my_group_l_size))
262 ALLOCATE (mat_munu_local(my_group_l_size))
263 l_counter = 0
264 DO lll = my_group_l_start, my_group_l_end
265 l_counter = l_counter + 1
266 ALLOCATE (mat_munu_local(l_counter)%matrix)
267 CALL dbcsr_create(mat_munu_local(l_counter)%matrix, template=mat_munu%matrix, &
268 matrix_type=dbcsr_type_symmetric)
269 CALL dbcsr_copy(mat_munu_local(l_counter)%matrix, mat_munu%matrix)
270 CALL dbcsr_set(mat_munu_local(l_counter)%matrix, 0.0_dp)
271
272 CALL g_p_transform_mo_to_ao(matrix_p_munu_local(l_counter)%matrix, matrix_p_munu_nosym, mat_munu%matrix, &
273 g_p_ia(:, l_counter), matrix_p_inu, &
274 mo_coeff_v, mo_coeff_o, eps_filter)
275 END DO
276
277 ALLOCATE (i_tmp2(dimen_ri, my_group_l_size))
278 i_tmp2(:, :) = 0.0_dp
279 CALL mp2_eri_2c_integrate(eri_param, mp2_env%potential_parameter, para_env_sub, qs_env, &
280 basis_type_a="RI_AUX", basis_type_b="RI_AUX", &
281 hab=i_tmp2, first_b=my_group_l_start, last_b=my_group_l_end, &
282 eri_method=eri_method, pab=g_pq_local, force_a=force_2c)
283 IF (.NOT. compare_potential_types(mp2_env%potential_parameter, mp2_env%ri_metric)) THEN
284 i_tmp2(:, :) = 0.0_dp
285 CALL mp2_eri_2c_integrate(eri_param, mp2_env%ri_metric, para_env_sub, qs_env, &
286 basis_type_a="RI_AUX", basis_type_b="RI_AUX", &
287 hab=i_tmp2, first_b=my_group_l_start, last_b=my_group_l_end, &
288 eri_method=eri_method, pab=g_pq_local_2, force_a=force_2c_ri)
289 END IF
290 DEALLOCATE (i_tmp2)
291
292 CALL mp2_eri_3c_integrate(eri_param, mp2_env%ri_metric, para_env_sub, qs_env, &
293 first_c=my_group_l_start, last_c=my_group_l_end, mat_ab=mat_munu_local, &
294 basis_type_a="ORB", basis_type_b="ORB", basis_type_c="RI_AUX", &
295 sab_nl=sab_orb_sub, eri_method=eri_method, &
296 pabc=matrix_p_munu_local, &
297 force_a=force_3c_orb_mu, force_b=force_3c_orb_nu, force_c=force_3c_aux)
298
299 l_counter = 0
300 DO lll = my_group_l_start, my_group_l_end
301 l_counter = l_counter + 1
302 DO ispin = 1, nspins
303 CALL dbcsr_multiply("N", "T", 1.0_dp, mo_coeff_v(ispin)%matrix, g_p_ia(ispin, l_counter)%matrix, &
304 0.0_dp, matrix_p_inu(ispin), filter_eps=eps_filter)
305 END DO
306
307 ! The matrices of G_P_ia are deallocated here
308 CALL update_lagrangian(mat_munu_local(l_counter)%matrix, matrix_p_inu, lag_mu_i_1, &
309 g_p_ia(:, l_counter), mo_coeff_o, lag_nu_a_2, &
310 eps_filter)
311 END DO
312
313 DO ikind = 1, SIZE(force)
314 mp2_force(ikind)%mp2_non_sep(:, :) = factor_2c*force_2c(ikind)%forces(:, :) + &
315 force_3c_orb_mu(ikind)%forces(:, :) + &
316 force_3c_orb_nu(ikind)%forces(:, :) + &
317 force_3c_aux(ikind)%forces(:, :)
318
319 IF (.NOT. compare_potential_types(mp2_env%potential_parameter, mp2_env%ri_metric)) THEN
320 mp2_force(ikind)%mp2_non_sep(:, :) = mp2_force(ikind)%mp2_non_sep(:, :) + factor_2c*force_2c_ri(ikind)%forces
321 END IF
322 END DO
323
324 CALL mp2_eri_deallocate_forces(force_2c)
325 IF (.NOT. compare_potential_types(mp2_env%potential_parameter, mp2_env%ri_metric)) THEN
326 CALL mp2_eri_deallocate_forces(force_2c_ri)
327 END IF
328 CALL mp2_eri_deallocate_forces(force_3c_aux)
329 CALL mp2_eri_deallocate_forces(force_3c_orb_mu)
330 CALL mp2_eri_deallocate_forces(force_3c_orb_nu)
331 CALL dbcsr_deallocate_matrix_set(matrix_p_munu_local)
332 CALL dbcsr_deallocate_matrix_set(mat_munu_local)
333
334 ELSEIF (eri_method == do_eri_gpw) THEN
335 CALL get_qs_env(qs_env, ks_env=ks_env)
336
337 CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of, atom_of_kind=atom_of_kind)
338
339 ! Supporting stuff for GPW
340 CALL prepare_gpw(qs_env, dft_control, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
341 auxbas_pw_pool, poisson_env, task_list_sub, rho_r, rho_g, pot_g, psi_l, sab_orb_sub)
342
343 ! in case virial is required we need auxiliary pw
344 ! for calculate the MP2-volume contribution to the virial
345 ! (hartree potential derivatives)
346 IF (use_virial) THEN
347 CALL auxbas_pw_pool%create_pw(rho_g_copy)
348 DO i = 1, 3
349 CALL auxbas_pw_pool%create_pw(dvg(i))
350 END DO
351 END IF
352
353 ! start main loop over auxiliary basis functions
354 CALL timeset(routinen//"_loop", handle2)
355
356 IF (use_virial) h_stress = 0.0_dp
357
358 l_counter = 0
359 DO lll = my_group_l_start, my_group_l_end
360 l_counter = l_counter + 1
361
362 CALL g_p_transform_mo_to_ao(matrix_p_munu%matrix, matrix_p_munu_nosym, mat_munu%matrix, &
363 g_p_ia(:, l_counter), matrix_p_inu, &
364 mo_coeff_v, mo_coeff_o, eps_filter)
365
366 CALL integrate_potential_forces_2c(rho_r, lll, rho_g, atomic_kind_set, &
367 qs_kind_set, particle_set, cell, pw_env_sub, poisson_env, &
368 pot_g, mp2_env%potential_parameter, use_virial, &
369 rho_g_copy, dvg, kind_of, atom_of_kind, g_pq_local(:, l_counter), &
370 mp2_force, h_stress, para_env_sub, dft_control, psi_l, factor_2c)
371
372 IF (.NOT. compare_potential_types(mp2_env%ri_metric, mp2_env%potential_parameter)) THEN
373
374 CALL integrate_potential_forces_2c(rho_r, lll, rho_g, atomic_kind_set, &
375 qs_kind_set, particle_set, cell, pw_env_sub, poisson_env, &
376 pot_g, mp2_env%ri_metric, use_virial, &
377 rho_g_copy, dvg, kind_of, atom_of_kind, g_pq_local_2(:, l_counter), &
378 mp2_force, h_stress, para_env_sub, dft_control, psi_l, factor_2c)
379 END IF
380
381 IF (use_virial) pv_virial = virial%pv_virial
382 CALL integrate_potential_forces_3c_1c(mat_munu, rho_r, matrix_p_munu, qs_env, pw_env_sub, &
383 task_list_sub)
384 IF (use_virial) THEN
385 h_stress = h_stress + (virial%pv_virial - pv_virial)
386 virial%pv_virial = pv_virial
387 END IF
388
389 ! The matrices of G_P_ia are deallocated here
390 CALL update_lagrangian(mat_munu%matrix, matrix_p_inu, lag_mu_i_1, &
391 g_p_ia(:, l_counter), mo_coeff_o, lag_nu_a_2, &
392 eps_filter)
393
394 CALL integrate_potential_forces_3c_2c(matrix_p_munu, rho_r, rho_g, task_list_sub, pw_env_sub, &
395 mp2_env%ri_metric, &
396 ks_env, poisson_env, pot_g, use_virial, rho_g_copy, dvg, &
397 h_stress, para_env_sub, kind_of, atom_of_kind, &
398 qs_kind_set, particle_set, cell, lll, mp2_force, dft_control)
399 END DO
400
401 CALL timestop(handle2)
402
403 DEALLOCATE (kind_of)
404 DEALLOCATE (atom_of_kind)
405
406 IF (use_virial) THEN
407 CALL auxbas_pw_pool%give_back_pw(rho_g_copy)
408 DO i = 1, 3
409 CALL auxbas_pw_pool%give_back_pw(dvg(i))
410 END DO
411 END IF
412
413 CALL cleanup_gpw(qs_env, e_cutoff_old, cutoff_old, relative_cutoff_old, para_env_sub, pw_env_sub, &
414 task_list_sub, auxbas_pw_pool, rho_r, rho_g, pot_g, psi_l)
415
416 CALL dbcsr_release(matrix_p_munu%matrix)
417 DEALLOCATE (matrix_p_munu%matrix)
418
419 END IF
420
421 IF (use_virial) mp2_env%ri_grad%mp2_virial = h_stress
422
423 DEALLOCATE (g_pq_local)
424 IF (.NOT. compare_potential_types(mp2_env%ri_metric, mp2_env%potential_parameter)) DEALLOCATE (g_pq_local_2)
425
426 CALL dbcsr_release(matrix_p_munu_nosym)
427
428 DO ispin = 1, nspins
429 CALL dbcsr_release(matrix_p_inu(ispin))
430 END DO
431 DEALLOCATE (matrix_p_inu, g_p_ia)
432
433 ! move the forces in the correct place
434 IF (eri_method .EQ. do_eri_gpw) THEN
435 DO ikind = 1, SIZE(mp2_force)
436 mp2_force(ikind)%mp2_non_sep(:, :) = force(ikind)%rho_elec(:, :)
437 force(ikind)%rho_elec(:, :) = 0.0_dp
438 END DO
439 END IF
440
441 ! Now we move from the local matrices to the global ones
442 ! defined over all MPI tasks
443 ! Start with moving from the DBCSR to FM for the lagrangians
444
445 ALLOCATE (l1_mu_i(nspins), l2_nu_a(nspins))
446 DO ispin = 1, nspins
447 ! Now we move from the local matrices to the global ones
448 ! defined over all MPI tasks
449 ! Start with moving from the DBCSR to FM for the lagrangians
450 NULLIFY (fm_struct_tmp)
451 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env_sub, context=blacs_env_sub, &
452 nrow_global=nao, ncol_global=homo(ispin))
453 CALL cp_fm_create(l1_mu_i(ispin), fm_struct_tmp, name="Lag_mu_i")
454 CALL cp_fm_struct_release(fm_struct_tmp)
455 CALL cp_fm_set_all(l1_mu_i(ispin), 0.0_dp)
456 CALL copy_dbcsr_to_fm(matrix=lag_mu_i_1(ispin), fm=l1_mu_i(ispin))
457
458 ! release Lag_mu_i_1
459 CALL dbcsr_release(lag_mu_i_1(ispin))
460
461 NULLIFY (fm_struct_tmp)
462 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env_sub, context=blacs_env_sub, &
463 nrow_global=nao, ncol_global=virtual(ispin))
464 CALL cp_fm_create(l2_nu_a(ispin), fm_struct_tmp, name="Lag_nu_a")
465 CALL cp_fm_struct_release(fm_struct_tmp)
466 CALL cp_fm_set_all(l2_nu_a(ispin), 0.0_dp)
467 CALL copy_dbcsr_to_fm(matrix=lag_nu_a_2(ispin), fm=l2_nu_a(ispin))
468
469 ! release Lag_nu_a_2
470 CALL dbcsr_release(lag_nu_a_2(ispin))
471 END DO
472 DEALLOCATE (lag_mu_i_1, lag_nu_a_2)
473
474 ! Set the factor to multiply P_ij (depends on the open or closed shell)
475 factor = 1.0_dp
476 IF (alpha_beta) factor = 0.50_dp
477
478 DO ispin = 1, nspins
479 CALL create_w_p(qs_env, mp2_env, mo_coeff(ispin), homo(ispin), virtual(ispin), para_env, &
480 para_env_sub, eigenval(:, ispin), l1_mu_i(ispin), l2_nu_a(ispin), &
481 factor, ispin)
482 END DO
483 DEALLOCATE (l1_mu_i, l2_nu_a)
484
485 CALL timestop(handle)
486
487 END SUBROUTINE calc_ri_mp2_nonsep
488
489! **************************************************************************************************
490!> \brief Transforms G_P_ia to G_P_munu
491!> \param G_P_munu The container for G_P_munu, will be allocated and created if not allocated on entry
492!> \param G_P_munu_nosym ...
493!> \param mat_munu ...
494!> \param G_P_ia ...
495!> \param G_P_inu ...
496!> \param mo_coeff_v ...
497!> \param mo_coeff_o ...
498!> \param eps_filter ...
499! **************************************************************************************************
500 SUBROUTINE g_p_transform_mo_to_ao(G_P_munu, G_P_munu_nosym, mat_munu, G_P_ia, G_P_inu, &
501 mo_coeff_v, mo_coeff_o, eps_filter)
502 TYPE(dbcsr_type), POINTER :: g_p_munu
503 TYPE(dbcsr_type), INTENT(INOUT) :: g_p_munu_nosym, mat_munu
504 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: g_p_ia
505 TYPE(dbcsr_type), DIMENSION(:), INTENT(INOUT) :: g_p_inu
506 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: mo_coeff_v, mo_coeff_o
507 REAL(kind=dp), INTENT(IN) :: eps_filter
508
509 CHARACTER(LEN=*), PARAMETER :: routinen = 'G_P_transform_MO_to_AO'
510
511 INTEGER :: handle
512
513 IF (.NOT. ASSOCIATED(g_p_munu)) THEN
514 ALLOCATE (g_p_munu)
515 CALL dbcsr_create(g_p_munu, template=mat_munu, &
516 matrix_type=dbcsr_type_symmetric)
517 END IF
518
519 CALL g_p_transform_alpha_beta(g_p_ia, g_p_inu, g_p_munu_nosym, mo_coeff_v, mo_coeff_o, eps_filter)
520
521 ! symmetrize
522 CALL timeset(routinen//"_symmetrize", handle)
523 CALL dbcsr_set(g_p_munu, 0.0_dp)
524 CALL dbcsr_transposed(g_p_munu, g_p_munu_nosym)
525 CALL dbcsr_add(g_p_munu, g_p_munu_nosym, &
526 alpha_scalar=2.0_dp, beta_scalar=2.0_dp)
527 ! this is a trick to avoid that integrate_v_rspace starts to cry
528 CALL dbcsr_copy(mat_munu, g_p_munu, keep_sparsity=.true.)
529 CALL dbcsr_copy(g_p_munu, mat_munu)
530
531 CALL timestop(handle)
532
533 END SUBROUTINE g_p_transform_mo_to_ao
534
535! **************************************************************************************************
536!> \brief ...
537!> \param G_P_ia ...
538!> \param G_P_inu ...
539!> \param G_P_munu ...
540!> \param mo_coeff_v ...
541!> \param mo_coeff_o ...
542!> \param eps_filter ...
543! **************************************************************************************************
544 SUBROUTINE g_p_transform_alpha_beta(G_P_ia, G_P_inu, G_P_munu, mo_coeff_v, mo_coeff_o, eps_filter)
545 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: g_p_ia
546 TYPE(dbcsr_type), DIMENSION(:), INTENT(INOUT) :: g_p_inu
547 TYPE(dbcsr_type), INTENT(INOUT) :: g_p_munu
548 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: mo_coeff_v, mo_coeff_o
549 REAL(kind=dp), INTENT(IN) :: eps_filter
550
551 CHARACTER(LEN=*), PARAMETER :: routinen = 'G_P_transform_alpha_beta'
552
553 INTEGER :: handle, ispin
554 REAL(kind=dp) :: factor
555
556 CALL timeset(routinen, handle)
557
558 factor = 1.0_dp/real(SIZE(g_p_ia), dp)
559
560 CALL dbcsr_set(g_p_munu, 0.0_dp)
561
562 DO ispin = 1, SIZE(g_p_ia)
563 ! first back-transformation a->nu
564 CALL dbcsr_multiply("N", "T", 1.0_dp, mo_coeff_v(ispin)%matrix, g_p_ia(ispin)%matrix, &
565 0.0_dp, g_p_inu(ispin), filter_eps=eps_filter)
566
567 ! second back-transformation i->mu
568 CALL dbcsr_multiply("N", "T", factor, g_p_inu(ispin), mo_coeff_o(ispin)%matrix, &
569 1.0_dp, g_p_munu, filter_eps=eps_filter)
570 END DO
571
572 CALL timestop(handle)
573
574 END SUBROUTINE g_p_transform_alpha_beta
575
576! **************************************************************************************************
577!> \brief ...
578!> \param mat_munu ...
579!> \param matrix_P_inu ...
580!> \param Lag_mu_i_1 ...
581!> \param G_P_ia ...
582!> \param mo_coeff_o ...
583!> \param Lag_nu_a_2 ...
584!> \param eps_filter ...
585! **************************************************************************************************
586 SUBROUTINE update_lagrangian(mat_munu, matrix_P_inu, Lag_mu_i_1, &
587 G_P_ia, mo_coeff_o, Lag_nu_a_2, &
588 eps_filter)
589 TYPE(dbcsr_type), INTENT(IN) :: mat_munu
590 TYPE(dbcsr_type), DIMENSION(:), INTENT(INOUT) :: matrix_p_inu, lag_mu_i_1
591 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT) :: g_p_ia
592 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: mo_coeff_o
593 TYPE(dbcsr_type), DIMENSION(:), INTENT(INOUT) :: lag_nu_a_2
594 REAL(kind=dp), INTENT(IN) :: eps_filter
595
596 CHARACTER(LEN=*), PARAMETER :: routinen = 'update_lagrangian'
597
598 INTEGER :: handle, ispin
599
600 ! update lagrangian
601 CALL timeset(routinen, handle)
602
603 DO ispin = 1, SIZE(g_p_ia)
604 ! first contract mat_munu with the half back transformed Gamma_i_nu
605 ! in order to update Lag_mu_i_1
606 CALL dbcsr_multiply("N", "N", 1.0_dp, mat_munu, matrix_p_inu(ispin), &
607 1.0_dp, lag_mu_i_1(ispin), filter_eps=eps_filter)
608
609 ! transform first index of mat_munu and store the result into matrix_P_inu
610 CALL dbcsr_set(matrix_p_inu(ispin), 0.0_dp)
611 CALL dbcsr_multiply("N", "N", 1.0_dp, mat_munu, mo_coeff_o(ispin)%matrix, &
612 0.0_dp, matrix_p_inu(ispin), filter_eps=eps_filter)
613
614 ! contract the transformend matrix_P_inu with the untransformend Gamma_i_a
615 ! in order to update Lag_nu_a_2
616 CALL dbcsr_multiply("N", "N", -1.0_dp, matrix_p_inu(ispin), g_p_ia(ispin)%matrix, &
617 1.0_dp, lag_nu_a_2(ispin), filter_eps=eps_filter)
618
619 ! release the actual gamma_P_ia
620 CALL dbcsr_release(g_p_ia(ispin)%matrix)
621 DEALLOCATE (g_p_ia(ispin)%matrix)
622 END DO
623
624 CALL timestop(handle)
625
626 END SUBROUTINE update_lagrangian
627
628! **************************************************************************************************
629!> \brief ...
630!> \param qs_env ...
631!> \param mp2_env ...
632!> \param mo_coeff ...
633!> \param homo ...
634!> \param virtual ...
635!> \param para_env ...
636!> \param para_env_sub ...
637!> \param Eigenval ...
638!> \param L1_mu_i ...
639!> \param L2_nu_a ...
640!> \param factor ...
641!> \param kspin ...
642! **************************************************************************************************
643 SUBROUTINE create_w_p(qs_env, mp2_env, mo_coeff, homo, virtual, para_env, para_env_sub, &
644 Eigenval, L1_mu_i, L2_nu_a, factor, kspin)
645 TYPE(qs_environment_type), POINTER :: qs_env
646 TYPE(mp2_type) :: mp2_env
647 TYPE(cp_fm_type), INTENT(IN) :: mo_coeff
648 INTEGER, INTENT(IN) :: homo, virtual
649 TYPE(mp_para_env_type), POINTER :: para_env, para_env_sub
650 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: eigenval
651 TYPE(cp_fm_type), INTENT(INOUT) :: l1_mu_i, l2_nu_a
652 REAL(kind=dp), INTENT(IN) :: factor
653 INTEGER, INTENT(IN) :: kspin
654
655 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_W_P'
656
657 INTEGER :: color_exchange, dummy_proc, handle, handle2, handle3, i_global, i_local, iib, &
658 iii, iproc, itmp(2), j_global, j_local, jjb, max_col_size, max_row_size, &
659 my_b_virtual_end, my_b_virtual_start, mypcol, myprow, nao, ncol_local, ncol_local_1i, &
660 ncol_local_2a, nmo, npcol, nprow, nrow_local, nrow_local_1i, nrow_local_2a, &
661 number_of_rec, number_of_send, proc_receive, proc_receive_static, proc_send, &
662 proc_send_ex, proc_send_static, proc_send_sub, proc_shift, rec_col_size, rec_counter, &
663 rec_row_size, send_col_size, send_counter, send_pcol, send_prow, send_row_size, &
664 size_rec_buffer
665 INTEGER :: size_send_buffer
666 INTEGER, ALLOCATABLE, DIMENSION(:) :: iii_vet, map_rec_size, map_send_size, &
667 pos_info, pos_info_ex, proc_2_send_pos
668 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: grid_2_mepos, mepos_2_grid, my_col_indeces_info_1i, &
669 my_col_indeces_info_2a, my_row_indeces_info_1i, my_row_indeces_info_2a, sizes, sizes_1i, &
670 sizes_2a
671 INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: col_indeces_info_1i, &
672 col_indeces_info_2a, &
673 row_indeces_info_1i, &
674 row_indeces_info_2a
675 INTEGER, DIMENSION(:), POINTER :: col_indices, col_indices_1i, &
676 col_indices_2a, row_indices, &
677 row_indices_1i, row_indices_2a
678 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: ab_rec, ab_send, mat_rec, mat_send
679 TYPE(cp_blacs_env_type), POINTER :: blacs_env
680 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
681 TYPE(cp_fm_type) :: fm_p_ij, l_mu_q
682 TYPE(integ_mat_buffer_type), ALLOCATABLE, &
683 DIMENSION(:) :: buffer_rec, buffer_send
684 TYPE(integ_mat_buffer_type_2d), ALLOCATABLE, &
685 DIMENSION(:) :: buffer_cyclic
686 TYPE(mp_para_env_type), POINTER :: para_env_exchange
687 TYPE(mp_request_type), ALLOCATABLE, DIMENSION(:) :: req_send
688
689 CALL timeset(routinen, handle)
690
691 ! create the globally distributed mixed lagrangian
692 NULLIFY (blacs_env)
693 CALL get_qs_env(qs_env, blacs_env=blacs_env)
694
695 CALL cp_fm_get_info(mo_coeff, nrow_global=nao, ncol_global=nmo)
696
697 NULLIFY (fm_struct_tmp)
698 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
699 nrow_global=nao, ncol_global=nmo)
700 CALL cp_fm_create(l_mu_q, fm_struct_tmp, name="Lag_mu_q")
701 CALL cp_fm_struct_release(fm_struct_tmp)
702 CALL cp_fm_set_all(l_mu_q, 0.0_dp)
703
704 ! create all information array
705 ALLOCATE (pos_info(0:para_env%num_pe - 1))
706 CALL para_env%allgather(para_env_sub%mepos, pos_info)
707
708 ! get matrix information for the global
709 CALL cp_fm_get_info(matrix=l_mu_q, &
710 nrow_local=nrow_local, &
711 ncol_local=ncol_local, &
712 row_indices=row_indices, &
713 col_indices=col_indices)
714 myprow = l_mu_q%matrix_struct%context%mepos(1)
715 mypcol = l_mu_q%matrix_struct%context%mepos(2)
716 nprow = l_mu_q%matrix_struct%context%num_pe(1)
717 npcol = l_mu_q%matrix_struct%context%num_pe(2)
718
719 ALLOCATE (grid_2_mepos(0:nprow - 1, 0:npcol - 1))
720 grid_2_mepos = 0
721 grid_2_mepos(myprow, mypcol) = para_env%mepos
722 CALL para_env%sum(grid_2_mepos)
723
724 ! get matrix information for L1_mu_i
725 CALL cp_fm_get_info(matrix=l1_mu_i, &
726 nrow_local=nrow_local_1i, &
727 ncol_local=ncol_local_1i, &
728 row_indices=row_indices_1i, &
729 col_indices=col_indices_1i)
730
731 ALLOCATE (sizes_1i(2, 0:para_env_sub%num_pe - 1))
732 CALL para_env_sub%allgather([nrow_local_1i, ncol_local_1i], sizes_1i)
733
734 ! get matrix information for L2_nu_a
735 CALL cp_fm_get_info(matrix=l2_nu_a, &
736 nrow_local=nrow_local_2a, &
737 ncol_local=ncol_local_2a, &
738 row_indices=row_indices_2a, &
739 col_indices=col_indices_2a)
740
741 ALLOCATE (sizes_2a(2, 0:para_env_sub%num_pe - 1))
742 CALL para_env_sub%allgather([nrow_local_2a, ncol_local_2a], sizes_2a)
743
744 ! Here we perform a ring communication scheme taking into account
745 ! for the sub-group distribution of the source matrices.
746 ! as a first step we need to redistribute the data within
747 ! the subgroup.
748 ! In order to do so we have to allocate the structure
749 ! that will hold the local data involved in communication, this
750 ! structure will be the same for processes in different subgroups
751 ! sharing the same position in the subgroup.
752 ! -1) create the exchange para_env
753 color_exchange = para_env_sub%mepos
754 ALLOCATE (para_env_exchange)
755 CALL para_env_exchange%from_split(para_env, color_exchange)
756 ALLOCATE (pos_info_ex(0:para_env%num_pe - 1))
757 CALL para_env%allgather(para_env_exchange%mepos, pos_info_ex)
758 ALLOCATE (sizes(2, 0:para_env_exchange%num_pe - 1))
759 CALL para_env_exchange%allgather([nrow_local, ncol_local], sizes)
760
761 ! 0) store some info about indeces of the fm matrices (subgroup)
762 CALL timeset(routinen//"_inx", handle2)
763 ! matrix L1_mu_i
764 max_row_size = maxval(sizes_1i(1, :))
765 max_col_size = maxval(sizes_1i(2, :))
766 ALLOCATE (row_indeces_info_1i(2, max_row_size, 0:para_env_sub%num_pe - 1))
767 ALLOCATE (col_indeces_info_1i(2, max_col_size, 0:para_env_sub%num_pe - 1))
768 ALLOCATE (my_row_indeces_info_1i(2, max_row_size))
769 ALLOCATE (my_col_indeces_info_1i(2, max_col_size))
770 row_indeces_info_1i = 0
771 col_indeces_info_1i = 0
772 dummy_proc = 0
773 ! row
774 DO iib = 1, nrow_local_1i
775 i_global = row_indices_1i(iib)
776 send_prow = l_mu_q%matrix_struct%g2p_row(i_global)
777 i_local = l_mu_q%matrix_struct%g2l_row(i_global)
778 my_row_indeces_info_1i(1, iib) = send_prow
779 my_row_indeces_info_1i(2, iib) = i_local
780 END DO
781 ! col
782 DO jjb = 1, ncol_local_1i
783 j_global = col_indices_1i(jjb)
784 send_pcol = l_mu_q%matrix_struct%g2p_col(j_global)
785 j_local = l_mu_q%matrix_struct%g2l_col(j_global)
786 my_col_indeces_info_1i(1, jjb) = send_pcol
787 my_col_indeces_info_1i(2, jjb) = j_local
788 END DO
789 CALL para_env_sub%allgather(my_row_indeces_info_1i, row_indeces_info_1i)
790 CALL para_env_sub%allgather(my_col_indeces_info_1i, col_indeces_info_1i)
791 DEALLOCATE (my_row_indeces_info_1i, my_col_indeces_info_1i)
792
793 ! matrix L2_nu_a
794 max_row_size = maxval(sizes_2a(1, :))
795 max_col_size = maxval(sizes_2a(2, :))
796 ALLOCATE (row_indeces_info_2a(2, max_row_size, 0:para_env_sub%num_pe - 1))
797 ALLOCATE (col_indeces_info_2a(2, max_col_size, 0:para_env_sub%num_pe - 1))
798 ALLOCATE (my_row_indeces_info_2a(2, max_row_size))
799 ALLOCATE (my_col_indeces_info_2a(2, max_col_size))
800 row_indeces_info_2a = 0
801 col_indeces_info_2a = 0
802 ! row
803 DO iib = 1, nrow_local_2a
804 i_global = row_indices_2a(iib)
805 send_prow = l_mu_q%matrix_struct%g2p_row(i_global)
806 i_local = l_mu_q%matrix_struct%g2l_row(i_global)
807 my_row_indeces_info_2a(1, iib) = send_prow
808 my_row_indeces_info_2a(2, iib) = i_local
809 END DO
810 ! col
811 DO jjb = 1, ncol_local_2a
812 j_global = col_indices_2a(jjb) + homo
813 send_pcol = l_mu_q%matrix_struct%g2p_col(j_global)
814 j_local = l_mu_q%matrix_struct%g2l_col(j_global)
815 my_col_indeces_info_2a(1, jjb) = send_pcol
816 my_col_indeces_info_2a(2, jjb) = j_local
817 END DO
818 CALL para_env_sub%allgather(my_row_indeces_info_2a, row_indeces_info_2a)
819 CALL para_env_sub%allgather(my_col_indeces_info_2a, col_indeces_info_2a)
820 DEALLOCATE (my_row_indeces_info_2a, my_col_indeces_info_2a)
821 CALL timestop(handle2)
822
823 ! 1) define the map for sending data in the subgroup starting with L1_mu_i
824 CALL timeset(routinen//"_subinfo", handle2)
825 ALLOCATE (map_send_size(0:para_env_sub%num_pe - 1))
826 map_send_size = 0
827 DO jjb = 1, ncol_local_1i
828 send_pcol = col_indeces_info_1i(1, jjb, para_env_sub%mepos)
829 DO iib = 1, nrow_local_1i
830 send_prow = row_indeces_info_1i(1, iib, para_env_sub%mepos)
831 proc_send = grid_2_mepos(send_prow, send_pcol)
832 proc_send_sub = pos_info(proc_send)
833 map_send_size(proc_send_sub) = map_send_size(proc_send_sub) + 1
834 END DO
835 END DO
836 ! and the same for L2_nu_a
837 DO jjb = 1, ncol_local_2a
838 send_pcol = col_indeces_info_2a(1, jjb, para_env_sub%mepos)
839 DO iib = 1, nrow_local_2a
840 send_prow = row_indeces_info_2a(1, iib, para_env_sub%mepos)
841 proc_send = grid_2_mepos(send_prow, send_pcol)
842 proc_send_sub = pos_info(proc_send)
843 map_send_size(proc_send_sub) = map_send_size(proc_send_sub) + 1
844 END DO
845 END DO
846 ! and exchange data in order to create map_rec_size
847 ALLOCATE (map_rec_size(0:para_env_sub%num_pe - 1))
848 map_rec_size = 0
849 CALL para_env_sub%alltoall(map_send_size, map_rec_size, 1)
850 CALL timestop(handle2)
851
852 ! 2) reorder data in sending buffer
853 CALL timeset(routinen//"_sub_Bsend", handle2)
854 ! count the number of messages (include myself)
855 number_of_send = 0
856 DO proc_shift = 0, para_env_sub%num_pe - 1
857 proc_send = modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
858 IF (map_send_size(proc_send) > 0) THEN
859 number_of_send = number_of_send + 1
860 END IF
861 END DO
862 ! allocate the structure that will hold the messages to be sent
863 ALLOCATE (buffer_send(number_of_send))
864 send_counter = 0
865 ALLOCATE (proc_2_send_pos(0:para_env_sub%num_pe - 1))
866 proc_2_send_pos = 0
867 DO proc_shift = 0, para_env_sub%num_pe - 1
868 proc_send = modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
869 size_send_buffer = map_send_size(proc_send)
870 IF (map_send_size(proc_send) > 0) THEN
871 send_counter = send_counter + 1
872 ! allocate the sending buffer (msg)
873 ALLOCATE (buffer_send(send_counter)%msg(size_send_buffer))
874 buffer_send(send_counter)%msg = 0.0_dp
875 buffer_send(send_counter)%proc = proc_send
876 proc_2_send_pos(proc_send) = send_counter
877 END IF
878 END DO
879 ! loop over the locally held data and fill the buffer_send
880 ! for doing that we need an array that keep track if the
881 ! sequential increase of the index for each message
882 ALLOCATE (iii_vet(number_of_send))
883 iii_vet = 0
884 DO jjb = 1, ncol_local_1i
885 send_pcol = col_indeces_info_1i(1, jjb, para_env_sub%mepos)
886 DO iib = 1, nrow_local_1i
887 send_prow = row_indeces_info_1i(1, iib, para_env_sub%mepos)
888 proc_send = grid_2_mepos(send_prow, send_pcol)
889 proc_send_sub = pos_info(proc_send)
890 send_counter = proc_2_send_pos(proc_send_sub)
891 iii_vet(send_counter) = iii_vet(send_counter) + 1
892 iii = iii_vet(send_counter)
893 buffer_send(send_counter)%msg(iii) = l1_mu_i%local_data(iib, jjb)
894 END DO
895 END DO
896 ! release the local data of L1_mu_i
897 DEALLOCATE (l1_mu_i%local_data)
898 ! and the same for L2_nu_a
899 DO jjb = 1, ncol_local_2a
900 send_pcol = col_indeces_info_2a(1, jjb, para_env_sub%mepos)
901 DO iib = 1, nrow_local_2a
902 send_prow = row_indeces_info_2a(1, iib, para_env_sub%mepos)
903 proc_send = grid_2_mepos(send_prow, send_pcol)
904 proc_send_sub = pos_info(proc_send)
905 send_counter = proc_2_send_pos(proc_send_sub)
906 iii_vet(send_counter) = iii_vet(send_counter) + 1
907 iii = iii_vet(send_counter)
908 buffer_send(send_counter)%msg(iii) = l2_nu_a%local_data(iib, jjb)
909 END DO
910 END DO
911 DEALLOCATE (l2_nu_a%local_data)
912 DEALLOCATE (proc_2_send_pos)
913 DEALLOCATE (iii_vet)
914 CALL timestop(handle2)
915
916 ! 3) create the buffer for receive, post the message with irecv
917 ! and send the messages non-blocking
918 CALL timeset(routinen//"_sub_isendrecv", handle2)
919 ! count the number of messages to be received
920 number_of_rec = 0
921 DO proc_shift = 0, para_env_sub%num_pe - 1
922 proc_receive = modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
923 IF (map_rec_size(proc_receive) > 0) THEN
924 number_of_rec = number_of_rec + 1
925 END IF
926 END DO
927 ALLOCATE (buffer_rec(number_of_rec))
928 rec_counter = 0
929 DO proc_shift = 0, para_env_sub%num_pe - 1
930 proc_receive = modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
931 size_rec_buffer = map_rec_size(proc_receive)
932 IF (map_rec_size(proc_receive) > 0) THEN
933 rec_counter = rec_counter + 1
934 ! prepare the buffer for receive
935 ALLOCATE (buffer_rec(rec_counter)%msg(size_rec_buffer))
936 buffer_rec(rec_counter)%msg = 0.0_dp
937 buffer_rec(rec_counter)%proc = proc_receive
938 ! post the message to be received (not need to send to myself)
939 IF (proc_receive /= para_env_sub%mepos) THEN
940 CALL para_env_sub%irecv(buffer_rec(rec_counter)%msg, proc_receive, &
941 buffer_rec(rec_counter)%msg_req)
942 END IF
943 END IF
944 END DO
945 ! send messages
946 ALLOCATE (req_send(number_of_send))
947 req_send = mp_request_null
948 send_counter = 0
949 DO proc_shift = 0, para_env_sub%num_pe - 1
950 proc_send = modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
951 IF (map_send_size(proc_send) > 0) THEN
952 send_counter = send_counter + 1
953 IF (proc_send == para_env_sub%mepos) THEN
954 buffer_rec(send_counter)%msg(:) = buffer_send(send_counter)%msg
955 ELSE
956 CALL para_env_sub%isend(buffer_send(send_counter)%msg, proc_send, &
957 buffer_send(send_counter)%msg_req)
958 req_send(send_counter) = buffer_send(send_counter)%msg_req
959 END IF
960 END IF
961 END DO
962 DEALLOCATE (map_send_size)
963 CALL timestop(handle2)
964
965 ! 4) (if memory is a problem we should move this part after point 5)
966 ! Here we create the new buffer for cyclic(ring) communication and
967 ! we fill it with the data received from the other member of the
968 ! subgroup
969 CALL timeset(routinen//"_Bcyclic", handle2)
970 ! first allocata new structure
971 ALLOCATE (buffer_cyclic(0:para_env_exchange%num_pe - 1))
972 DO iproc = 0, para_env_exchange%num_pe - 1
973 rec_row_size = sizes(1, iproc)
974 rec_col_size = sizes(2, iproc)
975 ALLOCATE (buffer_cyclic(iproc)%msg(rec_row_size, rec_col_size))
976 buffer_cyclic(iproc)%msg = 0.0_dp
977 END DO
978 ! now collect data from other member of the subgroup and fill
979 ! buffer_cyclic
980 rec_counter = 0
981 DO proc_shift = 0, para_env_sub%num_pe - 1
982 proc_receive = modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
983 size_rec_buffer = map_rec_size(proc_receive)
984 IF (map_rec_size(proc_receive) > 0) THEN
985 rec_counter = rec_counter + 1
986
987 ! wait for the message
988 IF (proc_receive /= para_env_sub%mepos) CALL buffer_rec(rec_counter)%msg_req%wait()
989
990 CALL timeset(routinen//"_fill", handle3)
991 iii = 0
992 DO jjb = 1, sizes_1i(2, proc_receive)
993 send_pcol = col_indeces_info_1i(1, jjb, proc_receive)
994 j_local = col_indeces_info_1i(2, jjb, proc_receive)
995 DO iib = 1, sizes_1i(1, proc_receive)
996 send_prow = row_indeces_info_1i(1, iib, proc_receive)
997 proc_send = grid_2_mepos(send_prow, send_pcol)
998 proc_send_sub = pos_info(proc_send)
999 IF (proc_send_sub /= para_env_sub%mepos) cycle
1000 iii = iii + 1
1001 i_local = row_indeces_info_1i(2, iib, proc_receive)
1002 proc_send_ex = pos_info_ex(proc_send)
1003 buffer_cyclic(proc_send_ex)%msg(i_local, j_local) = buffer_rec(rec_counter)%msg(iii)
1004 END DO
1005 END DO
1006 ! and the same for L2_nu_a
1007 DO jjb = 1, sizes_2a(2, proc_receive)
1008 send_pcol = col_indeces_info_2a(1, jjb, proc_receive)
1009 j_local = col_indeces_info_2a(2, jjb, proc_receive)
1010 DO iib = 1, sizes_2a(1, proc_receive)
1011 send_prow = row_indeces_info_2a(1, iib, proc_receive)
1012 proc_send = grid_2_mepos(send_prow, send_pcol)
1013 proc_send_sub = pos_info(proc_send)
1014 IF (proc_send_sub /= para_env_sub%mepos) cycle
1015 iii = iii + 1
1016 i_local = row_indeces_info_2a(2, iib, proc_receive)
1017 proc_send_ex = pos_info_ex(proc_send)
1018 buffer_cyclic(proc_send_ex)%msg(i_local, j_local) = buffer_rec(rec_counter)%msg(iii)
1019 END DO
1020 END DO
1021 CALL timestop(handle3)
1022
1023 ! deallocate the received message
1024 DEALLOCATE (buffer_rec(rec_counter)%msg)
1025 END IF
1026 END DO
1027 DEALLOCATE (row_indeces_info_1i)
1028 DEALLOCATE (col_indeces_info_1i)
1029 DEALLOCATE (row_indeces_info_2a)
1030 DEALLOCATE (col_indeces_info_2a)
1031 DEALLOCATE (buffer_rec)
1032 DEALLOCATE (map_rec_size)
1033 CALL timestop(handle2)
1034
1035 ! 5) Wait for all messeges to be sent in the subgroup
1036 CALL timeset(routinen//"_sub_waitall", handle2)
1037 CALL mp_waitall(req_send(:))
1038 DO send_counter = 1, number_of_send
1039 DEALLOCATE (buffer_send(send_counter)%msg)
1040 END DO
1041 DEALLOCATE (buffer_send)
1042 DEALLOCATE (req_send)
1043 CALL timestop(handle2)
1044
1045 ! 6) Start with ring communication
1046 CALL timeset(routinen//"_ring", handle2)
1047 proc_send_static = modulo(para_env_exchange%mepos + 1, para_env_exchange%num_pe)
1048 proc_receive_static = modulo(para_env_exchange%mepos - 1, para_env_exchange%num_pe)
1049 max_row_size = maxval(sizes(1, :))
1050 max_col_size = maxval(sizes(2, :))
1051 ALLOCATE (mat_send(max_row_size, max_col_size))
1052 ALLOCATE (mat_rec(max_row_size, max_col_size))
1053 mat_send = 0.0_dp
1054 mat_send(1:nrow_local, 1:ncol_local) = buffer_cyclic(para_env_exchange%mepos)%msg(:, :)
1055 DEALLOCATE (buffer_cyclic(para_env_exchange%mepos)%msg)
1056 DO proc_shift = 1, para_env_exchange%num_pe - 1
1057 proc_receive = modulo(para_env_exchange%mepos - proc_shift, para_env_exchange%num_pe)
1058
1059 rec_row_size = sizes(1, proc_receive)
1060 rec_col_size = sizes(2, proc_receive)
1061
1062 mat_rec = 0.0_dp
1063 CALL para_env_exchange%sendrecv(mat_send, proc_send_static, &
1064 mat_rec, proc_receive_static)
1065
1066 mat_send = 0.0_dp
1067 mat_send(1:rec_row_size, 1:rec_col_size) = mat_rec(1:rec_row_size, 1:rec_col_size) + &
1068 buffer_cyclic(proc_receive)%msg(:, :)
1069
1070 DEALLOCATE (buffer_cyclic(proc_receive)%msg)
1071 END DO
1072 ! and finally
1073 CALL para_env_exchange%sendrecv(mat_send, proc_send_static, &
1074 mat_rec, proc_receive_static)
1075 l_mu_q%local_data(1:nrow_local, 1:ncol_local) = mat_rec(1:nrow_local, 1:ncol_local)
1076 DEALLOCATE (buffer_cyclic)
1077 DEALLOCATE (mat_send)
1078 DEALLOCATE (mat_rec)
1079 CALL timestop(handle2)
1080
1081 ! release para_env_exchange
1082 CALL mp_para_env_release(para_env_exchange)
1083
1084 CALL cp_fm_release(l1_mu_i)
1085 CALL cp_fm_release(l2_nu_a)
1086 DEALLOCATE (pos_info_ex)
1087 DEALLOCATE (grid_2_mepos)
1088 DEALLOCATE (sizes)
1089 DEALLOCATE (sizes_1i)
1090 DEALLOCATE (sizes_2a)
1091
1092 ! update the P_ij block of P_MP2 with the
1093 ! non-singular ij pairs
1094 CALL timeset(routinen//"_Pij", handle2)
1095 NULLIFY (fm_struct_tmp)
1096 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
1097 nrow_global=homo, ncol_global=homo)
1098 CALL cp_fm_create(fm_p_ij, fm_struct_tmp, name="fm_P_ij")
1099 CALL cp_fm_struct_release(fm_struct_tmp)
1100 CALL cp_fm_set_all(fm_p_ij, 0.0_dp)
1101
1102 ! we have it, update P_ij local
1103 CALL cp_fm_get_info(matrix=fm_p_ij, &
1104 nrow_local=nrow_local, &
1105 ncol_local=ncol_local, &
1106 row_indices=row_indices, &
1107 col_indices=col_indices)
1108
1109 IF (.NOT. mp2_env%method == ri_rpa_method_gpw) THEN
1110 CALL parallel_gemm('T', 'N', homo, homo, nao, 1.0_dp, &
1111 mo_coeff, l_mu_q, 0.0_dp, fm_p_ij, &
1112 a_first_col=1, &
1113 a_first_row=1, &
1114 b_first_col=1, &
1115 b_first_row=1, &
1116 c_first_col=1, &
1117 c_first_row=1)
1118 CALL parallel_gemm('T', 'N', homo, homo, nao, -2.0_dp, &
1119 l_mu_q, mo_coeff, 2.0_dp, fm_p_ij, &
1120 a_first_col=1, &
1121 a_first_row=1, &
1122 b_first_col=1, &
1123 b_first_row=1, &
1124 c_first_col=1, &
1125 c_first_row=1)
1126
1127 DO jjb = 1, ncol_local
1128 j_global = col_indices(jjb)
1129 DO iib = 1, nrow_local
1130 i_global = row_indices(iib)
1131 ! diagonal elements and nearly degenerate ij pairs already updated
1132 IF (abs(eigenval(j_global) - eigenval(i_global)) < mp2_env%ri_grad%eps_canonical) THEN
1133 fm_p_ij%local_data(iib, jjb) = mp2_env%ri_grad%P_ij(kspin)%array(i_global, j_global)
1134 ELSE
1135 fm_p_ij%local_data(iib, jjb) = &
1136 factor*fm_p_ij%local_data(iib, jjb)/(eigenval(j_global) - eigenval(i_global))
1137 END IF
1138 END DO
1139 END DO
1140 ELSE
1141 DO jjb = 1, ncol_local
1142 j_global = col_indices(jjb)
1143 DO iib = 1, nrow_local
1144 i_global = row_indices(iib)
1145 fm_p_ij%local_data(iib, jjb) = mp2_env%ri_grad%P_ij(kspin)%array(i_global, j_global)
1146 END DO
1147 END DO
1148 END IF
1149 ! deallocate the local P_ij
1150 DEALLOCATE (mp2_env%ri_grad%P_ij(kspin)%array)
1151 CALL timestop(handle2)
1152
1153 ! Now create and fill the P matrix (MO)
1154 ! FOR NOW WE ASSUME P_ab AND P_ij ARE REPLICATED OVER EACH MPI RANK
1155 IF (.NOT. ALLOCATED(mp2_env%ri_grad%P_mo)) THEN
1156 ALLOCATE (mp2_env%ri_grad%P_mo(SIZE(mp2_env%ri_grad%mo_coeff_o)))
1157 END IF
1158
1159 CALL timeset(routinen//"_PMO", handle2)
1160 NULLIFY (fm_struct_tmp)
1161 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
1162 nrow_global=nmo, ncol_global=nmo)
1163 CALL cp_fm_create(mp2_env%ri_grad%P_mo(kspin), fm_struct_tmp, name="P_MP2_MO")
1164 CALL cp_fm_set_all(mp2_env%ri_grad%P_mo(kspin), 0.0_dp)
1165
1166 ! start with the (easy) occ-occ block and locally held P_ab elements
1167 itmp = get_limit(virtual, para_env_sub%num_pe, para_env_sub%mepos)
1168 my_b_virtual_start = itmp(1)
1169 my_b_virtual_end = itmp(2)
1170
1171 ! Fill occ-occ block
1172 CALL cp_fm_to_fm_submat(fm_p_ij, mp2_env%ri_grad%P_mo(kspin), homo, homo, 1, 1, 1, 1)
1173 CALL cp_fm_release(fm_p_ij)
1174
1175 CALL cp_fm_get_info(mp2_env%ri_grad%P_mo(kspin), &
1176 nrow_local=nrow_local, &
1177 ncol_local=ncol_local, &
1178 row_indices=row_indices, &
1179 col_indices=col_indices)
1180
1181 IF (mp2_env%method == ri_mp2_laplace) THEN
1182 CALL parallel_gemm('T', 'N', virtual, virtual, nao, 1.0_dp, &
1183 mo_coeff, l_mu_q, 0.0_dp, mp2_env%ri_grad%P_mo(kspin), &
1184 a_first_col=homo + 1, &
1185 a_first_row=1, &
1186 b_first_col=homo + 1, &
1187 b_first_row=1, &
1188 c_first_col=homo + 1, &
1189 c_first_row=homo + 1)
1190 CALL parallel_gemm('T', 'N', virtual, virtual, nao, -2.0_dp, &
1191 l_mu_q, mo_coeff, 2.0_dp, mp2_env%ri_grad%P_mo(kspin), &
1192 a_first_col=homo + 1, &
1193 a_first_row=1, &
1194 b_first_col=homo + 1, &
1195 b_first_row=1, &
1196 c_first_col=homo + 1, &
1197 c_first_row=homo + 1)
1198 END IF
1199
1200 IF (mp2_env%method == ri_mp2_method_gpw .OR. mp2_env%method == ri_rpa_method_gpw) THEN
1201 ! With MP2 and RPA, we have already calculated the density matrix elements
1202 DO jjb = 1, ncol_local
1203 j_global = col_indices(jjb)
1204 IF (j_global <= homo) cycle
1205 DO iib = 1, nrow_local
1206 i_global = row_indices(iib)
1207 IF (my_b_virtual_start <= i_global - homo .AND. i_global - homo <= my_b_virtual_end) THEN
1208 mp2_env%ri_grad%P_mo(kspin)%local_data(iib, jjb) = &
1209 mp2_env%ri_grad%P_ab(kspin)%array(i_global - homo - my_b_virtual_start + 1, j_global - homo)
1210 END IF
1211 END DO
1212 END DO
1213 ELSE IF (mp2_env%method == ri_mp2_laplace) THEN
1214 ! With Laplace-SOS-MP2, we still have to calculate the matrix elements of the non-degenerate pairs
1215 DO jjb = 1, ncol_local
1216 j_global = col_indices(jjb)
1217 IF (j_global <= homo) cycle
1218 DO iib = 1, nrow_local
1219 i_global = row_indices(iib)
1220 IF (abs(eigenval(i_global) - eigenval(j_global)) < mp2_env%ri_grad%eps_canonical) THEN
1221 IF (my_b_virtual_start <= i_global - homo .AND. i_global - homo <= my_b_virtual_end) THEN
1222 mp2_env%ri_grad%P_mo(kspin)%local_data(iib, jjb) = &
1223 mp2_env%ri_grad%P_ab(kspin)%array(i_global - homo - my_b_virtual_start + 1, j_global - homo)
1224 ELSE
1225 mp2_env%ri_grad%P_mo(kspin)%local_data(iib, jjb) = 0.0_dp
1226 END IF
1227 ELSE
1228 mp2_env%ri_grad%P_mo(kspin)%local_data(iib, jjb) = &
1229 factor*mp2_env%ri_grad%P_mo(kspin)%local_data(iib, jjb)/ &
1230 (eigenval(i_global) - eigenval(j_global))
1231 END IF
1232 END DO
1233 END DO
1234 ELSE
1235 cpabort("Calculation of virt-virt block of density matrix is dealt with elsewhere!")
1236 END IF
1237
1238 ! send around the sub_group the local data and check if we
1239 ! have to update our block with external elements
1240 ALLOCATE (mepos_2_grid(2, 0:para_env_sub%num_pe - 1))
1241 CALL para_env_sub%allgather([myprow, mypcol], mepos_2_grid)
1242
1243 ALLOCATE (sizes(2, 0:para_env_sub%num_pe - 1))
1244 CALL para_env_sub%allgather([nrow_local, ncol_local], sizes)
1245
1246 ALLOCATE (ab_rec(nrow_local, ncol_local))
1247 DO proc_shift = 1, para_env_sub%num_pe - 1
1248 proc_send = modulo(para_env_sub%mepos + proc_shift, para_env_sub%num_pe)
1249 proc_receive = modulo(para_env_sub%mepos - proc_shift, para_env_sub%num_pe)
1250
1251 send_prow = mepos_2_grid(1, proc_send)
1252 send_pcol = mepos_2_grid(2, proc_send)
1253
1254 send_row_size = sizes(1, proc_send)
1255 send_col_size = sizes(2, proc_send)
1256
1257 ALLOCATE (ab_send(send_row_size, send_col_size))
1258 ab_send = 0.0_dp
1259
1260 ! first loop over row since in this way we can cycle
1261 DO iib = 1, send_row_size
1262 i_global = mp2_env%ri_grad%P_mo(kspin)%matrix_struct%l2g_row(iib, send_prow)
1263 IF (i_global <= homo) cycle
1264 i_global = i_global - homo
1265 IF (.NOT. (my_b_virtual_start <= i_global .AND. i_global <= my_b_virtual_end)) cycle
1266 DO jjb = 1, send_col_size
1267 j_global = mp2_env%ri_grad%P_mo(kspin)%matrix_struct%l2g_col(jjb, send_pcol)
1268 IF (j_global <= homo) cycle
1269 j_global = j_global - homo
1270 ab_send(iib, jjb) = mp2_env%ri_grad%P_ab(kspin)%array(i_global - my_b_virtual_start + 1, j_global)
1271 END DO
1272 END DO
1273
1274 ab_rec = 0.0_dp
1275 CALL para_env_sub%sendrecv(ab_send, proc_send, &
1276 ab_rec, proc_receive)
1277 mp2_env%ri_grad%P_mo(kspin)%local_data(1:nrow_local, 1:ncol_local) = &
1278 mp2_env%ri_grad%P_mo(kspin)%local_data(1:nrow_local, 1:ncol_local) + &
1279 ab_rec(1:nrow_local, 1:ncol_local)
1280
1281 DEALLOCATE (ab_send)
1282 END DO
1283 DEALLOCATE (ab_rec)
1284 DEALLOCATE (mepos_2_grid)
1285 DEALLOCATE (sizes)
1286
1287 ! deallocate the local P_ab
1288 DEALLOCATE (mp2_env%ri_grad%P_ab(kspin)%array)
1289 CALL timestop(handle2)
1290
1291 ! create also W_MP2_MO
1292 CALL timeset(routinen//"_WMO", handle2)
1293 IF (.NOT. ALLOCATED(mp2_env%ri_grad%W_mo)) THEN
1294 ALLOCATE (mp2_env%ri_grad%W_mo(SIZE(mp2_env%ri_grad%mo_coeff_o)))
1295 END IF
1296
1297 CALL cp_fm_create(mp2_env%ri_grad%W_mo(kspin), fm_struct_tmp, name="W_MP2_MO")
1298 CALL cp_fm_struct_release(fm_struct_tmp)
1299
1300 ! all block
1301 CALL parallel_gemm('T', 'N', nmo, nmo, nao, 2.0_dp*factor, &
1302 l_mu_q, mo_coeff, 0.0_dp, mp2_env%ri_grad%W_mo(kspin), &
1303 a_first_col=1, &
1304 a_first_row=1, &
1305 b_first_col=1, &
1306 b_first_row=1, &
1307 c_first_col=1, &
1308 c_first_row=1)
1309
1310 ! occ-occ block
1311 CALL parallel_gemm('T', 'N', homo, homo, nao, -2.0_dp*factor, &
1312 l_mu_q, mo_coeff, 0.0_dp, mp2_env%ri_grad%W_mo(kspin), &
1313 a_first_col=1, &
1314 a_first_row=1, &
1315 b_first_col=1, &
1316 b_first_row=1, &
1317 c_first_col=1, &
1318 c_first_row=1)
1319
1320 ! occ-virt block
1321 CALL parallel_gemm('T', 'N', homo, virtual, nao, 2.0_dp*factor, &
1322 mo_coeff, l_mu_q, 0.0_dp, mp2_env%ri_grad%W_mo(kspin), &
1323 a_first_col=1, &
1324 a_first_row=1, &
1325 b_first_col=homo + 1, &
1326 b_first_row=1, &
1327 c_first_col=homo + 1, &
1328 c_first_row=1)
1329 CALL timestop(handle2)
1330
1331 ! Calculate occ-virt block of the lagrangian in MO
1332 CALL timeset(routinen//"_Ljb", handle2)
1333 IF (.NOT. ALLOCATED(mp2_env%ri_grad%L_jb)) THEN
1334 ALLOCATE (mp2_env%ri_grad%L_jb(SIZE(mp2_env%ri_grad%mo_coeff_o)))
1335 END IF
1336
1337 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
1338 nrow_global=homo, ncol_global=virtual)
1339 CALL cp_fm_create(mp2_env%ri_grad%L_jb(kspin), fm_struct_tmp, name="fm_L_jb")
1340 CALL cp_fm_struct_release(fm_struct_tmp)
1341
1342 ! first Virtual
1343 CALL parallel_gemm('T', 'N', homo, virtual, nao, 2.0_dp*factor, &
1344 l_mu_q, mo_coeff, 0.0_dp, mp2_env%ri_grad%L_jb(kspin), &
1345 a_first_col=1, &
1346 a_first_row=1, &
1347 b_first_col=homo + 1, &
1348 b_first_row=1, &
1349 c_first_col=1, &
1350 c_first_row=1)
1351 ! then occupied
1352 CALL parallel_gemm('T', 'N', homo, virtual, nao, 2.0_dp*factor, &
1353 mo_coeff, l_mu_q, 1.0_dp, mp2_env%ri_grad%L_jb(kspin), &
1354 a_first_col=1, &
1355 a_first_row=1, &
1356 b_first_col=homo + 1, &
1357 b_first_row=1, &
1358 c_first_col=1, &
1359 c_first_row=1)
1360
1361 ! finally release L_mu_q
1362 CALL cp_fm_release(l_mu_q)
1363 CALL timestop(handle2)
1364
1365 ! here we should be done next CPHF
1366
1367 DEALLOCATE (pos_info)
1368
1369 CALL timestop(handle)
1370
1371 END SUBROUTINE create_w_p
1372
1373END MODULE mp2_ri_grad
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
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_transposed(transposed, normal, shallow_data_copy, transpose_distribution, use_distribution)
...
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)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
DBCSR operations in CP2K.
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.
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_to_fm_submat(msource, mtarget, nrow, ncol, s_firstrow, s_firstcol, t_firstrow, t_firstcol)
copy just a part ot the 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
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_eri_mme
integer, parameter, public ri_rpa_method_gpw
integer, parameter, public ri_mp2_method_gpw
integer, parameter, public ri_mp2_laplace
integer, parameter, public do_eri_gpw
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
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.
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)
type(mp_request_type), parameter, public mp_request_null
Routines to calculate 2c- and 3c-integrals for RI with GPW.
Definition mp2_eri_gpw.F:13
subroutine, public integrate_potential_forces_3c_2c(matrix_p_munu, rho_r, rho_g, task_list_sub, pw_env_sub, potential_parameter, ks_env, poisson_env, pot_g, use_virial, rho_g_copy, dvg, h_stress, para_env_sub, kind_of, atom_of_kind, qs_kind_set, particle_set, cell, lll, force, dft_control)
Integrates potential of two Gaussians to a potential.
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 integrate_potential_forces_2c(rho_r, lll, rho_g, atomic_kind_set, qs_kind_set, particle_set, cell, pw_env_sub, poisson_env, pot_g, potential_parameter, use_virial, rho_g_copy, dvg, kind_of, atom_of_kind, g_pq_local, force, h_stress, para_env_sub, dft_control, psi_l, factor)
Integrates the potential of a RI function obtaining the forces and stress tensor.
subroutine, public integrate_potential_forces_3c_1c(mat_munu, rho_r, matrix_p_munu, qs_env, pw_env_sub, task_list_sub)
Takes the precomputed potential of an RI wave-function and determines matrix element and gradients wi...
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_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
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
pure subroutine, public mp2_eri_deallocate_forces(force)
...
Definition mp2_eri.F:5842
Routines to calculate gradients of RI-GPW-MP2 energy using pw.
Definition mp2_ri_grad.F:13
subroutine, public calc_ri_mp2_nonsep(qs_env, mp2_env, para_env, para_env_sub, cell, particle_set, atomic_kind_set, qs_kind_set, mo_coeff, dimen_ri, eigenval, my_group_l_start, my_group_l_end, my_group_l_size, sab_orb_sub, mat_munu, blacs_env_sub)
Calculate the non-separable part of the gradients and update the Lagrangian.
Types needed for MP2 calculations.
Definition mp2_types.F:14
basic linear algebra operations for full matrixes
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, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
subroutine, public zero_qs_force(qs_force)
Initialize a Quickstep force data structure.
subroutine, public allocate_qs_force(qs_force, natom_of_kind)
Allocate a Quickstep force data structure.
Define the quickstep kind type and their sub types.
Define the neighbor list data types and the corresponding functionality.
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
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.
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...