21#ifndef _libint2_src_bin_libint_hrr_h_
22#define _libint2_src_bin_libint_hrr_h_
34#include <prefactors.h>
35#include <default_params.h>
54 template<
class IntType,
class BFSet,
int part, FunctionPosition loc_a,
55 unsigned int pos_a, FunctionPosition loc_b,
unsigned int pos_b>
62 typedef IntType TargetType;
63 typedef IntType ChildType;
74 static SafePtr<ThisType>
Instance(
const SafePtr<TargetType>&,
unsigned int dir = 0);
79 if (loc_b == InBra && loc_a == InKet)
80 return BraketDirection::BraToKet;
81 else if (loc_b == InKet && loc_a == InBra)
82 return BraketDirection::KetToBra;
84 return BraketDirection::None;
91 if (boost::is_same<BasisFunctionType,CGShell>::value)
99 SafePtr<TargetType>
target()
const {
return target_;};
101 SafePtr<ChildType>
child(
unsigned int i)
const;
103 SafePtr<DGVertex>
rr_target()
const override {
return static_pointer_cast<DGVertex,TargetType>(
target());}
105 SafePtr<DGVertex>
rr_child(
unsigned int i)
const override {
return static_pointer_cast<DGVertex,ChildType>(
child(i));}
112 const SafePtr<ImplicitDimensions>& dims)
const override;
120 HRR(
const SafePtr<TargetType>&,
unsigned int dir);
123 SafePtr<TargetType> target_;
124 static const unsigned int max_nchildren_ = 8;
125 SafePtr<ChildType> children_[max_nchildren_];
126 unsigned int nchildren_;
128 void oper_checks()
const;
131 std::string generate_label()
const override;
133 SafePtr<ImplicitDimensions> adapt_dims_(
const SafePtr<ImplicitDimensions>& dims)
const override;
135 bool register_with_rrstack()
const;
140 bool expl_high_dim()
const;
141 bool expl_low_dim()
const;
144 template <
class IntType,
class F,
int part,
145 FunctionPosition loc_a,
unsigned int pos_a,
146 FunctionPosition loc_b,
unsigned int pos_b>
147 SafePtr< HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b> >
150 SafePtr<ThisType> this_ptr(
new ThisType(Tint,dir));
152 if (this_ptr->num_children() != 0) {
153 this_ptr->register_with_rrstack();
156 return SafePtr<ThisType>();
159 template <
class IntType,
class F,
int part,
160 FunctionPosition loc_a,
unsigned int pos_a,
161 FunctionPosition loc_b,
unsigned int pos_b>
163 dir_(dir), target_(Tint), nchildren_(0)
165 using namespace libint2::algebra;
166 using namespace libint2::prefactor;
169 assert(loc_a != loc_b);
172 const typename IntType::AuxQuantaType& aux = Tint->aux();
173 const typename IntType::OperType& oper = Tint->oper();
176 if (loc_a != loc_b && oper.hermitian(part) != +1) {
180 typedef typename IntType::BraType IBraType;
181 typedef typename IntType::KetType IKetType;
182 IBraType* bra =
new IBraType(Tint->bra());
183 IKetType* ket =
new IKetType(Tint->ket());
188 if (loc_a == InKet && loc_b == InBra) {
189 F a(ket->member(part,pos_a));
190 F b(bra->member(part,pos_b));
193 F bm1(b); bm1.dec(dir_);
199 bra->set_member(bm1,part,pos_b);
202 F ap1(a); ap1.inc(dir_);
203 ket->set_member(ap1,part,pos_a);
204 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
205 ket->set_member(a,part,pos_a);
208 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
214 for(
unsigned int xyz=0; xyz<3; ++xyz) {
216 if (a.deriv().d(xyz) > 0) {
218 a_der_m1.deriv().dec(xyz);
219 ket->set_member(a_der_m1,part,pos_a);
220 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
221 ket->set_member(a,part,pos_a);
224 if (bm1.deriv().d(xyz) > 0) {
226 bm1_der_m1.deriv().dec(xyz);
227 bra->set_member(bm1_der_m1,part,pos_b);
228 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
229 bra->set_member(bm1,part,pos_b);
237 expr_ = children_[0] + prefactors.
Y_X[part][dir] * children_[1];
240 const bool aderiv = a.deriv().d(dir_) > 0;
243 a_der_m1.deriv().dec(dir_);
244 ket->set_member(a_der_m1,part,pos_a);
245 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
246 ket->set_member(a,part,pos_a);
250 const bool bderiv = bm1.deriv().d(dir_) > 0;
253 bm1_der_m1.deriv().dec(dir_);
254 bra->set_member(bm1_der_m1,part,pos_b);
255 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
256 bra->set_member(bm1,part,pos_b);
260 expr_ += Vector(a.deriv())[dir_] * children_[2];
262 expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
266 if (loc_a == InBra && loc_b == InKet) {
267 F a(bra->member(part,pos_a));
268 F b(ket->member(part,pos_b));
271 F bm1(b); bm1.dec(dir_);
277 ket->set_member(bm1,part,pos_b);
280 F ap1(a); ap1.inc(dir_);
281 bra->set_member(ap1,part,pos_a);
282 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
283 bra->set_member(a,part,pos_a);
286 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
292 for(
unsigned int xyz=0; xyz<3; ++xyz) {
294 if (a.deriv().d(xyz) > 0) {
296 a_der_m1.deriv().dec(xyz);
297 bra->set_member(a_der_m1,part,pos_a);
298 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
299 bra->set_member(a,part,pos_a);
302 if (bm1.deriv().d(xyz) > 0) {
304 bm1_der_m1.deriv().dec(xyz);
305 ket->set_member(bm1_der_m1,part,pos_b);
306 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
307 ket->set_member(bm1,part,pos_b);
314 expr_ = children_[0] + prefactors.
X_Y[part][dir] * children_[1];
317 const bool aderiv = a.deriv().d(dir_) > 0;
320 a_der_m1.deriv().dec(dir_);
321 bra->set_member(a_der_m1,part,pos_a);
322 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
323 bra->set_member(a,part,pos_a);
327 const bool bderiv = bm1.deriv().d(dir_) > 0;
330 bm1_der_m1.deriv().dec(dir_);
331 ket->set_member(bm1_der_m1,part,pos_b);
332 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
333 ket->set_member(bm1,part,pos_b);
337 expr_ += Vector(a.deriv())[dir_] * children_[2];
339 expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
348 template <
class IntType,
class F,
int part,
349 FunctionPosition loc_a,
unsigned int pos_a,
350 FunctionPosition loc_b,
unsigned int pos_b>
352 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::register_with_rrstack()
const
361 if (TrivialBFSet<F>::result)
363 typedef typename IntType::BraType IBraType;
364 typedef typename IntType::KetType IKetType;
365 const IBraType& bra = target_->bra();
366 const IKetType& ket = target_->ket();
369 bool nonzero_quanta =
false;
370 unsigned const int npart = IntType::OperatorType::Properties::np;
371 for(
unsigned int p=0; p<npart; p++) {
374 int nfbra = bra.num_members(p);
376 for(
int f=0; f<nfbra; f++)
377 if (!bra.member(p,f).zero() || !bra.member(p,f).deriv().zero())
378 nonzero_quanta =
true;
379 int nfket = ket.num_members(p);
381 for(
int f=0; f<nfket; f++)
382 if (!ket.member(p,f).zero() || !ket.member(p,f).deriv().zero())
383 nonzero_quanta =
true;
386 if (!nonzero_quanta) {
388 SafePtr<ThisType> this_ptr =
389 const_pointer_cast<ThisType,const ThisType>(
390 static_pointer_cast<const ThisType, const ParentType>(
391 EnableSafePtrFromThis<ParentType>::SafePtr_from_this()
394 rrstack->find(this_ptr);
403 IBraType bra_zero(bra);
404 IKetType ket_zero(ket);
405 for(
unsigned int p=0; p<npart; p++) {
408 int nfbra = bra_zero.num_members(p);
409 for(
int f=0; f<nfbra; f++) {
410 typedef typename IBraType::bfs_type bfs_type;
411 typedef typename IBraType::bfs_ref bfs_ref;
412 bfs_ref bfs = bra_zero.member(p,f);
413 if (!bfs.zero() || !bfs.deriv().zero()) {
418 int nfket = ket_zero.num_members(p);
419 for(
int f=0; f<nfket; f++) {
420 typedef typename IKetType::bfs_type bfs_type;
421 typedef typename IKetType::bfs_ref bfs_ref;
422 bfs_ref bfs = ket_zero.member(p,f);
423 if (!bfs.zero() || !bfs.deriv().zero()) {
431 typedef GenOper< GenMultSymmOper_Descr<IntType::OperatorType::Properties::np> > DummyOper;
432 typedef typename IBraType::bfs_type bfs_type;
434 typedef GenIntegralSet<DummyOper, IncableBFSet, IBraType, IKetType, DummyQuanta> DummyIntegral;
435 DummyOper dummy_oper;
436 DummyQuanta dummy_quanta(std::vector<int>(0,0));
437 SafePtr<DummyIntegral> dummy_integral = DummyIntegral::Instance(bra_zero,ket_zero,dummy_quanta,dummy_oper);
440 typedef HRR<DummyIntegral,F,part,loc_a,pos_a,loc_b,pos_b> DummyHRR;
441 SafePtr<DummyHRR> dummy_hrr = DummyHRR::Instance(dummy_integral,dir_);
443 rrstack->find(dummy_hrr);
447 template <
class IntType,
class F,
int part,
448 FunctionPosition loc_a,
unsigned int pos_a,
449 FunctionPosition loc_b,
unsigned int pos_b>
450 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::~HRR()
455 template <
class IntType,
class F,
int part,
456 FunctionPosition loc_a,
unsigned int pos_a,
457 FunctionPosition loc_b,
unsigned int pos_b>
459 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::oper_checks()
const
467 typedef typename IntType::OperatorType Oper;
468 if (part < 0 || part >= Oper::Properties::np) {
473 if (loc_a == loc_b && pos_a == pos_b) {
479 template <
class IntType,
class F,
int part,
480 FunctionPosition loc_a,
unsigned int pos_a,
481 FunctionPosition loc_b,
unsigned int pos_b>
482 SafePtr<typename HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::ChildType>
485 assert(i>=0 && i<nchildren_);
488 for(
unsigned int c=0; c<max_nchildren_; c++) {
498 template <
class IntType,
class F,
int part,
499 FunctionPosition loc_a,
unsigned int pos_a,
500 FunctionPosition loc_b,
unsigned int pos_b>
504 std::ostringstream os;
506 os <<
"HRR Part " << part <<
" "
507 << (loc_a == InBra ?
"bra" :
"ket") <<
" " << pos_a <<
" "
508 << (loc_b == InBra ?
"bra" :
"ket") <<
" " << pos_b <<
" ";
510 if (loc_a == InBra) {
511 F sh_a(target_->bra(part,pos_a));
515 os << sh_a.label() <<
" ";
517 if (loc_b == InBra) {
518 F sh_b(target_->bra(part,pos_b));
523 F sh_b(target_->ket(part,pos_b));
529 F sh_a(target_->ket(part,pos_a));
531 os << sh_a.label() <<
" ";
533 if (loc_b == InBra) {
534 F sh_b(target_->bra(part,pos_b));
539 F sh_b(target_->ket(part,pos_b));
548 template <
class IntType,
class F,
int part,
549 FunctionPosition loc_a,
unsigned int pos_a,
550 FunctionPosition loc_b,
unsigned int pos_b>
553 const SafePtr<CodeContext>& context,
const SafePtr<ImplicitDimensions>& dims)
const
555 std::ostringstream os;
556 os << context->label_to_name(
label_to_funcname(context->cparams()->api_prefix() + label()))
560 << context->value_to_pointer(rr_target()->symbol());
562 const unsigned int nchildren = num_children();
563 for(
unsigned int c=0; c<nchildren; c++) {
564 os <<
", " << context->value_to_pointer(rr_child(c)->symbol());
567 unsigned int hsr = 1;
572 for(
int p=0; p<part; p++) {
573 unsigned int nbra = target_->bra().num_members(p);
574 for(
unsigned int i=0; i<nbra; i++) {
575 SubIterator* iter = target_->bra().member_subiter(p,i);
579 unsigned int nket = target_->ket().num_members(p);
580 for(
unsigned int i=0; i<nket; i++) {
581 SubIterator* iter = target_->ket().member_subiter(p,i);
588 taskmgr.
current().params()->max_hrr_hsrank(hsr);
592 if (loc_a == loc_b && pos_a != 0 && pos_b != 0)
593 throw CodeDoesNotExist(
"HRR::spfunction_call -- has not been generalized yet");
596 unsigned int lsr = 1;
597 unsigned int np = IntType::OperType::Properties::np;
598 for(
unsigned int p=part+1; p<np; p++) {
599 unsigned int nbra = target_->bra().num_members(p);
600 for(
unsigned int i=0; i<nbra; i++) {
601 SubIterator* iter = target_->bra().member_subiter(p,i);
605 unsigned int nket = target_->ket().num_members(p);
606 for(
unsigned int i=0; i<nket; i++) {
607 SubIterator* iter = target_->ket().member_subiter(p,i);
613 taskmgr.
current().params()->max_hrr_hsrank(hsr);
619 os <<
")" << context->end_of_stat() << std::endl;
623 template <
class IntType,
class F,
int part,
624 FunctionPosition loc_a,
unsigned int pos_a,
625 FunctionPosition loc_b,
unsigned int pos_b>
635 template <
class IntType,
class F,
int part,
636 FunctionPosition loc_a,
unsigned int pos_a,
637 FunctionPosition loc_b,
unsigned int pos_b>
639 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::expl_low_dim()
const
641 unsigned int np = IntType::OperType::Properties::np;
652 template <
class IntType,
class F,
int part,
653 FunctionPosition loc_a,
unsigned int pos_a,
654 FunctionPosition loc_b,
unsigned int pos_b>
655 SafePtr<ImplicitDimensions>
656 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::adapt_dims_(
const SafePtr<ImplicitDimensions>& dims)
const
658 bool high_rank = expl_high_dim();
659 bool low_rank = expl_low_dim();
661 SafePtr<Entity> high_dim, low_dim;
666 high_dim = dims->high();
672 low_dim = dims->low();
675 SafePtr<ImplicitDimensions> localdims(
new ImplicitDimensions(high_dim,low_dim,dims->vecdim()));
AlgebraicOperator is an algebraic operator that acts on objects of type T.
Definition: algebra.h:50
Set of basis functions.
Definition: bfset.h:42
This exception used to indicate that some code hasn't been developed or generalized yet.
Definition: exception.h:87
A generic Horizontal Recurrence Relation:
Definition: hrr.h:56
bool is_simple() const override
Implementation of RecurrenceRelation::is_simple()
Definition: hrr.h:107
SafePtr< TargetType > target() const
returns pointer to the target
Definition: hrr.h:99
SafePtr< DGVertex > rr_child(unsigned int i) const override
Implementation of RecurrenceRelation::child()
Definition: hrr.h:105
static SafePtr< ThisType > Instance(const SafePtr< TargetType > &, unsigned int dir=0)
Use Instance() to obtain an instance of RR.
Definition: hrr.h:148
unsigned int num_children() const override
Implementation of RecurrenceRelation::num_children()
Definition: hrr.h:97
static bool directional()
is this recurrence relation parameterized by a direction.
Definition: hrr.h:90
RecurrenceRelation::ExprType ExprType
A short alias.
Definition: hrr.h:65
BraketDirection braket_direction() const override
overrides RecurrenceRelation::braket_direction()
Definition: hrr.h:78
SafePtr< ChildType > child(unsigned int i) const
child(i) returns pointer to i-th child
Definition: hrr.h:483
std::string spfunction_call(const SafePtr< CodeContext > &context, const SafePtr< ImplicitDimensions > &dims) const override
Implementation of RecurrenceRelation::spfunction_call()
Definition: hrr.h:552
SafePtr< DGVertex > rr_target() const override
Implementation of RecurrenceRelation::target()
Definition: hrr.h:103
Manages tasks. This is a Singleton.
Definition: task.h:63
void current(const std::string &task_label)
Makes this task current (must have been added already)
Definition: task.cc:76
static LibraryTaskManager & Instance()
LibraryTaskManager is a Singleton.
Definition: task.cc:34
SafePtr< rdouble > Y_X[np][3]
Cartesian components of Y_X vectors.
Definition: prefactors.h:66
SafePtr< rdouble > X_Y[np][3]
Cartesian components of X-Y vectors.
Definition: prefactors.h:58
static SafePtr< RRStackBase< RR > > & Instance()
Obtain the unique Instance of RRStack.
Definition: rr.h:69
RecurrenceRelation describes all recurrence relations.
Definition: rr.h:99
Iterator provides a base class for all object iterator classes.
Definition: iter.h:42
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:92
std::string label_to_funcname(const std::string &label)
Converts a label, e.g. name of the target node, to the name of the function to compute it.
Definition: default_params.cc:216
DefaultQuantumNumbers< int, 0 >::Result EmptySet
EmptySet is the type that describes null set of auxiliary indices.
Definition: quanta.h:404
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition: bfset.h:892