21#ifndef _libint2_src_bin_libint_vrr11r12kg1211_h_
22#define _libint2_src_bin_libint_vrr11r12kg1211_h_
24#include <generic_rr.h>
25#include <r12kg12_11_11.h>
33 template <
class BFSet,
int part, FunctionPosition where>
36 GenIntegralSet_11_11<BFSet,R12kG12,mType> >
44 static const unsigned int max_nchildren = 8;
52 using ParentType::RecurrenceRelation::expr_;
53 using ParentType::RecurrenceRelation::nflops_;
54 using ParentType::target_;
60 static std::string descr() {
return "VRR"; }
64 std::string generate_label()
const override
66 typedef typename TargetType::AuxIndexType
mType;
67 static SafePtr<mType> aux0(
new mType(0u));
68 std::ostringstream os;
69 os << descr() <<
"P" << part <<
to_string(where)
70 << genintegralset_label(target_->bra(),target_->ket(),aux0,target_->oper());
74 #if LIBINT_ENABLE_GENERIC_CODE
76 bool has_generic(
const SafePtr<CompilationParameters>& cparams)
const override;
78 std::string generic_header()
const override;
80 std::string generic_instance(
const SafePtr<CodeContext>& context,
const SafePtr<CodeSymbols>& args)
const override;
84 template <
class F,
int part, FunctionPosition where>
85 VRR_11_R12kG12_11<F,part,where>::VRR_11_R12kG12_11(
const SafePtr< TargetType >& Tint,
89 using namespace libint2::algebra;
90 using namespace libint2::prefactor;
91 const int K = Tint->oper()->descr().K();
92 typedef R12_k_G12_Descr R12kG12Descr;
93 const R12kG12 oK((R12kG12Descr(K)));
94 const unsigned int m = Tint->aux()->elem(0);
95 const F _1 = unit<F>(dir);
103 if (a.contracted() ||
107 Tint->oper()->descr().contracted())
112 const OriginDerivative<3u> dA = Tint->bra(0,0).deriv();
113 const OriginDerivative<3u> dB = Tint->ket(0,0).deriv();
114 const OriginDerivative<3u> dC = Tint->bra(1,0).deriv();
115 const OriginDerivative<3u> dD = Tint->ket(1,0).deriv();
116 const bool deriv = !dA.zero() ||
123 typedef TargetType ChildType;
124 ChildFactory<ThisType,ChildType> factory(
this);
130 if (part == 0 && where == InBra) {
131 F a(Tint->bra(0,0) - _1);
137 auto ABCD_m = factory.make_child(a,b,c,d,m,oK);
138 auto ABCD_mp1 = factory.make_child(a,b,c,d,m+1,oK);
139 if (is_simple()) { expr_ = Vector(
"PA")[dir] * ABCD_m + Vector(
"WP")[dir] * ABCD_mp1; nflops_+=3; }
141 const F& am1 = a - _1;
143 auto Am1BCD_m = factory.make_child(am1,b,c,d,m,oK);
144 auto Am1BCD_mp1 = factory.make_child(am1,b,c,d,m+1,oK);
145 if (is_simple()) { expr_ += Scalar(a[dir]) * Scalar(
"oo2z") * (Am1BCD_m - Scalar(
"roz") * Am1BCD_mp1); nflops_+=5; }
147 const F& bm1 = b - _1;
149 auto ABm1CD_m = factory.make_child(a,bm1,c,d,m,oK);
150 auto ABm1CD_mp1 = factory.make_child(a,bm1,c,d,m+1,oK);
151 if (is_simple()) { expr_ += Scalar(b[dir]) * Scalar(
"oo2z") * (ABm1CD_m - Scalar(
"roz") * ABm1CD_mp1); nflops_+=5; }
153 const F& cm1 = c - _1;
155 auto ABCm1D_mp1 = factory.make_child(a,b,cm1,d,m+1,oK);
156 if (is_simple()) { expr_ += Scalar(c[dir]) * Scalar(
"oo2ze") * ABCm1D_mp1; nflops_+=3; }
158 const F& dm1 = d - _1;
160 auto ABCDm1_mp1 = factory.make_child(a,b,c,dm1,m+1,oK);
161 if (is_simple()) { expr_ += Scalar(d[dir]) * Scalar(
"oo2ze") * ABCDm1_mp1; nflops_+=3; }
166 if (part == 0 && where == InKet) {
168 F b(Tint->ket(0,0) - _1);
173 auto ABCD_m = factory.make_child(a,b,c,d,m,oK);
174 auto ABCD_mp1 = factory.make_child(a,b,c,d,m+1,oK);
175 if (is_simple()) { expr_ = Vector(
"PB")[dir] * ABCD_m + Vector(
"WP")[dir] * ABCD_mp1; nflops_+=3; }
177 const F& am1 = a - _1;
179 auto Am1BCD_m = factory.make_child(am1,b,c,d,m,oK);
180 auto Am1BCD_mp1 = factory.make_child(am1,b,c,d,m+1,oK);
181 if (is_simple()) { expr_ += Scalar(a[dir]) * Scalar(
"oo2z") * (Am1BCD_m - Scalar(
"roz") * Am1BCD_mp1); nflops_+=5; }
183 const F& bm1 = b - _1;
185 auto ABm1CD_m = factory.make_child(a,bm1,c,d,m,oK);
186 auto ABm1CD_mp1 = factory.make_child(a,bm1,c,d,m+1,oK);
187 if (is_simple()) { expr_ += Scalar(b[dir]) * Scalar(
"oo2z") * (ABm1CD_m - Scalar(
"roz") * ABm1CD_mp1); nflops_+=5; }
189 const F& cm1 = c - _1;
191 auto ABCm1D_mp1 = factory.make_child(a,b,cm1,d,m+1,oK);
192 if (is_simple()) { expr_ += Scalar(c[dir]) * Scalar(
"oo2ze") * ABCm1D_mp1; nflops_+=3; }
194 const F& dm1 = d - _1;
196 auto ABCDm1_mp1 = factory.make_child(a,b,c,dm1,m+1,oK);
197 if (is_simple()) { expr_ += Scalar(d[dir]) * Scalar(
"oo2ze") * ABCDm1_mp1; nflops_+=3; }
202 if (part == 1 && where == InBra) {
205 F c(Tint->bra(1,0) - _1);
209 auto ABCD_m = factory.make_child(a,b,c,d,m,oK);
210 auto ABCD_mp1 = factory.make_child(a,b,c,d,m+1,oK);
211 if (is_simple()) { expr_ = Vector(
"QC")[dir] * ABCD_m + Vector(
"WQ")[dir] * ABCD_mp1; nflops_+=3; }
213 const F& cm1 = c - _1;
215 auto ABCm1D_m = factory.make_child(a,b,cm1,d,m,oK);
216 auto ABCm1D_mp1 = factory.make_child(a,b,cm1,d,m+1,oK);
217 if (is_simple()) { expr_ += Scalar(c[dir]) * Scalar(
"oo2e") * (ABCm1D_m - Scalar(
"roe") * ABCm1D_mp1); nflops_+=5; }
219 const F& dm1 = d - _1;
221 auto ABCDm1_m = factory.make_child(a,b,c,dm1,m,oK);
222 auto ABCDm1_mp1 = factory.make_child(a,b,c,dm1,m+1,oK);
223 if (is_simple()) { expr_ += Scalar(d[dir]) * Scalar(
"oo2e") * (ABCDm1_m - Scalar(
"roe") * ABCDm1_mp1); nflops_+=5; }
225 const F& am1 = a - _1;
227 auto Am1BCD_mp1 = factory.make_child(am1,b,c,d,m+1,oK);
228 if (is_simple()) { expr_ += Scalar(a[dir]) * Scalar(
"oo2ze") * Am1BCD_mp1; nflops_+=3; }
230 const F& bm1 = b - _1;
232 auto ABm1CD_mp1 = factory.make_child(a,bm1,c,d,m+1,oK);
233 if (is_simple()) { expr_ += Scalar(b[dir]) * Scalar(
"oo2ze") * ABm1CD_mp1; nflops_+=3; }
238 if (part == 1 && where == InKet) {
242 F d(Tint->ket(1,0) - _1);
245 auto ABCD_m = factory.make_child(a,b,c,d,m,oK);
246 auto ABCD_mp1 = factory.make_child(a,b,c,d,m+1,oK);
247 if (is_simple()) { expr_ = Vector(
"QD")[dir] * ABCD_m + Vector(
"WQ")[dir] * ABCD_mp1; nflops_+=3; }
249 const F& cm1 = c - _1;
251 auto ABCm1D_m = factory.make_child(a,b,cm1,d,m,oK);
252 auto ABCm1D_mp1 = factory.make_child(a,b,cm1,d,m+1,oK);
253 if (is_simple()) { expr_ += Scalar(c[dir]) * Scalar(
"oo2e") * (ABCm1D_m - Scalar(
"roe") * ABCm1D_mp1); nflops_+=5; }
255 const F& dm1 = d - _1;
257 auto ABCDm1_m = factory.make_child(a,b,c,dm1,m,oK);
258 auto ABCDm1_mp1 = factory.make_child(a,b,c,dm1,m+1,oK);
259 if (is_simple()) { expr_ += Scalar(d[dir]) * Scalar(
"oo2e") * (ABCDm1_m - Scalar(
"roe") * ABCDm1_mp1); nflops_+=5; }
261 const F& am1 = a - _1;
263 auto Am1BCD_mp1 = factory.make_child(am1,b,c,d,m+1,oK);
264 if (is_simple()) { expr_ += Scalar(a[dir]) * Scalar(
"oo2ze") * Am1BCD_mp1; nflops_+=3; }
266 const F& bm1 = b - _1;
268 auto ABm1CD_mp1 = factory.make_child(a,bm1,c,d,m+1,oK);
269 if (is_simple()) { expr_ += Scalar(b[dir]) * Scalar(
"oo2ze") * ABm1CD_mp1; nflops_+=3; }
278 throw std::logic_error(
"VRR_11_R12kG12_11<I,F,K,part,where>::children_and_expr_Kge0() -- nonzero auxiliary quantum detected.");
284 F b(Tint->ket(0,0) - _1);
285 F d(Tint->ket(1,0) - _1);
290 F a(Tint->bra(0,0) - _1);
291 F c(Tint->bra(1,0) - _1);
304 if (part == 0 && where == InBra) {
305 F a(Tint->bra(0,0) - _1);
311 auto ABCD_K = factory.make_child(a,b,c,d,0u,oK);
312 if (is_simple()) { expr_ = Vector(
"R12kG12_pfac0_0")[dir] * ABCD_K; nflops_+=1; }
313 const F& am1 = a - _1;
315 auto Am1BCD_K = factory.make_child(am1,b,c,d,0u,oK);
316 if (is_simple()) { expr_ += Scalar(a[dir]) * Scalar(
"R12kG12_pfac1_0") * Am1BCD_K; nflops_+=3; }
318 const F& cm1 = c - _1;
320 auto ABCm1D_K = factory.make_child(a,b,cm1,d,0u,oK);
321 if (is_simple()) { expr_ += Scalar(c[dir]) * Scalar(
"R12kG12_pfac2") * ABCm1D_K; nflops_+=3; }
324 const R12kG12 oKm2((R12kG12Descr(K-2)));
325 auto Ap1BCD_Km2 = factory.make_child(a+_1,b,c,d,0u,oKm2);
326 auto ABCp1D_Km2 = factory.make_child(a,b,c+_1,d,0u,oKm2);
327 auto ABCD_Km2 = factory.make_child(a,b,c,d,0u,oKm2);
328 if (is_simple()) { expr_ += Scalar((
double)K) * Scalar(
"R12kG12_pfac3_0")
329 * (Ap1BCD_Km2 - ABCp1D_Km2 + Vector(
"R12kG12_pfac4_0")[dir] * ABCD_Km2); nflops_+=6; }
334 if (part == 1 && where == InBra) {
337 F c(Tint->bra(1,0) - _1);
341 auto ABCD_K = factory.make_child(a,b,c,d,0u,oK);
342 if (is_simple()) { expr_ = Vector(
"R12kG12_pfac0_1")[dir] * ABCD_K; nflops_+=1; }
343 const F& cm1 = c - _1;
345 auto ABCm1D_K = factory.make_child(a,b,cm1,d,0u,oK);
346 if (is_simple()) { expr_ += Scalar(c[dir]) * Scalar(
"R12kG12_pfac1_1") * ABCm1D_K; nflops_+=3; }
348 const F& am1 = a - _1;
350 auto Am1BCD_K = factory.make_child(am1,b,c,d,0u,oK);
351 if (is_simple()) { expr_ += Scalar(a[dir]) * Scalar(
"R12kG12_pfac2") * Am1BCD_K; nflops_+=3; }
354 const R12kG12 oKm2((R12kG12Descr(K-2)));
355 auto ABCp1D_Km2 = factory.make_child(a,b,c+_1,d,0u,oKm2);
356 auto Ap1BCD_Km2 = factory.make_child(a+_1,b,c,d,0u,oKm2);
357 auto ABCD_Km2 = factory.make_child(a,b,c,d,0u,oKm2);
358 if (is_simple()) { expr_ += Scalar((
double)K) * Scalar(
"R12kG12_pfac3_1")
359 * (ABCp1D_Km2 - Ap1BCD_Km2 + Vector(
"R12kG12_pfac4_1")[dir] * ABCD_Km2); nflops_+=6; }
367 if (part == 0 && where == InKet) {
369 F b(Tint->ket(0,0) - _1);
374 auto ABCD_K = factory.make_child(a,b,c,d,0u,oK);
375 if (is_simple()) { expr_ = Vector(
"R12kG12_pfac0_0")[dir] * ABCD_K; nflops_+=1; }
376 const F& bm1 = b - _1;
378 auto ABm1CD_K = factory.make_child(a,bm1,c,d,0u,oK);
379 if (is_simple()) { expr_ += Scalar(b[dir]) * Scalar(
"R12kG12_pfac1_0") * ABm1CD_K; nflops_+=3; }
381 const F& dm1 = d - _1;
383 auto ABCDm1_K = factory.make_child(a,b,c,dm1,0u,oK);
384 if (is_simple()) { expr_ += Scalar(d[dir]) * Scalar(
"R12kG12_pfac2") * ABCDm1_K; nflops_+=3; }
387 const R12kG12 oKm2((R12kG12Descr(K-2)));
388 auto ABp1CD_Km2 = factory.make_child(a,b+_1,c,d,0u,oKm2);
389 auto ABCDp1_Km2 = factory.make_child(a,b,c,d+_1,0u,oKm2);
390 auto ABCD_Km2 = factory.make_child(a,b,c,d,0u,oKm2);
391 if (is_simple()) { expr_ += Scalar((
double)K) * Scalar(
"R12kG12_pfac3_0")
392 * (ABp1CD_Km2 - ABCDp1_Km2 + Vector(
"R12kG12_pfac4_0")[dir] * ABCD_Km2); nflops_+=6; }
397 if (part == 1 && where == InKet) {
401 F d(Tint->ket(1,0) - _1);
404 auto ABCD_K = factory.make_child(a,b,c,d,0u,oK);
405 if (is_simple()) { expr_ = Vector(
"R12kG12_pfac0_1")[dir] * ABCD_K; nflops_+=1; }
406 const F& dm1 = d - _1;
408 auto ABCDm1_K = factory.make_child(a,b,c,dm1,0u,oK);
409 if (is_simple()) { expr_ += Scalar(d[dir]) * Scalar(
"R12kG12_pfac1_1") * ABCDm1_K; nflops_+=3; }
411 const F& bm1 = b - _1;
413 auto ABm1CD_K = factory.make_child(a,bm1,c,d,0u,oK);
414 if (is_simple()) { expr_ += Scalar(b[dir]) * Scalar(
"R12kG12_pfac2") * ABm1CD_K; nflops_+=3; }
417 const R12kG12 oKm2((R12kG12Descr(K-2)));
418 auto ABCDp1_Km2 = factory.make_child(a,b,c,d+_1,0u,oKm2);
419 auto ABp1CD_Km2 = factory.make_child(a,b+_1,c,d,0u,oKm2);
420 auto ABCD_Km2 = factory.make_child(a,b,c,d,0u,oKm2);
421 if (is_simple()) { expr_ += Scalar((
double)K) * Scalar(
"R12kG12_pfac3_1")
422 * (ABCDp1_Km2 - ABp1CD_Km2 + Vector(
"R12kG12_pfac4_1")[dir] * ABCD_Km2); nflops_+=6; }
432 #if LIBINT_ENABLE_GENERIC_CODE
433 template <
class F,
int part, FunctionPosition where>
435 VRR_11_R12kG12_11<F,part,where>::has_generic(
const SafePtr<CompilationParameters>& cparams)
const
437 F sh_a(target_->bra(0,0));
438 F sh_b(target_->ket(0,0));
439 F sh_c(target_->bra(1,0));
440 F sh_d(target_->ket(1,0));
441 const unsigned int max_opt_am = cparams->max_am_opt();
444 if (!TrivialBFSet<F>::result &&
445 sh_b.zero() && sh_d.zero() &&
446 (sh_a.norm() > std::max(2*max_opt_am,1u) ||
447 sh_c.norm() > std::max(2*max_opt_am,1u)
449 (sh_a.norm() > 1u && sh_c.norm() > 1u)
452 if (!TrivialBFSet<F>::result &&
453 sh_a.zero() && sh_c.zero() &&
454 (sh_b.norm() > std::max(2*max_opt_am,1u) ||
455 sh_d.norm() > std::max(2*max_opt_am,1u)
457 (sh_b.norm() > 1u && sh_d.norm() > 1u)
463 template <
class F,
int part, FunctionPosition where>
465 VRR_11_R12kG12_11<F,part,where>::generic_header()
const
467 F sh_a(target_->bra(0,0));
468 F sh_b(target_->ket(0,0));
469 F sh_c(target_->bra(1,0));
470 F sh_d(target_->ket(1,0));
471 const bool xsxs = sh_b.zero() && sh_d.zero();
472 const bool sxsx = sh_a.zero() && sh_c.zero();
473 const int K = target_->oper()->descr().K();
476 return std::string(
"OSVRR_xs_xs.h");
478 return std::string(
"OSVRR_sx_sx.h");
481 return std::string(
"VRR_r12kg12_xs_xs.h");
486 template <
class F,
int part, FunctionPosition where>
488 VRR_11_R12kG12_11<F,part,where>::generic_instance(
const SafePtr<CodeContext>& context,
const SafePtr<CodeSymbols>& args)
const
490 const int K = target_->oper()->descr().K();
491 std::ostringstream oss;
492 F sh_a(target_->bra(0,0));
493 F sh_b(target_->ket(0,0));
494 F sh_c(target_->bra(1,0));
495 F sh_d(target_->ket(1,0));
496 const bool xsxs = sh_b.zero() && sh_d.zero();
497 const bool sxsx = sh_a.zero() && sh_c.zero();
499 bool ahlrichs_simplification =
false;
502 unit_s = sh_b.is_unit();
505 unit_s = sh_a.is_unit();
508 oss <<
"using namespace libint2;" << std::endl;
511 oss <<
"libint2::OSVRR_xs_xs<" << part <<
"," << sh_a.norm() <<
"," << sh_c.norm() <<
",";
512 if (not ahlrichs_simplification) oss << (unit_s ?
"true," :
"false,");
513 oss << ((context->cparams()->max_vector_length() == 1) ?
"false" :
"true");
516 oss <<
"libint2::OSVRR_sx_sx<" << part <<
"," << sh_b.norm() <<
"," << sh_d.norm() <<
",";
517 if (not ahlrichs_simplification) oss << (unit_s ?
"true," :
"false,");
518 oss << ((context->cparams()->max_vector_length() == 1) ?
"false" :
"true");
523 oss <<
"libint2::VRR_r12kg12_xs_xs<" << part <<
"," << sh_a.norm() <<
"," << sh_c.norm() <<
",";
524 oss << K <<
"," << ((context->cparams()->max_vector_length() == 1) ?
"false" :
"true");
528 oss <<
"libint2::VRR_r12kg12_xs_xs<" << part <<
"," << sh_b.norm() <<
"," << sh_d.norm() <<
",";
529 oss << K <<
"," << ((context->cparams()->max_vector_length() == 1) ?
"false" :
"true");
532 oss <<
">::compute(inteval";
536 oss <<
"," << args->symbol(0);
537 if (not ahlrichs_simplification && unit_s)
539 const unsigned int nargs = args->n();
540 for(
unsigned int a=1; a<nargs; a++) {
541 oss <<
"," << args->symbol(a);
545 const unsigned int nargs = args->n();
546 for(
unsigned int a=0; a<nargs; a++) {
547 oss <<
"," << args->symbol(a);
552 for(
unsigned int a=0; a<3; ++a) {
553 oss <<
",(LIBINT2_REALTYPE*)0";
Set of basis functions.
Definition: bfset.h:42
Generic integral over a two-body operator with one bfs for each particle in bra and ket.
Definition: integral_11_11.h:33
RRImpl must inherit GenericRecurrenceRelation<RRImpl>
Definition: generic_rr.h:47
bool is_simple() const override
Implementation of RecurrenceRelation::is_simple()
Definition: generic_rr.h:79
static SafePtr< RRImpl > Instance(const SafePtr< TargetType > &Tint, unsigned int dir)
Return an instance if applicable, or a null pointer otherwise.
Definition: generic_rr.h:55
static bool default_directional()
is this recurrence relation parameterized by a direction (x, y, or z).
Definition: generic_rr.h:99
VRR Recurrence Relation for 2-e integrals of the R12_k_G12 operators.
Definition: vrr_11_r12kg12_11.h:37
static bool directional()
Default directionality.
Definition: vrr_11_r12kg12_11.h:49
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
bool exists(const IncableBFSet &A)
Return true if A is valid.
Definition: bfset.h:92
DefaultQuantumNumbers< unsignedint, 1 >::Result mType
mType is the type that describes the auxiliary index of standard 2-body repulsion integrals
Definition: quanta.h:408
std::string to_string(const T &x)
Converts x to its string representation.
Definition: entity.h:74