(git:f7b9015)
Loading...
Searching...
No Matches
four_center_integral_interface.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Four-center integral evaluation with an encapsulated Libint backend.
10!> \par History
11!> 11.2006 created [Manuel Guidon]
12!> 11.2019 Fixed potential_id initial values (A. Bussy)
13!> \author Manuel Guidon
14! **************************************************************************************************
16
17 USE cell_types, ONLY: cell_type,&
24 eri4_pgf_product_type
30 USE kinds, ONLY: dp,&
31 int_8
32 USE libint_wrapper, ONLY: &
36 USE orbital_pointers, ONLY: nco
37#include "./base/base_uses.f90"
38
39 IMPLICIT NONE
40 PRIVATE
45
46!> \brief Context owning the energy and first-derivative backend workspaces.
47!> \note Intrinsic copies share backend storage and must not be cleaned up independently.
49 PRIVATE
50 TYPE(cp_libint_t) :: eri, deriv
52
53CONTAINS
54
55! **************************************************************************************************
56!> \brief Initialize the four-center energy and first-derivative workspaces.
57!> \param context owning context; global backend initialization is provided by init_cp2k
58!> \param max_am maximum angular momentum on any center
59! **************************************************************************************************
60 SUBROUTINE four_center_integral_init(context, max_am)
62 INTENT(INOUT) :: context
63 INTEGER, INTENT(IN) :: max_am
64
65 CALL cp_libint_init_eri(context%eri, max_am)
66 CALL cp_libint_init_eri1(context%deriv, max_am)
67 CALL cp_libint_set_contrdepth(context%eri, 1)
68 CALL cp_libint_set_contrdepth(context%deriv, 1)
69 END SUBROUTINE four_center_integral_init
70
71! **************************************************************************************************
72!> \brief Release the workspaces of an owning four-center context.
73!> \param context original initialized owner; borrowed copies must not be passed here
74! **************************************************************************************************
75 SUBROUTINE four_center_integral_cleanup(context)
77 INTENT(INOUT) :: context
78
79 CALL cp_libint_cleanup_eri(context%eri)
80 CALL cp_libint_cleanup_eri1(context%deriv)
81 END SUBROUTINE four_center_integral_cleanup
82
83! **************************************************************************************************
84!> \brief Return the canonical quartet order required by the Libint ERI kernels.
85!> \param la angular momentum of the original first center
86!> \param lb angular momentum of the original second center
87!> \param lc angular momentum of the original third center
88!> \param ld angular momentum of the original fourth center
89!> \param permutation original center index for each canonical center
90! **************************************************************************************************
91 PURE SUBROUTINE get_eri_permutation(la, lb, lc, ld, permutation)
92 INTEGER, INTENT(IN) :: la, lb, lc, ld
93 INTEGER, INTENT(OUT) :: permutation(4)
94
95 permutation = [1, 2, 3, 4]
96 IF (la < lb) permutation(1:2) = [2, 1]
97 IF (lc < ld) permutation(3:4) = [4, 3]
98 IF (la + lb > lc + ld) permutation = permutation([3, 4, 1, 2])
99 END SUBROUTINE get_eri_permutation
100
101! **************************************************************************************************
102!> \brief Restore original Cartesian axes and center labels from a canonical ERI block.
103!> \param source canonical block, with the fourth Cartesian index varying fastest
104!> \param destination original block, with the first Cartesian index varying fastest
105!> \param ncart Cartesian shell sizes in original center order
106!> \param permutation original center index for each canonical center
107!> \param ncomponents one integral component or twelve center-derivative components
108!> \param nplanes independent planes, one for integrals/forces or three for virial
109! **************************************************************************************************
110 PURE SUBROUTINE reorder_eri_block(source, destination, ncart, permutation, ncomponents, nplanes)
111 INTEGER, INTENT(IN) :: ncart(4), permutation(4), ncomponents, &
112 nplanes
113 REAL(dp), INTENT(OUT) :: destination(product(ncart), ncomponents, nplanes)
114 REAL(dp), INTENT(IN) :: source(product(ncart), ncomponents, nplanes)
115
116 INTEGER :: component, extent(4), i, isource, j, k, &
117 l, output_component, p1, p2, p3, p4, &
118 plane, stride(4)
119
120 stride = [1, ncart(1), ncart(1)*ncart(2), ncart(1)*ncart(2)*ncart(3)]
121 stride = stride(permutation)
122 extent = ncart(permutation)
123 ! Read the Libint block contiguously and restore the original Fortran layout with strides.
124 DO plane = 1, nplanes
125 DO component = 1, ncomponents
126 output_component = component
127 IF (ncomponents == 12) THEN
128 output_component = 3*(permutation((component - 1)/3 + 1) - 1) + mod(component - 1, 3) + 1
129 END IF
130 isource = 0
131 p1 = 1
132 DO i = 1, extent(1)
133 p2 = p1
134 DO j = 1, extent(2)
135 p3 = p2
136 DO k = 1, extent(3)
137 p4 = p3
138 DO l = 1, extent(4)
139 isource = isource + 1
140 destination(p4, output_component, plane) = source(isource, component, plane)
141 p4 = p4 + stride(4)
142 END DO
143 p3 = p3 + stride(3)
144 END DO
145 p2 = p2 + stride(2)
146 END DO
147 p1 = p1 + stride(1)
148 END DO
149 END DO
150 END DO
151 END SUBROUTINE reorder_eri_block
152
153! **************************************************************************************************
154!> \brief Evaluates derivatives of electron repulsion integrals for a primitive quartet
155!> \param context four-center integral context
156!> \param nproducts ...
157!> \param pgf_product_list ...
158!> \param n_a ...
159!> \param n_b ...
160!> \param n_c ...
161!> \param n_d ...
162!> \param ncoa ...
163!> \param ncob ...
164!> \param ncoc ...
165!> \param ncod ...
166!> \param nsgfa ...
167!> \param nsgfb ...
168!> \param nsgfc ...
169!> \param nsgfd ...
170!> \param primitives ...
171!> \param max_contraction ...
172!> \param tmp_max_all ...
173!> \param eps_schwarz ...
174!> \param neris ...
175!> \param s_offset_a ...
176!> \param s_offset_b ...
177!> \param s_offset_c ...
178!> \param s_offset_d ...
179!> \param nl_a ...
180!> \param nl_b ...
181!> \param nl_c ...
182!> \param nl_d ...
183!> \param nsoa ...
184!> \param nsob ...
185!> \param nsoc ...
186!> \param nsod ...
187!> \param sphi_a ...
188!> \param sphi_b ...
189!> \param sphi_c ...
190!> \param sphi_d ...
191!> \param work ...
192!> \param work2 ...
193!> \param work_forces ...
194!> \param buffer1 ...
195!> \param buffer2 ...
196!> \param primitives_tmp ...
197!> \param use_virial ...
198!> \param work_virial ...
199!> \param work2_virial ...
200!> \param primitives_tmp_virial ...
201!> \param primitives_virial ...
202!> \param cell ...
203!> \param tmp_max_all_virial ...
204!> \par History
205!> 03.2007 created [Manuel Guidon]
206!> 08.2007 refactured permutation part [Manuel Guidon]
207!> \author Manuel Guidon
208! **************************************************************************************************
209 SUBROUTINE evaluate_deriv_eri(context, nproducts, pgf_product_list, &
210 n_a, n_b, n_c, n_d, &
211 ncoa, ncob, ncoc, ncod, &
212 nsgfa, nsgfb, nsgfc, nsgfd, &
213 primitives, max_contraction, tmp_max_all, &
214 eps_schwarz, neris, &
215 s_offset_a, s_offset_b, s_offset_c, s_offset_d, &
216 nl_a, nl_b, nl_c, nl_d, nsoa, nsob, nsoc, nsod, &
217 sphi_a, sphi_b, sphi_c, sphi_d, &
218 work, work2, work_forces, buffer1, buffer2, primitives_tmp, &
219 use_virial, work_virial, work2_virial, primitives_tmp_virial, &
220 primitives_virial, cell, tmp_max_all_virial)
221
222 TYPE(four_center_integral_context_type) :: context
223 INTEGER, INTENT(IN) :: nproducts
224 TYPE(eri4_pgf_product_type), DIMENSION(nproducts) :: pgf_product_list
225 INTEGER, INTENT(IN) :: n_a, n_b, n_c, n_d, ncoa, ncob, ncoc, &
226 ncod, nsgfa, nsgfb, nsgfc, nsgfd
227 REAL(dp), &
228 DIMENSION(nsgfa, nsgfb, nsgfc, nsgfd, 12) :: primitives
229 REAL(dp) :: max_contraction, tmp_max_all, eps_schwarz
230 INTEGER(int_8) :: neris
231 INTEGER :: s_offset_a, s_offset_b, s_offset_c, &
232 s_offset_d, nl_a, nl_b, nl_c, nl_d, &
233 nsoa, nsob, nsoc, nsod
234 REAL(dp), DIMENSION(ncoa, nsoa*nl_a) :: sphi_a
235 REAL(dp), DIMENSION(ncob, nsob*nl_b) :: sphi_b
236 REAL(dp), DIMENSION(ncoc, nsoc*nl_c) :: sphi_c
237 REAL(dp), DIMENSION(ncod, nsod*nl_d) :: sphi_d
238 REAL(dp) :: work(ncoa*ncob*ncoc*ncod, 12), work2(ncoa, ncob, ncoc, ncod, 12), &
239 work_forces(ncoa*ncob*ncoc*ncod, 12)
240 REAL(dp), DIMENSION(ncoa*ncob*ncoc*ncod) :: buffer1, buffer2
241 REAL(dp), DIMENSION(nsoa*nl_a, nsob*nl_b, nsoc*& nl_c, nsod*nl_d) :: primitives_tmp
242 LOGICAL, INTENT(IN) :: use_virial
243 REAL(dp) :: work_virial(ncoa*ncob*ncoc*ncod, 12, 3), &
244 work2_virial(ncoa, ncob, ncoc, ncod, 12, 3)
245 REAL(dp), DIMENSION(nsoa*nl_a, nsob*nl_b, nsoc*& nl_c, nsod*nl_d) :: primitives_tmp_virial
246 REAL(dp), &
247 DIMENSION(nsgfa, nsgfb, nsgfc, nsgfd, 12, 3) :: primitives_virial
248 TYPE(cell_type), POINTER :: cell
249 REAL(dp) :: tmp_max_all_virial
250
251 INTEGER :: a_mysize(1), angular_momenta(4), i, j, &
252 k, m, m_max, mysize, n, permutation(4)
253 LOGICAL :: direct_contract
254 REAL(dp) :: scoord(12), tmp_max, tmp_max_virial
255
256 m_max = n_a + n_b + n_c + n_d
257 m_max = m_max + 1
258 mysize = ncoa*ncob*ncoc*ncod
259 a_mysize = mysize
260
261 work = 0.0_dp
262
263 IF (use_virial) THEN
264 work_virial = 0.0_dp
265 END IF
266
267 CALL get_eri_permutation(n_a, n_b, n_c, n_d, permutation)
268 angular_momenta = [n_a, n_b, n_c, n_d]
269 angular_momenta = angular_momenta(permutation)
270
271 DO i = 1, nproducts
272 CALL cp_libint_set_params_eri_deriv(context%deriv, pgf_product_list(i), permutation, m_max)
273 CALL cp_libint_get_derivs(angular_momenta(4), angular_momenta(3), angular_momenta(2), &
274 angular_momenta(1), context%deriv, work_forces, a_mysize)
275 DO k = 1, 12
276 DO j = 1, mysize
277 work(j, k) = work(j, k) + work_forces(j, k)
278 END DO
279 END DO
280 neris = neris + 12*mysize
281 IF (use_virial) THEN
282 DO j = 1, 4
283 CALL real_to_scaled(scoord(3*j - 2:3*j), pgf_product_list(i)%centers(:, permutation(j)), cell)
284 END DO
285 DO k = 1, 12
286 DO j = 1, mysize
287 DO m = 1, 3
288 work_virial(j, k, m) = work_virial(j, k, m) + work_forces(j, k)*scoord(int((k - 1)/3)*3 + m)
289 END DO
290 END DO
291 END DO
292 END IF
293 END DO
294
295 DO n = 1, 12
296 tmp_max = 0.0_dp
297 DO i = 1, mysize
298 tmp_max = max(tmp_max, abs(work(i, n)))
299 END DO
300 tmp_max = tmp_max*max_contraction
301 tmp_max_all = max(tmp_max_all, tmp_max)
302 END DO
303 CALL reorder_eri_block(work, work2, [ncoa, ncob, ncoc, ncod], permutation, 12, 1)
304 IF (use_virial) THEN
305 DO n = 1, 12
306 tmp_max_virial = 0.0_dp
307 DO i = 1, mysize
308 tmp_max_virial = max(tmp_max_virial, &
309 abs(work_virial(i, n, 1)), abs(work_virial(i, n, 2)), abs(work_virial(i, n, 3)))
310 END DO
311 tmp_max_virial = tmp_max_virial*max_contraction
312 tmp_max_all_virial = max(tmp_max_all_virial, tmp_max_virial)
313 END DO
314 CALL reorder_eri_block(work_virial, work2_virial, [ncoa, ncob, ncoc, ncod], permutation, 12, 3)
315 END IF
316
317 IF (.NOT. use_virial) THEN
318 IF (tmp_max_all < eps_schwarz) RETURN
319 END IF
320
321 direct_contract = (s_offset_a == 0 .AND. s_offset_b == 0 .AND. &
322 s_offset_c == 0 .AND. s_offset_d == 0 .AND. &
323 nsgfa == nsoa*nl_a .AND. nsgfb == nsob*nl_b .AND. &
324 nsgfc == nsoc*nl_c .AND. nsgfd == nsod*nl_d)
325
326 IF (tmp_max_all >= eps_schwarz) THEN
327 IF (direct_contract) THEN
328 DO i = 1, 12
329 CALL contract(ncoa, ncob, ncoc, ncod, nsoa, nsob, nsoc, nsod, &
330 n_a, n_b, n_c, n_d, nl_a, nl_b, nl_c, nl_d, work2(1, 1, 1, 1, i), &
331 sphi_a, &
332 sphi_b, &
333 sphi_c, &
334 sphi_d, &
335 primitives(1, 1, 1, 1, i), &
336 buffer1, buffer2)
337 END DO
338 ELSE
339 DO i = 1, 12
340 primitives_tmp(:, :, :, :) = 0.0_dp
341 CALL contract(ncoa, ncob, ncoc, ncod, nsoa, nsob, nsoc, nsod, &
342 n_a, n_b, n_c, n_d, nl_a, nl_b, nl_c, nl_d, work2(1, 1, 1, 1, i), &
343 sphi_a, &
344 sphi_b, &
345 sphi_c, &
346 sphi_d, &
347 primitives_tmp(1, 1, 1, 1), &
348 buffer1, buffer2)
349
350 primitives(s_offset_a + 1:s_offset_a + nsoa*nl_a, &
351 s_offset_b + 1:s_offset_b + nsob*nl_b, &
352 s_offset_c + 1:s_offset_c + nsoc*nl_c, &
353 s_offset_d + 1:s_offset_d + nsod*nl_d, i) = &
354 primitives(s_offset_a + 1:s_offset_a + nsoa*nl_a, &
355 s_offset_b + 1:s_offset_b + nsob*nl_b, &
356 s_offset_c + 1:s_offset_c + nsoc*nl_c, &
357 s_offset_d + 1:s_offset_d + nsod*nl_d, i) + primitives_tmp(:, :, :, :)
358 END DO
359 END IF
360 END IF
361
362 IF (use_virial .AND. tmp_max_all_virial >= eps_schwarz) THEN
363 IF (direct_contract) THEN
364 DO i = 1, 12
365 DO m = 1, 3
366 CALL contract(ncoa, ncob, ncoc, ncod, nsoa, nsob, nsoc, nsod, &
367 n_a, n_b, n_c, n_d, nl_a, nl_b, nl_c, nl_d, work2_virial(1, 1, 1, 1, i, m), &
368 sphi_a, &
369 sphi_b, &
370 sphi_c, &
371 sphi_d, &
372 primitives_virial(1, 1, 1, 1, i, m), &
373 buffer1, buffer2)
374 END DO
375 END DO
376 ELSE
377 DO i = 1, 12
378 DO m = 1, 3
379 primitives_tmp_virial(:, :, :, :) = 0.0_dp
380 CALL contract(ncoa, ncob, ncoc, ncod, nsoa, nsob, nsoc, nsod, &
381 n_a, n_b, n_c, n_d, nl_a, nl_b, nl_c, nl_d, work2_virial(1, 1, 1, 1, i, m), &
382 sphi_a, &
383 sphi_b, &
384 sphi_c, &
385 sphi_d, &
386 primitives_tmp_virial(1, 1, 1, 1), &
387 buffer1, buffer2)
388
389 primitives_virial(s_offset_a + 1:s_offset_a + nsoa*nl_a, &
390 s_offset_b + 1:s_offset_b + nsob*nl_b, &
391 s_offset_c + 1:s_offset_c + nsoc*nl_c, &
392 s_offset_d + 1:s_offset_d + nsod*nl_d, i, m) = &
393 primitives_virial(s_offset_a + 1:s_offset_a + nsoa*nl_a, &
394 s_offset_b + 1:s_offset_b + nsob*nl_b, &
395 s_offset_c + 1:s_offset_c + nsoc*nl_c, &
396 s_offset_d + 1:s_offset_d + nsod*nl_d, i, m) + primitives_tmp_virial(:, :, :, :)
397 END DO
398 END DO
399 END IF
400 END IF
401
402 END SUBROUTINE evaluate_deriv_eri
403
404! **************************************************************************************************
405!> \brief Evaluates max-abs values of electron repulsion integrals for a primitive quartet
406!> \param context four-center integral context
407!> \param A ...
408!> \param B ...
409!> \param C ...
410!> \param D ...
411!> \param Zeta_A ...
412!> \param Zeta_B ...
413!> \param Zeta_C ...
414!> \param Zeta_D ...
415!> \param n_a ...
416!> \param n_b ...
417!> \param n_c ...
418!> \param n_d ...
419!> \param max_val ...
420!> \param potential_parameter ...
421!> \param R1 ...
422!> \param R2 ...
423!> \par History
424!> 03.2007 created [Manuel Guidon]
425!> 08.2007 refactured permutation part [Manuel Guidon]
426!> \author Manuel Guidon
427! **************************************************************************************************
428 SUBROUTINE evaluate_eri_screen(context, A, B, C, D, Zeta_A, Zeta_B, Zeta_C, Zeta_D, &
429 n_a, n_b, n_c, n_d, &
430 max_val, potential_parameter, R1, R2)
431
432 TYPE(four_center_integral_context_type) :: context
433 REAL(dp), INTENT(IN) :: a(3), b(3), c(3), d(3), zeta_a, zeta_b, &
434 zeta_c, zeta_d
435 INTEGER, INTENT(IN) :: n_a, n_b, n_c, n_d
436 REAL(dp), INTENT(INOUT) :: max_val
437 TYPE(coulomb_operator_type) :: potential_parameter
438 REAL(dp) :: r1, r2
439
440 INTEGER :: a_mysize(1), angular_momenta(4), i, &
441 m_max, mysize, permutation(4)
442 REAL(dp) :: centers(3, 4), exponents(4), pq(3), pq2, &
443 s1234
444 REAL(dp), DIMENSION(:), POINTER :: p_work
445 TYPE(eri4_pgf_image_type) :: image_a, image_b
446 TYPE(eri4_pgf_pair_type) :: pair_a, pair_b
447 TYPE(eri4_pgf_product_type) :: params, product
448
449 m_max = n_a + n_b + n_c + n_d
450 mysize = nco(n_a)*nco(n_b)*nco(n_c)*nco(n_d)
451 a_mysize = mysize
452
453 CALL get_eri_permutation(n_a, n_b, n_c, n_d, permutation)
454 angular_momenta = [n_a, n_b, n_c, n_d]
455 angular_momenta = angular_momenta(permutation)
456 centers(:, 1) = a
457 centers(:, 2) = b
458 centers(:, 3) = c
459 centers(:, 4) = d
460 centers = centers(:, permutation)
461 exponents = [zeta_a, zeta_b, zeta_c, zeta_d]
462 exponents = exponents(permutation)
463
464 pq = centers(:, 1) - centers(:, 2)
465 CALL prepare_eri4_pair(centers(:, 1), centers(:, 2), exponents(1), exponents(2), &
466 dot_product(pq, pq), pair_a, image_a)
467 pq = centers(:, 3) - centers(:, 4)
468 CALL prepare_eri4_pair(centers(:, 3), centers(:, 4), exponents(3), exponents(4), &
469 dot_product(pq, pq), pair_b, image_b)
470 pq = image_a%P - image_b%P
471 pq2 = dot_product(pq, pq)
472 SELECT CASE (potential_parameter%potential_type)
474 IF (pq2 > (r1 + r2 + potential_parameter%cutoff_radius)**2) RETURN
475 END SELECT
476
477 CALL prepare_eri4_product(pair_a, pair_b, m_max, product)
478 s1234 = exp(image_a%S1234 + image_b%S1234)
479 CALL prepare_eri4_primitive(product, image_a, image_b, s1234, pq2, potential_parameter, params)
480 IF (m_max /= 0) THEN
481 CALL cp_libint_set_params_eri(context%eri, params, [1, 2, 3, 4], m_max)
482 CALL cp_libint_get_eris(angular_momenta(4), angular_momenta(3), angular_momenta(2), &
483 angular_momenta(1), context%eri, p_work, a_mysize)
484 DO i = 1, mysize
485 max_val = max(max_val, abs(p_work(i)))
486 END DO
487 ELSE
488 max_val = abs(params%Fm(1))
489 END IF
490
491 END SUBROUTINE evaluate_eri_screen
492
493! **************************************************************************************************
494!> \brief Evaluate electron repulsion integrals for a primitive quartet
495!> \param context four-center integral context
496!> \param nproducts ...
497!> \param pgf_product_list ...
498!> \param n_a ...
499!> \param n_b ...
500!> \param n_c ...
501!> \param n_d ...
502!> \param ncoa ...
503!> \param ncob ...
504!> \param ncoc ...
505!> \param ncod ...
506!> \param nsgfa ...
507!> \param nsgfb ...
508!> \param nsgfc ...
509!> \param nsgfd ...
510!> \param primitives ...
511!> \param max_contraction ...
512!> \param tmp_max ...
513!> \param eps_schwarz ...
514!> \param neris ...
515!> \param s_offset_a ...
516!> \param s_offset_b ...
517!> \param s_offset_c ...
518!> \param s_offset_d ...
519!> \param nl_a ...
520!> \param nl_b ...
521!> \param nl_c ...
522!> \param nl_d ...
523!> \param nsoa ...
524!> \param nsob ...
525!> \param nsoc ...
526!> \param nsod ...
527!> \param sphi_a ...
528!> \param sphi_b ...
529!> \param sphi_c ...
530!> \param sphi_d ...
531!> \param work ...
532!> \param work2 ...
533!> \param buffer1 ...
534!> \param buffer2 ...
535!> \param primitives_tmp ...
536!> \par History
537!> 11.2006 created [Manuel Guidon]
538!> 08.2007 refactured permutation part [Manuel Guidon]
539!> \author Manuel Guidon
540! **************************************************************************************************
541 SUBROUTINE evaluate_eri(context, nproducts, pgf_product_list, &
542 n_a, n_b, n_c, n_d, &
543 ncoa, ncob, ncoc, ncod, &
544 nsgfa, nsgfb, nsgfc, nsgfd, &
545 primitives, max_contraction, tmp_max, &
546 eps_schwarz, neris, &
547 s_offset_a, s_offset_b, s_offset_c, s_offset_d, &
548 nl_a, nl_b, nl_c, nl_d, nsoa, nsob, nsoc, nsod, &
549 sphi_a, sphi_b, sphi_c, sphi_d, work, work2, buffer1, buffer2, &
550 primitives_tmp)
551
552 TYPE(four_center_integral_context_type) :: context
553 INTEGER, INTENT(IN) :: nproducts
554 TYPE(eri4_pgf_product_type), DIMENSION(nproducts) :: pgf_product_list
555 INTEGER, INTENT(IN) :: n_a, n_b, n_c, n_d, ncoa, ncob, ncoc, &
556 ncod, nsgfa, nsgfb, nsgfc, nsgfd
557 REAL(dp), DIMENSION(nsgfa, nsgfb, nsgfc, nsgfd) :: primitives
558 REAL(dp) :: max_contraction, tmp_max, eps_schwarz
559 INTEGER(int_8) :: neris
560 INTEGER :: s_offset_a, s_offset_b, s_offset_c, &
561 s_offset_d, nl_a, nl_b, nl_c, nl_d, &
562 nsoa, nsob, nsoc, nsod
563 REAL(dp), DIMENSION(ncoa, nsoa*nl_a), INTENT(IN) :: sphi_a
564 REAL(dp), DIMENSION(ncob, nsob*nl_b), INTENT(IN) :: sphi_b
565 REAL(dp), DIMENSION(ncoc, nsoc*nl_c), INTENT(IN) :: sphi_c
566 REAL(dp), DIMENSION(ncod, nsod*nl_d), INTENT(IN) :: sphi_d
567 REAL(dp), TARGET :: work(ncoa*ncob*ncoc*ncod)
568 REAL(dp) :: work2(ncoa, ncob, ncoc, ncod)
569 REAL(dp), DIMENSION(ncoa*ncob*ncoc*ncod) :: buffer1, buffer2
570 REAL(dp), DIMENSION(nsoa*nl_a, nsob*nl_b, nsoc*& nl_c, nsod*nl_d) :: primitives_tmp
571
572 INTEGER :: a_mysize(1), angular_momenta(4), i, &
573 m_max, mysize, permutation(4)
574 LOGICAL :: direct_contract
575 REAL(dp), DIMENSION(:), POINTER :: eri_src, p_work
576
577 IF (nproducts == 0) RETURN
578
579 m_max = n_a + n_b + n_c + n_d
580 mysize = ncoa*ncob*ncoc*ncod
581 a_mysize = mysize
582
583 IF (m_max /= 0) THEN
584 IF (nproducts > 1) work(1:mysize) = 0.0_dp
585 CALL get_eri_permutation(n_a, n_b, n_c, n_d, permutation)
586 angular_momenta = [n_a, n_b, n_c, n_d]
587 angular_momenta = angular_momenta(permutation)
588
589 DO i = 1, nproducts
590 CALL cp_libint_set_params_eri(context%eri, pgf_product_list(i), permutation, m_max)
591 CALL cp_libint_get_eris(angular_momenta(4), angular_momenta(3), angular_momenta(2), &
592 angular_momenta(1), context%eri, p_work, a_mysize)
593 IF (nproducts > 1) work(1:mysize) = work(1:mysize) + p_work(1:mysize)
594 neris = neris + mysize
595 END DO
596 IF (nproducts == 1) THEN
597 eri_src => p_work
598 ELSE
599 eri_src => work
600 END IF
601 DO i = 1, mysize
602 tmp_max = max(tmp_max, abs(eri_src(i)))
603 END DO
604 tmp_max = tmp_max*max_contraction
605 IF (tmp_max < eps_schwarz) RETURN
606 CALL reorder_eri_block(eri_src, work2, [ncoa, ncob, ncoc, ncod], permutation, 1, 1)
607 ELSE
608 work(1) = 0.0_dp
609 DO i = 1, nproducts
610 work(1) = work(1) + pgf_product_list(i)%Fm(1)
611 neris = neris + mysize
612 END DO
613 work2(1, 1, 1, 1) = work(1)
614 tmp_max = max_contraction*abs(work(1))
615 IF (tmp_max < eps_schwarz) RETURN
616 END IF
617
618 direct_contract = (s_offset_a == 0 .AND. s_offset_b == 0 .AND. &
619 s_offset_c == 0 .AND. s_offset_d == 0 .AND. &
620 nsgfa == nsoa*nl_a .AND. nsgfb == nsob*nl_b .AND. &
621 nsgfc == nsoc*nl_c .AND. nsgfd == nsod*nl_d)
622 IF (direct_contract) THEN
623 CALL contract(ncoa, ncob, ncoc, ncod, nsoa, nsob, nsoc, nsod, &
624 n_a, n_b, n_c, n_d, nl_a, nl_b, nl_c, nl_d, work2, &
625 sphi_a, &
626 sphi_b, &
627 sphi_c, &
628 sphi_d, &
629 primitives, &
630 buffer1, buffer2)
631 ELSE
632 primitives_tmp = 0.0_dp
633
634 CALL contract(ncoa, ncob, ncoc, ncod, nsoa, nsob, nsoc, nsod, &
635 n_a, n_b, n_c, n_d, nl_a, nl_b, nl_c, nl_d, work2, &
636 sphi_a, &
637 sphi_b, &
638 sphi_c, &
639 sphi_d, &
640 primitives_tmp, &
641 buffer1, buffer2)
642
643 primitives(s_offset_a + 1:s_offset_a + nsoa*nl_a, &
644 s_offset_b + 1:s_offset_b + nsob*nl_b, &
645 s_offset_c + 1:s_offset_c + nsoc*nl_c, &
646 s_offset_d + 1:s_offset_d + nsod*nl_d) = &
647 primitives(s_offset_a + 1:s_offset_a + nsoa*nl_a, &
648 s_offset_b + 1:s_offset_b + nsob*nl_b, &
649 s_offset_c + 1:s_offset_c + nsoc*nl_c, &
650 s_offset_d + 1:s_offset_d + nsod*nl_d) + primitives_tmp(:, :, :, :)
651 END IF
652
653 END SUBROUTINE evaluate_eri
654
656
Handles all functions related to the CELL.
Definition cell_types.F:15
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
Definition cell_types.F:631
Four-center integral evaluation with an encapsulated Libint backend.
subroutine, public four_center_integral_init(context, max_am)
Initialize the four-center energy and first-derivative workspaces.
subroutine, public evaluate_deriv_eri(context, nproducts, pgf_product_list, n_a, n_b, n_c, n_d, ncoa, ncob, ncoc, ncod, nsgfa, nsgfb, nsgfc, nsgfd, primitives, max_contraction, tmp_max_all, eps_schwarz, neris, s_offset_a, s_offset_b, s_offset_c, s_offset_d, nl_a, nl_b, nl_c, nl_d, nsoa, nsob, nsoc, nsod, sphi_a, sphi_b, sphi_c, sphi_d, work, work2, work_forces, buffer1, buffer2, primitives_tmp, use_virial, work_virial, work2_virial, primitives_tmp_virial, primitives_virial, cell, tmp_max_all_virial)
Evaluates derivatives of electron repulsion integrals for a primitive quartet.
subroutine, public four_center_integral_cleanup(context)
Release the workspaces of an owning four-center context.
subroutine, public evaluate_eri_screen(context, a, b, c, d, zeta_a, zeta_b, zeta_c, zeta_d, n_a, n_b, n_c, n_d, max_val, potential_parameter, r1, r2)
Evaluates max-abs values of electron repulsion integrals for a primitive quartet.
subroutine, public evaluate_eri(context, nproducts, pgf_product_list, n_a, n_b, n_c, n_d, ncoa, ncob, ncoc, ncod, nsgfa, nsgfb, nsgfc, nsgfd, primitives, max_contraction, tmp_max, eps_schwarz, neris, s_offset_a, s_offset_b, s_offset_c, s_offset_d, nl_a, nl_b, nl_c, nl_d, nsoa, nsob, nsoc, nsod, sphi_a, sphi_b, sphi_c, sphi_d, work, work2, buffer1, buffer2, primitives_tmp)
Evaluate electron repulsion integrals for a primitive quartet.
Gaussian-product geometry and radial seeds shared by four-center evaluation and screening.
subroutine, public prepare_eri4_primitive(product, image_a, image_b, attenuation, pq2, potential_parameter, params)
Complete a prepared quartet for one selected image, including normalized radial seeds.
subroutine, public prepare_eri4_pair(ra, rb, zeta, zetb, rab2, pair, image)
Prepare one Gaussian pair, retaining the caller's image topology and screening metadata.
subroutine, public prepare_eri4_product(pair_a, pair_b, m_max, product)
Prepare the image-independent quartet data once per combination of Gaussian pairs.
Primitive Gaussian pairs and products for four-center integrals. The fixed radial workspace capacity ...
Contains routines for contraction without dgemms. \notes Contains specific routines for contraction....
subroutine, public contract(ncoa, ncob, ncoc, ncod, nsoa, nsob, nsoc, nsod, n_a, n_b, n_c, n_d, nl_a, nl_b, nl_c, nl_d, work, sphi_a, sphi_b, sphi_c, sphi_d, primitives, buffer1, buffer2)
...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_potential_truncated
integer, parameter, public do_potential_short
integer, parameter, public do_potential_mix_cl_trunc
Library choices for electronic integral APIs.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
Interface to the Libint-Library or a c++ wrapper.
subroutine, public cp_libint_init_eri1(lib, max_am)
subroutine, public cp_libint_get_eris(n_d, n_c, n_b, n_a, lib, p_work, a_mysize)
...
subroutine, public cp_libint_set_params_eri_deriv(libint, params, permutation, m_max)
Fill common ERI fields and the additional first-derivative recurrence fields.
subroutine, public cp_libint_set_params_eri(libint, params, permutation, m_max)
Fill an ERI backend from one prepared primitive and a pair-symmetry permutation.
subroutine, public cp_libint_get_derivs(n_d, n_c, n_b, n_a, lib, work_forces, a_mysize)
...
subroutine, public cp_libint_cleanup_eri1(lib)
subroutine, public cp_libint_init_eri(lib, max_am)
subroutine, public cp_libint_cleanup_eri(lib)
subroutine, public cp_libint_set_contrdepth(lib, contrdepth)
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public nco
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
Context owning the energy and first-derivative backend workspaces.