21#ifndef _libint2_src_lib_libint_engineimpl_h_
22#define _libint2_src_lib_libint_engineimpl_h_
26#include "./deriv_map.h"
29#pragma GCC diagnostic push
30#pragma GCC system_header
32#pragma GCC diagnostic pop
34#include <libint2/boys.h>
35#if LIBINT_HAS_SYSTEM_BOOST_PREPROCESSOR_VARIADICS
36#include <boost/preprocessor.hpp>
37#include <boost/preprocessor/facilities/is_1.hpp>
39#include <libint2/boost/preprocessor.hpp>
40#include <libint2/boost/preprocessor/facilities/is_1.hpp>
45#define BOOST_PP_MAKE_TUPLE_INTERNAL(z, i, last) \
46 i BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(i, last))
48#define BOOST_PP_MAKE_TUPLE(n) \
49 (BOOST_PP_REPEAT(n, BOOST_PP_MAKE_TUPLE_INTERNAL, BOOST_PP_DEC(n)))
54#define LIBINT2_ENGINE_TIMERS
56#define LIBINT2_ENGINE_PROFILE_CLASS
64template <
typename T,
unsigned N>
65typename std::remove_all_extents<T>::type* to_ptr1(T (&a)[N]) {
66 return reinterpret_cast<typename std::remove_all_extents<T>::type*
>(&a);
73#define BOOST_PP_NBODY_OPERATOR_LIST \
90 (eri, (eri, (eri, (eri, BOOST_PP_NIL))))))))))))))))))))
92#define BOOST_PP_NBODY_OPERATOR_INDEX_TUPLE \
93 BOOST_PP_MAKE_TUPLE(BOOST_PP_LIST_SIZE(BOOST_PP_NBODY_OPERATOR_LIST))
94#define BOOST_PP_NBODY_OPERATOR_INDEX_LIST \
95 BOOST_PP_TUPLE_TO_LIST(BOOST_PP_NBODY_OPERATOR_INDEX_TUPLE)
96#define BOOST_PP_NBODY_OPERATOR_LAST_ONEBODY_INDEX \
101#define BOOST_PP_NBODY_BRAKET_INDEX_TUPLE \
102 BOOST_PP_MAKE_TUPLE(BOOST_PP_INC(BOOST_PP_NBODY_BRAKET_MAX_INDEX))
103#define BOOST_PP_NBODY_BRAKET_INDEX_LIST \
104 BOOST_PP_TUPLE_TO_LIST(BOOST_PP_NBODY_BRAKET_INDEX_TUPLE)
105#define BOOST_PP_NBODY_BRAKET_RANK_TUPLE (2, 3, 4)
106#define BOOST_PP_NBODY_BRAKET_RANK_LIST \
107 BOOST_PP_TUPLE_TO_LIST(BOOST_PP_NBODY_BRAKET_RANK_TUPLE)
110#define BOOST_PP_NBODY_DERIV_ORDER_TUPLE \
111 BOOST_PP_MAKE_TUPLE(BOOST_PP_INC(LIBINT2_MAX_DERIV_ORDER))
112#define BOOST_PP_NBODY_DERIV_ORDER_LIST \
113 BOOST_PP_TUPLE_TO_LIST(BOOST_PP_NBODY_DERIV_ORDER_TUPLE)
117 switch (
static_cast<int>(oper)) {
118#define BOOST_PP_NBODYENGINE_MCR1(r, data, i, elem) \
120 return operator_traits<static_cast<Operator>(i)>::default_params();
121 BOOST_PP_LIST_FOR_EACH_I(BOOST_PP_NBODYENGINE_MCR1, _,
122 BOOST_PP_NBODY_OPERATOR_LIST)
126 assert(
false &&
"missing case in switch");
139template <
typename... ShellPack>
140__libint2_engine_inline
const Engine::target_ptr_vec& Engine::compute(
141 const libint2::Shell& first_shell,
const ShellPack&... rest_of_shells) {
142 constexpr auto nargs = 1 +
sizeof...(rest_of_shells);
143 assert(nargs == braket_rank() &&
144 "# of arguments to compute() does not match the braket type");
146 std::array<std::reference_wrapper<const Shell>, nargs> shells{
147 {first_shell, rest_of_shells...}};
149 if (operator_rank() == 1) {
150 if (nargs == 2)
return compute1(shells[0], shells[1]);
151 }
else if (operator_rank() == 2) {
152 auto compute_ptr_idx = ((
static_cast<int>(oper_) -
153 static_cast<int>(Operator::first_2body_oper)) *
155 (
static_cast<int>(braket_) -
156 static_cast<int>(BraKet::first_2body_braket))) *
159 assert(compute_ptr_idx >= 0 && compute_ptr_idx < compute2_ptrs().size());
160 auto compute_ptr = compute2_ptrs()[compute_ptr_idx];
161 assert(compute_ptr !=
nullptr &&
"2-body compute function not found");
163 return (this->*compute_ptr)(shells[0],
Shell::unit(), shells[1],
166 return (this->*compute_ptr)(shells[0],
Shell::unit(), shells[1],
167 shells[2],
nullptr,
nullptr);
169 return (this->*compute_ptr)(shells[0], shells[1], shells[2], shells[3],
173 assert(
false &&
"missing feature");
181__libint2_engine_inline
const Engine::target_ptr_vec& Engine::compute1(
184 assert((s1.ncontr() == 1 && s2.ncontr() == 1) &&
185 "generally-contracted shells not yet supported");
187 const auto oper_is_nuclear =
188 (oper_ == Operator::nuclear || oper_ == Operator::erf_nuclear ||
189 oper_ == Operator::erfc_nuclear || oper_ == Operator::opVop);
191 const auto l1 = s1.
contr[0].l;
192 const auto l2 = s2.
contr[0].l;
193 assert(l1 <= lmax_ &&
"the angular momentum limit is exceeded");
194 assert(l2 <= lmax_ &&
"the angular momentum limit is exceeded");
198 if (oper_is_nuclear && nparams() == 0)
199 throw std::logic_error(
200 "Engine requires charges, but no charges found; forgot to call "
203 const auto n1 = s1.size();
204 const auto n2 = s2.size();
205 const auto n12 = n1 * n2;
206 const auto ncart1 = s1.cartesian_size();
207 const auto ncart2 = s2.cartesian_size();
208 const auto ncart12 = ncart1 * ncart2;
211 const auto nprim1 = s1.nprim();
212 const auto nprim2 = s2.nprim();
213 const auto nprimpairs = nprim1 * nprim2;
214 assert(nprimpairs <= primdata_.size() &&
215 "the max number of primitive pairs exceeded");
217 auto nparam_sets = nparams();
220 bool set_targets = set_targets_;
223 const auto ntargets = nopers() * num_geometrical_derivatives(2, deriv_order_);
230 const auto nderivcenters_shset = 2 + (oper_is_nuclear ? nparam_sets : 0);
231 const auto nderivcoord = 3 * nderivcenters_shset;
232 const auto num_shellsets_computed =
233 nopers() * num_geometrical_derivatives(nderivcenters_shset, deriv_order_);
241 const auto accumulate_ints_in_scratch = oper_is_nuclear;
244 const auto lmax = std::max(l1, l2);
245 assert(lmax <= lmax_ &&
"the angular momentum limit is exceeded");
251 const auto tform_to_solids =
252 (s1.
contr[0].pure || s2.
contr[0].pure) && lmax != 0;
256 const auto compute_directly =
257 lmax == 0 && deriv_order_ == 0 &&
258 (oper_ == Operator::overlap || oper_is_nuclear) &&
259 oper_ != Operator::opVop;
260 if (compute_directly) {
261 primdata_[0].stack[0] = 0;
262 targets_[0] = primdata_[0].stack;
265 if (accumulate_ints_in_scratch)
266 std::fill(std::begin(scratch_),
267 std::begin(scratch_) + num_shellsets_computed * ncart12, 0.0);
270 for (
auto pset = 0u; pset != nparam_sets; ++pset) {
271 if (!oper_is_nuclear)
272 assert(nparam_sets == 1 &&
"unexpected number of operator parameters");
275 for (
auto p1 = 0; p1 != nprim1; ++p1) {
276 for (
auto p2 = 0; p2 != nprim2; ++p2, ++p12) {
277 compute_primdata(primdata_[p12], s1, s2, p1, p2, pset);
280 primdata_[0].contrdepth = p12;
282 if (compute_directly) {
283 auto& result = primdata_[0].stack[0];
285 case Operator::overlap:
286 for (
auto p12 = 0; p12 != primdata_[0].contrdepth; ++p12)
287 result += primdata_[p12]._0_Overlap_0_x[0] *
288 primdata_[p12]._0_Overlap_0_y[0] *
289 primdata_[p12]._0_Overlap_0_z[0];
291 case Operator::nuclear:
292 case Operator::erf_nuclear:
293 case Operator::erfc_nuclear:
294 for (
auto p12 = 0; p12 != primdata_[0].contrdepth; ++p12)
295 result += primdata_[p12].LIBINT_T_S_ELECPOT_S(0)[0];
298 assert(
false &&
"missing case in switch");
300 primdata_[0].targets[0] = &result;
302 const auto buildfnidx = s1.
contr[0].l * hard_lmax_ + s2.
contr[0].l;
303 assert(buildfnptrs_[buildfnidx] &&
"null build function ptr");
304 buildfnptrs_[buildfnidx](&primdata_[0]);
306 if (accumulate_ints_in_scratch) {
313 if (deriv_order_ <= 1) {
316 auto s_target = &scratch_[0];
317 for (
auto s = 0; s != ntargets; ++s, s_target += ncart12)
319 std::transform(primdata_[0].targets[s],
320 primdata_[0].targets[s] + ncart12, s_target,
321 s_target, std::plus<value_type>());
323 std::copy(primdata_[0].targets[s],
324 primdata_[0].targets[s] + ncart12, s_target);
332 if (deriv_order_ > 0) {
333 switch (deriv_order_) {
339 assert(ntargets == 6 &&
"unexpected # of targets");
340 auto dest = &scratch_[0] + (6 + pset * 3) * ncart12;
341 for (
auto s = 0; s != 3; ++s, dest += ncart12) {
342 auto src = primdata_[0].targets[s];
343 for (
auto i = 0; i != ncart12; ++i) {
348 for (
auto s = 3; s != 6; ++s, dest += ncart12) {
349 auto src = primdata_[0].targets[s];
350 for (
auto i = 0; i != ncart12; ++i) {
360 auto upper_triangle_index_ord = [](
int n2,
int i,
int j) {
361 return i * (n2 - i - 1) / 2 + j;
364 auto upper_triangle_index = [&](
int n2,
int i,
int j) {
365 return upper_triangle_index_ord(n2, std::min(i, j),
371 const auto ncoords_times_two = nderivcoord * 2;
372 for (
auto d0 = 0, d01 = 0; d0 != 6; ++d0) {
373 for (
auto d1 = d0; d1 != 6; ++d1, ++d01) {
374 const auto d01_full =
375 upper_triangle_index_ord(ncoords_times_two, d0, d1);
376 auto tgt = &scratch_[d01_full * ncart12];
378 std::transform(primdata_[0].targets[d01],
379 primdata_[0].targets[d01] + ncart12, tgt,
380 tgt, std::plus<value_type>());
382 std::copy(primdata_[0].targets[d01],
383 primdata_[0].targets[d01] + ncart12, tgt);
392 const auto c1 = 2 + pset;
393 for (
auto c0 = 0; c0 != 2; ++c0) {
394 for (
auto xyz0 = 0; xyz0 != 3; ++xyz0) {
395 const auto coord0 = c0 * 3 + xyz0;
396 for (
auto xyz1 = 0; xyz1 != 3; ++xyz1) {
397 const auto coord1 = c1 * 3 + xyz1;
399 const auto coord01_abs = upper_triangle_index_ord(
400 ncoords_times_two, coord0, coord1);
401 auto tgt = &scratch_[coord01_abs * ncart12];
405 auto coord1_A = xyz1;
406 const auto coord01_A =
407 upper_triangle_index(12, coord0, coord1_A);
408 const auto src = primdata_[0].targets[coord01_A];
409 for (
auto i = 0; i != ncart12; ++i) tgt[i] = -src[i];
414 auto coord1_B = 3 + xyz1;
415 const auto coord01_B =
416 upper_triangle_index(12, coord0, coord1_B);
417 const auto src = primdata_[0].targets[coord01_B];
418 for (
auto i = 0; i != ncart12; ++i) tgt[i] -= src[i];
426 const auto c0 = 2 + pset;
428 for (
auto xyz0 = 0; xyz0 != 3; ++xyz0) {
429 const auto coord0 = c0 * 3 + xyz0;
430 for (
auto xyz1 = xyz0; xyz1 != 3; ++xyz1) {
431 const auto coord1 = c1 * 3 + xyz1;
433 const auto coord01_abs = upper_triangle_index_ord(
434 ncoords_times_two, coord0, coord1);
435 auto tgt = &scratch_[coord01_abs * ncart12];
439 auto coord0_A = xyz0;
440 auto coord1_A = xyz1;
441 const auto coord01_AA =
442 upper_triangle_index_ord(12, coord0_A, coord1_A);
443 const auto src = primdata_[0].targets[coord01_AA];
444 for (
auto i = 0; i != ncart12; ++i) tgt[i] = src[i];
449 auto coord0_A = xyz0;
450 auto coord1_B = 3 + xyz1;
451 const auto coord01_AB =
452 upper_triangle_index_ord(12, coord0_A, coord1_B);
453 const auto src = primdata_[0].targets[coord01_AB];
454 for (
auto i = 0; i != ncart12; ++i) tgt[i] += src[i];
459 auto coord0_B = 3 + xyz0;
460 auto coord1_A = xyz1;
461 const auto coord01_BA =
462 upper_triangle_index_ord(12, coord1_A, coord0_B);
463 const auto src = primdata_[0].targets[coord01_BA];
464 for (
auto i = 0; i != ncart12; ++i) tgt[i] += src[i];
469 auto coord0_B = 3 + xyz0;
470 auto coord1_B = 3 + xyz1;
471 const auto coord01_BB =
472 upper_triangle_index_ord(12, coord0_B, coord1_B);
473 const auto src = primdata_[0].targets[coord01_BB];
474 for (
auto i = 0; i != ncart12; ++i) tgt[i] += src[i];
483 assert(deriv_order_ <= 2 &&
"feature not implemented");
488 using ShellSetDerivIterator =
490 std::vector<unsigned int>>;
491 ShellSetDerivIterator shellset_gaussian_diter(deriv_order_, 2);
492 ShellSetDerivIterator shellset_full_diter(deriv_order_,
493 nderivcenters_shset);
494 std::vector<unsigned int> full_deriv(3 * nderivcenters_shset, 0);
496 while (shellset_gaussian_diter) {
498 const auto& s1s2_deriv = *shellset_gaussian_diter;
499 std::copy(std::begin(s1s2_deriv), std::end(s1s2_deriv),
500 std::begin(full_deriv));
501 const auto full_rank = ShellSetDerivIterator::rank(full_deriv);
502 targets_[full_rank] = primdata_[0].targets[s];
514 if (tform_to_solids) {
517 auto* spherical_ints =
518 (accumulate_ints_in_scratch) ? scratch2_ : &scratch_[0];
522 for (
auto s = 0ul; s != num_shellsets_computed;
523 ++s, spherical_ints += n12) {
524 auto cartesian_ints = accumulate_ints_in_scratch
525 ? &scratch_[s * ncart12]
526 : primdata_[0].targets[s];
529 libint2::solidharmonics::tform(l1, l2, cartesian_ints, spherical_ints);
531 if (s1.
contr[0].pure)
532 libint2::solidharmonics::tform_rows(l1, n2, cartesian_ints,
535 libint2::solidharmonics::tform_cols(n1, l2, cartesian_ints,
539 targets_[s] = spherical_ints;
544 for (
auto s = 0ul; s != num_shellsets_computed; ++s) {
545 auto cartesian_ints = accumulate_ints_in_scratch
546 ? &scratch_[s * ncart12]
547 : primdata_[0].targets[s];
548 targets_[s] = cartesian_ints;
552 if (cartesian_shell_normalization() == CartesianShellNormalization::uniform) {
553 std::array<std::reference_wrapper<const Shell>, 2> shells{s1, s2};
554 for (
auto s = 0ul; s != num_shellsets_computed; ++s) {
564__libint2_engine_inline
void Engine::_initialize() {
565#define BOOST_PP_NBODYENGINE_MCR3_ncenter(product) \
566 BOOST_PP_TUPLE_ELEM(3, 1, product)
568#define BOOST_PP_NBODYENGINE_MCR3_default_ncenter(product) \
569 BOOST_PP_IIF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(3, 0, product), \
570 BOOST_PP_NBODY_OPERATOR_LAST_ONEBODY_INDEX), \
573#define BOOST_PP_NBODYENGINE_MCR3_NCENTER(product) \
575 BOOST_PP_NOT_EQUAL(BOOST_PP_NBODYENGINE_MCR3_ncenter(product), \
576 BOOST_PP_NBODYENGINE_MCR3_default_ncenter(product)), \
577 BOOST_PP_NBODYENGINE_MCR3_ncenter(product), BOOST_PP_EMPTY())
579#define BOOST_PP_NBODYENGINE_MCR3_OPER(product) \
580 BOOST_PP_LIST_AT(BOOST_PP_NBODY_OPERATOR_LIST, \
581 BOOST_PP_TUPLE_ELEM(3, 0, product))
583#define BOOST_PP_NBODYENGINE_MCR3_DERIV(product) \
584 BOOST_PP_IIF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(3, 2, product), 0), \
585 BOOST_PP_TUPLE_ELEM(3, 2, product), BOOST_PP_EMPTY())
587#define BOOST_PP_NBODYENGINE_MCR3_task(product) \
588 BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_NBODYENGINE_MCR3_ncenter(product), \
589 BOOST_PP_NBODYENGINE_MCR3_OPER(product)), \
590 BOOST_PP_NBODYENGINE_MCR3_DERIV(product))
592#define BOOST_PP_NBODYENGINE_MCR3_TASK(product) \
594 BOOST_PP_CAT(LIBINT2_TASK_EXISTS_, \
595 BOOST_PP_NBODYENGINE_MCR3_task(product)), \
596 BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_NBODYENGINE_MCR3_NCENTER(product), \
597 BOOST_PP_NBODYENGINE_MCR3_OPER(product)), \
598 BOOST_PP_NBODYENGINE_MCR3_DERIV(product)), \
601#define BOOST_PP_NBODYENGINE_MCR3(r, product) \
602 if (static_cast<int>(oper_) == BOOST_PP_TUPLE_ELEM(3, 0, product) && \
603 static_cast<int>(rank(braket_)) == BOOST_PP_TUPLE_ELEM(3, 1, product) && \
604 deriv_order_ == BOOST_PP_TUPLE_ELEM(3, 2, product)) { \
605 hard_lmax_ = BOOST_PP_CAT(LIBINT2_MAX_AM_, \
606 BOOST_PP_NBODYENGINE_MCR3_TASK(product)) + \
608 hard_default_lmax_ = BOOST_PP_IF( \
609 BOOST_PP_IS_1(BOOST_PP_CAT(LIBINT2_CENTER_DEPENDENT_MAX_AM_, \
610 BOOST_PP_NBODYENGINE_MCR3_task(product))), \
613 BOOST_PP_CAT(default, BOOST_PP_NBODYENGINE_MCR3_DERIV(product))) + \
615 std::numeric_limits<int>::max()); \
616 const auto lmax = BOOST_PP_IF( \
617 BOOST_PP_IS_1(BOOST_PP_CAT(LIBINT2_CENTER_DEPENDENT_MAX_AM_, \
618 BOOST_PP_NBODYENGINE_MCR3_task(product))), \
619 std::max(hard_lmax_, hard_default_lmax_), hard_lmax_); \
620 if (lmax_ >= lmax) { \
621 throw Engine::lmax_exceeded(BOOST_PP_STRINGIZE(BOOST_PP_NBODYENGINE_MCR3_TASK(product)), lmax, lmax_); \
623 if (stack_size_ > 0) libint2_cleanup_default(&primdata_[0]); \
624 stack_size_ = LIBINT2_PREFIXED_NAME(BOOST_PP_CAT( \
625 libint2_need_memory_, BOOST_PP_NBODYENGINE_MCR3_TASK(product)))( \
627 LIBINT2_PREFIXED_NAME( \
628 BOOST_PP_CAT(libint2_init_, BOOST_PP_NBODYENGINE_MCR3_TASK(product))) \
629 (&primdata_[0], lmax_, 0); \
630 BOOST_PP_IF(BOOST_PP_IS_1(LIBINT2_FLOP_COUNT), \
631 LIBINT2_PREFIXED_NAME(libint2_init_flopcounter)( \
632 &primdata_[0], primdata_.size()), \
634 buildfnptrs_ = to_ptr1(LIBINT2_PREFIXED_NAME(BOOST_PP_CAT( \
635 libint2_build_, BOOST_PP_NBODYENGINE_MCR3_TASK(product)))); \
640 BOOST_PP_LIST_FOR_EACH_PRODUCT(
641 BOOST_PP_NBODYENGINE_MCR3, 3,
642 (BOOST_PP_NBODY_OPERATOR_INDEX_LIST, BOOST_PP_NBODY_BRAKET_RANK_LIST,
643 BOOST_PP_NBODY_DERIV_ORDER_LIST))
646 "missing case in switch");
650__libint2_engine_inline
void Engine::initialize(
size_t max_nprim) {
652 assert(deriv_order_ <= LIBINT2_MAX_DERIV_ORDER &&
653 "exceeded the max derivative order of the library");
656#ifndef INCLUDE_ONEBODY
657 assert(braket_ != BraKet::x_x &&
658 "this braket type not supported by the library; give --enable-1body "
662 assert(braket_ != BraKet::xx_xx &&
663 "this braket type not supported by the library; give --enable-eri to "
667 assert((braket_ != BraKet::xs_xx && braket_ != BraKet::xx_xs) &&
668 "this braket type not supported by the library; give --enable-eri3 to "
672 assert(braket_ != BraKet::xs_xs &&
673 "this braket type not supported by the library; give --enable-eri2 to "
678 if (lmax_ < 0)
throw using_default_initialized();
681 if (braket_ == BraKet::invalid) braket_ = default_braket(oper_);
683 if (max_nprim != 0) primdata_.resize(std::pow(max_nprim, braket_rank()));
687 decltype(targets_)::allocator_type alloc(primdata_[0].targets);
688 targets_ =
decltype(targets_)(alloc);
694 const auto permutable_targets =
696 (braket_ == BraKet::xx_xx || braket_ == BraKet::xs_xx ||
697 braket_ == BraKet::xx_xs);
698 if (permutable_targets)
699 targets_.reserve(max_ntargets + 1);
701 targets_.reserve(max_ntargets);
705#ifdef LIBINT2_ENGINE_TIMERS
706 timers.set_now_overhead(25);
708#ifdef LIBINT2_PROFILE
709 primdata_[0].timers->set_now_overhead(25);
716__libint2_engine_inline std::vector<Engine::compute2_ptr_type>
717init_compute2_ptrs() {
718 auto max_ncompute2_ptrs = nopers_2body * nbrakets_2body * nderivorders_2body;
719 std::vector<Engine::compute2_ptr_type> result(max_ncompute2_ptrs,
nullptr);
721#define BOOST_PP_NBODYENGINE_MCR7(r, product) \
722 if (BOOST_PP_TUPLE_ELEM(3, 0, product) >= \
723 static_cast<int>(Operator::first_2body_oper) && \
724 BOOST_PP_TUPLE_ELEM(3, 0, product) <= \
725 static_cast<int>(Operator::last_2body_oper) && \
726 BOOST_PP_TUPLE_ELEM(3, 1, product) >= \
727 static_cast<int>(BraKet::first_2body_braket) && \
728 BOOST_PP_TUPLE_ELEM(3, 1, product) <= \
729 static_cast<int>(BraKet::last_2body_braket)) { \
730 auto compute_ptr_idx = ((BOOST_PP_TUPLE_ELEM(3, 0, product) - \
731 static_cast<int>(Operator::first_2body_oper)) * \
733 (BOOST_PP_TUPLE_ELEM(3, 1, product) - \
734 static_cast<int>(BraKet::first_2body_braket))) * \
735 nderivorders_2body + \
736 BOOST_PP_TUPLE_ELEM(3, 2, product); \
737 result.at(compute_ptr_idx) = &Engine::compute2< \
738 static_cast<Operator>(BOOST_PP_TUPLE_ELEM(3, 0, product)), \
739 static_cast<BraKet>(BOOST_PP_TUPLE_ELEM(3, 1, product)), \
740 BOOST_PP_TUPLE_ELEM(3, 2, product)>; \
743 BOOST_PP_LIST_FOR_EACH_PRODUCT(
744 BOOST_PP_NBODYENGINE_MCR7, 3,
745 (BOOST_PP_NBODY_OPERATOR_INDEX_LIST, BOOST_PP_NBODY_BRAKET_INDEX_LIST,
746 BOOST_PP_NBODY_DERIV_ORDER_LIST))
752__libint2_engine_inline
const std::vector<Engine::compute2_ptr_type>&
753Engine::compute2_ptrs()
const {
754 static std::vector<compute2_ptr_type> compute2_ptrs_ =
755 detail::init_compute2_ptrs();
756 return compute2_ptrs_;
759__libint2_engine_inline
unsigned int Engine::nparams()
const {
761 case Operator::nuclear:
762 case Operator::opVop:
764 const operator_traits<Operator::nuclear>::oper_params_type&>(
767 case Operator::erf_nuclear:
768 case Operator::erfc_nuclear:
770 any_cast<
const operator_traits<
771 Operator::erfc_nuclear>::oper_params_type&>(params_))
778__libint2_engine_inline
unsigned int Engine::nopers()
const {
779 switch (
static_cast<int>(oper_)) {
780#define BOOST_PP_NBODYENGINE_MCR4(r, data, i, elem) \
782 return operator_traits<static_cast<Operator>(i)>::nopers;
783 BOOST_PP_LIST_FOR_EACH_I(BOOST_PP_NBODYENGINE_MCR4, _,
784 BOOST_PP_NBODY_OPERATOR_LIST)
788 assert(
false &&
"missing case in switch");
791__libint2_engine_inline
unsigned int Engine::intrinsic_deriv_order()
const {
792 switch (
static_cast<int>(oper_)) {
793#define BOOST_PP_NBODYENGINE_MCR9(r, data, i, elem) \
795 return operator_traits<static_cast<Operator>(i)>::intrinsic_deriv_order;
796 BOOST_PP_LIST_FOR_EACH_I(BOOST_PP_NBODYENGINE_MCR9, _,
797 BOOST_PP_NBODY_OPERATOR_LIST)
801 assert(
false &&
"missing case in switch");
806__libint2_engine_inline any Engine::enforce_params_type<any>(
807 Operator oper,
const any& params,
bool throw_if_wrong_type) {
809 switch (
static_cast<int>(oper)) {
810#define BOOST_PP_NBODYENGINE_MCR5A(r, data, i, elem) \
812 if (any_cast<operator_traits<static_cast<Operator>(i)>::oper_params_type>( \
813 ¶ms) != nullptr) { \
816 if (throw_if_wrong_type) throw bad_any_cast(); \
817 result = operator_traits<static_cast<Operator>(i)>::default_params(); \
821 BOOST_PP_LIST_FOR_EACH_I(BOOST_PP_NBODYENGINE_MCR5A, _,
822 BOOST_PP_NBODY_OPERATOR_LIST)
825 assert(
false &&
"missing case in switch");
831template <
typename Params>
832__libint2_engine_inline any Engine::enforce_params_type(
833 Operator oper,
const Params& params,
bool throw_if_wrong_type) {
835 switch (
static_cast<int>(oper)) {
836#define BOOST_PP_NBODYENGINE_MCR5B(r, data, i, elem) \
838 if (std::is_same<Params, operator_traits<static_cast<Operator>( \
839 i)>::oper_params_type>::value) { \
842 if (throw_if_wrong_type) throw std::bad_cast(); \
843 result = operator_traits<static_cast<Operator>(i)>::default_params(); \
847 BOOST_PP_LIST_FOR_EACH_I(BOOST_PP_NBODYENGINE_MCR5B, _,
848 BOOST_PP_NBODY_OPERATOR_LIST)
851 assert(
false &&
"missing case in switch");
861__libint2_engine_inline any Engine::make_core_eval_pack(Operator oper)
const {
863 switch (
static_cast<int>(oper)) {
864#define BOOST_PP_NBODYENGINE_MCR6(r, data, i, elem) \
866 result = libint2::detail::make_compressed_pair( \
867 operator_traits<static_cast<Operator>(i)>::core_eval_type::instance( \
868 braket_rank() * lmax_ + deriv_order_ + \
869 operator_traits<static_cast<Operator>( \
870 i)>::intrinsic_deriv_order, \
871 std::numeric_limits<scalar_type>::epsilon()), \
872 libint2::detail::CoreEvalScratch< \
873 operator_traits<static_cast<Operator>(i)>::core_eval_type>( \
874 braket_rank() * lmax_ + deriv_order_ + \
875 operator_traits<static_cast<Operator>( \
876 i)>::intrinsic_deriv_order)); \
877 assert(any_cast<detail::core_eval_pack_type<static_cast<Operator>(i)>>( \
878 &result) != nullptr); \
881 BOOST_PP_LIST_FOR_EACH_I(BOOST_PP_NBODYENGINE_MCR6, _,
882 BOOST_PP_NBODY_OPERATOR_LIST)
885 assert(
false &&
"missing case in switch");
891__libint2_engine_inline
void Engine::init_core_ints_params(
const any& params) {
892 if (oper_ == Operator::delcgtg2) {
897 const auto& oparams =
898 any_cast<const operator_traits<Operator::delcgtg2>::oper_params_type&>(
900 const auto ng = oparams.size();
901 operator_traits<Operator::delcgtg2>::oper_params_type core_ints_params;
902 core_ints_params.reserve(ng * (ng + 1) / 2);
903 for (
size_t b = 0; b < ng; ++b)
904 for (
size_t k = 0; k <= b; ++k) {
905 const auto gexp = oparams[b].first + oparams[k].first;
906 const auto gcoeff = oparams[b].second * oparams[k].second *
908 const auto gcoeff_rescaled =
909 4 * oparams[b].first * oparams[k].first * gcoeff;
910 core_ints_params.push_back(std::make_pair(gexp, gcoeff_rescaled));
912 core_ints_params_ = core_ints_params;
914 core_ints_params_ = params;
918__libint2_engine_inline
void Engine::compute_primdata(Libint_t& primdata,
921 size_t p1,
size_t p2,
923 const auto& A = s1.O;
924 const auto& B = s2.O;
926 const auto alpha1 = s1.alpha[p1];
927 const auto alpha2 = s2.alpha[p2];
929 const auto c1 = s1.contr[0].coeff[p1];
930 const auto c2 = s2.contr[0].coeff[p2];
932 const auto gammap = alpha1 + alpha2;
933 const auto oogammap = 1 / gammap;
934 const auto rhop_over_alpha1 = alpha2 * oogammap;
935 const auto rhop = alpha1 * rhop_over_alpha1;
936 const auto Px = (alpha1 * A[0] + alpha2 * B[0]) * oogammap;
937 const auto Py = (alpha1 * A[1] + alpha2 * B[1]) * oogammap;
938 const auto Pz = (alpha1 * A[2] + alpha2 * B[2]) * oogammap;
939 const auto AB_x = A[0] - B[0];
940 const auto AB_y = A[1] - B[1];
941 const auto AB_z = A[2] - B[2];
942 const auto AB2_x = AB_x * AB_x;
943 const auto AB2_y = AB_y * AB_y;
944 const auto AB2_z = AB_z * AB_z;
946 assert(LIBINT2_SHELLQUARTET_SET == LIBINT2_SHELLQUARTET_SET_STANDARD &&
947 "non-standard shell ordering");
949 const auto oper_is_nuclear =
950 (oper_ == Operator::nuclear || oper_ == Operator::erf_nuclear ||
951 oper_ == Operator::erfc_nuclear || oper_ == Operator::opVop);
954 const auto l1 = s1.contr[0].l;
955 const auto l2 = s2.contr[0].l;
957 (oper_is_nuclear || oper_ == Operator::sphemultipole) && l1 > 0 && l2 > 0;
960 const bool hrr_ket_to_bra = l1 >= l2;
962 if (hrr_ket_to_bra) {
963#if LIBINT2_DEFINED(eri, AB_x)
964 primdata.AB_x[0] = AB_x;
966#if LIBINT2_DEFINED(eri, AB_y)
967 primdata.AB_y[0] = AB_y;
969#if LIBINT2_DEFINED(eri, AB_z)
970 primdata.AB_z[0] = AB_z;
973#if LIBINT2_DEFINED(eri, BA_x)
974 primdata.BA_x[0] = -AB_x;
976#if LIBINT2_DEFINED(eri, BA_y)
977 primdata.BA_y[0] = -AB_y;
979#if LIBINT2_DEFINED(eri, BA_z)
980 primdata.BA_z[0] = -AB_z;
987#if LIBINT2_DEFINED(eri, PA_x)
988 primdata.PA_x[0] = Px - A[0];
990#if LIBINT2_DEFINED(eri, PA_y)
991 primdata.PA_y[0] = Py - A[1];
993#if LIBINT2_DEFINED(eri, PA_z)
994 primdata.PA_z[0] = Pz - A[2];
999#if LIBINT2_DEFINED(eri, PB_x)
1000 primdata.PB_x[0] = Px - B[0];
1002#if LIBINT2_DEFINED(eri, PB_y)
1003 primdata.PB_y[0] = Py - B[1];
1005#if LIBINT2_DEFINED(eri, PB_z)
1006 primdata.PB_z[0] = Pz - B[2];
1010 if (oper_ == Operator::emultipole1 || oper_ == Operator::emultipole2 ||
1011 oper_ == Operator::emultipole3) {
1012 const auto& O = any_cast<
1013 const operator_traits<Operator::emultipole1>::oper_params_type&>(
1015#if LIBINT2_DEFINED(eri, BO_x)
1016 primdata.BO_x[0] = B[0] - O[0];
1018#if LIBINT2_DEFINED(eri, BO_y)
1019 primdata.BO_y[0] = B[1] - O[1];
1021#if LIBINT2_DEFINED(eri, BO_z)
1022 primdata.BO_z[0] = B[2] - O[2];
1025 if (oper_ == Operator::sphemultipole) {
1026 const auto& O = any_cast<
1027 const operator_traits<Operator::emultipole1>::oper_params_type&>(
1029#if LIBINT2_DEFINED(eri, PO_x)
1030 primdata.PO_x[0] = Px - O[0];
1032#if LIBINT2_DEFINED(eri, PO_y)
1033 primdata.PO_y[0] = Py - O[1];
1035#if LIBINT2_DEFINED(eri, PO_z)
1036 primdata.PO_z[0] = Pz - O[2];
1038#if LIBINT2_DEFINED(eri, PO2)
1039 primdata.PO2[0] = (Px - O[0]) * (Px - O[0]) + (Py - O[1]) * (Py - O[1]) +
1040 (Pz - O[2]) * (Pz - O[2]);
1044#if LIBINT2_DEFINED(eri, oo2z)
1045 primdata.oo2z[0] = 0.5 * oogammap;
1048 decltype(c1) sqrt_PI(1.77245385090551602729816748334);
1049 const auto xyz_pfac = sqrt_PI * sqrt(oogammap);
1050 const auto ovlp_ss_x = exp(-rhop * AB2_x) * xyz_pfac * c1 * c2 * scale_;
1051 const auto ovlp_ss_y = exp(-rhop * AB2_y) * xyz_pfac;
1052 const auto ovlp_ss_z = exp(-rhop * AB2_z) * xyz_pfac;
1054 primdata._0_Overlap_0_x[0] = ovlp_ss_x;
1055 primdata._0_Overlap_0_y[0] = ovlp_ss_y;
1056 primdata._0_Overlap_0_z[0] = ovlp_ss_z;
1058 if (oper_ == Operator::kinetic || (deriv_order_ > 0) ||
1059 oper_ == Operator::opVop) {
1060#if LIBINT2_DEFINED(eri, two_alpha0_bra)
1061 primdata.two_alpha0_bra[0] = 2.0 * alpha1;
1063#if LIBINT2_DEFINED(eri, two_alpha0_ket)
1064 primdata.two_alpha0_ket[0] = 2.0 * alpha2;
1068 if (oper_is_nuclear) {
1069 const auto& params =
1070 (oper_ == Operator::nuclear || oper_ == Operator::opVop)
1072 const operator_traits<Operator::nuclear>::oper_params_type&>(
1075 any_cast<
const operator_traits<
1076 Operator::erfc_nuclear>::oper_params_type&>(params_));
1078 const auto& C = params[oset].second;
1079 const auto& q = params[oset].first;
1080#if LIBINT2_DEFINED(eri, PC_x)
1081 primdata.PC_x[0] = Px - C[0];
1083#if LIBINT2_DEFINED(eri, PC_y)
1084 primdata.PC_y[0] = Py - C[1];
1086#if LIBINT2_DEFINED(eri, PC_z)
1087 primdata.PC_z[0] = Pz - C[2];
1090#if LIBINT2_DEFINED(eri, rho12_over_alpha1) || \
1091 LIBINT2_DEFINED(eri, rho12_over_alpha2)
1092 if (deriv_order_ + intrinsic_deriv_order() > 0) {
1093#if LIBINT2_DEFINED(eri, rho12_over_alpha1)
1094 primdata.rho12_over_alpha1[0] = rhop_over_alpha1;
1096#if LIBINT2_DEFINED(eri, rho12_over_alpha2)
1097 primdata.rho12_over_alpha2[0] = alpha1 * oogammap;
1101#if LIBINT2_DEFINED(eri, PC_x) && LIBINT2_DEFINED(eri, PC_y) && \
1102 LIBINT2_DEFINED(eri, PC_z)
1103 const auto PC2 = primdata.PC_x[0] * primdata.PC_x[0] +
1104 primdata.PC_y[0] * primdata.PC_y[0] +
1105 primdata.PC_z[0] * primdata.PC_z[0];
1106 const scalar_type U = gammap * PC2;
1108 s1.contr[0].l + s2.contr[0].l + deriv_order_ + intrinsic_deriv_order();
1109 auto* fm_ptr = &(primdata.LIBINT_T_S_ELECPOT_S(0)[0]);
1110 if (oper_ == Operator::nuclear || oper_ == Operator::opVop) {
1111 const auto& fm_engine_ptr =
1112 any_cast<const detail::core_eval_pack_type<Operator::nuclear>&>(
1115 fm_engine_ptr->eval(fm_ptr, U, mmax);
1116 }
else if (oper_ == Operator::erf_nuclear) {
1117 const auto& core_eval_ptr =
1118 any_cast<const detail::core_eval_pack_type<Operator::erf_nuclear>&>(
1121 const auto& core_ints_params = std::get<0>(
1122 any_cast<
const typename operator_traits<
1123 Operator::erf_nuclear>::oper_params_type&>(core_ints_params_));
1124 core_eval_ptr->eval(fm_ptr, gammap, U, mmax, core_ints_params);
1125 }
else if (oper_ == Operator::erfc_nuclear) {
1126 const auto& core_eval_ptr =
1127 any_cast<const detail::core_eval_pack_type<Operator::erfc_nuclear>&>(
1130 const auto& core_ints_params = std::get<0>(
1131 any_cast<
const typename operator_traits<
1132 Operator::erfc_nuclear>::oper_params_type&>(core_ints_params_));
1133 core_eval_ptr->eval(fm_ptr, gammap, U, mmax, core_ints_params);
1136 decltype(U) two_o_sqrt_PI(1.12837916709551257389615890312);
1138 -q * sqrt(gammap) * two_o_sqrt_PI * ovlp_ss_x * ovlp_ss_y * ovlp_ss_z;
1139 const auto m_fence = mmax + 1;
1140 for (
auto m = 0; m != m_fence; ++m) {
1151template <Operator op, BraKet bk,
size_t der>
1152__libint2_engine_inline
const Engine::target_ptr_vec& Engine::compute2(
1155 const ShellPair* tspbra,
const ShellPair* tspket) {
1156 assert(op == oper_ &&
"Engine::compute2 -- operator mismatch");
1157 assert(bk == braket_ &&
"Engine::compute2 -- braket mismatch");
1158 assert(der == deriv_order_ &&
"Engine::compute2 -- deriv_order mismatch");
1159 assert(((tspbra ==
nullptr && tspket ==
nullptr) ||
1160 (tspbra !=
nullptr && tspket !=
nullptr)) &&
1161 "Engine::compute2 -- expects zero or two ShellPair objects");
1162 assert(screening_method_ != ScreeningMethod::Invalid);
1169 assert((tbra1.ncontr() == 1 && tbra2.ncontr() == 1 && tket1.ncontr() == 1 &&
1170 tket2.ncontr() == 1) &&
1171 "generally-contracted shells are not yet supported");
1176 assert(tbra1.
contr[0].l <= lmax_ &&
"the angular momentum limit is exceeded");
1177 assert(tbra2.
contr[0].l <= lmax_ &&
"the angular momentum limit is exceeded");
1178 assert(tket1.
contr[0].l <= lmax_ &&
"the angular momentum limit is exceeded");
1179 assert(tket2.
contr[0].l <= lmax_ &&
"the angular momentum limit is exceeded");
1181#if LIBINT2_SHELLQUARTET_SET == \
1182 LIBINT2_SHELLQUARTET_SET_STANDARD
1183 const auto swap_tbra = (tbra1.
contr[0].l < tbra2.
contr[0].l);
1184 const auto swap_tket = (tket1.
contr[0].l < tket2.
contr[0].l);
1185 const auto swap_braket =
1186 ((braket_ == BraKet::xx_xx) && (tbra1.
contr[0].l + tbra2.
contr[0].l >
1188 braket_ == BraKet::xx_xs;
1190 const auto swap_tbra = (tbra1.
contr[0].l > tbra2.
contr[0].l);
1191 const auto swap_tket = (tket1.
contr[0].l > tket2.
contr[0].l);
1192 const auto swap_braket =
1193 ((braket_ == BraKet::xx_xx) && (tbra1.
contr[0].l + tbra2.
contr[0].l <
1195 braket_ == BraKet::xx_xs;
1196 assert(
false &&
"feature not implemented");
1200 swap_braket ? (swap_tket ? tket2 : tket1) : (swap_tbra ? tbra2 : tbra1);
1202 swap_braket ? (swap_tket ? tket1 : tket2) : (swap_tbra ? tbra1 : tbra2);
1204 swap_braket ? (swap_tbra ? tbra2 : tbra1) : (swap_tket ? tket2 : tket1);
1206 swap_braket ? (swap_tbra ? tbra1 : tbra2) : (swap_tket ? tket1 : tket2);
1207 const auto swap_bra = swap_braket ? swap_tket : swap_tbra;
1208 const auto swap_ket = swap_braket ? swap_tbra : swap_tket;
1210 const auto* spbra_precomputed = swap_braket ? tspket : tspbra;
1211 const auto* spket_precomputed = swap_braket ? tspbra : tspket;
1212 assert(((spbra_precomputed && spket_precomputed) ||
1215 "Engine::compute2: without precomputed shell pair data can only use "
1216 "original or conservative screening methods");
1218 const auto tform = bra1.contr[0].pure || bra2.contr[0].pure ||
1219 ket1.contr[0].pure || ket2.contr[0].pure;
1220 const auto permute = swap_braket || swap_tbra || swap_tket;
1221 const auto use_scratch = permute || tform;
1224 auto nprim_bra1 = bra1.nprim();
1225 auto nprim_bra2 = bra2.nprim();
1226 auto nprim_ket1 = ket1.nprim();
1227 auto nprim_ket2 = ket2.nprim();
1230 auto lmax = std::max(std::max(bra1.contr[0].l, bra2.contr[0].l),
1231 std::max(ket1.contr[0].l, ket2.contr[0].l));
1232 assert(lmax <= lmax_ &&
"the angular momentum limit is exceeded");
1233 const auto lmax_bra = std::max(bra1.contr[0].l, bra2.contr[0].l);
1234 const auto lmax_ket = std::max(ket1.contr[0].l, ket2.contr[0].l);
1236#ifdef LIBINT2_ENGINE_PROFILE_CLASS
1237 class_id id(bra1.contr[0].l, bra2.contr[0].l, ket1.contr[0].l,
1239 if (class_profiles.find(
id) == class_profiles.end()) {
1240 class_profile dummy;
1241 class_profiles[id] = dummy;
1246#ifdef LIBINT2_ENGINE_TIMERS
1258 const auto target_shellpair_ln_precision = ln_precision_;
1259 const auto recompute_spbra =
1260 !spbra_precomputed ||
1261 spbra_precomputed->ln_prec > target_shellpair_ln_precision;
1262 const auto recompute_spket =
1263 !spket_precomputed ||
1264 spket_precomputed->ln_prec > target_shellpair_ln_precision;
1265 const ShellPair& spbra =
1267 ? (spbra_.init(bra1, bra2, target_shellpair_ln_precision,
1270 : *spbra_precomputed;
1271 const ShellPair& spket =
1273 ? (spket_.init(ket1, ket2, target_shellpair_ln_precision,
1276 : *spket_precomputed;
1277 assert(spbra.screening_method_ == screening_method_ &&
1278 spket.screening_method_ == screening_method_ &&
1279 "Engine::compute2: received ShellPair initialized for an "
1280 "incompatible screening method");
1284 const auto spbra_is_swapped = recompute_spbra ? false : swap_bra;
1285 const auto spket_is_swapped = recompute_spket ? false : swap_ket;
1287 using real_t = Shell::real_t;
1290 if (spbra_is_swapped) {
1291 for (
auto xyz = 0; xyz != 3; ++xyz) BA[xyz] = -spbra_precomputed->AB[xyz];
1293 const auto& AB = spbra_is_swapped ? BA : spbra.AB;
1296 if (spket_is_swapped) {
1297 for (
auto xyz = 0; xyz != 3; ++xyz) DC[xyz] = -spket_precomputed->AB[xyz];
1299 const auto& CD = spket_is_swapped ? DC : spket.AB;
1301 const auto& A = bra1.O;
1302 const auto& B = bra2.O;
1303 const auto& C = ket1.O;
1304 const auto& D = ket2.O;
1307 const auto npbra = spbra.primpairs.size();
1308 const auto npket = spket.primpairs.size();
1309 const scalar_type npbraket = npbra * npket;
1310 for (
auto pb = 0; pb != npbra; ++pb) {
1311 for (
auto pk = 0; pk != npket; ++pk) {
1313 if (spbra.primpairs[pb].ln_scr + spket.primpairs[pk].ln_scr >
1315 Libint_t& primdata = primdata_[p];
1316 const auto& sbra1 = bra1;
1317 const auto& sbra2 = bra2;
1318 const auto& sket1 = ket1;
1319 const auto& sket2 = ket2;
1323 const auto& spbrapp = spbra.primpairs[pbra];
1324 const auto& spketpp = spket.primpairs[pket];
1326 const auto& pbra1 = spbra_is_swapped ? spbrapp.p2 : spbrapp.p1;
1327 const auto& pbra2 = spbra_is_swapped ? spbrapp.p1 : spbrapp.p2;
1328 const auto& pket1 = spket_is_swapped ? spketpp.p2 : spketpp.p1;
1329 const auto& pket2 = spket_is_swapped ? spketpp.p1 : spketpp.p2;
1331 const auto alpha0 = sbra1.alpha[pbra1];
1332 const auto alpha1 = sbra2.alpha[pbra2];
1333 const auto alpha2 = sket1.alpha[pket1];
1334 const auto alpha3 = sket2.alpha[pket2];
1336 const auto c0 = sbra1.contr[0].coeff[pbra1];
1337 const auto c1 = sbra2.contr[0].coeff[pbra2];
1338 const auto c2 = sket1.contr[0].coeff[pket1];
1339 const auto c3 = sket2.contr[0].coeff[pket2];
1341 const auto l0 = sbra1.contr[0].l;
1342 const auto l1 = sbra2.contr[0].l;
1343 const auto l2 = sket1.contr[0].l;
1344 const auto l3 = sket2.contr[0].l;
1345 const auto l = l0 + l1 + l2 + l3;
1347 const auto gammap = alpha0 + alpha1;
1348 const auto oogammap = spbrapp.one_over_gamma;
1349 const auto rhop = alpha0 * alpha1 * oogammap;
1351 const auto gammaq = alpha2 + alpha3;
1352 const auto oogammaq = spketpp.one_over_gamma;
1353 const auto rhoq = alpha2 * alpha3 * oogammaq;
1355 const auto& P = spbrapp.P;
1356 const auto& Q = spketpp.P;
1357 const auto PQx = P[0] - Q[0];
1358 const auto PQy = P[1] - Q[1];
1359 const auto PQz = P[2] - Q[2];
1360 const auto PQ2 = PQx * PQx + PQy * PQy + PQz * PQz;
1362 const auto K12 = spbrapp.K * spketpp.K;
1363 const auto gammapq = gammap + gammaq;
1364 const auto sqrt_gammapq = sqrt(gammapq);
1365 const auto oogammapq = 1.0 / (gammapq);
1366 auto pfac = K12 * sqrt_gammapq * oogammapq;
1367 pfac *= c0 * c1 * c2 * c3 * scale_;
1371 if (
static_cast<int>(screening_method_) &
1374 scalar_type magnitude_estimate = std::abs(pfac);
1381 const auto nonspherical_pfac_magnitude = std::max(
1382 1., spbrapp.nonsph_screen_fac * spketpp.nonsph_screen_fac);
1383 magnitude_estimate *= nonspherical_pfac_magnitude * npbraket;
1385 if (magnitude_estimate < precision_)
continue;
1389 const scalar_type rho = gammap * gammaq * oogammapq;
1390 const scalar_type T = PQ2 * rho;
1391 auto* gm_ptr = &(primdata.LIBINT_T_SS_EREP_SS(0)[0]);
1392 const auto mmax = l + deriv_order_;
1394 if (!skip_core_ints) {
1396 case Operator::coulomb: {
1397 const auto& core_eval_ptr =
1398 any_cast<
const detail::core_eval_pack_type<
1399 Operator::coulomb>&>(core_eval_pack_)
1401 core_eval_ptr->eval(gm_ptr, T, mmax);
1403 case Operator::cgtg_x_coulomb: {
1404 const auto& core_eval_ptr =
1405 any_cast<
const detail::core_eval_pack_type<
1406 Operator::cgtg_x_coulomb>&>(core_eval_pack_)
1408 auto& core_eval_scratch =
1409 any_cast<detail::core_eval_pack_type<
1410 Operator::cgtg_x_coulomb>&>(core_eval_pack_)
1412 const auto& core_ints_params =
1413 any_cast<
const typename operator_traits<
1414 Operator::cgtg>::oper_params_type&>(
1416 core_eval_ptr->eval(gm_ptr, rho, T, mmax, core_ints_params,
1417 &core_eval_scratch);
1419 case Operator::cgtg: {
1420 const auto& core_eval_ptr =
1422 const detail::core_eval_pack_type<Operator::cgtg>&>(
1425 const auto& core_ints_params =
1426 any_cast<
const typename operator_traits<
1427 Operator::cgtg>::oper_params_type&>(
1429 core_eval_ptr->eval(gm_ptr, rho, T, mmax, core_ints_params);
1431 case Operator::delcgtg2: {
1432 const auto& core_eval_ptr =
1433 any_cast<
const detail::core_eval_pack_type<
1434 Operator::delcgtg2>&>(core_eval_pack_)
1436 const auto& core_ints_params =
1437 any_cast<
const typename operator_traits<
1438 Operator::cgtg>::oper_params_type&>(
1440 core_eval_ptr->eval(gm_ptr, rho, T, mmax, core_ints_params);
1442 case Operator::delta: {
1443 const auto& core_eval_ptr =
1445 const detail::core_eval_pack_type<Operator::delta>&>(
1448 core_eval_ptr->eval(gm_ptr, rho, T, mmax);
1450 case Operator::r12: {
1451 const auto& core_eval_ptr =
1453 const detail::core_eval_pack_type<Operator::r12>&>(
1456 core_eval_ptr->eval(gm_ptr, rho, T, mmax);
1458 case Operator::erf_coulomb: {
1459 const auto& core_eval_ptr =
1460 any_cast<
const detail::core_eval_pack_type<
1461 Operator::erf_coulomb>&>(core_eval_pack_)
1463 const auto& core_ints_params =
1464 any_cast<
const typename operator_traits<
1465 Operator::erf_coulomb>::oper_params_type&>(
1467 core_eval_ptr->eval(gm_ptr, rho, T, mmax, core_ints_params);
1469 case Operator::erfc_coulomb: {
1470 const auto& core_eval_ptr =
1471 any_cast<
const detail::core_eval_pack_type<
1472 Operator::erfc_coulomb>&>(core_eval_pack_)
1474 const auto& core_ints_params =
1475 any_cast<
const typename operator_traits<
1476 Operator::erfc_coulomb>::oper_params_type&>(
1478 core_eval_ptr->eval(gm_ptr, rho, T, mmax, core_ints_params);
1480 case Operator::stg: {
1481 const auto& core_eval_ptr =
1483 const detail::core_eval_pack_type<Operator::stg>&>(
1486 auto zeta = any_cast<
const typename operator_traits<
1487 Operator::stg>::oper_params_type&>(core_ints_params_);
1488 const auto one_over_rho = gammapq * oogammap * oogammaq;
1489 core_eval_ptr->eval_slater(gm_ptr, one_over_rho, T, mmax,
1492 case Operator::stg_x_coulomb: {
1493 const auto& core_eval_ptr =
1495 const detail::core_eval_pack_type<Operator::stg>&>(
1498 auto zeta = any_cast<
const typename operator_traits<
1499 Operator::stg>::oper_params_type&>(core_ints_params_);
1500 const auto one_over_rho = gammapq * oogammap * oogammaq;
1501 core_eval_ptr->eval_yukawa(gm_ptr, one_over_rho, T, mmax,
1505 assert(
false &&
"missing case in a switch");
1510 for (
auto m = 0; m != mmax + 1; ++m) {
1515 if (braket_ == BraKet::xx_xx) {
1516#if LIBINT2_DEFINED(eri, PA_x)
1517 primdata.PA_x[0] = P[0] - A[0];
1519#if LIBINT2_DEFINED(eri, PA_y)
1520 primdata.PA_y[0] = P[1] - A[1];
1522#if LIBINT2_DEFINED(eri, PA_z)
1523 primdata.PA_z[0] = P[2] - A[2];
1525#if LIBINT2_DEFINED(eri, PB_x)
1526 primdata.PB_x[0] = P[0] - B[0];
1528#if LIBINT2_DEFINED(eri, PB_y)
1529 primdata.PB_y[0] = P[1] - B[1];
1531#if LIBINT2_DEFINED(eri, PB_z)
1532 primdata.PB_z[0] = P[2] - B[2];
1536 if (braket_ != BraKet::xs_xs) {
1537#if LIBINT2_DEFINED(eri, QC_x)
1538 primdata.QC_x[0] = Q[0] - C[0];
1540#if LIBINT2_DEFINED(eri, QC_y)
1541 primdata.QC_y[0] = Q[1] - C[1];
1543#if LIBINT2_DEFINED(eri, QC_z)
1544 primdata.QC_z[0] = Q[2] - C[2];
1546#if LIBINT2_DEFINED(eri, QD_x)
1547 primdata.QD_x[0] = Q[0] - D[0];
1549#if LIBINT2_DEFINED(eri, QD_y)
1550 primdata.QD_y[0] = Q[1] - D[1];
1552#if LIBINT2_DEFINED(eri, QD_z)
1553 primdata.QD_z[0] = Q[2] - D[2];
1557 if (braket_ == BraKet::xx_xx) {
1558#if LIBINT2_DEFINED(eri, AB_x)
1559 primdata.AB_x[0] = AB[0];
1561#if LIBINT2_DEFINED(eri, AB_y)
1562 primdata.AB_y[0] = AB[1];
1564#if LIBINT2_DEFINED(eri, AB_z)
1565 primdata.AB_z[0] = AB[2];
1567#if LIBINT2_DEFINED(eri, BA_x)
1568 primdata.BA_x[0] = -AB[0];
1570#if LIBINT2_DEFINED(eri, BA_y)
1571 primdata.BA_y[0] = -AB[1];
1573#if LIBINT2_DEFINED(eri, BA_z)
1574 primdata.BA_z[0] = -AB[2];
1578 if (braket_ != BraKet::xs_xs) {
1579#if LIBINT2_DEFINED(eri, CD_x)
1580 primdata.CD_x[0] = CD[0];
1582#if LIBINT2_DEFINED(eri, CD_y)
1583 primdata.CD_y[0] = CD[1];
1585#if LIBINT2_DEFINED(eri, CD_z)
1586 primdata.CD_z[0] = CD[2];
1588#if LIBINT2_DEFINED(eri, DC_x)
1589 primdata.DC_x[0] = -CD[0];
1591#if LIBINT2_DEFINED(eri, DC_y)
1592 primdata.DC_y[0] = -CD[1];
1594#if LIBINT2_DEFINED(eri, DC_z)
1595 primdata.DC_z[0] = -CD[2];
1599 const auto gammap_o_gammapgammaq = oogammapq * gammap;
1600 const auto gammaq_o_gammapgammaq = oogammapq * gammaq;
1603 (gammap_o_gammapgammaq * P[0] + gammaq_o_gammapgammaq * Q[0]);
1605 (gammap_o_gammapgammaq * P[1] + gammaq_o_gammapgammaq * Q[1]);
1607 (gammap_o_gammapgammaq * P[2] + gammaq_o_gammapgammaq * Q[2]);
1609 if (deriv_order_ > 0 || lmax_bra > 0) {
1610#if LIBINT2_DEFINED(eri, WP_x)
1611 primdata.WP_x[0] = Wx - P[0];
1613#if LIBINT2_DEFINED(eri, WP_y)
1614 primdata.WP_y[0] = Wy - P[1];
1616#if LIBINT2_DEFINED(eri, WP_z)
1617 primdata.WP_z[0] = Wz - P[2];
1620 if (deriv_order_ > 0 || lmax_ket > 0) {
1621#if LIBINT2_DEFINED(eri, WQ_x)
1622 primdata.WQ_x[0] = Wx - Q[0];
1624#if LIBINT2_DEFINED(eri, WQ_y)
1625 primdata.WQ_y[0] = Wy - Q[1];
1627#if LIBINT2_DEFINED(eri, WQ_z)
1628 primdata.WQ_z[0] = Wz - Q[2];
1631#if LIBINT2_DEFINED(eri, oo2z)
1632 primdata.oo2z[0] = 0.5 * oogammap;
1634#if LIBINT2_DEFINED(eri, oo2e)
1635 primdata.oo2e[0] = 0.5 * oogammaq;
1637#if LIBINT2_DEFINED(eri, oo2ze)
1638 primdata.oo2ze[0] = 0.5 * oogammapq;
1640#if LIBINT2_DEFINED(eri, roz)
1641 primdata.roz[0] = rho * oogammap;
1643#if LIBINT2_DEFINED(eri, roe)
1644 primdata.roe[0] = rho * oogammaq;
1648#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_0_0_x)
1649 primdata.TwoPRepITR_pfac0_0_0_x[0] =
1650 -(alpha1 * AB[0] + alpha3 * CD[0]) * oogammap;
1652#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_0_0_y)
1653 primdata.TwoPRepITR_pfac0_0_0_y[0] =
1654 -(alpha1 * AB[1] + alpha3 * CD[1]) * oogammap;
1656#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_0_0_z)
1657 primdata.TwoPRepITR_pfac0_0_0_z[0] =
1658 -(alpha1 * AB[2] + alpha3 * CD[2]) * oogammap;
1660#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_1_0_x)
1661 primdata.TwoPRepITR_pfac0_1_0_x[0] =
1662 -(alpha1 * AB[0] + alpha3 * CD[0]) * oogammaq;
1664#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_1_0_y)
1665 primdata.TwoPRepITR_pfac0_1_0_y[0] =
1666 -(alpha1 * AB[1] + alpha3 * CD[1]) * oogammaq;
1668#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_1_0_z)
1669 primdata.TwoPRepITR_pfac0_1_0_z[0] =
1670 -(alpha1 * AB[2] + alpha3 * CD[2]) * oogammaq;
1672#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_0_1_x)
1673 primdata.TwoPRepITR_pfac0_0_1_x[0] =
1674 (alpha0 * AB[0] + alpha2 * CD[0]) * oogammap;
1676#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_0_1_y)
1677 primdata.TwoPRepITR_pfac0_0_1_y[0] =
1678 (alpha0 * AB[1] + alpha2 * CD[1]) * oogammap;
1680#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_0_1_z)
1681 primdata.TwoPRepITR_pfac0_0_1_z[0] =
1682 (alpha0 * AB[2] + alpha2 * CD[2]) * oogammap;
1684#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_1_1_x)
1685 primdata.TwoPRepITR_pfac0_1_1_x[0] =
1686 (alpha0 * AB[0] + alpha2 * CD[0]) * oogammaq;
1688#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_1_1_y)
1689 primdata.TwoPRepITR_pfac0_1_1_y[0] =
1690 (alpha0 * AB[1] + alpha2 * CD[1]) * oogammaq;
1692#if LIBINT2_DEFINED(eri, TwoPRepITR_pfac0_1_1_z)
1693 primdata.TwoPRepITR_pfac0_1_1_z[0] =
1694 (alpha0 * AB[2] + alpha2 * CD[2]) * oogammaq;
1696#if LIBINT2_DEFINED(eri, eoz)
1697 primdata.eoz[0] = gammaq * oogammap;
1699#if LIBINT2_DEFINED(eri, zoe)
1700 primdata.zoe[0] = gammap * oogammaq;
1704 if (deriv_order_ > 0) {
1705#if LIBINT2_DEFINED(eri, alpha1_rho_over_zeta2)
1706 primdata.alpha1_rho_over_zeta2[0] =
1707 alpha0 * (oogammap * gammaq_o_gammapgammaq);
1709#if LIBINT2_DEFINED(eri, alpha2_rho_over_zeta2)
1710 primdata.alpha2_rho_over_zeta2[0] =
1711 alpha1 * (oogammap * gammaq_o_gammapgammaq);
1713#if LIBINT2_DEFINED(eri, alpha3_rho_over_eta2)
1714 primdata.alpha3_rho_over_eta2[0] =
1715 alpha2 * (oogammaq * gammap_o_gammapgammaq);
1717#if LIBINT2_DEFINED(eri, alpha4_rho_over_eta2)
1718 primdata.alpha4_rho_over_eta2[0] =
1719 alpha3 * (oogammaq * gammap_o_gammapgammaq);
1721#if LIBINT2_DEFINED(eri, alpha1_over_zetapluseta)
1722 primdata.alpha1_over_zetapluseta[0] = alpha0 * oogammapq;
1724#if LIBINT2_DEFINED(eri, alpha2_over_zetapluseta)
1725 primdata.alpha2_over_zetapluseta[0] = alpha1 * oogammapq;
1727#if LIBINT2_DEFINED(eri, alpha3_over_zetapluseta)
1728 primdata.alpha3_over_zetapluseta[0] = alpha2 * oogammapq;
1730#if LIBINT2_DEFINED(eri, alpha4_over_zetapluseta)
1731 primdata.alpha4_over_zetapluseta[0] = alpha3 * oogammapq;
1733#if LIBINT2_DEFINED(eri, rho12_over_alpha1)
1734 primdata.rho12_over_alpha1[0] = alpha1 * oogammap;
1736#if LIBINT2_DEFINED(eri, rho12_over_alpha2)
1737 primdata.rho12_over_alpha2[0] = alpha0 * oogammap;
1739#if LIBINT2_DEFINED(eri, rho34_over_alpha3)
1740 primdata.rho34_over_alpha3[0] = alpha3 * oogammaq;
1742#if LIBINT2_DEFINED(eri, rho34_over_alpha4)
1743 primdata.rho34_over_alpha4[0] = alpha2 * oogammaq;
1745#if LIBINT2_DEFINED(eri, two_alpha0_bra)
1746 primdata.two_alpha0_bra[0] = 2.0 * alpha0;
1748#if LIBINT2_DEFINED(eri, two_alpha0_ket)
1749 primdata.two_alpha0_ket[0] = 2.0 * alpha1;
1751#if LIBINT2_DEFINED(eri, two_alpha1_bra)
1752 primdata.two_alpha1_bra[0] = 2.0 * alpha2;
1754#if LIBINT2_DEFINED(eri, two_alpha1_ket)
1755 primdata.two_alpha1_ket[0] = 2.0 * alpha3;
1766 primdata_[0].contrdepth = p;
1769#ifdef LIBINT2_ENGINE_TIMERS
1770 const auto t0 = timers.stop(0);
1771#ifdef LIBINT2_ENGINE_PROFILE_CLASS
1772 class_profiles[id].prereqs += t0.count();
1773 if (primdata_[0].contrdepth != 0) {
1774 class_profiles[id].nshellset += 1;
1775 class_profiles[id].nprimset += primdata_[0].contrdepth;
1781 if (primdata_[0].contrdepth == 0) {
1782 targets_[0] =
nullptr;
1787 const auto compute_directly = lmax == 0 && deriv_order_ == 0;
1789 if (compute_directly) {
1790#ifdef LIBINT2_ENGINE_TIMERS
1793 auto& stack = primdata_[0].stack[0];
1795 for (
auto p = 0; p != primdata_[0].contrdepth; ++p)
1796 stack += primdata_[p].LIBINT_T_SS_EREP_SS(0)[0];
1797 primdata_[0].targets[0] = primdata_[0].stack;
1798#ifdef LIBINT2_ENGINE_TIMERS
1799 const auto t1 = timers.stop(1);
1800#ifdef LIBINT2_ENGINE_PROFILE_CLASS
1801 class_profiles[id].build_vrr += t1.count();
1806#ifdef LIBINT2_ENGINE_TIMERS
1807#ifdef LIBINT2_PROFILE
1808 const auto t1_hrr_start = primdata_[0].timers->read(0);
1809 const auto t1_vrr_start = primdata_[0].timers->read(1);
1817 assert(bra1.contr[0].l <= hard_lmax_ &&
1818 "the angular momentum limit is exceeded");
1819 assert(bra2.contr[0].l <= hard_lmax_ &&
1820 "the angular momentum limit is exceeded");
1821 assert(ket1.contr[0].l <= hard_lmax_ &&
1822 "the angular momentum limit is exceeded");
1823 assert(ket2.contr[0].l <= hard_lmax_ &&
1824 "the angular momentum limit is exceeded");
1826 ((bra1.contr[0].l * hard_lmax_ + bra2.contr[0].l) * hard_lmax_ +
1833 assert(
false &&
"this braket is not supported");
1836 case BraKet::xs_xx: {
1838 int ket_lmax = hard_lmax_;
1839 switch (deriv_order_) {
1843#define BOOST_PP_NBODYENGINE_MCR8(r, data, i, elem) \
1845 BOOST_PP_IF(BOOST_PP_IS_1(BOOST_PP_CAT( \
1846 LIBINT2_CENTER_DEPENDENT_MAX_AM_, \
1847 BOOST_PP_CAT(3eri, BOOST_PP_IIF(BOOST_PP_GREATER(i, 0), i, \
1848 BOOST_PP_EMPTY())))), \
1849 ket_lmax = hard_default_lmax_, BOOST_PP_EMPTY()); \
1852 BOOST_PP_LIST_FOR_EACH_I(BOOST_PP_NBODYENGINE_MCR8, _,
1853 BOOST_PP_NBODY_DERIV_ORDER_LIST)
1856 assert(
false &&
"missing case in switch");
1859 assert(bra1.contr[0].l <= hard_lmax_ &&
1860 "the angular momentum limit is exceeded");
1861 assert(ket1.contr[0].l <= ket_lmax &&
1862 "the angular momentum limit is exceeded");
1863 assert(ket2.contr[0].l <= ket_lmax &&
1864 "the angular momentum limit is exceeded");
1865 buildfnidx = (bra1.contr[0].l * ket_lmax + ket1.contr[0].l) * ket_lmax +
1868 if (bra1.contr[0].l > 1)
1869 assert(bra1.contr[0].pure &&
1870 "library assumes a solid harmonics shell in bra of a 3-center "
1871 "2-body int, but a cartesian shell given");
1876 assert(bra1.contr[0].l <= hard_lmax_ &&
1877 "the angular momentum limit is exceeded");
1878 assert(ket1.contr[0].l <= hard_lmax_ &&
1879 "the angular momentum limit is exceeded");
1880 buildfnidx = bra1.contr[0].l * hard_lmax_ + ket1.contr[0].l;
1882 if (bra1.contr[0].l > 1)
1883 assert(bra1.contr[0].pure &&
1884 "library assumes solid harmonics shells in a 2-center "
1885 "2-body int, but a cartesian shell given in bra");
1886 if (ket1.contr[0].l > 1)
1887 assert(ket1.contr[0].pure &&
1888 "library assumes solid harmonics shells in a 2-center "
1889 "2-body int, but a cartesian shell given in bra");
1894 assert(
false &&
"invalid braket");
1898 assert(buildfnptrs_[buildfnidx] &&
"null build function ptr");
1899 buildfnptrs_[buildfnidx](&primdata_[0]);
1901#ifdef LIBINT2_ENGINE_TIMERS
1902 const auto t1 = timers.stop(1);
1903#ifdef LIBINT2_ENGINE_PROFILE_CLASS
1904#ifndef LIBINT2_PROFILE
1905 class_profiles[id].build_vrr += t1.count();
1907 class_profiles[id].build_hrr += primdata_[0].timers->read(0) - t1_hrr_start;
1908 class_profiles[id].build_vrr += primdata_[0].timers->read(1) - t1_vrr_start;
1913#ifdef LIBINT2_ENGINE_TIMERS
1917 const auto ntargets = nshellsets();
1921 constexpr auto using_scalar_real =
1922 sizeof(value_type) ==
sizeof(scalar_type);
1923 static_assert(using_scalar_real,
1924 "Libint2 C++11 API only supports scalar real types");
1925 typedef Eigen::Matrix<scalar_type, Eigen::Dynamic, Eigen::Dynamic,
1930 const auto nr1_cart = bra1.cartesian_size();
1931 const auto nr2_cart = bra2.cartesian_size();
1932 const auto nc1_cart = ket1.cartesian_size();
1933 const auto nc2_cart = ket2.cartesian_size();
1934 const auto ncol_cart = nc1_cart * nc2_cart;
1935 const auto n1234_cart = nr1_cart * nr2_cart * ncol_cart;
1936 const auto nr1 = bra1.size();
1937 const auto nr2 = bra2.size();
1938 const auto nc1 = ket1.size();
1939 const auto nc2 = ket2.size();
1940 const auto nrow = nr1 * nr2;
1941 const auto ncol = nc1 * nc2;
1944 const auto nr1_tgt = tbra1.size();
1945 const auto nr2_tgt = tbra2.size();
1946 const auto nc1_tgt = tket1.size();
1947 const auto nc2_tgt = tket2.size();
1948 const auto ncol_tgt = nc1_tgt * nc2_tgt;
1949 const auto n_tgt = nr1_tgt * nr2_tgt * ncol_tgt;
1951 auto hotscr = &scratch_[0];
1954 for (
auto s = 0; s != ntargets; ++s) {
1962 primdata_[0].targets[s];
1963 auto target = hotscr;
1965 if (bra1.contr[0].pure) {
1966 libint2::solidharmonics::transform_first(
1967 bra1.contr[0].l, nr2_cart * ncol_cart, source, target);
1968 std::swap(source, target);
1970 if (bra2.contr[0].pure) {
1971 libint2::solidharmonics::transform_inner(bra1.size(), bra2.contr[0].l,
1972 ncol_cart, source, target);
1973 std::swap(source, target);
1975 if (ket1.contr[0].pure) {
1976 libint2::solidharmonics::transform_inner(nrow, ket1.contr[0].l,
1977 nc2_cart, source, target);
1978 std::swap(source, target);
1980 if (ket2.contr[0].pure) {
1981 libint2::solidharmonics::transform_last(
1982 bra1.size() * bra2.size() * ket1.size(), ket2.contr[0].l, source,
1984 std::swap(source, target);
1990 const auto* src_row_ptr = source;
1991 auto tgt_ptr = target;
1997 Tensor<size_t>& mapDerivIndex =
1998 libint2::DerivMapGenerator::instance(deriv_order_, braket_);
2000 case BraKet::xx_xx: {
2001 s_target = mapDerivIndex((
size_t)swap_braket, (
size_t)swap_tbra,
2002 (
size_t)swap_tket, (
size_t)s);
2004 case BraKet::xs_xx: {
2006 assert(!swap_braket);
2007 s_target = mapDerivIndex((
size_t)0, (
size_t)0,
2008 (
size_t)swap_tket, (
size_t)s);
2010 case BraKet::xs_xs: {
2013 assert(!swap_braket);
2019 "This braket type not yet supported for geometric "
2025 for (
auto r1 = 0; r1 != nr1; ++r1) {
2026 for (
auto r2 = 0; r2 != nr2; ++r2, src_row_ptr += ncol) {
2027 typedef Eigen::Map<const Matrix> ConstMap;
2028 typedef Eigen::Map<Matrix> Map;
2029 typedef Eigen::Map<Matrix, Eigen::Unaligned,
2030 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
2034 ConstMap src_blk_mat(src_row_ptr, nc1, nc2);
2043 const auto tgt_col_idx =
2044 !swap_tket ? r1 * nr2 + r2 : r2 * nr1 + r1;
2045 StridedMap tgt_blk_mat(
2046 tgt_ptr + tgt_col_idx, nr1_tgt, nr2_tgt,
2047 Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(
2048 nr2_tgt * ncol_tgt, ncol_tgt));
2050 tgt_blk_mat = src_blk_mat.transpose();
2052 tgt_blk_mat = src_blk_mat;
2056 const auto tgt_row_idx =
2057 !swap_tbra ? r1 * nr2 + r2 : r2 * nr1 + r1;
2058 Map tgt_blk_mat(tgt_ptr + tgt_row_idx * ncol, nc1_tgt, nc2_tgt);
2060 tgt_blk_mat = src_blk_mat.transpose();
2062 tgt_blk_mat = src_blk_mat;
2066 std::swap(source, target);
2072 if (source != primdata_[0].targets[s]) {
2073 hotscr += n1234_cart;
2075 assert(set_targets_ &&
"logic error");
2077 targets_[s_target] = source;
2082 assert(set_targets_ &&
"logic error");
2084 targets_[s_target] = source;
2090 for (
auto s = 0; s != ntargets; ++s)
2091 targets_[s] = primdata_[0].targets[s];
2095#ifdef LIBINT2_ENGINE_TIMERS
2096 const auto t2 = timers.stop(2);
2097#ifdef LIBINT2_ENGINE_PROFILE_CLASS
2098 class_profiles[id].tform += t2.count();
2103 if (cartesian_shell_normalization() == CartesianShellNormalization::uniform) {
2104 std::array<std::reference_wrapper<const Shell>, 4> shells{tbra1, tbra2,
2106 for (
auto s = 0ul; s != targets_.size(); ++s) {
2115#undef BOOST_PP_NBODY_OPERATOR_LIST
2116#undef BOOST_PP_NBODY_OPERATOR_INDEX_TUPLE
2117#undef BOOST_PP_NBODY_OPERATOR_INDEX_LIST
2118#undef BOOST_PP_NBODY_BRAKET_INDEX_TUPLE
2119#undef BOOST_PP_NBODY_BRAKET_INDEX_LIST
2120#undef BOOST_PP_NBODY_DERIV_ORDER_TUPLE
2121#undef BOOST_PP_NBODY_DERIV_ORDER_LIST
2122#undef BOOST_PP_NBODYENGINE_MCR3
2123#undef BOOST_PP_NBODYENGINE_MCR3_ncenter
2124#undef BOOST_PP_NBODYENGINE_MCR3_default_ncenter
2125#undef BOOST_PP_NBODYENGINE_MCR3_NCENTER
2126#undef BOOST_PP_NBODYENGINE_MCR3_OPER
2127#undef BOOST_PP_NBODYENGINE_MCR3_DERIV
2128#undef BOOST_PP_NBODYENGINE_MCR3_task
2129#undef BOOST_PP_NBODYENGINE_MCR3_TASK
2130#undef BOOST_PP_NBODYENGINE_MCR4
2131#undef BOOST_PP_NBODYENGINE_MCR5
2132#undef BOOST_PP_NBODYENGINE_MCR6
2133#undef BOOST_PP_NBODYENGINE_MCR7
2135#ifdef LIBINT2_DOES_NOT_INLINE_ENGINE
2136template any Engine::enforce_params_type<Engine::empty_pod>(
2137 Operator oper,
const Engine::empty_pod& params,
bool throw_if_wrong_type);
2139template const Engine::target_ptr_vec& Engine::compute<Shell>(
2140 const Shell& first_shell,
const Shell&);
2142template const Engine::target_ptr_vec& Engine::compute<Shell, Shell>(
2143 const Shell& first_shell,
const Shell&,
const Shell&);
2145template const Engine::target_ptr_vec& Engine::compute<Shell, Shell, Shell>(
2146 const Shell& first_shell,
const Shell&,
const Shell&,
const Shell&);
a partial C++17 std::any implementation (and less efficient than can be)
Definition any.h:67
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
@ Original
standard screening method:
@ Conservative
conservative screening:
bool initialized()
checks if the libint has been initialized.
Definition initialize.h:68
__libint2_engine_inline libint2::any default_params(const Operator &oper)
the runtime version of operator_traits<oper>::default_params()
Definition engine.impl.h:116
void uniform_normalize_cartesian_shells(Real *intset, std::array< std::reference_wrapper< const Shell >, N > shells)
rescales cartesian Gaussians to convert from standard to uniform-normalized convention
Definition cartesian.h:117
Iterates over all partitions of a non-negative integer into nonnegative integers in reverse lexicog...
Definition intpart_iter.h:74
generally-contracted Solid-Harmonic/Cartesion Gaussian Shell
Definition shell.h:720
svector< Contraction > contr
contractions
Definition shell.h:742
static const Shell & unit()
Definition shell.h:906