31 #include <util/ref/ref.h>
32 #include <util/misc/scexception.h>
33 #include <util/misc/consumableresources.h>
34 #include <chemistry/qc/basis/basis.h>
35 #include <chemistry/qc/libint2/shellpairs.h>
36 #include <chemistry/qc/basis/fjt.h>
37 #include <chemistry/qc/libint2/int2e.h>
38 #include <chemistry/qc/libint2/macros.h>
39 #include <chemistry/qc/libint2/libint2_utils.h>
41 #include <libint2/boys.h>
42 #include <chemistry/qc/libint2/core_ints_engine.h>
44 #if LIBINT2_SUPPORT_ERI
46 #ifndef _chemistry_qc_libint2_tbosar_h
47 #define _chemistry_qc_libint2_tbosar_h
52 template <TwoBodyOper::type OperType>
56 struct OSAR_CoreInts<TwoBodyOper::eri> {
59 typedef ::libint2::FmEval_Chebyshev7<double> _FmEvalType;
60 typedef CoreIntsEngine<_FmEvalType>::Engine FmEvalType;
61 Ref<FmEvalType> Fm_Eval_;
63 OSAR_CoreInts(
unsigned int mmax,
const Ref<IntParams>& params) :
64 Fm_Eval_(CoreIntsEngine<_FmEvalType>::instance(mmax)) {
67 const double* eval(
double* Fm_table,
unsigned int mmax,
double T,
double rho = 0.0,
69 static double oo2np1[] = {1.0, 1.0/3.0, 1.0/5.0, 1.0/7.0, 1.0/9.0,
70 1.0/11.0, 1.0/13.0, 1.0/15.0, 1.0/17.0, 1.0/19.0,
71 1.0/21.0, 1.0/23.0, 1.0/25.0, 1.0/27.0, 1.0/29.0,
72 1.0/31.0, 1.0/33.0, 1.0/35.0, 1.0/37.0, 1.0/39.0,
73 1.0/41.0, 1.0/43.0, 1.0/45.0, 1.0/47.0, 1.0/49.0,
74 1.0/51.0, 1.0/53.0, 1.0/55.0, 1.0/57.0, 1.0/59.0,
75 1.0/61.0, 1.0/63.0, 1.0/65.0, 1.0/67.0, 1.0/69.0,
76 1.0/71.0, 1.0/73.0, 1.0/75.0, 1.0/77.0, 1.0/79.0};
78 const static double small_T = 1E-15;
84 Fm_Eval_->eval(Fm_table, T, mmax);
94 struct OSAR_CoreInts_G12Base {
95 IntParamsG12::ContractedGeminal g12_;
97 OSAR_CoreInts_G12Base(
const Ref<IntParams>& p) {
99 Ref<IntParamsG12> params = require_dynamic_cast<IntParamsG12*>(p,
"");
102 g12_ = braonly ? params->bra() : IntParamsG12::product(params->bra(), params->ket());
105 struct softcomparer {
106 softcomparer(
double tol = DBL_EPSILON) : tol_(tol) {}
107 bool operator()(
double a,
double b)
const {
return a + tol_ < b; }
112 static IntParamsG12::ContractedGeminal
113 reduce(
const IntParamsG12::ContractedGeminal& g12) {
115 std::map<double, double, softcomparer> g12red(comp);
116 typedef std::map<double, double, softcomparer>::iterator iter;
118 const size_t np = g12.size();
119 for(
size_t p=0; p<np; ++p) {
120 iter i = g12red.find(g12[p].first);
121 if (i != g12red.end()) {
122 i->second += g12[p].second;
125 g12red[g12[p].first] = g12[p].second;
128 IntParamsG12::ContractedGeminal result;
129 for(iter i=g12red.begin();
132 result.push_back(*i);
141 struct OSAR_CoreInts<TwoBodyOper::r12_0_g12> : OSAR_CoreInts_G12Base {
142 typedef ::libint2::GaussianGmEval<double, 0> _GmEvalType;
143 typedef CoreIntsEngine<_GmEvalType>::Engine GmEvalType;
144 Ref<GmEvalType> Gm_Eval_;
146 OSAR_CoreInts(
unsigned int mmax,
const Ref<IntParams>& params) :
147 OSAR_CoreInts_G12Base(params), Gm_Eval_(CoreIntsEngine<_GmEvalType>::instance(mmax, 1e-14))
151 double* eval(
double* Gm_table,
unsigned int mmax,
double T,
double rho = 0.0,
153 Gm_Eval_->eval(Gm_table, rho, T, mmax, g12_);
158 struct OSAR_CoreInts<TwoBodyOper::r12_m1_g12> : OSAR_CoreInts_G12Base {
159 typedef ::libint2::GaussianGmEval<double, -1> _GmEvalType;
160 typedef CoreIntsEngine<_GmEvalType>::Engine GmEvalType;
161 Ref<GmEvalType> Gm_Eval_;
163 OSAR_CoreInts(
unsigned int mmax,
const Ref<IntParams>& params) :
164 OSAR_CoreInts_G12Base(params), Gm_Eval_(CoreIntsEngine<_GmEvalType>::instance(mmax, 1e-14))
168 double* eval(
double* Gm_table,
unsigned int mmax,
double T,
double rho = 0.0,
169 void* thread_local_scratch = 0) {
170 Gm_Eval_->eval(Gm_table, rho, T, mmax, g12_, thread_local_scratch);
176 struct OSAR_CoreInts<TwoBodyOper::g12t1g12> : OSAR_CoreInts_G12Base {
177 typedef ::libint2::GaussianGmEval<double, 2> _GmEvalType;
178 typedef CoreIntsEngine<_GmEvalType>::Engine GmEvalType;
179 Ref<GmEvalType> Gm_Eval_;
181 OSAR_CoreInts(
unsigned int mmax,
const Ref<IntParams>& params) :
182 OSAR_CoreInts_G12Base(params), Gm_Eval_(CoreIntsEngine<_GmEvalType>::instance(mmax, 1e-14))
186 Ref<IntParamsG12> p = require_dynamic_cast<IntParamsG12*>(params,
"");
187 const IntParamsG12::ContractedGeminal& gbra = p->bra();
188 const IntParamsG12::ContractedGeminal& gket = p->ket();
189 for(
size_t b=0, bk=0; b<gbra.size(); ++b)
190 for(
size_t k=0; k<gket.size(); ++k, ++bk)
191 g12_[bk].second *= 4.0 * gbra[b].first * gket[k].first;
194 double* eval(
double* Gm_table,
unsigned int mmax,
double T,
double rho = 0.0,
196 Gm_Eval_->eval(Gm_table, rho, T, mmax, g12_);
202 struct OSAR_CoreInts<TwoBodyOper::delta> {
203 OSAR_CoreInts(
unsigned int mmax,
const Ref<IntParams>& params) {}
204 const double* eval(
double* Fm_table,
unsigned int mmax,
double T,
double rho = 0.0,
206 const static double one_over_two_pi = 1.0 / (2.0 * M_PI);
207 const double G0 = exp(-T) * rho * one_over_two_pi;
209 std::fill(Fm_table, Fm_table+mmax+1, G0);
218 swtch(GaussianBasisSet* &i,GaussianBasisSet* &j)
220 GaussianBasisSet *tmp;
227 pswtch(
void**i,
void**j)
236 iswtch(
int *i,
int *j)
247 template <TwoBodyOper::type OperType>
248 class TwoBodyOSARLibint2:
public Int2eLibint2 {
251 static bool store_pair_data() {
return true; }
254 double *target_ints_buffer_;
258 double *sphharm_ints_;
263 double *contr_quartets_;
264 double *shell_quartet_;
267 Ref<ShellPairsLibint2> shell_pairs12_;
268 Ref<ShellPairsLibint2> shell_pairs34_;
272 int p12, p34, p13p24;
273 ShellPairLibint2 *shell_pair12, *shell_pair34;
275 int *op1, *op2, *op3, *op4;
277 double A[3], B[3], C[3], D[3];
279 int gc1, gc2, gc3, gc4;
283 typedef Libint_t prim_data;
285 size_t quartet_data_(prim_data *Data,
double scale);
287 std::vector<Libint_t> Libint_;
288 detail::OSAR_CoreInts<OperType> coreints_;
291 libint2::detail::CoreEvalScratch<libint2::GaussianGmEval<double, -1>> coreints_scratch_;
294 TwoBodyOSARLibint2(Integral *,
295 const Ref<GaussianBasisSet>&,
296 const Ref<GaussianBasisSet>&,
297 const Ref<GaussianBasisSet>&,
298 const Ref<GaussianBasisSet>&,
300 const Ref<IntParams>& oper_params);
301 ~TwoBodyOSARLibint2();
304 Ref<Int2eLibint2> clone();
306 double *buffer(
unsigned int t = 0)
const {
307 return target_ints_buffer_;
310 static size_t storage_required(
const Ref<GaussianBasisSet>& b1,
311 const Ref<GaussianBasisSet>& b2 = 0,
312 const Ref<GaussianBasisSet>& b3 = 0,
313 const Ref<GaussianBasisSet>& b4 = 0);
316 void compute_quartet(
int*,
int*,
int*,
int*);
322 TwoBodyOSARLibint2(
const TwoBodyOSARLibint2&
other);
326 template <TwoBodyOper::type OperType>
327 TwoBodyOSARLibint2<OperType>::TwoBodyOSARLibint2(Integral *integral,
328 const Ref<GaussianBasisSet>& b1,
329 const Ref<GaussianBasisSet>& b2,
330 const Ref<GaussianBasisSet>& b3,
331 const Ref<GaussianBasisSet>& b4,
333 const Ref<IntParams>& oper_params) :
334 Int2eLibint2(integral,b1,b2,b3,b4,storage),
335 coreints_(b1->max_angular_momentum() +
336 b2->max_angular_momentum() +
337 b3->max_angular_momentum() +
338 b4->max_angular_momentum(),
342 const int l1 = bs1_->max_angular_momentum();
343 const int l2 = bs2_->max_angular_momentum();
344 const int l3 = bs3_->max_angular_momentum();
345 const int l4 = bs4_->max_angular_momentum();
346 const int lmax = std::max(std::max(l1,l2),std::max(l3,l4));
347 if (lmax > LIBINT2_MAX_AM_eri) {
348 throw LimitExceeded<int>(
"TwoBodyOSARLibint2::TwoBodyOSARLibint2() -- maxam of the basis is too high,\
349 not supported by this libint2 library. Recompile libint2.",__FILE__,__LINE__,LIBINT2_MAX_AM_eri,lmax);
353 const int max_num_prim_comb = bs1_->max_nprimitive_in_shell()*
354 bs2_->max_nprimitive_in_shell()*
355 bs3_->max_nprimitive_in_shell()*
356 bs4_->max_nprimitive_in_shell();
359 #if LIBINT2_CONTRACTED_INTS
360 Libint_.resize(max_num_prim_comb);
366 const int max_cart_target_size = bs1_->max_ncartesian_in_shell()*bs2_->max_ncartesian_in_shell()*
367 bs3_->max_ncartesian_in_shell()*bs4_->max_ncartesian_in_shell();
368 const int max_target_size = bs1_->max_nfunction_in_shell()*bs2_->max_nfunction_in_shell()*
369 bs3_->max_nfunction_in_shell()*bs4_->max_nfunction_in_shell();
371 size_t storage_needed = LIBINT2_PREFIXED_NAME(libint2_need_memory_eri)(lmax) *
sizeof(LIBINT2_REALTYPE);
372 LIBINT2_PREFIXED_NAME(libint2_init_eri)(&Libint_[0],lmax,0);
373 manage_array(Libint_[0].stack, storage_needed/
sizeof(LIBINT2_REALTYPE));
375 target_ints_buffer_ = allocate<double>(max_target_size);
376 cart_ints_ = allocate<double>(max_cart_target_size);
377 if (bs1_->has_pure() || bs2_->has_pure() || bs3_->has_pure() || bs4_->has_pure() ||
378 bs1_->max_ncontraction() != 1 || bs2_->max_ncontraction() != 1 ||
379 bs3_->max_ncontraction() != 1 || bs4_->max_ncontraction() != 1) {
380 sphharm_ints_ = allocate<double>(max_target_size);
381 storage_needed += max_target_size*
sizeof(double);
386 if (l1 || l2 || l3 || l4) {
387 perm_ints_ = allocate<double>(max_target_size);
388 storage_needed += max_target_size*
sizeof(double);
394 size_t primitive_pair_storage_estimate = (bs1_->nprimitive()*(size_t)bs2_->nprimitive() +
395 bs3_->nprimitive()*(size_t)bs4_->nprimitive())*
sizeof(prim_pair_t);
398 MPQC_ASSERT(store_pair_data());
400 shell_pairs12_ =
new ShellPairsLibint2(bs1_,bs2_);
401 if ( (bs1_ == bs3_ && bs2_ == bs4_)
404 shell_pairs34_ =
new ShellPairsLibint2(*shell_pairs12_);
406 shell_pairs34_ =
new ShellPairsLibint2(bs3_,bs4_);
407 storage_needed += primitive_pair_storage_estimate;
411 coreints_scratch_ = libint2::detail::CoreEvalScratch<libint2::GaussianGmEval<double, -1>>(l1+l2+l3+l4);
413 storage_used_ = storage_needed;
418 template <TwoBodyOper::type OperType>
419 TwoBodyOSARLibint2<OperType>::~TwoBodyOSARLibint2()
421 unmanage_array(Libint_[0].stack);
422 LIBINT2_PREFIXED_NAME(libint2_cleanup_eri)(&Libint_[0]);
423 Libint_[0].stack = 0;
436 template <TwoBodyOper::type OperType>
437 TwoBodyOSARLibint2<OperType>::TwoBodyOSARLibint2(
const TwoBodyOSARLibint2&
other) :
439 shell_pairs12_(new ShellPairsLibint2(*
other.shell_pairs12_)),
440 shell_pairs34_(new ShellPairsLibint2(*
other.shell_pairs34_)),
441 coreints_(
other.coreints_)
444 const int l1 = bs1_->max_angular_momentum();
445 const int l2 = bs2_->max_angular_momentum();
446 const int l3 = bs3_->max_angular_momentum();
447 const int l4 = bs4_->max_angular_momentum();
448 const int lmax = std::max(std::max(l1,l2),std::max(l3,l4));
451 const int max_num_prim_comb = bs1_->max_nprimitive_in_shell()*
452 bs2_->max_nprimitive_in_shell()*
453 bs3_->max_nprimitive_in_shell()*
454 bs4_->max_nprimitive_in_shell();
457 #if LIBINT2_CONTRACTED_INTS
458 Libint_.resize(max_num_prim_comb);
464 const int max_cart_target_size = bs1_->max_ncartesian_in_shell()*bs2_->max_ncartesian_in_shell()*
465 bs3_->max_ncartesian_in_shell()*bs4_->max_ncartesian_in_shell();
466 const int max_target_size = bs1_->max_nfunction_in_shell()*bs2_->max_nfunction_in_shell()*
467 bs3_->max_nfunction_in_shell()*bs4_->max_nfunction_in_shell();
469 size_t storage_needed = LIBINT2_PREFIXED_NAME(libint2_need_memory_eri)(lmax) *
sizeof(LIBINT2_REALTYPE);
470 LIBINT2_PREFIXED_NAME(libint2_init_eri)(&Libint_[0],lmax,0);
471 manage_array(Libint_[0].stack, storage_needed/
sizeof(LIBINT2_REALTYPE));
473 target_ints_buffer_ = allocate<double>(max_target_size);
474 cart_ints_ = allocate<double>(max_cart_target_size);
475 if (bs1_->has_pure() || bs2_->has_pure() || bs3_->has_pure() || bs4_->has_pure() ||
476 bs1_->max_ncontraction() != 1 || bs2_->max_ncontraction() != 1 ||
477 bs3_->max_ncontraction() != 1 || bs4_->max_ncontraction() != 1) {
478 sphharm_ints_ = allocate<double>(max_target_size);
479 storage_needed += max_target_size*
sizeof(double);
484 if (l1 || l2 || l3 || l4) {
485 perm_ints_ = allocate<double>(max_target_size);
486 storage_needed += max_target_size*
sizeof(double);
492 coreints_scratch_ = libint2::detail::CoreEvalScratch<libint2::GaussianGmEval<double, -1>>(l1+l2+l3+l4);
494 storage_used_ = storage_needed;
499 template <TwoBodyOper::type OperType>
501 TwoBodyOSARLibint2<OperType>::clone() {
502 return new TwoBodyOSARLibint2<OperType>(*
this);
505 template <TwoBodyOper::type OperType>
507 TwoBodyOSARLibint2<OperType>::storage_required(
const Ref<GaussianBasisSet>& b1,
508 const Ref<GaussianBasisSet>& b2,
509 const Ref<GaussianBasisSet>& b3,
510 const Ref<GaussianBasisSet>& b4)
512 Ref<GaussianBasisSet> bs1 = b1;
513 Ref<GaussianBasisSet> bs2 = b2;
514 Ref<GaussianBasisSet> bs3 = b3;
515 Ref<GaussianBasisSet> bs4 = b4;
524 int l1 = bs1->max_angular_momentum();
525 int l2 = bs2->max_angular_momentum();
526 int l3 = bs3->max_angular_momentum();
527 int l4 = bs4->max_angular_momentum();
528 int lmax = std::max(std::max(l1,l2),std::max(l3,l4));
530 size_t storage_required = storage_required_(bs1,bs2,bs3,bs4);
532 const int max_num_prim_comb = bs1->max_nprimitive_in_shell()*
533 bs2->max_nprimitive_in_shell()*
534 bs3->max_nprimitive_in_shell()*
535 bs4->max_nprimitive_in_shell();
536 #if LIBINT2_CONTRACTED_INTS
537 storage_required += max_num_prim_comb *
sizeof(Libint_t);
539 storage_required +=
sizeof(Libint_t);
542 const int max_cart_target_size = bs1->max_ncartesian_in_shell()*bs2->max_ncartesian_in_shell()*
543 bs3->max_ncartesian_in_shell()*bs4->max_ncartesian_in_shell();
544 const int max_target_size = bs1->max_nfunction_in_shell()*bs2->max_nfunction_in_shell()*
545 bs3->max_nfunction_in_shell()*bs4->max_nfunction_in_shell();
547 storage_required += LIBINT2_PREFIXED_NAME(libint2_need_memory_eri)(lmax) *
sizeof(LIBINT2_REALTYPE);
549 if (bs1->has_pure() || bs2->has_pure() || bs3->has_pure() || bs4->has_pure() ||
550 bs1->max_ncontraction() != 1 || bs2->max_ncontraction() != 1 ||
551 bs3->max_ncontraction() != 1 || bs4->max_ncontraction() != 1) {
552 storage_required += max_target_size*
sizeof(double);
555 if (l1 || l2 || l3 || l4) {
556 storage_required += max_target_size*
sizeof(double);
560 size_t primitive_pair_storage_estimate = (bs1->nprimitive()*bs2->nprimitive() +
561 bs3->nprimitive()*bs4->nprimitive())*
sizeof(prim_pair_t);
563 storage_required += primitive_pair_storage_estimate;
566 return storage_required;
569 template <TwoBodyOper::type OperType>
571 TwoBodyOSARLibint2<OperType>::quartet_data_(prim_data *Data,
double scale)
576 if (!quartet_info_.p13p24) {
577 pair12 = quartet_info_.shell_pair12->prim_pair(*quartet_info_.op1,*quartet_info_.op2);
578 pair34 = quartet_info_.shell_pair34->prim_pair(*quartet_info_.op3,*quartet_info_.op4);
581 pair12 = quartet_info_.shell_pair34->prim_pair(*quartet_info_.op3,*quartet_info_.op4);
582 pair34 = quartet_info_.shell_pair12->prim_pair(*quartet_info_.op1,*quartet_info_.op2);
585 const int p1 = quartet_info_.p1;
586 const int p2 = quartet_info_.p2;
587 const int p3 = quartet_info_.p3;
588 const int p4 = quartet_info_.p4;
590 const double pfac_norm = int_shell1_->coefficient_unnorm(quartet_info_.gc1,p1)*
591 int_shell2_->coefficient_unnorm(quartet_info_.gc2,p2)*
592 int_shell3_->coefficient_unnorm(quartet_info_.gc3,p3)*
593 int_shell4_->coefficient_unnorm(quartet_info_.gc4,p4);
595 const double pfac_simple = pair12->ovlp*pair34->ovlp*pfac_norm;
600 double P[3], Q[3], PQ[3], W[3];
602 const double zeta = pair12->gamma;
603 const double eta = pair34->gamma;
604 const double ooz = 1.0/zeta;
605 const double ooe = 1.0/eta;
606 const double ooze = 1.0/(zeta+eta);
607 #if LIBINT2_DEFINED(eri,roz)
608 Data->roz[0] = eta*ooze;
609 const double rho = zeta*Data->roz[0];
611 const double rho = zeta * eta * ooze;
614 const double pfac = 2.0*sqrt(rho*M_1_PI)*scale*pfac_simple;
625 double PQ2 = PQ[0]*PQ[0];
630 if (!quartet_info_.am) {
631 const double* Fm = coreints_.eval(Data->LIBINT_T_SS_EREP_SS(0), 0, T, rho,
632 static_cast<void*>(&coreints_scratch_));
633 Data->LIBINT_T_SS_EREP_SS(0)[0] = Fm[0]*pfac;
636 #if LIBINT2_DEFINED(eri,oo2ze)
637 Data->oo2ze[0] = 0.5*ooze;
639 #if LIBINT2_DEFINED(eri,roe)
640 Data->roe[0] = zeta*ooze;
642 #if LIBINT2_DEFINED(eri,oo2z)
643 Data->oo2z[0] = 0.5/zeta;
645 #if LIBINT2_DEFINED(eri,oo2e)
646 Data->oo2e[0] = 0.5/eta;
648 W[0] = (zeta*P[0] + eta*Q[0])*ooze;
649 W[1] = (zeta*P[1] + eta*Q[1])*ooze;
650 W[2] = (zeta*P[2] + eta*Q[2])*ooze;
652 const double* Gm = coreints_.eval(Data->LIBINT_T_SS_EREP_SS(0), quartet_info_.am, T, rho,
653 static_cast<void*>(&coreints_scratch_));
655 Data->LIBINT_T_SS_EREP_SS(0),
656 std::bind2nd(std::multiplies<double>(), pfac));
659 #if LIBINT2_DEFINED(eri,PA_x)
660 Data->PA_x[0] = P[0] - quartet_info_.A[0];
662 #if LIBINT2_DEFINED(eri,PA_y)
663 Data->PA_y[0] = P[1] - quartet_info_.A[1];
665 #if LIBINT2_DEFINED(eri,PA_z)
666 Data->PA_z[0] = P[2] - quartet_info_.A[2];
669 #if LIBINT2_DEFINED(eri,QC_x)
670 Data->QC_x[0] = Q[0] - quartet_info_.C[0];
672 #if LIBINT2_DEFINED(eri,QC_y)
673 Data->QC_y[0] = Q[1] - quartet_info_.C[1];
675 #if LIBINT2_DEFINED(eri,QC_z)
676 Data->QC_z[0] = Q[2] - quartet_info_.C[2];
679 #if LIBINT2_DEFINED(eri,WP_x)
680 Data->WP_x[0] = W[0] - P[0];
682 #if LIBINT2_DEFINED(eri,WP_y)
683 Data->WP_y[0] = W[1] - P[1];
685 #if LIBINT2_DEFINED(eri,WP_z)
686 Data->WP_z[0] = W[2] - P[2];
689 #if LIBINT2_DEFINED(eri,WQ_x)
690 Data->WQ_x[0] = W[0] - Q[0];
692 #if LIBINT2_DEFINED(eri,WQ_y)
693 Data->WQ_y[0] = W[1] - Q[1];
695 #if LIBINT2_DEFINED(eri,WQ_z)
696 Data->WQ_z[0] = W[2] - Q[2];
699 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_0_x) || \
700 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_0_y) || \
701 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_0_z) || \
702 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_0_x) || \
703 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_0_y) || \
704 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_0_z)
705 double a2 = int_shell2_->exponent(quartet_info_.p2);
706 double a4 = int_shell4_->exponent(quartet_info_.p4);
708 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_1_x) || \
709 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_1_y) || \
710 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_1_z) || \
711 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_1_x) || \
712 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_1_y) || \
713 LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_1_z)
714 double a1 = int_shell1_->exponent(quartet_info_.p1);
715 double a3 = int_shell3_->exponent(quartet_info_.p3);
719 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_0_x)
720 Data->TwoPRepITR_pfac0_0_0_x[0] = - (a2*(quartet_info_.A[0]-quartet_info_.B[0]) + a4*(quartet_info_.C[0]-quartet_info_.D[0]))/zeta;
722 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_0_y)
723 Data->TwoPRepITR_pfac0_0_0_y[0] = - (a2*(quartet_info_.A[1]-quartet_info_.B[1]) + a4*(quartet_info_.C[1]-quartet_info_.D[1]))/zeta;
725 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_0_z)
726 Data->TwoPRepITR_pfac0_0_0_z[0] = - (a2*(quartet_info_.A[2]-quartet_info_.B[2]) + a4*(quartet_info_.C[2]-quartet_info_.D[2]))/zeta;
728 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_0_x)
729 Data->TwoPRepITR_pfac0_1_0_x[0] = - (a2*(quartet_info_.A[0]-quartet_info_.B[0]) + a4*(quartet_info_.C[0]-quartet_info_.D[0]))/eta;
731 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_0_y)
732 Data->TwoPRepITR_pfac0_1_0_y[0] = - (a2*(quartet_info_.A[1]-quartet_info_.B[1]) + a4*(quartet_info_.C[1]-quartet_info_.D[1]))/eta;
734 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_0_z)
735 Data->TwoPRepITR_pfac0_1_0_z[0] = - (a2*(quartet_info_.A[2]-quartet_info_.B[2]) + a4*(quartet_info_.C[2]-quartet_info_.D[2]))/eta;
737 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_1_x)
738 Data->TwoPRepITR_pfac0_0_1_x[0] = (a1*(quartet_info_.A[0]-quartet_info_.B[0]) + a3*(quartet_info_.C[0]-quartet_info_.D[0]))/zeta;
740 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_1_y)
741 Data->TwoPRepITR_pfac0_0_1_y[0] = (a1*(quartet_info_.A[1]-quartet_info_.B[1]) + a3*(quartet_info_.C[1]-quartet_info_.D[1]))/zeta;
743 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_0_1_z)
744 Data->TwoPRepITR_pfac0_0_1_z[0] = (a1*(quartet_info_.A[2]-quartet_info_.B[2]) + a3*(quartet_info_.C[2]-quartet_info_.D[2]))/zeta;
746 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_1_x)
747 Data->TwoPRepITR_pfac0_1_1_x[0] = (a1*(quartet_info_.A[0]-quartet_info_.B[0]) + a3*(quartet_info_.C[0]-quartet_info_.D[0]))/eta;
749 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_1_y)
750 Data->TwoPRepITR_pfac0_1_1_y[0] = (a1*(quartet_info_.A[1]-quartet_info_.B[1]) + a3*(quartet_info_.C[1]-quartet_info_.D[1]))/eta;
752 #if LIBINT2_DEFINED(eri,TwoPRepITR_pfac0_1_1_z)
753 Data->TwoPRepITR_pfac0_1_1_z[0] = (a1*(quartet_info_.A[2]-quartet_info_.B[2]) + a3*(quartet_info_.C[2]-quartet_info_.D[2]))/eta;
755 #if LIBINT2_DEFINED(eri,eoz)
756 Data->eoz[0] = eta * ooz;
758 #if LIBINT2_DEFINED(eri,zoe)
759 Data->zoe[0] = zeta * ooe;
766 template <TwoBodyOper::type OperType>
768 TwoBodyOSARLibint2<OperType>::compute_quartet(
int *psh1,
int *psh2,
int *psh3,
int *psh4)
773 GaussianBasisSet *pbs1=bs1_.
pointer();
774 GaussianBasisSet *pbs2=bs2_.pointer();
775 GaussianBasisSet *pbs3=bs3_.pointer();
776 GaussianBasisSet *pbs4=bs4_.pointer();
783 int size1, size2, size3, size4;
784 int tam1,tam2,tam3,tam4;
787 int gci, gcj, gck, gcl;
789 int osh1,osh2,osh3,osh4;
790 int am1,am2,am3,am4,am12,am34;
791 int minam1,minam2,minam3,minam4;
803 if ( sh1 < 0 || sh1 >= bs1_->nbasis()
804 || sh2 < 0 || sh2 >= bs2_->nbasis()
805 || sh3 < 0 || sh3 >= bs3_->nbasis()
806 || sh4 < 0 || sh4 >= bs4_->nbasis() ) {
807 ExEnv::errn() << scprintf(
"compute_erep has been incorrectly used\n");
808 ExEnv::errn() << scprintf(
"shells (bounds): %d (%d), %d (%d), %d (%d), %d (%d)\n",
809 sh1,bs1_->nbasis()-1,
810 sh2,bs2_->nbasis()-1,
811 sh3,bs3_->nbasis()-1,
812 sh4,bs4_->nbasis()-1);
817 int_shell1_ = &bs1_->shell(sh1);
818 int_shell2_ = &bs2_->shell(sh2);
819 int_shell3_ = &bs3_->shell(sh3);
820 int_shell4_ = &bs4_->shell(sh4);
826 minam1 = int_shell1_->min_am();
827 minam2 = int_shell2_->min_am();
828 minam3 = int_shell3_->min_am();
829 minam4 = int_shell4_->min_am();
830 am1 = int_shell1_->max_am();
831 am2 = int_shell2_->max_am();
832 am3 = int_shell3_->max_am();
833 am4 = int_shell4_->max_am();
847 bool need_cart2sph_transform =
false;
848 if (int_shell1_->has_pure() ||
849 int_shell2_->has_pure() ||
850 int_shell3_->has_pure() ||
851 int_shell4_->has_pure())
852 need_cart2sph_transform =
true;
856 bool need_sort_to_shell_quartet =
false;
857 int num_gen_shells = 0;
858 if (int_shell1_->ncontraction() > 1)
860 if (int_shell2_->ncontraction() > 1)
862 if (int_shell3_->ncontraction() > 1)
864 if (int_shell4_->ncontraction() > 1)
866 if (am12+am34 && num_gen_shells >= 1)
867 need_sort_to_shell_quartet =
true;
870 bool need_unique_ints_only =
false;
873 if (int_shell1_ == int_shell2_ && int_shell1_->nfunction()>1)
876 if (int_shell3_ == int_shell4_ && int_shell3_->nfunction()>1)
879 if (int_shell1_ == int_shell3_ && int_shell2_ == int_shell4_ && int_shell1_->nfunction()*int_shell2_->nfunction()>1)
882 if ( e12 || e34 || e13e24 )
883 need_unique_ints_only =
true;
888 sprintf(section,
"erep am=%02d",am12+am34);
900 iswtch(&am1,&am2);iswtch(&sh1,&sh2);iswtch(psh1,psh2);
901 iswtch(&minam1,&minam2);
902 pswtch((
void**)&int_shell1_,(
void**)&int_shell2_);
907 iswtch(&am3,&am4);iswtch(&sh3,&sh4);iswtch(psh3,psh4);
908 iswtch(&minam3,&minam4);
909 pswtch((
void**)&int_shell3_,(
void**)&int_shell4_);
914 iswtch(&am1,&am3);iswtch(&sh1,&sh3);iswtch(psh1,psh3);
915 iswtch(&am2,&am4);iswtch(&sh2,&sh4);iswtch(psh2,psh4);
917 iswtch(&minam1,&minam3);
918 iswtch(&minam2,&minam4);
919 pswtch((
void**)&int_shell1_,(
void**)&int_shell3_);
921 pswtch((
void**)&int_shell2_,(
void**)&int_shell4_);
924 bool shells_were_permuted = (p12||p34||p13p24);
929 iswtch(&int_expweight1,&int_expweight2);
932 iswtch(&int_expweight3,&int_expweight4);
935 iswtch(&int_expweight1,&int_expweight3);
936 iswtch(&int_expweight2,&int_expweight4);
940 size1 = int_shell1_->ncartesian();
941 size2 = int_shell2_->ncartesian();
942 size3 = int_shell3_->ncartesian();
943 size4 = int_shell4_->ncartesian();
944 size = size1*size2*size3*size4;
947 int ctr1 = pbs1->shell_to_center(sh1);
948 int ctr2 = pbs2->shell_to_center(sh2);
949 int ctr3 = pbs3->shell_to_center(sh3);
950 int ctr4 = pbs4->shell_to_center(sh4);
951 Libint_t& libint0 = Libint_[0];
952 libint0.AB_x[0] = pbs1->r(ctr1,0) - pbs2->r(ctr2,0);
953 libint0.AB_y[0] = pbs1->r(ctr1,1) - pbs2->r(ctr2,1);
954 libint0.AB_z[0] = pbs1->r(ctr1,2) - pbs2->r(ctr2,2);
955 libint0.CD_x[0] = pbs3->r(ctr3,0) - pbs4->r(ctr4,0);
956 libint0.CD_y[0] = pbs3->r(ctr3,1) - pbs4->r(ctr4,1);
957 libint0.CD_z[0] = pbs3->r(ctr3,2) - pbs4->r(ctr4,2);
959 quartet_info_.A[i] = pbs1->r(ctr1,i);
960 quartet_info_.B[i] = pbs2->r(ctr2,i);
961 quartet_info_.C[i] = pbs3->r(ctr3,i);
962 quartet_info_.D[i] = pbs4->r(ctr4,i);
964 quartet_info_.AB2 = libint0.AB_x[0]*libint0.AB_x[0];
965 quartet_info_.AB2 += libint0.AB_y[0]*libint0.AB_y[0];
966 quartet_info_.AB2 += libint0.AB_z[0]*libint0.AB_z[0];
967 quartet_info_.CD2 = libint0.CD_x[0]*libint0.CD_x[0];
968 quartet_info_.CD2 += libint0.CD_y[0]*libint0.CD_y[0];
969 quartet_info_.CD2 += libint0.CD_z[0]*libint0.CD_z[0];
972 quartet_info_.shell_pair12 = shell_pairs12_->shell_pair(osh1,osh2);
973 quartet_info_.shell_pair34 = shell_pairs34_->shell_pair(osh3,osh4);
977 quartet_info_.p12 = p12;
978 quartet_info_.p34 = p34;
979 quartet_info_.p13p24 = p13p24;
984 quartet_info_.op1 = &quartet_info_.p1;
985 quartet_info_.op2 = &quartet_info_.p2;
986 quartet_info_.op3 = &quartet_info_.p3;
987 quartet_info_.op4 = &quartet_info_.p4;
989 pswtch((
void **)&quartet_info_.op1,(
void **)&quartet_info_.op3);
990 pswtch((
void **)&quartet_info_.op2,(
void **)&quartet_info_.op4);
993 pswtch((
void **)&quartet_info_.op1,(
void **)&quartet_info_.op2);
995 pswtch((
void **)&quartet_info_.op3,(
void **)&quartet_info_.op4);
998 if (shells_were_permuted)
999 if (need_sort_to_shell_quartet) {
1000 prim_ints_ = cart_ints_;
1001 if (need_cart2sph_transform)
1002 contr_quartets_ = sphharm_ints_;
1004 contr_quartets_ = cart_ints_;
1005 shell_quartet_ = perm_ints_;
1008 prim_ints_ = cart_ints_;
1009 if (need_cart2sph_transform) {
1010 contr_quartets_ = sphharm_ints_;
1011 shell_quartet_ = contr_quartets_;
1014 shell_quartet_ = cart_ints_;
1017 if (need_sort_to_shell_quartet) {
1018 prim_ints_ = cart_ints_;
1019 if (need_cart2sph_transform)
1020 contr_quartets_ = sphharm_ints_;
1022 contr_quartets_ = cart_ints_;
1023 shell_quartet_ = target_ints_buffer_;
1026 if (need_cart2sph_transform) {
1027 prim_ints_ = cart_ints_;
1028 contr_quartets_ = target_ints_buffer_;
1029 shell_quartet_ = target_ints_buffer_;
1032 prim_ints_ = target_ints_buffer_;
1033 shell_quartet_ = target_ints_buffer_;
1038 int buffer_offset = 0;
1039 for (gci=0; gci<int_shell1_->ncontraction(); gci++) {
1040 tam1 = int_shell1_->am(gci);
1041 int tsize1 = INT_NCART_NN(tam1);
1042 quartet_info_.gc1 = gci;
1043 for (gcj=0; gcj<int_shell2_->ncontraction(); gcj++) {
1044 tam2 = int_shell2_->am(gcj);
1045 int tsize2 = INT_NCART_NN(tam2);
1046 quartet_info_.gc2 = gcj;
1047 for (gck=0; gck<int_shell3_->ncontraction(); gck++) {
1048 tam3 = int_shell3_->am(gck);
1049 int tsize3 = INT_NCART_NN(tam3);
1050 quartet_info_.gc3 = gck;
1051 for (gcl=0; gcl<int_shell4_->ncontraction(); gcl++) {
1052 tam4 = int_shell4_->am(gcl);
1053 int tsize4 = INT_NCART_NN(tam4);
1054 quartet_info_.gc4 = gcl;
1055 quartet_info_.am = tam1 + tam2 + tam3 + tam4;
1056 int size = tsize1*tsize2*tsize3*tsize4;
1059 int num_prim_combinations = 0;
1060 for (pi=0; pi<int_shell1_->nprimitive(); pi++) {
1061 quartet_info_.p1 = pi;
1062 for (pj=0; pj<int_shell2_->nprimitive(); pj++) {
1063 quartet_info_.p2 = pj;
1064 for (pk=0; pk<int_shell3_->nprimitive(); pk++) {
1065 quartet_info_.p3 = pk;
1066 for (pl=0; pl<int_shell4_->nprimitive(); pl++) {
1067 quartet_info_.p4 = pl;
1070 size_t ncomb = quartet_data_(&Libint_[num_prim_combinations], 1.0);
1071 num_prim_combinations += ncomb;
1074 if (quartet_info_.am) {
1076 Libint_[0].contrdepth = num_prim_combinations;
1077 LIBINT2_PREFIXED_NAME(libint2_build_eri)[tam1][tam2][tam3][tam4](&Libint_[0]);
1079 const LIBINT2_REALTYPE* prim_ints = Libint_[0].targets[0];
1080 for(
int ijkl=0; ijkl<size; ijkl++)
1081 prim_ints_[buffer_offset + ijkl] = (
double) prim_ints[ijkl];
1084 std::cout << *psh1 <<
" " << *psh2 <<
" " << *psh3 <<
" " << *psh4 <<
" " << std::endl;
1085 for(
int ijkl=0; ijkl<size; ijkl++) {
1086 std::cout <<
" " << prim_ints[ijkl] << std::endl;
1092 for(
int p=0; p<num_prim_combinations; ++p)
1093 ssss += Libint_[p].LIBINT_T_SS_EREP_SS(0)[0];
1094 prim_ints_[buffer_offset] = ssss;
1096 buffer_offset += size;
1102 if (need_cart2sph_transform)
1103 transform_contrquartets_(prim_ints_,contr_quartets_);
1108 #if INTEGRALLIBINT2_NORMCONV != INTEGRALLIBINT2_NORMCONV_CCA
1109 norm_contrcart1_(need_cart2sph_transform ? contr_quartets_ : prim_ints_);
1116 if (need_sort_to_shell_quartet)
1117 sort_contrquartets_to_shellquartet_(contr_quartets_,shell_quartet_);
1122 if ((!permute_)&&shells_were_permuted) {
1124 permute_target_(shell_quartet_,target_ints_buffer_,p13p24,p12,p34);
1127 iswtch(&sh1,&sh3);iswtch(psh1,psh3);
1128 iswtch(&sh2,&sh4);iswtch(psh2,psh4);
1131 iswtch(&am12,&am34);
1132 pswtch((
void**)&int_shell1_,(
void**)&int_shell3_);
1134 pswtch((
void**)&int_shell2_,(
void**)&int_shell4_);
1136 iswtch(&int_expweight1,&int_expweight3);
1137 iswtch(&int_expweight2,&int_expweight4);
1140 iswtch(&sh3,&sh4);iswtch(psh3,psh4);
1142 pswtch((
void**)&int_shell3_,(
void**)&int_shell4_);
1144 iswtch(&int_expweight3,&int_expweight4);
1147 iswtch(&sh1,&sh2);iswtch(psh1,psh2);
1149 pswtch((
void**)&int_shell1_,(
void**)&int_shell2_);
1151 iswtch(&int_expweight1,&int_expweight2);
1156 if (need_unique_ints_only)
1157 get_nonredundant_ints_(target_ints_buffer_,target_ints_buffer_,e13e24,e12,e34);
1163 #endif // header guard
1164 #endif // if LIBINT2_SUPPORT_ERI