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