Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Interface to direct methods for electron repulsion integrals for MP2.
10 : ! **************************************************************************************************
11 : #:def conditional(n)
12 : $:'' if n else '.NOT.'
13 : #:enddef
14 :
15 : MODULE mp2_eri
16 : USE ai_contraction_sphi, ONLY: ab_contract, &
17 : abc_contract
18 : USE ai_coulomb, ONLY: coulomb2_new, &
19 : coulomb3
20 : USE atomic_kind_types, ONLY: atomic_kind_type, &
21 : get_atomic_kind_set
22 : USE basis_set_types, ONLY: gto_basis_set_p_type, &
23 : gto_basis_set_type
24 : USE cell_types, ONLY: cell_type, &
25 : pbc
26 : USE cp_eri_mme_interface, ONLY: cp_eri_mme_finalize, &
27 : cp_eri_mme_init_read_input, &
28 : cp_eri_mme_param, &
29 : cp_eri_mme_set_params
30 : USE message_passing, ONLY: mp_para_env_type
31 : USE cp_dbcsr_api, ONLY: dbcsr_get_block_p, &
32 : dbcsr_p_type
33 : USE eri_mme_integrate, ONLY: eri_mme_2c_integrate, &
34 : eri_mme_3c_integrate
35 : USE eri_mme_test, ONLY: eri_mme_2c_perf_acc_test, &
36 : eri_mme_3c_perf_acc_test
37 : USE eri_mme_types, ONLY: eri_mme_param, &
38 : eri_mme_set_potential, eri_mme_coulomb, eri_mme_longrange
39 : USE input_constants, ONLY: do_eri_gpw, &
40 : do_eri_mme, &
41 : do_eri_os, &
42 : do_potential_coulomb, &
43 : do_potential_long
44 : USE input_section_types, ONLY: section_vals_get_subs_vals, &
45 : section_vals_type, &
46 : section_vals_val_get
47 : USE kinds, ONLY: dp
48 : USE libint_2c_3c, ONLY: libint_potential_type
49 : USE orbital_pointers, ONLY: coset, &
50 : init_orbital_pointers, &
51 : ncoset
52 : USE particle_types, ONLY: particle_type
53 : USE qs_environment_types, ONLY: get_qs_env, &
54 : qs_environment_type
55 : USE qs_integral_utils, ONLY: basis_set_list_setup
56 : USE qs_kind_types, ONLY: get_qs_kind, &
57 : qs_kind_type
58 : USE qs_neighbor_list_types, ONLY: get_iterator_info, &
59 : get_neighbor_list_set_p, &
60 : neighbor_list_iterate, &
61 : neighbor_list_iterator_create, &
62 : neighbor_list_iterator_p_type, &
63 : neighbor_list_iterator_release, &
64 : neighbor_list_set_p_type
65 : USE util, ONLY: get_limit
66 : USE cp_eri_mme_interface, ONLY: cp_eri_mme_update_local_counts
67 : #include "./base/base_uses.f90"
68 :
69 : IMPLICIT NONE
70 :
71 : PRIVATE
72 :
73 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
74 :
75 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mp2_eri'
76 :
77 : PUBLIC :: &
78 : mp2_eri_2c_integrate, &
79 : mp2_eri_3c_integrate, &
80 : mp2_eri_allocate_forces, &
81 : mp2_eri_deallocate_forces, &
82 : mp2_eri_force, &
83 : integrate_set_2c, &
84 : convert_potential_type
85 :
86 : TYPE mp2_eri_force
87 : REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: forces
88 : END TYPE mp2_eri_force
89 :
90 : CONTAINS
91 :
92 : ! **************************************************************************************************
93 : !> \brief high-level integration routine for 2c integrals over CP2K basis sets.
94 : !> Contiguous column-wise distribution and parallelization over pairs of sets.
95 : !> \param param ...
96 : !> \param para_env mpi environment for local columns
97 : !> \param potential_parameter ...
98 : !> \param qs_env ...
99 : !> \param basis_type_a ...
100 : !> \param basis_type_b ...
101 : !> \param hab columns of ERI matrix
102 : !> \param first_b first column of hab
103 : !> \param last_b last column of hab
104 : !> \param eri_method ...
105 : !> \param pab ...
106 : !> \param force_a ...
107 : !> \param force_b ...
108 : !> \param hdab ...
109 : !> \param hadb ...
110 : !> \param reflection_z_a ...
111 : !> \param reflection_z_b ...
112 : !> \param do_reflection_a ...
113 : !> \param do_reflection_b ...
114 : ! **************************************************************************************************
115 320 : SUBROUTINE mp2_eri_2c_integrate(param, potential_parameter, para_env, qs_env, basis_type_a, basis_type_b, hab, first_b, &
116 320 : last_b, eri_method, pab, force_a, force_b, hdab, hadb, &
117 : reflection_z_a, reflection_z_b, do_reflection_a, do_reflection_b)
118 : TYPE(cp_eri_mme_param), INTENT(INOUT) :: param
119 : TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
120 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
121 : TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
122 : CHARACTER(len=*), INTENT(IN), OPTIONAL :: basis_type_a, basis_type_b
123 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: hab
124 : INTEGER, INTENT(IN) :: first_b, last_b
125 : INTEGER, INTENT(IN), OPTIONAL :: eri_method
126 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
127 : OPTIONAL :: pab
128 : TYPE(mp2_eri_force), ALLOCATABLE, &
129 : DIMENSION(:), INTENT(OUT), OPTIONAL :: force_a, force_b
130 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT), &
131 : OPTIONAL :: hdab, hadb
132 : REAL(KIND=dp), INTENT(IN), OPTIONAL :: reflection_z_a, reflection_z_b
133 : LOGICAL, INTENT(IN), OPTIONAL :: do_reflection_a, do_reflection_b
134 :
135 : CHARACTER(len=*), PARAMETER :: routineN = 'mp2_eri_2c_integrate'
136 :
137 : INTEGER :: atom_a, atom_b, atom_end, atom_start, first_set, G_count, handle, iatom, ikind, &
138 : iset, jatom, jkind, jset, jset_end, jset_start, last_set, my_eri_method, my_setpair, &
139 : n_setpair, natom, nkind, nseta, nseta_total, nsetb, nsetb_total, offset_a_end, &
140 : offset_a_start, offset_b_end, offset_b_start, R_count, set_end, set_offset_end, &
141 : set_offset_start, set_start, sgfa, sgfb
142 320 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of, natom_of_kind
143 320 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: eri_offsets
144 320 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
145 320 : npgfb, nsgfa, nsgfb
146 320 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
147 : LOGICAL :: map_it_here, my_do_reflection_a, &
148 : my_do_reflection_b
149 : REAL(KIND=dp) :: dab
150 : REAL(KIND=dp), DIMENSION(3) :: ra, rab, rb
151 320 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: sphi_a, sphi_b, zeta, zetb
152 320 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
153 : TYPE(cell_type), POINTER :: cell
154 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
155 320 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
156 320 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
157 :
158 320 : CALL timeset(routineN, handle)
159 :
160 320 : my_eri_method = do_eri_mme
161 320 : IF (PRESENT(eri_method)) my_eri_method = eri_method
162 :
163 320 : my_do_reflection_a = .FALSE.
164 320 : IF (PRESENT(do_reflection_a) .AND. PRESENT(reflection_z_a)) my_do_reflection_a = do_reflection_a
165 :
166 320 : my_do_reflection_b = .FALSE.
167 320 : IF (PRESENT(do_reflection_b) .AND. PRESENT(reflection_z_b)) my_do_reflection_b = do_reflection_b
168 :
169 320 : G_count = 0; R_count = 0;
170 : ! get mapping between ERIs and atoms, sets, set offsets
171 320 : CALL get_eri_offsets(qs_env, basis_type_b, eri_offsets)
172 :
173 320 : atom_start = eri_offsets(first_b, 1)
174 320 : set_start = eri_offsets(first_b, 2)
175 320 : set_offset_start = eri_offsets(first_b, 3)
176 :
177 320 : atom_end = eri_offsets(last_b, 1)
178 320 : set_end = eri_offsets(last_b, 2)
179 320 : set_offset_end = eri_offsets(last_b, 3)
180 :
181 : ! get QS stuff
182 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
183 320 : cell=cell, particle_set=particle_set, natom=natom, nkind=nkind)
184 :
185 320 : CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of, natom_of_kind=natom_of_kind, atom_of_kind=atom_of_kind)
186 :
187 320 : IF (PRESENT(force_a)) CALL mp2_eri_allocate_forces(force_a, natom_of_kind)
188 320 : IF (PRESENT(force_b)) CALL mp2_eri_allocate_forces(force_b, natom_of_kind)
189 :
190 : ! get total number of local set pairs to integrate
191 320 : nseta_total = 0
192 1224 : DO iatom = 1, natom
193 904 : ikind = kind_of(iatom)
194 904 : CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, basis_type=basis_type_a)
195 1224 : nseta_total = nseta_total + basis_set_a%nset
196 : END DO
197 :
198 : nsetb_total = 0
199 898 : DO jatom = atom_start, atom_end
200 578 : jkind = kind_of(jatom)
201 578 : CALL get_qs_kind(qs_kind=qs_kind_set(jkind), basis_set=basis_set_b, basis_type=basis_type_b)
202 898 : nsetb_total = nsetb_total + basis_set_b%nset
203 : END DO
204 :
205 : n_setpair = nseta_total*nsetb_total
206 :
207 320 : my_setpair = 0
208 :
209 320 : offset_a_end = 0
210 1224 : DO iatom = 1, natom
211 904 : ikind = kind_of(iatom)
212 904 : atom_a = atom_of_kind(iatom)
213 904 : CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set_a, basis_type=basis_type_a)
214 :
215 904 : first_sgfa => basis_set_a%first_sgf
216 904 : la_max => basis_set_a%lmax
217 904 : la_min => basis_set_a%lmin
218 904 : nseta = basis_set_a%nset
219 904 : nsgfa => basis_set_a%nsgf_set
220 904 : sphi_a => basis_set_a%sphi
221 904 : zeta => basis_set_a%zet
222 904 : npgfa => basis_set_a%npgf
223 :
224 904 : ra(:) = pbc(particle_set(iatom)%r, cell)
225 :
226 904 : IF (my_do_reflection_a) THEN
227 0 : ra(3) = 2.0_dp*reflection_z_a - ra(3)
228 : END IF
229 :
230 9390 : DO iset = 1, nseta
231 8166 : offset_a_start = offset_a_end
232 8166 : offset_a_end = offset_a_end + nsgfa(iset)
233 8166 : sgfa = first_sgfa(1, iset)
234 :
235 8166 : offset_b_end = 0
236 25191 : DO jatom = atom_start, atom_end
237 16121 : jkind = kind_of(jatom)
238 16121 : atom_b = atom_of_kind(jatom)
239 16121 : CALL get_qs_kind(qs_kind=qs_kind_set(jkind), basis_set=basis_set_b, basis_type=basis_type_b)
240 :
241 16121 : first_sgfb => basis_set_b%first_sgf
242 16121 : lb_max => basis_set_b%lmax
243 16121 : lb_min => basis_set_b%lmin
244 16121 : nsetb = basis_set_b%nset
245 16121 : nsgfb => basis_set_b%nsgf_set
246 16121 : sphi_b => basis_set_b%sphi
247 16121 : zetb => basis_set_b%zet
248 16121 : npgfb => basis_set_b%npgf
249 :
250 16121 : rb(:) = pbc(particle_set(jatom)%r, cell)
251 :
252 16121 : IF (my_do_reflection_b) THEN
253 0 : rb(3) = 2.0_dp*reflection_z_b - rb(3)
254 : END IF
255 :
256 64484 : rab(:) = ra(:) - rb(:) ! pbc not needed?
257 : dab = SQRT(rab(1)**2 + rab(2)**2 + rab(3)**2)
258 :
259 16121 : jset_start = 1; jset_end = nsetb
260 16121 : IF (jatom == atom_start) jset_start = set_start
261 16121 : IF (jatom == atom_end) jset_end = set_end
262 :
263 148012 : DO jset = jset_start, jset_end
264 123725 : first_set = 1; last_set = nsgfb(jset)
265 123725 : IF (jset == jset_start .AND. jatom == atom_start) first_set = set_offset_start
266 123725 : IF (jset == jset_end .AND. jatom == atom_end) last_set = set_offset_end
267 :
268 123725 : offset_b_start = offset_b_end
269 123725 : offset_b_end = offset_b_end + last_set + 1 - first_set
270 123725 : sgfb = first_sgfb(1, jset)
271 123725 : my_setpair = my_setpair + 1
272 123725 : map_it_here = MODULO(my_setpair, para_env%num_pe) == para_env%mepos
273 :
274 139846 : IF (map_it_here) THEN
275 : #!some fypp magic to deal with combinations of optional arguments
276 : #:for doforce_1 in [0, 1]
277 : #:for doforce_2 in [0, 1]
278 241144 : IF (${conditional(doforce_1)}$PRESENT(force_a) .AND. &
279 : ${conditional(doforce_2)}$PRESENT(force_b)) THEN
280 :
281 : CALL integrate_set_2c( &
282 : param%par, potential_parameter, &
283 : la_min(iset), la_max(iset), &
284 : lb_min(jset), lb_max(jset), &
285 : npgfa(iset), npgfb(jset), &
286 : zeta(:, iset), zetb(:, jset), &
287 : ra, rb, &
288 : hab, nsgfa(iset), last_set - first_set + 1, &
289 : offset_a_start, offset_b_start, &
290 : 0, first_set - 1, &
291 : sphi_a, sphi_b, &
292 : sgfa, sgfb, nsgfa(iset), nsgfb(jset), &
293 : my_eri_method, &
294 : pab, &
295 : $: 'force_a=force_a(ikind)%forces(:, atom_a), &'*doforce_1
296 : $: 'force_b=force_b(jkind)%forces(:, atom_b), &'*doforce_2
297 : hdab=hdab, hadb=hadb, &
298 : G_count=G_count, R_count=R_count, &
299 472144 : do_reflection_a=do_reflection_a, do_reflection_b=do_reflection_b)
300 : END IF
301 : #:endfor
302 : #:endfor
303 : END IF
304 : END DO
305 : END DO
306 : END DO
307 : END DO
308 :
309 320 : IF (my_eri_method == do_eri_mme) THEN
310 :
311 156 : CALL cp_eri_mme_update_local_counts(param, para_env, G_count_2c=G_count, R_count_2c=R_count)
312 :
313 : END IF
314 :
315 1998312 : CALL para_env%sum(hab)
316 320 : IF (PRESENT(hdab)) CALL para_env%sum(hdab)
317 320 : IF (PRESENT(hadb)) CALL para_env%sum(hadb)
318 :
319 320 : CALL timestop(handle)
320 640 : END SUBROUTINE mp2_eri_2c_integrate
321 :
322 : ! **************************************************************************************************
323 : !> \brief Integrate set pair and contract with sphi matrix.
324 : !> \param param ...
325 : !> \param potential_parameter ...
326 : !> \param la_min ...
327 : !> \param la_max ...
328 : !> \param lb_min ...
329 : !> \param lb_max ...
330 : !> \param npgfa ...
331 : !> \param npgfb ...
332 : !> \param zeta ...
333 : !> \param zetb ...
334 : !> \param ra ...
335 : !> \param rb ...
336 : !> \param hab ...
337 : !> \param n_hab_a ...
338 : !> \param n_hab_b ...
339 : !> \param offset_hab_a ...
340 : !> \param offset_hab_b ...
341 : !> \param offset_set_a ...
342 : !> \param offset_set_b ...
343 : !> \param sphi_a ...
344 : !> \param sphi_b ...
345 : !> \param sgfa ...
346 : !> \param sgfb ...
347 : !> \param nsgfa ...
348 : !> \param nsgfb ...
349 : !> \param eri_method ...
350 : !> \param pab ...
351 : !> \param force_a ...
352 : !> \param force_b ...
353 : !> \param hdab ...
354 : !> \param hadb ...
355 : !> \param G_count ...
356 : !> \param R_count ...
357 : !> \param do_reflection_a ...
358 : !> \param do_reflection_b ...
359 : ! **************************************************************************************************
360 252440 : SUBROUTINE integrate_set_2c(param, potential_parameter, la_min, la_max, lb_min, lb_max, npgfa, npgfb, zeta, zetb, &
361 126220 : ra, rb, hab, n_hab_a, n_hab_b, offset_hab_a, offset_hab_b, &
362 126220 : offset_set_a, offset_set_b, sphi_a, sphi_b, sgfa, sgfb, nsgfa, nsgfb, &
363 126220 : eri_method, pab, force_a, force_b, hdab, hadb, G_count, R_count, &
364 : do_reflection_a, do_reflection_b)
365 : TYPE(eri_mme_param), INTENT(INOUT) :: param
366 : TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
367 : INTEGER, INTENT(IN) :: la_min, la_max, lb_min, lb_max, npgfa
368 : REAL(KIND=dp), DIMENSION(npgfa), INTENT(IN) :: zeta
369 : INTEGER, INTENT(IN) :: npgfb
370 : REAL(KIND=dp), DIMENSION(npgfb), INTENT(IN) :: zetb
371 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: ra, rb
372 : REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT) :: hab
373 : INTEGER, INTENT(IN) :: n_hab_a, n_hab_b, offset_hab_a, &
374 : offset_hab_b, offset_set_a, &
375 : offset_set_b
376 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: sphi_a
377 : INTEGER, INTENT(IN) :: sgfa, nsgfa
378 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: sphi_b
379 : INTEGER, INTENT(IN) :: sgfb, nsgfb, eri_method
380 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
381 : OPTIONAL :: pab
382 : REAL(KIND=dp), DIMENSION(3), INTENT(INOUT), &
383 : OPTIONAL :: force_a, force_b
384 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT), &
385 : OPTIONAL :: hdab, hadb
386 : INTEGER, INTENT(INOUT), OPTIONAL :: G_count, R_count
387 : LOGICAL, INTENT(IN), OPTIONAL :: do_reflection_a, do_reflection_b
388 :
389 : CHARACTER(LEN=*), PARAMETER :: routineN = 'integrate_set_2c'
390 :
391 : INTEGER :: ax, ay, az, bx, by, bz, hab_a_end, hab_a_start, hab_b_end, hab_b_start, handle, &
392 : i_xyz, ico, icox, icoy, icoz, ipgf, jco, jcox, jcoy, jcoz, jpgf, la, la_max_d, lb, &
393 : lb_max_d, na, nb, ncoa, ncob, set_a_end, set_a_start, set_b_end, set_b_start, &
394 : sphi_a_start, sphi_b_start
395 : INTEGER, DIMENSION(3) :: la_xyz, lb_xyz
396 : LOGICAL :: calculate_forces, my_do_reflection_a, &
397 : my_do_reflection_b, do_force_a, do_force_b
398 : REAL(KIND=dp) :: rab2
399 126220 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: f_work
400 126220 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: hab_contr, hab_uncontr, &
401 126220 : hab_uncontr_d, pab_hh, pab_hs, &
402 126220 : pab_ss
403 126220 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: hadb_contr, hadb_uncontr, hdab_contr, &
404 126220 : hdab_uncontr, v_work
405 :
406 : ! note: tested only for one exponent per pair (npgfa = npgfb = 1)
407 126220 : CALL timeset(routineN, handle)
408 :
409 126220 : my_do_reflection_a = .FALSE.
410 126220 : IF (PRESENT(do_reflection_a)) my_do_reflection_a = do_reflection_a
411 :
412 126220 : my_do_reflection_b = .FALSE.
413 126220 : IF (PRESENT(do_reflection_b)) my_do_reflection_b = do_reflection_b
414 :
415 126220 : do_force_a = PRESENT(force_a) .OR. PRESENT(hdab)
416 126220 : do_force_b = PRESENT(force_b) .OR. PRESENT(hadb)
417 126220 : calculate_forces = do_force_a .OR. do_force_b
418 :
419 126220 : IF (PRESENT(force_a) .OR. PRESENT(force_b)) THEN
420 10144 : CPASSERT(PRESENT(pab))
421 30432 : CPASSERT(ALL(SHAPE(pab) .EQ. SHAPE(hab)))
422 : END IF
423 :
424 126220 : la_max_d = la_max
425 126220 : lb_max_d = lb_max
426 :
427 126220 : IF (calculate_forces) THEN
428 15792 : IF (do_force_a) la_max_d = la_max + 1
429 15792 : IF (do_force_b) lb_max_d = lb_max + 1
430 : END IF
431 :
432 126220 : ncoa = npgfa*ncoset(la_max)
433 126220 : ncob = npgfb*ncoset(lb_max)
434 :
435 126220 : rab2 = (ra(1) - rb(1))**2 + (ra(2) - rb(2))**2 + (ra(3) - rb(3))**2
436 :
437 5108196 : ALLOCATE (hab_uncontr_d(ncoset(la_max_d), ncoset(lb_max_d))); hab_uncontr_d(:, :) = 0.0_dp
438 4577496 : ALLOCATE (hab_uncontr(ncoa, ncob)); hab_uncontr(:, :) = 0.0_dp
439 126220 : IF (PRESENT(hdab)) THEN
440 655468 : ALLOCATE (hdab_uncontr(3, ncoa, ncob)); hdab_uncontr(:, :, :) = 0.0_dp
441 : END IF
442 126220 : IF (PRESENT(hadb)) THEN
443 0 : ALLOCATE (hadb_uncontr(3, ncoa, ncob)); hadb_uncontr(:, :, :) = 0.0_dp
444 : END IF
445 :
446 126220 : hab_a_start = offset_hab_a + 1; hab_a_end = offset_hab_a + n_hab_a
447 126220 : hab_b_start = offset_hab_b + 1; hab_b_end = offset_hab_b + n_hab_b
448 126220 : set_a_start = offset_set_a + 1; set_a_end = offset_set_a + n_hab_a
449 126220 : set_b_start = offset_set_b + 1; set_b_end = offset_set_b + n_hab_b
450 :
451 126220 : IF (eri_method == do_eri_mme) THEN
452 48982 : CALL eri_mme_set_potential(param, convert_potential_type(potential_parameter%potential_type), potential_parameter%omega)
453 :
454 48982 : IF (calculate_forces .AND. PRESENT(pab)) THEN
455 : ! uncontracted hermite-gaussian representation of density matrix
456 10144 : sphi_a_start = sgfa - 1 + set_a_start
457 10144 : sphi_b_start = sgfb - 1 + set_b_start
458 :
459 40576 : ALLOCATE (pab_ss(n_hab_a, n_hab_b))
460 121184 : pab_ss(:, :) = pab(hab_a_start:hab_a_end, hab_b_start:hab_b_end)
461 60864 : ALLOCATE (pab_hs(ncoa, n_hab_b)); ALLOCATE (pab_hh(ncoa, ncob))
462 : CALL dgemm("N", "N", ncoa, n_hab_b, n_hab_a, 1.0_dp, &
463 10144 : sphi_a(:, sphi_a_start), SIZE(sphi_a, 1), pab_ss, n_hab_a, 0.0_dp, pab_hs, ncoa)
464 : CALL dgemm("N", "T", ncoa, ncob, n_hab_b, 1.0_dp, &
465 10144 : pab_hs, ncoa, sphi_b(:, sphi_b_start), SIZE(sphi_b, 1), 0.0_dp, pab_hh, ncoa)
466 : END IF
467 :
468 97964 : DO ipgf = 1, npgfa
469 48982 : na = (ipgf - 1)*ncoset(la_max)
470 146946 : DO jpgf = 1, npgfb
471 48982 : nb = (jpgf - 1)*ncoset(lb_max)
472 2130574 : hab_uncontr_d(:, :) = 0.0_dp
473 : CALL eri_mme_2c_integrate(param, &
474 : la_min, la_max_d, lb_min, lb_max_d, &
475 195928 : zeta(ipgf), zetb(jpgf), ra - rb, hab_uncontr_d, 0, 0, G_count, R_count)
476 :
477 : hab_uncontr(na + 1:na + ncoset(la_max), nb + 1:nb + ncoset(lb_max)) = &
478 1599874 : hab_uncontr_d(:ncoset(la_max), :ncoset(lb_max))
479 :
480 97964 : IF (calculate_forces) THEN
481 31584 : DO lb = lb_min, lb_max
482 62368 : DO bx = 0, lb
483 99346 : DO by = 0, lb - bx
484 52770 : bz = lb - bx - by
485 52770 : jco = coset(bx, by, bz)
486 52770 : jcox = coset(bx + 1, by, bz)
487 52770 : jcoy = coset(bx, by + 1, bz)
488 52770 : jcoz = coset(bx, by, bz + 1)
489 136324 : DO la = la_min, la_max
490 209820 : DO ax = 0, la
491 336900 : DO ay = 0, la - ax
492 179850 : az = la - ax - ay
493 719400 : la_xyz = [ax, ay, az]
494 719400 : lb_xyz = [bx, by, bz]
495 179850 : ico = coset(ax, ay, az)
496 179850 : icox = coset(ax + 1, ay, az)
497 179850 : icoy = coset(ax, ay + 1, az)
498 179850 : icoz = coset(ax, ay, az + 1)
499 179850 : IF (PRESENT(force_a)) THEN
500 : force_a(:) = force_a(:) + 2.0_dp*zeta(ipgf)* &
501 : [pab_hh(na + ico, nb + jco)*hab_uncontr_d(icox, jco), &
502 : pab_hh(na + ico, nb + jco)*hab_uncontr_d(icoy, jco), &
503 473800 : pab_hh(na + ico, nb + jco)*hab_uncontr_d(icoz, jco)]
504 : END IF
505 179850 : IF (PRESENT(force_b)) THEN
506 : force_b(:) = force_b(:) + 2.0_dp*zetb(jpgf)* &
507 : [pab_hh(na + ico, nb + jco)*hab_uncontr_d(ico, jcox), &
508 : pab_hh(na + ico, nb + jco)*hab_uncontr_d(ico, jcoy), &
509 0 : pab_hh(na + ico, nb + jco)*hab_uncontr_d(ico, jcoz)]
510 : END IF
511 179850 : IF (PRESENT(hdab)) THEN
512 : hdab_uncontr(1:3, na + ico, nb + jco) = 2.0_dp*zeta(ipgf)* &
513 : [hab_uncontr_d(icox, jco), &
514 : hab_uncontr_d(icoy, jco), &
515 245600 : hab_uncontr_d(icoz, jco)]
516 : END IF
517 284130 : IF (PRESENT(hadb)) THEN
518 : hadb_uncontr(1:3, na + ico, nb + jco) = 2.0_dp*zetb(jpgf)* &
519 : [hab_uncontr_d(ico, jcox), &
520 : hab_uncontr_d(ico, jcoy), &
521 0 : hab_uncontr_d(ico, jcoz)]
522 : END IF
523 : END DO
524 : END DO
525 : END DO
526 : END DO
527 : END DO
528 : END DO
529 : END IF
530 :
531 : END DO
532 : END DO
533 :
534 77238 : ELSE IF (eri_method == do_eri_os) THEN
535 :
536 77238 : IF (calculate_forces) CPABORT("NYI")
537 :
538 231714 : ALLOCATE (f_work(0:la_max + lb_max + 2))
539 386190 : ALLOCATE (v_work(ncoa, ncob, la_max + lb_max + 1))
540 12007555 : v_work(:, :, :) = 0.0_dp
541 455532 : f_work = 0.0_dp
542 :
543 : CALL coulomb2_new(la_max, npgfa, zeta, la_min, lb_max, npgfb, zetb, lb_min, &
544 308952 : rb - ra, rab2, hab_uncontr, v_work, f_work)
545 :
546 77238 : DEALLOCATE (v_work, f_work)
547 :
548 0 : ELSE IF (eri_method == do_eri_gpw) THEN
549 :
550 0 : CPABORT("GPW not enabled in the ERI interface.")
551 :
552 : END IF
553 :
554 504880 : ALLOCATE (hab_contr(nsgfa, nsgfb))
555 126220 : IF (PRESENT(hdab)) THEN
556 22592 : ALLOCATE (hdab_contr(3, nsgfa, nsgfb))
557 : END IF
558 126220 : IF (PRESENT(hadb)) THEN
559 0 : ALLOCATE (hadb_contr(3, nsgfa, nsgfb))
560 : END IF
561 :
562 126220 : CALL ab_contract(hab_contr, hab_uncontr, sphi_a(:, sgfa:), sphi_b(:, sgfb:), ncoa, ncob, nsgfa, nsgfb)
563 :
564 126220 : IF (calculate_forces) THEN
565 63168 : DO i_xyz = 1, 3
566 47376 : IF (PRESENT(hdab)) THEN
567 : CALL ab_contract(hdab_contr(i_xyz, :, :), hdab_uncontr(i_xyz, :, :), &
568 16944 : sphi_a(:, sgfa:), sphi_b(:, sgfb:), ncoa, ncob, nsgfa, nsgfb)
569 : END IF
570 63168 : IF (PRESENT(hadb)) THEN
571 : CALL ab_contract(hadb_contr(i_xyz, :, :), hadb_uncontr(i_xyz, :, :), &
572 0 : sphi_a(:, sgfa:), sphi_b(:, sgfb:), ncoa, ncob, nsgfa, nsgfb)
573 : END IF
574 : END DO
575 : END IF
576 :
577 1479668 : hab(hab_a_start:hab_a_end, hab_b_start:hab_b_end) = hab_contr(set_a_start:set_a_end, set_b_start:set_b_end)
578 :
579 126220 : IF (calculate_forces) THEN
580 15792 : IF (PRESENT(hdab)) hdab(:, hab_a_start:hab_a_end, hab_b_start:hab_b_end) = &
581 207536 : hdab_contr(:, set_a_start:set_a_end, set_b_start:set_b_end)
582 15792 : IF (PRESENT(hadb)) hadb(:, hab_a_start:hab_a_end, hab_b_start:hab_b_end) = &
583 0 : hadb_contr(:, set_a_start:set_a_end, set_b_start:set_b_end)
584 : END IF
585 :
586 126220 : CALL timestop(handle)
587 :
588 252440 : END SUBROUTINE integrate_set_2c
589 :
590 : ! **************************************************************************************************
591 : !> \brief high-level integration routine for 3c integrals (ab|c) over CP2K basis sets.
592 : !> For each local function of c, (ab|c) is written to a DBCSR matrix mat_ab.
593 : !> \param param ...
594 : !> \param potential_parameter ...
595 : !> \param para_env ...
596 : !> \param qs_env ...
597 : !> \param first_c start index of local range of c
598 : !> \param last_c end index of local range of c
599 : !> \param mat_ab DBCSR matrices for each c
600 : !> \param basis_type_a ...
601 : !> \param basis_type_b ...
602 : !> \param basis_type_c ...
603 : !> \param sab_nl neighbor list for a, b
604 : !> \param eri_method ...
605 : !> \param pabc ...
606 : !> \param force_a ...
607 : !> \param force_b ...
608 : !> \param force_c ...
609 : !> \param mat_dabc ...
610 : !> \param mat_adbc ...
611 : !> \param mat_abdc ...
612 : ! **************************************************************************************************
613 198 : SUBROUTINE mp2_eri_3c_integrate(param, potential_parameter, para_env, qs_env, &
614 198 : first_c, last_c, mat_ab, &
615 : basis_type_a, basis_type_b, basis_type_c, &
616 : sab_nl, eri_method, &
617 198 : pabc, force_a, force_b, force_c, &
618 198 : mat_dabc, mat_adbc, mat_abdc)
619 : TYPE(cp_eri_mme_param), INTENT(INOUT) :: param
620 : TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
621 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
622 : TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
623 : INTEGER, INTENT(IN) :: first_c, last_c
624 : TYPE(dbcsr_p_type), DIMENSION(last_c - first_c + 1), &
625 : INTENT(INOUT) :: mat_ab
626 : CHARACTER(LEN=*), INTENT(IN) :: basis_type_a, basis_type_b, basis_type_c
627 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
628 : POINTER :: sab_nl
629 : INTEGER, INTENT(IN), OPTIONAL :: eri_method
630 : TYPE(dbcsr_p_type), DIMENSION(last_c - first_c + 1), &
631 : INTENT(INOUT), OPTIONAL :: pabc
632 : TYPE(mp2_eri_force), ALLOCATABLE, &
633 : DIMENSION(:), INTENT(OUT), OPTIONAL :: force_a, force_b, force_c
634 : TYPE(dbcsr_p_type), &
635 : DIMENSION(3, last_c - first_c + 1), INTENT(INOUT), &
636 : OPTIONAL :: mat_dabc, mat_adbc, mat_abdc
637 :
638 : CHARACTER(LEN=*), PARAMETER :: routineN = 'mp2_eri_3c_integrate'
639 :
640 : INTEGER :: atom_a, atom_b, atom_c, atom_end, atom_start, first_set, GG_count, GR_count, &
641 : handle, i_xyz, iatom, ic, icol, ikind, inode, irow, iset, jatom, jkind, jset, katom, &
642 : kkind, kset, kset_end, kset_start, last_jatom, last_set, mepos, my_eri_method, na, natom, &
643 : nb, nc, nkind, nseta, nsetb, nsetc, nthread, offset_a_end, offset_a_start, offset_b_end, &
644 : offset_b_start, offset_c_end, offset_c_start, RR_count, set_end, set_offset_end, &
645 : set_offset_start, set_start, sgfa, sgfb, sgfc
646 198 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of, natom_of_kind
647 198 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: eri_offsets
648 198 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, lc_max, &
649 198 : lc_min, npgfa, npgfb, npgfc, nsgfa, &
650 198 : nsgfb, nsgfc
651 198 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb, first_sgfc
652 : LOGICAL :: calculate_forces, do_symmetric, found, &
653 : to_be_asserted
654 : REAL(KIND=dp) :: dab
655 198 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: habc, pabc_block
656 198 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: habdc, hadbc, hdabc
657 : REAL(KIND=dp), DIMENSION(3) :: ra, rab, rb, rc
658 198 : REAL(KIND=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
659 198 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: munu_block, pab_block, rpgfb, sphi_a, &
660 198 : sphi_b, sphi_c, zeta, zetb, zetc
661 198 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
662 : TYPE(cell_type), POINTER :: cell
663 198 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
664 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b, basis_set_c
665 : TYPE(neighbor_list_iterator_p_type), &
666 198 : DIMENSION(:), POINTER :: nl_iterator
667 198 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
668 198 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
669 :
670 198 : CALL timeset(routineN, handle)
671 :
672 : calculate_forces = PRESENT(force_a) .OR. PRESENT(force_b) .OR. PRESENT(force_c) .OR. &
673 198 : PRESENT(mat_dabc) .OR. PRESENT(mat_adbc) .OR. PRESENT(mat_abdc)
674 :
675 198 : my_eri_method = do_eri_mme
676 198 : IF (PRESENT(eri_method)) my_eri_method = eri_method
677 :
678 198 : IF (PRESENT(force_a) .OR. PRESENT(force_b) .OR. PRESENT(force_c)) THEN
679 26 : CPASSERT(PRESENT(pabc))
680 : END IF
681 :
682 198 : GG_count = 0; GR_count = 0; RR_count = 0
683 :
684 198 : nthread = 1
685 :
686 : ! get mapping between ERIs and atoms, sets, set offsets
687 : CALL get_eri_offsets(qs_env, basis_type_c, eri_offsets)
688 :
689 198 : atom_start = eri_offsets(first_c, 1)
690 198 : set_start = eri_offsets(first_c, 2)
691 198 : set_offset_start = eri_offsets(first_c, 3)
692 :
693 198 : atom_end = eri_offsets(last_c, 1)
694 198 : set_end = eri_offsets(last_c, 2)
695 198 : set_offset_end = eri_offsets(last_c, 3)
696 :
697 : ! get QS stuff
698 : CALL get_qs_env(qs_env, &
699 : atomic_kind_set=atomic_kind_set, &
700 : natom=natom, &
701 : qs_kind_set=qs_kind_set, &
702 : particle_set=particle_set, &
703 : cell=cell, &
704 198 : nkind=nkind)
705 :
706 198 : CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of, natom_of_kind=natom_of_kind)
707 :
708 198 : IF (PRESENT(force_a)) CALL mp2_eri_allocate_forces(force_a, natom_of_kind)
709 198 : IF (PRESENT(force_b)) CALL mp2_eri_allocate_forces(force_b, natom_of_kind)
710 198 : IF (PRESENT(force_c)) CALL mp2_eri_allocate_forces(force_c, natom_of_kind)
711 :
712 198 : nc = last_c - first_c + 1
713 :
714 : ! check for symmetry
715 198 : CPASSERT(SIZE(sab_nl) > 0)
716 198 : CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
717 :
718 198 : IF (do_symmetric) THEN
719 198 : CPASSERT(basis_type_a == basis_type_b)
720 : END IF
721 :
722 1436 : ALLOCATE (basis_set_list_a(nkind), basis_set_list_b(nkind))
723 198 : CALL basis_set_list_setup(basis_set_list_a, basis_type_a, qs_kind_set)
724 198 : CALL basis_set_list_setup(basis_set_list_b, basis_type_b, qs_kind_set)
725 :
726 198 : CALL neighbor_list_iterator_create(nl_iterator, sab_nl, nthread=nthread)
727 :
728 198 : mepos = 0
729 :
730 11912 : DO WHILE (neighbor_list_iterate(nl_iterator, mepos=mepos) == 0)
731 : CALL get_iterator_info(nl_iterator, mepos=mepos, ikind=ikind, jkind=jkind, inode=inode, &
732 11714 : iatom=iatom, jatom=jatom, r=rab)
733 :
734 : ! exclude periodic images because method is periodic intrinsically
735 11714 : IF (inode == 1) last_jatom = 0
736 :
737 11714 : IF (jatom /= last_jatom) THEN
738 942 : last_jatom = jatom
739 : ELSE
740 : CYCLE
741 : END IF
742 :
743 942 : basis_set_a => basis_set_list_a(ikind)%gto_basis_set
744 942 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
745 942 : basis_set_b => basis_set_list_b(jkind)%gto_basis_set
746 942 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
747 942 : atom_a = atom_of_kind(iatom)
748 942 : atom_b = atom_of_kind(jatom)
749 :
750 942 : first_sgfa => basis_set_a%first_sgf
751 942 : la_max => basis_set_a%lmax
752 942 : la_min => basis_set_a%lmin
753 942 : npgfa => basis_set_a%npgf
754 942 : nseta = basis_set_a%nset
755 942 : nsgfa => basis_set_a%nsgf_set
756 942 : set_radius_a => basis_set_a%set_radius
757 942 : sphi_a => basis_set_a%sphi
758 942 : zeta => basis_set_a%zet
759 3300 : na = SUM(nsgfa)
760 :
761 942 : ra(:) = pbc(particle_set(iatom)%r, cell)
762 :
763 : ! basis jkind
764 942 : first_sgfb => basis_set_b%first_sgf
765 942 : lb_max => basis_set_b%lmax
766 942 : lb_min => basis_set_b%lmin
767 942 : npgfb => basis_set_b%npgf
768 942 : nsetb = basis_set_b%nset
769 942 : nsgfb => basis_set_b%nsgf_set
770 942 : rpgfb => basis_set_b%pgf_radius
771 942 : set_radius_b => basis_set_b%set_radius
772 942 : sphi_b => basis_set_b%sphi
773 942 : zetb => basis_set_b%zet
774 3300 : nb = SUM(nsgfb)
775 :
776 942 : rb(:) = pbc(particle_set(jatom)%r, cell)
777 :
778 942 : IF (do_symmetric) THEN
779 942 : IF (iatom <= jatom) THEN
780 628 : irow = iatom
781 628 : icol = jatom
782 : ELSE
783 314 : irow = jatom
784 314 : icol = iatom
785 : END IF
786 : ELSE
787 0 : irow = iatom
788 0 : icol = jatom
789 : END IF
790 :
791 4710 : ALLOCATE (habc(na, nb, nc))
792 1902174 : habc(:, :, :) = 0.0_dp ! needs to be initialized due to screening
793 942 : IF (PRESENT(mat_dabc)) THEN
794 0 : ALLOCATE (hdabc(3, na, nb, nc))
795 0 : hdabc(:, :, :, :) = 0.0_dp
796 : END IF
797 942 : IF (PRESENT(mat_adbc)) THEN
798 0 : ALLOCATE (hadbc(3, na, nb, nc))
799 0 : hadbc(:, :, :, :) = 0.0_dp
800 : END IF
801 942 : IF (PRESENT(mat_abdc)) THEN
802 0 : ALLOCATE (habdc(3, na, nb, nc))
803 0 : habdc(:, :, :, :) = 0.0_dp
804 : END IF
805 :
806 942 : IF (calculate_forces .AND. PRESENT(pabc)) THEN
807 540 : ALLOCATE (pabc_block(na, nb, nc))
808 5613 : DO ic = 1, nc
809 5478 : NULLIFY (pab_block)
810 : CALL dbcsr_get_block_p(matrix=pabc(ic)%matrix, &
811 5478 : row=irow, col=icol, block=pab_block, found=found)
812 5478 : CPASSERT(found)
813 11091 : IF (irow .EQ. iatom) THEN
814 3652 : to_be_asserted = SIZE(pab_block, 1) .EQ. SIZE(pabc_block, 1) .AND. SIZE(pab_block, 2) .EQ. SIZE(pabc_block, 2)
815 0 : CPASSERT(to_be_asserted)
816 188567 : pabc_block(:, :, ic) = pab_block(:, :)
817 : ELSE
818 1826 : to_be_asserted = SIZE(pab_block, 2) .EQ. SIZE(pabc_block, 1) .AND. SIZE(pab_block, 1) .EQ. SIZE(pabc_block, 2)
819 0 : CPASSERT(to_be_asserted)
820 72496 : pabc_block(:, :, ic) = TRANSPOSE(pab_block(:, :))
821 : END IF
822 : END DO
823 : END IF
824 :
825 3768 : rab(:) = pbc(rab, cell)
826 942 : dab = SQRT(rab(1)**2 + rab(2)**2 + rab(3)**2)
827 :
828 942 : offset_a_end = 0
829 3300 : DO iset = 1, nseta
830 2358 : offset_a_start = offset_a_end
831 2358 : offset_a_end = offset_a_end + nsgfa(iset)
832 2358 : sgfa = first_sgfa(1, iset)
833 :
834 2358 : offset_b_end = 0
835 9924 : DO jset = 1, nsetb
836 6624 : offset_b_start = offset_b_end
837 6624 : offset_b_end = offset_b_end + nsgfb(jset)
838 :
839 6624 : sgfb = first_sgfb(1, jset)
840 :
841 : ! Screening
842 6624 : IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
843 :
844 : offset_c_end = 0
845 20760 : DO katom = atom_start, atom_end
846 :
847 11778 : atom_c = atom_of_kind(katom)
848 :
849 11778 : kkind = kind_of(katom)
850 11778 : CALL get_qs_kind(qs_kind=qs_kind_set(kkind), basis_set=basis_set_c, basis_type=basis_type_c)
851 11778 : first_sgfc => basis_set_c%first_sgf
852 11778 : lc_max => basis_set_c%lmax
853 11778 : lc_min => basis_set_c%lmin
854 11778 : nsetc = basis_set_c%nset
855 11778 : nsgfc => basis_set_c%nsgf_set
856 11778 : sphi_c => basis_set_c%sphi
857 11778 : zetc => basis_set_c%zet
858 11778 : npgfc => basis_set_c%npgf
859 :
860 11778 : rc(:) = pbc(particle_set(katom)%r, cell)
861 :
862 11778 : kset_start = 1; kset_end = nsetc
863 11778 : IF (katom == atom_start) kset_start = set_start
864 11778 : IF (katom == atom_end) kset_end = set_end
865 :
866 105990 : DO kset = kset_start, kset_end
867 87588 : first_set = 1; last_set = nsgfc(kset)
868 87588 : IF (kset == kset_start .AND. katom == atom_start) first_set = set_offset_start
869 87588 : IF (kset == kset_end .AND. katom == atom_end) last_set = set_offset_end
870 :
871 87588 : offset_c_start = offset_c_end
872 87588 : offset_c_end = offset_c_end + last_set + 1 - first_set
873 87588 : sgfc = first_sgfc(1, kset)
874 :
875 : #!some fypp magic to deal with combinations of optional arguments
876 : #:for pabc_present in [0, 1]
877 : #:for doforce_1 in [0, 1]
878 : #:for doforce_2 in [0, 1]
879 : #:for doforce_3 in [0, 1]
880 : #:for dabc in [0, 1]
881 : #:for adbc in [0, 1]
882 : #:for abdc in [0, 1]
883 : IF (${conditional(doforce_1)}$PRESENT(force_a) .AND. &
884 : ${conditional(doforce_2)}$PRESENT(force_b) .AND. &
885 : ${conditional(doforce_3)}$PRESENT(force_c) .AND. &
886 : ${conditional(pabc_present)}$PRESENT(pabc) .AND. &
887 : ${conditional(dabc)}$PRESENT(mat_dabc) .AND. &
888 175176 : ${conditional(adbc)}$PRESENT(mat_adbc) .AND. &
889 11778 : ${conditional(abdc)}$PRESENT(mat_abdc)) THEN
890 : CALL integrate_set_3c( &
891 : param%par, potential_parameter, &
892 : la_min(iset), la_max(iset), &
893 : lb_min(jset), lb_max(jset), &
894 : lc_min(kset), lc_max(kset), &
895 : npgfa(iset), npgfb(jset), npgfc(kset), &
896 : zeta(:, iset), zetb(:, jset), zetc(:, kset), &
897 : ra, rb, rc, &
898 : habc, &
899 : nsgfa(iset), nsgfb(jset), last_set - first_set + 1, &
900 : offset_a_start, offset_b_start, offset_c_start, &
901 : 0, 0, first_set - 1, &
902 : sphi_a, sphi_b, sphi_c, &
903 : sgfa, sgfb, sgfc, &
904 : nsgfa(iset), nsgfb(jset), nsgfc(kset), &
905 : my_eri_method, &
906 : $: 'pabc=pabc_block, &'*pabc_present
907 : $: 'force_a=force_a(ikind)%forces(:, atom_a), &'*doforce_1
908 : $: 'force_b=force_b(jkind)%forces(:, atom_b), &'*doforce_2
909 : $: 'force_c=force_c(kkind)%forces(:, atom_c), &'*doforce_3
910 : do_symmetric=do_symmetric, &
911 : on_diagonal=iatom .EQ. jatom, &
912 : $: 'hdabc=hdabc, &'*dabc
913 : $: 'hadbc=hadbc, &'*adbc
914 : $: 'habdc=habdc, &'*abdc
915 87588 : GG_count=GG_count, GR_count=GR_count, RR_count=RR_count)
916 : END IF
917 : #:endfor
918 : #:endfor
919 : #:endfor
920 : #:endfor
921 : #:endfor
922 : #:endfor
923 : #:endfor
924 : END DO
925 : END DO
926 : END DO
927 : END DO
928 :
929 942 : IF (calculate_forces .AND. PRESENT(pabc)) DEALLOCATE (pabc_block)
930 34836 : DO ic = 1, nc
931 33894 : NULLIFY (munu_block)
932 : CALL dbcsr_get_block_p(matrix=mat_ab(ic)%matrix, &
933 33894 : row=irow, col=icol, block=munu_block, found=found)
934 33894 : CPASSERT(found)
935 1868090 : munu_block(:, :) = 0.0_dp
936 68730 : IF (irow .EQ. iatom) THEN
937 22596 : to_be_asserted = SIZE(munu_block, 1) .EQ. SIZE(habc, 1) .AND. SIZE(munu_block, 2) .EQ. SIZE(habc, 2)
938 0 : CPASSERT(to_be_asserted)
939 1385517 : munu_block(:, :) = habc(:, :, ic)
940 : ELSE
941 11298 : to_be_asserted = SIZE(munu_block, 2) .EQ. SIZE(habc, 1) .AND. SIZE(munu_block, 1) .EQ. SIZE(habc, 2)
942 0 : CPASSERT(to_be_asserted)
943 482573 : munu_block(:, :) = TRANSPOSE(habc(:, :, ic))
944 : END IF
945 : END DO
946 942 : DEALLOCATE (habc)
947 1140 : IF (calculate_forces) THEN
948 5613 : DO ic = 1, nc
949 22047 : DO i_xyz = 1, 3
950 16434 : IF (PRESENT(mat_dabc)) THEN
951 0 : NULLIFY (munu_block)
952 : CALL dbcsr_get_block_p(matrix=mat_dabc(i_xyz, ic)%matrix, &
953 0 : row=irow, col=icol, block=munu_block, found=found)
954 0 : CPASSERT(found)
955 0 : munu_block(:, :) = 0.0_dp
956 0 : IF (irow .EQ. iatom) THEN
957 0 : munu_block(:, :) = hdabc(i_xyz, :, :, ic)
958 : ELSE
959 0 : munu_block(:, :) = TRANSPOSE(hdabc(i_xyz, :, :, ic))
960 : END IF
961 : END IF
962 16434 : IF (PRESENT(mat_adbc)) THEN
963 0 : NULLIFY (munu_block)
964 : CALL dbcsr_get_block_p(matrix=mat_adbc(i_xyz, ic)%matrix, &
965 0 : row=irow, col=icol, block=munu_block, found=found)
966 0 : CPASSERT(found)
967 0 : munu_block(:, :) = 0.0_dp
968 0 : IF (irow .EQ. iatom) THEN
969 0 : munu_block(:, :) = hadbc(i_xyz, :, :, ic)
970 : ELSE
971 0 : munu_block(:, :) = TRANSPOSE(hadbc(i_xyz, :, :, ic))
972 : END IF
973 : END IF
974 21912 : IF (PRESENT(mat_abdc)) THEN
975 0 : NULLIFY (munu_block)
976 : CALL dbcsr_get_block_p(matrix=mat_abdc(i_xyz, ic)%matrix, &
977 0 : row=irow, col=icol, block=munu_block, found=found)
978 0 : CPASSERT(found)
979 0 : munu_block(:, :) = 0.0_dp
980 0 : IF (irow .EQ. iatom) THEN
981 0 : munu_block(:, :) = habdc(i_xyz, :, :, ic)
982 : ELSE
983 0 : munu_block(:, :) = TRANSPOSE(habdc(i_xyz, :, :, ic))
984 : END IF
985 : END IF
986 : END DO
987 : END DO
988 135 : IF (PRESENT(mat_dabc)) DEALLOCATE (hdabc)
989 135 : IF (PRESENT(mat_adbc)) DEALLOCATE (hadbc)
990 135 : IF (PRESENT(mat_abdc)) DEALLOCATE (habdc)
991 : END IF
992 : END DO
993 :
994 198 : DEALLOCATE (basis_set_list_a, basis_set_list_b)
995 198 : CALL neighbor_list_iterator_release(nl_iterator)
996 :
997 198 : CALL cp_eri_mme_update_local_counts(param, para_env, GG_count_3c=GG_count, GR_count_3c=GR_count, RR_count_3c=RR_count)
998 :
999 198 : CALL timestop(handle)
1000 792 : END SUBROUTINE mp2_eri_3c_integrate
1001 :
1002 : ! **************************************************************************************************
1003 : !> \brief Integrate set triple and contract with sphi matrix
1004 : !> \param param ...
1005 : !> \param potential_parameter ...
1006 : !> \param la_min ...
1007 : !> \param la_max ...
1008 : !> \param lb_min ...
1009 : !> \param lb_max ...
1010 : !> \param lc_min ...
1011 : !> \param lc_max ...
1012 : !> \param npgfa ...
1013 : !> \param npgfb ...
1014 : !> \param npgfc ...
1015 : !> \param zeta ...
1016 : !> \param zetb ...
1017 : !> \param zetc ...
1018 : !> \param ra ...
1019 : !> \param rb ...
1020 : !> \param rc ...
1021 : !> \param habc ...
1022 : !> \param n_habc_a ...
1023 : !> \param n_habc_b ...
1024 : !> \param n_habc_c ...
1025 : !> \param offset_habc_a ...
1026 : !> \param offset_habc_b ...
1027 : !> \param offset_habc_c ...
1028 : !> \param offset_set_a ...
1029 : !> \param offset_set_b ...
1030 : !> \param offset_set_c ...
1031 : !> \param sphi_a ...
1032 : !> \param sphi_b ...
1033 : !> \param sphi_c ...
1034 : !> \param sgfa ...
1035 : !> \param sgfb ...
1036 : !> \param sgfc ...
1037 : !> \param nsgfa ...
1038 : !> \param nsgfb ...
1039 : !> \param nsgfc ...
1040 : !> \param eri_method ...
1041 : !> \param pabc ...
1042 : !> \param force_a ...
1043 : !> \param force_b ...
1044 : !> \param force_c ...
1045 : !> \param do_symmetric ...
1046 : !> \param on_diagonal ...
1047 : !> \param hdabc ...
1048 : !> \param hadbc ...
1049 : !> \param habdc ...
1050 : !> \param GG_count ...
1051 : !> \param GR_count ...
1052 : !> \param RR_count ...
1053 : !> \note
1054 : ! **************************************************************************************************
1055 87588 : SUBROUTINE integrate_set_3c(param, potential_parameter, &
1056 : la_min, la_max, lb_min, lb_max, lc_min, lc_max, &
1057 : npgfa, npgfb, npgfc, &
1058 87588 : zeta, zetb, zetc, &
1059 : ra, rb, rc, &
1060 175176 : habc, &
1061 : n_habc_a, n_habc_b, n_habc_c, &
1062 : offset_habc_a, offset_habc_b, offset_habc_c, &
1063 : offset_set_a, offset_set_b, offset_set_c, &
1064 87588 : sphi_a, sphi_b, sphi_c, &
1065 : sgfa, sgfb, sgfc, &
1066 : nsgfa, nsgfb, nsgfc, &
1067 : eri_method, &
1068 87588 : pabc, &
1069 : force_a, force_b, force_c, &
1070 : do_symmetric, on_diagonal, &
1071 87588 : hdabc, hadbc, habdc, &
1072 : GG_count, GR_count, RR_count)
1073 :
1074 : TYPE(eri_mme_param), INTENT(INOUT) :: param
1075 : TYPE(libint_potential_type), INTENT(IN) :: potential_parameter
1076 : INTEGER, INTENT(IN) :: la_min, la_max, lb_min, lb_max, lc_min, &
1077 : lc_max, npgfa, npgfb, npgfc
1078 : REAL(KIND=dp), DIMENSION(npgfa), INTENT(IN) :: zeta
1079 : REAL(KIND=dp), DIMENSION(npgfb), INTENT(IN) :: zetb
1080 : REAL(KIND=dp), DIMENSION(npgfc), INTENT(IN) :: zetc
1081 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: ra, rb, rc
1082 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT) :: habc
1083 : INTEGER, INTENT(IN) :: n_habc_a, n_habc_b, n_habc_c, offset_habc_a, offset_habc_b, &
1084 : offset_habc_c, offset_set_a, offset_set_b, offset_set_c
1085 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: sphi_a, sphi_b, sphi_c
1086 : INTEGER, INTENT(IN) :: sgfa, sgfb, sgfc, nsgfa, nsgfb, nsgfc, &
1087 : eri_method
1088 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN), &
1089 : OPTIONAL :: pabc
1090 : REAL(KIND=dp), DIMENSION(3), INTENT(INOUT), &
1091 : OPTIONAL :: force_a, force_b, force_c
1092 : LOGICAL, INTENT(IN) :: do_symmetric
1093 : LOGICAL, INTENT(IN), OPTIONAL :: on_diagonal
1094 : REAL(KIND=dp), DIMENSION(:, :, :, :), &
1095 : INTENT(OUT), OPTIONAL :: hdabc, hadbc, habdc
1096 : INTEGER, INTENT(INOUT), OPTIONAL :: GG_count, GR_count, RR_count
1097 :
1098 : CHARACTER(len=*), PARAMETER :: routineN = 'integrate_set_3c'
1099 :
1100 : INTEGER :: ax, ay, az, bx, by, bz, cx, cy, cz, habc_a_end, habc_a_start, habc_b_end, &
1101 : habc_b_start, habc_c_end, habc_c_start, handle, i_xyz, ico, icoc, icox, icoy, icoz, ipgf, &
1102 : jco, jcox, jcoy, jcoz, jpgf, kco, kcox, kcoy, kcoz, kpgf, la, la_max_d, lb, &
1103 : lb_max_d, lc, lc_max_d, na, nb, nc, nc_end, nc_start, ncoa, ncoa_d, ncob, &
1104 : ncob_d, ncoc, ncoc_d, set_a_end, set_a_start, set_b_end, set_b_start, &
1105 : set_c_end, set_c_start, sphi_a_start, sphi_b_start, sphi_c_start
1106 : INTEGER, DIMENSION(3) :: la_xyz, lb_xyz
1107 : LOGICAL :: calculate_forces, do_force_a, do_force_b, &
1108 : do_force_c
1109 : REAL(KIND=dp) :: rab2, rac2, rbc2, w
1110 87588 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: f_work, gccc, rpgfa, rpgfb, rpgfc
1111 87588 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: pab_hh, pab_hs, vabc
1112 87588 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: habc_contr, habc_uncontr, &
1113 87588 : habc_uncontr_d, pabc_hhh, &
1114 87588 : pabc_hsh, pabc_hss, pabc_sss
1115 87588 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: habdc_contr, habdc_uncontr, hadbc_contr, &
1116 87588 : hadbc_uncontr, hdabc_contr, &
1117 87588 : hdabc_uncontr, v_work
1118 :
1119 87588 : CALL timeset(routineN, handle)
1120 :
1121 87588 : do_force_a = PRESENT(force_a) .OR. PRESENT(hdabc)
1122 87588 : do_force_b = PRESENT(force_b) .OR. PRESENT(hadbc)
1123 87588 : do_force_c = PRESENT(force_c) .OR. PRESENT(habdc)
1124 87588 : calculate_forces = do_force_a .OR. do_force_b .OR. do_force_c
1125 :
1126 87588 : IF (do_symmetric) THEN
1127 87588 : CPASSERT(PRESENT(on_diagonal))
1128 : END IF
1129 :
1130 87588 : la_max_d = la_max
1131 87588 : lb_max_d = lb_max
1132 87588 : lc_max_d = lc_max
1133 :
1134 87588 : IF (calculate_forces) THEN
1135 10386 : IF (do_force_a) la_max_d = la_max + 1
1136 10386 : IF (do_force_b) lb_max_d = lb_max + 1
1137 10386 : IF (do_force_c) lc_max_d = lc_max + 1
1138 : END IF
1139 :
1140 87588 : ncoa = npgfa*ncoset(la_max)
1141 87588 : ncob = npgfb*ncoset(lb_max)
1142 87588 : ncoc = npgfc*ncoset(lc_max)
1143 :
1144 87588 : ncoa_d = npgfa*ncoset(la_max_d)
1145 87588 : ncob_d = npgfb*ncoset(lb_max_d)
1146 87588 : ncoc_d = npgfc*ncoset(lc_max_d)
1147 :
1148 437940 : ALLOCATE (habc_uncontr_d(ncoset(la_max_d), ncoset(lb_max_d), ncoset(lc_max_d)))
1149 18025956 : habc_uncontr_d(:, :, :) = 0.0_dp
1150 15432312 : ALLOCATE (habc_uncontr(ncoa, ncob, ncoc)); habc_uncontr(:, :, :) = 0.0_dp
1151 87588 : IF (PRESENT(hdabc)) THEN
1152 0 : ALLOCATE (hdabc_uncontr(3, ncoa, ncob, ncoc)); hdabc_uncontr(:, :, :, :) = 0.0_dp
1153 : END IF
1154 87588 : IF (PRESENT(hadbc)) THEN
1155 0 : ALLOCATE (hadbc_uncontr(3, ncoa, ncob, ncoc)); hadbc_uncontr(:, :, :, :) = 0.0_dp
1156 : END IF
1157 87588 : IF (PRESENT(habdc)) THEN
1158 0 : ALLOCATE (habdc_uncontr(3, ncoa, ncob, ncoc)); habdc_uncontr(:, :, :, :) = 0.0_dp
1159 : END IF
1160 :
1161 87588 : habc_a_start = offset_habc_a + 1; habc_a_end = offset_habc_a + n_habc_a
1162 87588 : habc_b_start = offset_habc_b + 1; habc_b_end = offset_habc_b + n_habc_b
1163 87588 : habc_c_start = offset_habc_c + 1; habc_c_end = offset_habc_c + n_habc_c
1164 87588 : set_a_start = offset_set_a + 1; set_a_end = offset_set_a + n_habc_a
1165 87588 : set_b_start = offset_set_b + 1; set_b_end = offset_set_b + n_habc_b
1166 87588 : set_c_start = offset_set_c + 1; set_c_end = offset_set_c + n_habc_c
1167 :
1168 87588 : IF (eri_method == do_eri_mme) THEN
1169 36342 : CALL eri_mme_set_potential(param, convert_potential_type(potential_parameter%potential_type), potential_parameter%omega)
1170 :
1171 36342 : IF (calculate_forces .AND. PRESENT(pabc)) THEN
1172 : ! uncontracted hermite-gaussian representation of density matrix
1173 10386 : sphi_a_start = sgfa - 1 + set_a_start
1174 10386 : sphi_b_start = sgfb - 1 + set_b_start
1175 10386 : sphi_c_start = sgfc - 1 + set_c_start
1176 :
1177 51930 : ALLOCATE (pabc_sss(n_habc_a, n_habc_b, n_habc_c))
1178 342953 : pabc_sss(:, :, :) = pabc(habc_a_start:habc_a_end, habc_b_start:habc_b_end, habc_c_start:habc_c_end)
1179 51930 : ALLOCATE (pabc_hss(ncoa, n_habc_b, n_habc_c))
1180 51930 : ALLOCATE (pabc_hsh(ncoa, n_habc_b, ncoc))
1181 41544 : ALLOCATE (pabc_hhh(ncoa, ncob, ncoc))
1182 41544 : ALLOCATE (pab_hs(ncoa, n_habc_b))
1183 41544 : ALLOCATE (pab_hh(ncoa, ncob))
1184 :
1185 : CALL dgemm("N", "N", ncoa, n_habc_b*n_habc_c, n_habc_a, 1.0_dp, &
1186 10386 : sphi_a(:, sphi_a_start), SIZE(sphi_a, 1), pabc_sss, n_habc_a, 0.0_dp, pabc_hss, ncoa)
1187 : CALL dgemm("N", "T", ncoa*n_habc_b, ncoc, n_habc_c, 1.0_dp, &
1188 10386 : pabc_hss, ncoa*n_habc_b, sphi_c(:, sphi_c_start), SIZE(sphi_c, 1), 0.0_dp, pabc_hsh, ncoa*n_habc_b)
1189 :
1190 68148 : DO icoc = 1, ncoc
1191 1108764 : pab_hs(:, :) = pabc_hsh(:, :, icoc)
1192 : CALL dgemm("N", "T", ncoa, ncob, n_habc_b, 1.0_dp, &
1193 57762 : pab_hs, ncoa, sphi_b(:, sphi_b_start), SIZE(sphi_b, 1), 0.0_dp, pab_hh, ncoa)
1194 2262300 : pabc_hhh(:, :, icoc) = pab_hh(:, :)
1195 : END DO
1196 : END IF
1197 :
1198 105732 : DO ipgf = 1, npgfa
1199 69390 : na = (ipgf - 1)*ncoset(la_max)
1200 254142 : DO jpgf = 1, npgfb
1201 148410 : nb = (jpgf - 1)*ncoset(lb_max)
1202 366210 : DO kpgf = 1, npgfc
1203 148410 : nc = (kpgf - 1)*ncoset(lc_max)
1204 37248210 : habc_uncontr_d(:, :, :) = 0.0_dp
1205 : CALL eri_mme_3c_integrate(param, &
1206 : la_min, la_max_d, lb_min, lb_max_d, lc_min, lc_max_d, &
1207 : zeta(ipgf), zetb(jpgf), zetc(kpgf), ra, rb, rc, habc_uncontr_d, 0, 0, 0, &
1208 148410 : GG_count, GR_count, RR_count)
1209 :
1210 : habc_uncontr(na + 1:na + ncoset(la_max), nb + 1:nb + ncoset(lb_max), nc + 1:nc + ncoset(lc_max)) = &
1211 8154180 : habc_uncontr_d(:ncoset(la_max), :ncoset(lb_max), :ncoset(lc_max))
1212 :
1213 296820 : IF (calculate_forces) THEN
1214 82500 : DO lc = lc_min, lc_max
1215 164700 : DO cx = 0, lc
1216 266850 : DO cy = 0, lc - cx
1217 143400 : cz = lc - cx - cy
1218 143400 : kco = coset(cx, cy, cz)
1219 143400 : kcox = coset(cx + 1, cy, cz)
1220 143400 : kcoy = coset(cx, cy + 1, cz)
1221 143400 : kcoz = coset(cx, cy, cz + 1)
1222 414600 : DO lb = lb_min, lb_max
1223 592800 : DO bx = 0, lb
1224 788400 : DO by = 0, lb - bx
1225 339000 : bz = lb - bx - by
1226 339000 : jco = coset(bx, by, bz)
1227 339000 : jcox = coset(bx + 1, by, bz)
1228 339000 : jcoy = coset(bx, by + 1, bz)
1229 339000 : jcoz = coset(bx, by, bz + 1)
1230 1075620 : DO la = la_min, la_max
1231 1500105 : DO ax = 0, la
1232 2078460 : DO ay = 0, la - ax
1233 917355 : az = la - ax - ay
1234 3669420 : la_xyz = [ax, ay, az]
1235 3669420 : lb_xyz = [bx, by, bz]
1236 917355 : ico = coset(ax, ay, az)
1237 917355 : icox = coset(ax + 1, ay, az)
1238 917355 : icoy = coset(ax, ay + 1, az)
1239 917355 : icoz = coset(ax, ay, az + 1)
1240 :
1241 917355 : w = 1.0_dp
1242 917355 : IF (do_symmetric .AND. .NOT. on_diagonal) w = 2.0_dp
1243 :
1244 917355 : IF (PRESENT(force_a)) THEN
1245 : force_a = force_a + 2.0_dp*w*zeta(ipgf)* &
1246 : [pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(icox, jco, kco), &
1247 : pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(icoy, jco, kco), &
1248 3669420 : pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(icoz, jco, kco)]
1249 :
1250 : END IF
1251 917355 : IF (PRESENT(force_b)) THEN
1252 : force_b = force_b + 2.0_dp*w*zetb(jpgf)* &
1253 : [pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(ico, jcox, kco), &
1254 : pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(ico, jcoy, kco), &
1255 3669420 : pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(ico, jcoz, kco)]
1256 : END IF
1257 917355 : IF (PRESENT(force_c)) THEN
1258 : force_c = force_c + 2.0_dp*w*zetc(kpgf)* &
1259 : [pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(ico, jco, kcox), &
1260 : pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(ico, jco, kcoy), &
1261 3669420 : pabc_hhh(na + ico, nb + jco, nc + kco)*habc_uncontr_d(ico, jco, kcoz)]
1262 : END IF
1263 :
1264 917355 : IF (PRESENT(hdabc)) THEN
1265 : hdabc_uncontr(1:3, na + ico, nb + jco, nc + kco) = 2.0_dp*zeta(ipgf)* &
1266 : [habc_uncontr_d(icox, jco, kco), &
1267 : habc_uncontr_d(icoy, jco, kco), &
1268 0 : habc_uncontr_d(icoz, jco, kco)]
1269 : END IF
1270 917355 : IF (PRESENT(hadbc)) THEN
1271 : hadbc_uncontr(1:3, na + ico, nb + jco, nc + kco) = 2.0_dp*zetb(jpgf)* &
1272 : [habc_uncontr_d(ico, jcox, kco), &
1273 : habc_uncontr_d(ico, jcoy, kco), &
1274 0 : habc_uncontr_d(ico, jcoz, kco)]
1275 : END IF
1276 1602240 : IF (PRESENT(habdc)) THEN
1277 : habdc_uncontr(1:3, na + ico, nb + jco, nc + kco) = 2.0_dp*zetc(kpgf)* &
1278 : [habc_uncontr_d(ico, jco, kcox), &
1279 : habc_uncontr_d(ico, jco, kcoy), &
1280 0 : habc_uncontr_d(ico, jco, kcoz)]
1281 : END IF
1282 : END DO
1283 : END DO
1284 : END DO
1285 : END DO
1286 : END DO
1287 : END DO
1288 : END DO
1289 : END DO
1290 : END DO
1291 : END IF
1292 :
1293 : END DO
1294 : END DO
1295 : END DO
1296 :
1297 51246 : ELSE IF (eri_method == do_eri_os) THEN
1298 :
1299 51246 : IF (calculate_forces) CPABORT("NYI")
1300 :
1301 153738 : ALLOCATE (f_work(0:la_max + lb_max + lc_max + 2))
1302 326124 : f_work(:) = 0.0_dp
1303 307476 : ALLOCATE (v_work(ncoa, ncob, ncoc, la_max + lb_max + lc_max + 1))
1304 44158812 : v_work(:, :, :, :) = 0.0_dp
1305 : ! no screening
1306 153738 : ALLOCATE (rpgfa(npgfa))
1307 153738 : ALLOCATE (rpgfb(npgfb))
1308 153738 : ALLOCATE (rpgfc(npgfc))
1309 135396 : rpgfa(:) = 1.0E10_dp
1310 135396 : rpgfb(:) = 1.0E10_dp
1311 102492 : rpgfc(:) = 1.0E10_dp
1312 153738 : ALLOCATE (gccc(ncoc))
1313 338364 : gccc(:) = 0.0_dp
1314 204984 : ALLOCATE (vabc(ncoa, ncob))
1315 1520910 : vabc(:, :) = 0.0_dp
1316 51246 : rab2 = (rb(1) - ra(1))**2 + (rb(2) - ra(2))**2 + (rb(3) - ra(3))**2
1317 51246 : rac2 = (rc(1) - ra(1))**2 + (rc(2) - ra(2))**2 + (rc(3) - ra(3))**2
1318 51246 : rbc2 = (rc(1) - rb(1))**2 + (rc(2) - rb(2))**2 + (rc(3) - rb(3))**2
1319 :
1320 : ! in the RI basis, there is only a single primitive Gaussian
1321 51246 : kpgf = 1
1322 :
1323 51246 : IF (lc_max == 0) THEN
1324 : nc_start = 1
1325 : ELSE
1326 30780 : nc_start = ncoset(lc_max - 1) + 1
1327 : END IF
1328 51246 : nc_end = ncoset(lc_max)
1329 :
1330 : CALL coulomb3(la_max, npgfa, zeta(:), rpgfa(:), la_min, &
1331 : lb_max, npgfb, zetb(:), rpgfb(:), lb_min, &
1332 : lc_max, zetc(kpgf), rpgfc(kpgf), lc_min, &
1333 : gccc, rb - ra, rab2, rc - ra, rac2, rbc2, &
1334 409968 : vabc, habc_uncontr(:, :, nc_start:nc_end), v_work, f_work)
1335 :
1336 51246 : DEALLOCATE (v_work, f_work, rpgfa, rpgfb, rpgfc, gccc, vabc)
1337 :
1338 0 : ELSE IF (eri_method == do_eri_gpw) THEN
1339 :
1340 0 : CPABORT("GPW not enabled in the ERI interface.")
1341 :
1342 : END IF
1343 :
1344 437940 : ALLOCATE (habc_contr(nsgfa, nsgfb, nsgfc))
1345 87588 : IF (PRESENT(hdabc)) THEN
1346 0 : ALLOCATE (hdabc_contr(3, nsgfa, nsgfb, nsgfc))
1347 : END IF
1348 87588 : IF (PRESENT(hadbc)) THEN
1349 0 : ALLOCATE (hadbc_contr(3, nsgfa, nsgfb, nsgfc))
1350 : END IF
1351 87588 : IF (PRESENT(habdc)) THEN
1352 0 : ALLOCATE (habdc_contr(3, nsgfa, nsgfb, nsgfc))
1353 : END IF
1354 :
1355 : CALL abc_contract(habc_contr, habc_uncontr, &
1356 : sphi_a(:, sgfa:), sphi_b(:, sgfb:), sphi_c(:, sgfc:), &
1357 87588 : ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc)
1358 :
1359 87588 : IF (calculate_forces) THEN
1360 41544 : DO i_xyz = 1, 3
1361 31158 : IF (PRESENT(hdabc)) THEN
1362 : CALL abc_contract(hdabc_contr(i_xyz, :, :, :), hdabc_uncontr(i_xyz, :, :, :), &
1363 : sphi_a(:, sgfa:), sphi_b(:, sgfb:), sphi_c(:, sgfc:), &
1364 0 : ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc)
1365 : END IF
1366 31158 : IF (PRESENT(hadbc)) THEN
1367 : CALL abc_contract(hadbc_contr(i_xyz, :, :, :), hadbc_uncontr(i_xyz, :, :, :), &
1368 : sphi_a(:, sgfa:), sphi_b(:, sgfb:), sphi_c(:, sgfc:), &
1369 0 : ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc)
1370 : END IF
1371 41544 : IF (PRESENT(habdc)) THEN
1372 : CALL abc_contract(habdc_contr(i_xyz, :, :, :), habdc_uncontr(i_xyz, :, :, :), &
1373 : sphi_a(:, sgfa:), sphi_b(:, sgfb:), sphi_c(:, sgfc:), &
1374 0 : ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc)
1375 : END IF
1376 : END DO
1377 : END IF
1378 :
1379 : habc(habc_a_start:habc_a_end, habc_b_start:habc_b_end, habc_c_start:habc_c_end) = &
1380 2591836 : habc_contr(set_a_start:set_a_end, set_b_start:set_b_end, set_c_start:set_c_end)
1381 :
1382 87588 : IF (calculate_forces) THEN
1383 10386 : IF (PRESENT(hdabc)) hdabc(:, habc_a_start:habc_a_end, habc_b_start:habc_b_end, habc_c_start:habc_c_end) = &
1384 0 : hdabc_contr(:, set_a_start:set_a_end, set_b_start:set_b_end, set_c_start:set_c_end)
1385 10386 : IF (PRESENT(hadbc)) hadbc(:, habc_a_start:habc_a_end, habc_b_start:habc_b_end, habc_c_start:habc_c_end) = &
1386 0 : hadbc_contr(:, set_a_start:set_a_end, set_b_start:set_b_end, set_c_start:set_c_end)
1387 10386 : IF (PRESENT(habdc)) habdc(:, habc_a_start:habc_a_end, habc_b_start:habc_b_end, habc_c_start:habc_c_end) = &
1388 0 : habdc_contr(:, set_a_start:set_a_end, set_b_start:set_b_end, set_c_start:set_c_end)
1389 : END IF
1390 :
1391 87588 : CALL timestop(handle)
1392 :
1393 175176 : END SUBROUTINE integrate_set_3c
1394 :
1395 : ! **************************************************************************************************
1396 : !> \brief get pointer to atom, pointer to set and offset in a set for each spherical orbital of a
1397 : !> basis.
1398 : !> \param qs_env ...
1399 : !> \param basis_type ...
1400 : !> \param eri_offsets (:,1) atom numbers
1401 : !> (:,2) set numbers
1402 : !> (:,3) set offsets
1403 : ! **************************************************************************************************
1404 518 : SUBROUTINE get_eri_offsets(qs_env, basis_type, eri_offsets)
1405 : TYPE(qs_environment_type), INTENT(IN), POINTER :: qs_env
1406 : CHARACTER(len=*), INTENT(IN), OPTIONAL :: basis_type
1407 : INTEGER, ALLOCATABLE, DIMENSION(:, :), INTENT(OUT) :: eri_offsets
1408 :
1409 : INTEGER :: dimen_basis, iatom, ikind, iset, isgf, &
1410 : natom, nkind, nset, nsgf, offset, &
1411 : set_offset
1412 518 : INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
1413 518 : INTEGER, DIMENSION(:), POINTER :: nsgf_set
1414 518 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1415 : TYPE(gto_basis_set_type), POINTER :: basis_set
1416 518 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1417 518 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1418 :
1419 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
1420 518 : particle_set=particle_set, natom=natom, nkind=nkind)
1421 :
1422 518 : CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of)
1423 :
1424 518 : dimen_basis = 0
1425 1938 : DO iatom = 1, natom
1426 1420 : ikind = kind_of(iatom)
1427 1420 : CALL get_qs_kind(qs_kind=qs_kind_set(ikind), nsgf=nsgf, basis_type=basis_type)
1428 1938 : dimen_basis = dimen_basis + nsgf
1429 : END DO
1430 :
1431 1554 : ALLOCATE (eri_offsets(dimen_basis, 3))
1432 :
1433 518 : offset = 0
1434 1938 : DO iatom = 1, natom
1435 1420 : ikind = kind_of(iatom)
1436 1420 : CALL get_qs_kind(qs_kind=qs_kind_set(ikind), basis_set=basis_set, basis_type=basis_type)
1437 1420 : nset = basis_set%nset
1438 1420 : nsgf_set => basis_set%nsgf_set
1439 14652 : DO iset = 1, nset
1440 12714 : set_offset = 0
1441 48236 : DO isgf = 1, nsgf_set(iset)
1442 35522 : set_offset = set_offset + 1
1443 154802 : eri_offsets(offset + set_offset, :) = [iatom, iset, set_offset]
1444 : END DO
1445 14134 : offset = offset + nsgf_set(iset)
1446 : END DO
1447 : END DO
1448 1036 : END SUBROUTINE get_eri_offsets
1449 :
1450 : ! **************************************************************************************************
1451 : !> \brief ...
1452 : !> \param force ...
1453 : !> \param natom_of_kind ...
1454 : ! **************************************************************************************************
1455 104 : PURE SUBROUTINE mp2_eri_allocate_forces(force, natom_of_kind)
1456 : TYPE(mp2_eri_force), ALLOCATABLE, &
1457 : DIMENSION(:), INTENT(OUT) :: force
1458 : INTEGER, DIMENSION(:), INTENT(IN) :: natom_of_kind
1459 :
1460 : INTEGER :: ikind, n, nkind
1461 :
1462 104 : nkind = SIZE(natom_of_kind)
1463 :
1464 496 : ALLOCATE (force(nkind))
1465 :
1466 288 : DO ikind = 1, nkind
1467 184 : n = natom_of_kind(ikind)
1468 552 : ALLOCATE (force(ikind)%forces(3, n))
1469 1440 : force(ikind)%forces(:, :) = 0.0_dp
1470 : END DO
1471 104 : END SUBROUTINE mp2_eri_allocate_forces
1472 :
1473 : ! **************************************************************************************************
1474 : !> \brief ...
1475 : !> \param force ...
1476 : ! **************************************************************************************************
1477 104 : PURE SUBROUTINE mp2_eri_deallocate_forces(force)
1478 : TYPE(mp2_eri_force), ALLOCATABLE, &
1479 : DIMENSION(:), INTENT(INOUT) :: force
1480 :
1481 : INTEGER :: ikind, nkind
1482 :
1483 104 : IF (ALLOCATED(force)) THEN
1484 104 : nkind = SIZE(force)
1485 288 : DO ikind = 1, nkind
1486 288 : IF (ALLOCATED(force(ikind)%forces)) DEALLOCATE (force(ikind)%forces)
1487 : END DO
1488 :
1489 288 : DEALLOCATE (force)
1490 : END IF
1491 104 : END SUBROUTINE mp2_eri_deallocate_forces
1492 :
1493 85324 : FUNCTION convert_potential_type(potential_type) RESULT(res)
1494 : INTEGER, INTENT(IN) :: potential_type
1495 : INTEGER :: res
1496 :
1497 85324 : IF (potential_type == do_potential_coulomb) THEN
1498 : res = eri_mme_coulomb
1499 12541 : ELSE IF (potential_type == do_potential_long) THEN
1500 : res = eri_mme_longrange
1501 : ELSE
1502 0 : CPABORT("MME potential not implemented!")
1503 : END IF
1504 :
1505 85324 : END FUNCTION convert_potential_type
1506 :
1507 0 : END MODULE mp2_eri
|