21#ifndef _libint2_src_bin_libint_hrr_h_
22#define _libint2_src_bin_libint_hrr_h_
26#include <default_params.h>
30#include <prefactors.h>
55template <
class IntType,
class BFSet,
int part, FunctionPosition loc_a,
56 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
62 typedef IntType TargetType;
63 typedef IntType ChildType;
75 static std::shared_ptr<ThisType>
Instance(
const std::shared_ptr<TargetType>&,
76 unsigned int dir = 0);
81 if (loc_b == InBra && loc_a == InKet)
82 return BraketDirection::BraToKet;
83 else if (loc_b == InKet && loc_a == InBra)
84 return BraketDirection::KetToBra;
86 return BraketDirection::None;
93 if (boost::is_same<BasisFunctionType, CGShell>::value)
return false;
100 std::shared_ptr<TargetType>
target()
const {
return target_; };
102 std::shared_ptr<ChildType>
child(
unsigned int i)
const;
105 return std::static_pointer_cast<DGVertex, TargetType>(
target());
108 std::shared_ptr<DGVertex>
rr_child(
unsigned int i)
const override {
109 return std::static_pointer_cast<DGVertex, ChildType>(
child(i));
115 const std::shared_ptr<CodeContext>& context,
116 const std::shared_ptr<ImplicitDimensions>& dims)
const override;
124 HRR(
const std::shared_ptr<TargetType>&,
unsigned int dir);
127 std::shared_ptr<TargetType> target_;
128 static const unsigned int max_nchildren_ = 8;
129 std::shared_ptr<ChildType> children_[max_nchildren_];
130 unsigned int nchildren_;
132 void oper_checks()
const;
135 std::string generate_label()
const override;
137 std::shared_ptr<ImplicitDimensions> adapt_dims_(
138 const std::shared_ptr<ImplicitDimensions>& dims)
const override;
140 bool register_with_rrstack()
const;
146 bool expl_high_dim()
const;
147 bool expl_low_dim()
const;
150template <
class IntType,
class F,
int part, FunctionPosition loc_a,
151 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
152std::shared_ptr<HRR<IntType, F, part, loc_a, pos_a, loc_b, pos_b> >
154 const std::shared_ptr<TargetType>& Tint,
unsigned int dir) {
155 std::shared_ptr<ThisType> this_ptr(
new ThisType(Tint, dir));
157 if (this_ptr->num_children() != 0) {
158 this_ptr->register_with_rrstack();
161 return std::shared_ptr<ThisType>();
164template <
class IntType,
class F,
int part, FunctionPosition loc_a,
165 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
167 const std::shared_ptr<TargetType>& Tint,
unsigned int dir)
168 : dir_(dir), target_(Tint), nchildren_(0) {
169 using namespace libint2::algebra;
170 using namespace libint2::prefactor;
173 assert(loc_a != loc_b);
176 const typename IntType::AuxQuantaType& aux = Tint->aux();
177 const typename IntType::OperType& oper = Tint->oper();
180 if (loc_a != loc_b && oper.hermitian(part) != +1) {
184 typedef typename IntType::BraType IBraType;
185 typedef typename IntType::KetType IKetType;
186 IBraType* bra =
new IBraType(Tint->bra());
187 IKetType* ket =
new IKetType(Tint->ket());
193 if (loc_a == InKet && loc_b == InBra) {
194 F a(ket->member(part, pos_a));
195 F b(bra->member(part, pos_b));
205 bra->set_member(bm1, part, pos_b);
210 ket->set_member(ap1, part, pos_a);
211 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
212 ket->set_member(a, part, pos_a);
215 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
222 for (
unsigned int xyz = 0; xyz < 3; ++xyz) {
224 if (a.deriv().d(xyz) > 0) {
226 a_der_m1.deriv().dec(xyz);
227 ket->set_member(a_der_m1, part, pos_a);
228 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
229 ket->set_member(a, part, pos_a);
232 if (bm1.deriv().d(xyz) > 0) {
234 bm1_der_m1.deriv().dec(xyz);
235 bra->set_member(bm1_der_m1, part, pos_b);
236 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
237 bra->set_member(bm1, part, pos_b);
246 expr_ = children_[0] + prefactors.
Y_X[part][dir] * children_[1];
249 const bool aderiv = a.deriv().d(dir_) > 0;
252 a_der_m1.deriv().dec(dir_);
253 ket->set_member(a_der_m1, part, pos_a);
254 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
255 ket->set_member(a, part, pos_a);
259 const bool bderiv = bm1.deriv().d(dir_) > 0;
262 bm1_der_m1.deriv().dec(dir_);
263 bra->set_member(bm1_der_m1, part, pos_b);
264 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
265 bra->set_member(bm1, part, pos_b);
268 if (aderiv) expr_ += Vector(a.deriv())[dir_] * children_[2];
269 if (bderiv) expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
273 if (loc_a == InBra && loc_b == InKet) {
274 F a(bra->member(part, pos_a));
275 F b(ket->member(part, pos_b));
285 ket->set_member(bm1, part, pos_b);
290 bra->set_member(ap1, part, pos_a);
291 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
292 bra->set_member(a, part, pos_a);
295 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
302 for (
unsigned int xyz = 0; xyz < 3; ++xyz) {
304 if (a.deriv().d(xyz) > 0) {
306 a_der_m1.deriv().dec(xyz);
307 bra->set_member(a_der_m1, part, pos_a);
308 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
309 bra->set_member(a, part, pos_a);
312 if (bm1.deriv().d(xyz) > 0) {
314 bm1_der_m1.deriv().dec(xyz);
315 ket->set_member(bm1_der_m1, part, pos_b);
316 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
317 ket->set_member(bm1, part, pos_b);
324 expr_ = children_[0] + prefactors.
X_Y[part][dir] * children_[1];
327 const bool aderiv = a.deriv().d(dir_) > 0;
330 a_der_m1.deriv().dec(dir_);
331 bra->set_member(a_der_m1, part, pos_a);
332 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
333 bra->set_member(a, part, pos_a);
337 const bool bderiv = bm1.deriv().d(dir_) > 0;
340 bm1_der_m1.deriv().dec(dir_);
341 ket->set_member(bm1_der_m1, part, pos_b);
342 children_[nchildren_++] = IntType::Instance(*bra, *ket, aux, oper);
343 ket->set_member(bm1, part, pos_b);
346 if (aderiv) expr_ += Vector(a.deriv())[dir_] * children_[2];
347 if (bderiv) expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
356template <
class IntType,
class F,
int part, FunctionPosition loc_a,
357 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
369 typedef typename IntType::BraType IBraType;
370 typedef typename IntType::KetType IKetType;
371 const IBraType& bra = target_->bra();
372 const IKetType& ket = target_->ket();
375 bool nonzero_quanta =
false;
376 unsigned const int npart = IntType::OperatorType::Properties::np;
377 for (
unsigned int p = 0; p < npart; p++) {
378 if (p == part)
continue;
379 int nfbra = bra.num_members(p);
381 for (
int f = 0; f < nfbra; f++)
382 if (!bra.member(p, f).zero() || !bra.member(p, f).deriv().zero())
383 nonzero_quanta =
true;
384 int nfket = ket.num_members(p);
386 for (
int f = 0; f < nfket; f++)
387 if (!ket.member(p, f).zero() || !ket.member(p, f).deriv().zero())
388 nonzero_quanta =
true;
392 if (!nonzero_quanta) {
394 std::shared_ptr<ThisType> this_ptr =
395 std::const_pointer_cast<ThisType, const ThisType>(
396 std::static_pointer_cast<const ThisType, const ParentType>(
397 std::enable_shared_from_this<ParentType>::shared_from_this()));
398 rrstack->find(this_ptr);
407 IBraType bra_zero(bra);
408 IKetType ket_zero(ket);
409 for (
unsigned int p = 0; p < npart; p++) {
410 if (p == part)
continue;
411 int nfbra = bra_zero.num_members(p);
412 for (
int f = 0; f < nfbra; f++) {
413 typedef typename IBraType::bfs_type bfs_type;
414 typedef typename IBraType::bfs_ref bfs_ref;
415 bfs_ref bfs = bra_zero.member(p, f);
416 if (!bfs.zero() || !bfs.deriv().zero()) {
421 int nfket = ket_zero.num_members(p);
422 for (
int f = 0; f < nfket; f++) {
423 typedef typename IKetType::bfs_type bfs_type;
424 typedef typename IKetType::bfs_ref bfs_ref;
425 bfs_ref bfs = ket_zero.member(p, f);
426 if (!bfs.zero() || !bfs.deriv().zero()) {
440 DummyOper dummy_oper;
441 DummyQuanta dummy_quanta(std::vector<int>(0, 0));
442 std::shared_ptr<DummyIntegral> dummy_integral =
443 DummyIntegral::Instance(bra_zero, ket_zero, dummy_quanta, dummy_oper);
447 std::shared_ptr<DummyHRR> dummy_hrr =
448 DummyHRR::Instance(dummy_integral, dir_);
450 rrstack->find(dummy_hrr);
454template <
class IntType,
class F,
int part, FunctionPosition loc_a,
455 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
460template <
class IntType,
class F,
int part, FunctionPosition loc_a,
461 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
469 typedef typename IntType::OperatorType
Oper;
470 if (part < 0 || part >= Oper::Properties::np) {
475 if (loc_a == loc_b && pos_a == pos_b) {
481template <
class IntType,
class F,
int part, FunctionPosition loc_a,
482 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
484 typename HRR<IntType, F, part, loc_a, pos_a, loc_b, pos_b>::ChildType>
486 assert(i >= 0 && i < nchildren_);
489 for (
unsigned int c = 0; c < max_nchildren_; c++) {
491 if (nc == i)
return children_[c];
498template <
class IntType,
class F,
int part, FunctionPosition loc_a,
499 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
502 std::ostringstream os;
504 os <<
"HRR Part " << part <<
" " << (loc_a == InBra ?
"bra" :
"ket") <<
" "
505 << pos_a <<
" " << (loc_b == InBra ?
"bra" :
"ket") <<
" " << pos_b
508 if (loc_a == InBra) {
509 F sh_a(target_->bra(part, pos_a));
513 os << sh_a.label() <<
" ";
515 if (loc_b == InBra) {
516 F sh_b(target_->bra(part, pos_b));
520 F sh_b(target_->ket(part, pos_b));
525 F sh_a(target_->ket(part, pos_a));
527 os << sh_a.label() <<
" ";
529 if (loc_b == InBra) {
530 F sh_b(target_->bra(part, pos_b));
534 F sh_b(target_->ket(part, pos_b));
543template <
class IntType,
class F,
int part, FunctionPosition loc_a,
544 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
546 const std::shared_ptr<CodeContext>& context,
547 const std::shared_ptr<ImplicitDimensions>& dims)
const {
548 std::ostringstream os;
549 os << context->label_to_name(
554 << context->value_to_pointer(rr_target()->symbol());
556 const unsigned int nchildren = num_children();
557 for (
unsigned int c = 0; c < nchildren; c++) {
558 os <<
", " << context->value_to_pointer(rr_child(c)->symbol());
561 unsigned int hsr = 1;
566 for (
int p = 0; p < part; p++) {
567 unsigned int nbra = target_->bra().num_members(p);
568 for (
unsigned int i = 0; i < nbra; i++) {
569 SubIterator* iter = target_->bra().member_subiter(p, i);
573 unsigned int nket = target_->ket().num_members(p);
574 for (
unsigned int i = 0; i < nket; i++) {
575 SubIterator* iter = target_->ket().member_subiter(p, i);
582 taskmgr.
current().params()->max_hrr_hsrank(hsr);
586 if (loc_a == loc_b && pos_a != 0 && pos_b != 0)
588 "HRR::spfunction_call -- has not been generalized yet");
591 unsigned int lsr = 1;
592 unsigned int np = IntType::OperType::Properties::np;
593 for (
unsigned int p = part + 1; p < np; p++) {
594 unsigned int nbra = target_->bra().num_members(p);
595 for (
unsigned int i = 0; i < nbra; i++) {
596 SubIterator* iter = target_->bra().member_subiter(p, i);
600 unsigned int nket = target_->ket().num_members(p);
601 for (
unsigned int i = 0; i < nket; i++) {
602 SubIterator* iter = target_->ket().member_subiter(p, i);
608 taskmgr.
current().params()->max_hrr_hsrank(hsr);
610 if (expl_high_dim()) os <<
"," << hsr;
611 if (expl_low_dim()) os <<
"," << lsr;
612 os <<
")" << context->end_of_stat() << std::endl;
616template <
class IntType,
class F,
int part, FunctionPosition loc_a,
617 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
620 if (part == 0) high =
false;
624template <
class IntType,
class F,
int part, FunctionPosition loc_a,
625 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
627 unsigned int np = IntType::OperType::Properties::np;
629 if (part == np - 1) low =
false;
638template <
class IntType,
class F,
int part, FunctionPosition loc_a,
639 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
640std::shared_ptr<ImplicitDimensions>
642 const std::shared_ptr<ImplicitDimensions>& dims)
const {
643 bool high_rank = expl_high_dim();
644 bool low_rank = expl_low_dim();
646 std::shared_ptr<Entity> high_dim, low_dim;
651 high_dim = dims->high();
657 low_dim = dims->low();
660 std::shared_ptr<ImplicitDimensions> localdims(
AlgebraicOperator is an algebraic operator that acts on objects of type T.
Definition algebra.h:47
Set of basis functions.
Definition bfset.h:43
This exception used to indicate that some code hasn't been developed or generalized yet.
Definition exception.h:79
GenIntegralSet is a set of integrals over functions derived from BFS.
Definition integral.h:99
GenOper is a single operator described by descriptor Descr.
Definition oper.h:164
A generic Horizontal Recurrence Relation:
Definition hrr.h:57
bool is_simple() const override
Implementation of RecurrenceRelation::is_simple()
Definition hrr.h:112
std::shared_ptr< TargetType > target() const
returns pointer to the target
Definition hrr.h:100
unsigned int num_children() const override
Implementation of RecurrenceRelation::num_children()
Definition hrr.h:98
std::shared_ptr< DGVertex > rr_child(unsigned int i) const override
Implementation of RecurrenceRelation::child()
Definition hrr.h:108
std::shared_ptr< DGVertex > rr_target() const override
Implementation of RecurrenceRelation::target()
Definition hrr.h:104
static bool directional()
is this recurrence relation parameterized by a direction.
Definition hrr.h:92
std::shared_ptr< ChildType > child(unsigned int i) const
child(i) returns pointer to i-th child
Definition hrr.h:485
std::string spfunction_call(const std::shared_ptr< CodeContext > &context, const std::shared_ptr< ImplicitDimensions > &dims) const override
Implementation of RecurrenceRelation::spfunction_call()
Definition hrr.h:545
RecurrenceRelation::ExprType ExprType
A short alias.
Definition hrr.h:65
BraketDirection braket_direction() const override
overrides RecurrenceRelation::braket_direction()
Definition hrr.h:80
static std::shared_ptr< ThisType > Instance(const std::shared_ptr< TargetType > &, unsigned int dir=0)
Use Instance() to obtain an instance of RR.
Definition hrr.h:153
ImplicitDimensions describes basis functions or other "degrees of freedom" not actively engaged in a ...
Definition dims.h:43
Set of basis functions with incrementable/decrementable quantum numbers.
Definition bfset.h:62
Manages tasks. This is a Singleton.
Definition task.h:65
void current(const std::string &task_label)
Makes this task current (must have been added already)
Definition task.cc:63
static LibraryTaskManager & Instance()
LibraryTaskManager is a Singleton.
Definition task.cc:32
Oper is OperSet characterized by properties Props.
Definition oper.h:91
std::shared_ptr< rdouble > X_Y[np][3]
Cartesian components of X-Y vectors.
Definition prefactors.h:59
std::shared_ptr< rdouble > Y_X[np][3]
Cartesian components of Y_X vectors.
Definition prefactors.h:67
QuantumNumbersA<T,N> is a set of N quantum numbers of type T implemented in terms of a C-style array.
Definition quanta.h:193
static std::shared_ptr< RRStackBase< RR > > & Instance()
Obtain the unique Instance of RRStack.
Definition rr.h:69
RecurrenceRelation describes all recurrence relations.
Definition rr.h:97
Iterator provides a base class for all object iterator classes.
Definition iter.h:43
virtual unsigned int num_iter() const =0
Returns a number of iterations (number of elements in a set over which to iterate).
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:96
std::string label_to_funcname(const std::string &label)
Converts a label, e.g.
Definition default_params.cc:201
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition bfset.h:906