LIBINT 2.7.2
hrr.h
1/*
2 * Copyright (C) 2004-2021 Edward F. Valeev
3 *
4 * This file is part of Libint.
5 *
6 * Libint is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Libint is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Libint. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef _libint2_src_bin_libint_hrr_h_
22#define _libint2_src_bin_libint_hrr_h_
23
24#include <iostream>
25#include <sstream>
26#include <string>
27#include <vector>
28#include <stdexcept>
29#include <cassert>
30#include <rr.h>
31#include <integral.h>
32#include <algebra.h>
33#include <dgvertex.h>
34#include <prefactors.h>
35#include <default_params.h>
36#include <dims.h>
37#include <task.h>
38#include <context.h>
39
40namespace libint2 {
41
54 template<class IntType, class BFSet, int part, FunctionPosition loc_a,
55 unsigned int pos_a, FunctionPosition loc_b, unsigned int pos_b>
56 class HRR: public RecurrenceRelation {
57
58 public:
62 typedef IntType TargetType;
63 typedef IntType ChildType;
66
74 static SafePtr<ThisType> Instance(const SafePtr<TargetType>&, unsigned int dir = 0);
75 virtual ~HRR();
76
78 BraketDirection braket_direction() const override {
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;
83 else
84 return BraketDirection::None;
85 }
86
90 static bool directional() {
91 if (boost::is_same<BasisFunctionType,CGShell>::value)
92 return false;
93 return true;
94 }
95
97 unsigned int num_children() const override {return nchildren_;}
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));}
107 bool is_simple() const override {
109 }
111 std::string spfunction_call(const SafePtr<CodeContext>& context,
112 const SafePtr<ImplicitDimensions>& dims) const override;
113
114 private:
120 HRR(const SafePtr<TargetType>&, unsigned int dir);
121
122 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_;
127
128 void oper_checks() const;
129
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;
142 };
143
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> >
148 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::Instance(const SafePtr<TargetType>& Tint, unsigned int dir)
149 {
150 SafePtr<ThisType> this_ptr(new ThisType(Tint,dir));
151 // Do post-construction duties
152 if (this_ptr->num_children() != 0) {
153 this_ptr->register_with_rrstack();
154 return this_ptr;
155 }
156 return SafePtr<ThisType>();
157 }
158
159 template <class IntType, class F, int part,
160 FunctionPosition loc_a, unsigned int pos_a,
161 FunctionPosition loc_b, unsigned int pos_b>
162 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::HRR(const SafePtr<TargetType>& Tint, unsigned int dir) :
163 dir_(dir), target_(Tint), nchildren_(0)
164 {
165 using namespace libint2::algebra;
166 using namespace libint2::prefactor;
167
168 // assume that always transfering from Bra to Ket and vice versa
169 assert(loc_a != loc_b);
170
171 target_ = Tint;
172 const typename IntType::AuxQuantaType& aux = Tint->aux();
173 const typename IntType::OperType& oper = Tint->oper();
174
175 // can move across operator only if it's multiplicative
176 if (loc_a != loc_b && oper.hermitian(part) != +1) {
177 return;
178 }
179
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());
184
185 //
186 // InBra and InKet cases have to be treated explicitly since BraType and KetType don't have to match
187 //
188 if (loc_a == InKet && loc_b == InBra) {
189 F a(ket->member(part,pos_a));
190 F b(bra->member(part,pos_b));
191
192 // See if b-1 exists
193 F bm1(b); bm1.dec(dir_);
194 if (!exists(bm1)) {
195 delete bra;
196 delete ket;
197 return;
198 }
199 bra->set_member(bm1,part,pos_b); // set b permanently to b-1_i
200
201 {
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);
206 }
207
208 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
209
210 if (!is_simple()) { // treatment of derivative terms differs for shell sets and integrals
211 // since in computing shell sets transfer/build will occur in all 3 directions
212 // change in up to all three derivative indices will occur
213
214 for(unsigned int xyz=0; xyz<3; ++xyz) {
215 // is a differentiated in this direction? add another term
216 if (a.deriv().d(xyz) > 0) {
217 F a_der_m1(a);
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);
222 }
223 // is b differentiated in this direction? add another term
224 if (bm1.deriv().d(xyz) > 0) {
225 F bm1_der_m1(bm1);
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);
230 }
231 }
232 }
233
234 if (is_simple()) {
235 // ( b | a ) = ( b-1_i | a+1_i ) - AB_i ( b-1_i | a ) = ( b-1_i | a+1_i ) + BA_i ( b-1_i | a )
236 // the latter is amenable to generate fmadd instruction
237 expr_ = children_[0] + prefactors.Y_X[part][dir] * children_[1];
238
239 // is a differentiated in this direction? add another term
240 const bool aderiv = a.deriv().d(dir_) > 0;
241 if (aderiv) {
242 F a_der_m1(a);
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);
247 }
248
249 // is b differentiated in this direction? add another term
250 const bool bderiv = bm1.deriv().d(dir_) > 0;
251 if (bderiv) {
252 F bm1_der_m1(bm1);
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);
257 }
258
259 if (aderiv)
260 expr_ += Vector(a.deriv())[dir_] * children_[2];
261 if (bderiv)
262 expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
263 }
264 } // a in ket, b in bra
265
266 if (loc_a == InBra && loc_b == InKet) {
267 F a(bra->member(part,pos_a));
268 F b(ket->member(part,pos_b));
269
270 // See if b-1 exists
271 F bm1(b); bm1.dec(dir_);
272 if (!exists(bm1)) {
273 delete bra;
274 delete ket;
275 return;
276 }
277 ket->set_member(bm1,part,pos_b); // set b permanently to b-1_i
278
279 {
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);
284 }
285
286 children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
287
288 if (!is_simple()) { // treatment of derivative terms differs for shell sets and integrals
289 // since in computing shell sets transfer/build will occur in all 3 directions
290 // change in up to all three derivative indices will occur
291
292 for(unsigned int xyz=0; xyz<3; ++xyz) {
293 // is a differentiated in this direction? add another term
294 if (a.deriv().d(xyz) > 0) {
295 F a_der_m1(a);
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);
300 }
301 // is b differentiated in this direction? add another term
302 if (bm1.deriv().d(xyz) > 0) {
303 F bm1_der_m1(bm1);
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);
308 }
309 }
310 }
311
312 if (is_simple()) {
313 // ( a | b) = ( a+1_i | b-1_i ) + AB_i ( a | b-1_i )
314 expr_ = children_[0] + prefactors.X_Y[part][dir] * children_[1];
315
316 // is a differentiated in this direction? add another term
317 const bool aderiv = a.deriv().d(dir_) > 0;
318 if (aderiv) {
319 F a_der_m1(a);
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);
324 }
325
326 // is b differentiated in this direction? add another term
327 const bool bderiv = bm1.deriv().d(dir_) > 0;
328 if (bderiv) {
329 F bm1_der_m1(bm1);
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);
334 }
335
336 if (aderiv)
337 expr_ += Vector(a.deriv())[dir_] * children_[2];
338 if (bderiv)
339 expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
340 }
341
342 } // a in bra, b in ket
343
344 delete bra;
345 delete ket;
346 }
347
348 template <class IntType, class F, int part,
349 FunctionPosition loc_a, unsigned int pos_a,
350 FunctionPosition loc_b, unsigned int pos_b>
351 bool
352 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::register_with_rrstack() const
353 {
354 // This is an ugly hack -- add HRR's to the RRStack preemptively for targets in which all functions not involved
355 // in transfer have zero quanta. The reason is that for the HRR quartet level code to work correctly
356 // I must use these particular instances of HRR to generate the source.
357
358 using std::swap;
359
360 // only register RRs with for shell sets
361 if (TrivialBFSet<F>::result)
362 return false;
363 typedef typename IntType::BraType IBraType;
364 typedef typename IntType::KetType IKetType;
365 const IBraType& bra = target_->bra();
366 const IKetType& ket = target_->ket();
367
368 //check for nonzero quanta for all particles other than part
369 bool nonzero_quanta = false;
370 unsigned const int npart = IntType::OperatorType::Properties::np;
371 for(unsigned int p=0; p<npart; p++) {
372 if (p == part)
373 continue;
374 int nfbra = bra.num_members(p);
375 assert(nfbra == 1);
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);
380 assert(nfket == 1);
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;
384 }
385 // if all bfsets not involved in transfer have zero quanta then this instance needs to be added to the stack
386 if (!nonzero_quanta) {
387 SafePtr<RRStack> rrstack = RRStack::Instance();
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()
392 )
393 );
394 rrstack->find(this_ptr);
395 return true;
396 }
397
398 //
399 // else create the needed instance of HRR
400 //
401
402 // zero out unneeded bfs'
403 IBraType bra_zero(bra);
404 IKetType ket_zero(ket);
405 for(unsigned int p=0; p<npart; p++) {
406 if (p == part)
407 continue;
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()) {
414 bfs_type null_bfs;
415 swap(bfs,null_bfs);
416 }
417 }
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()) {
424 bfs_type null_bfs;
425 swap(bfs,null_bfs);
426 }
427 }
428 }
429
430 // create a generic GenIntegralSet over a multiplicative operator
431 typedef GenOper< GenMultSymmOper_Descr<IntType::OperatorType::Properties::np> > DummyOper;
432 typedef typename IBraType::bfs_type bfs_type;
433 typedef EmptySet DummyQuanta;
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);
438
439 // Construct generic HRR and add it to the stack instead of this HRR
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_);
442 SafePtr<RRStack> rrstack = RRStack::Instance();
443 rrstack->find(dummy_hrr);
444 return true;
445 }
446
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()
451 {
452 oper_checks();
453 }
454
455 template <class IntType, class F, int part,
456 FunctionPosition loc_a, unsigned int pos_a,
457 FunctionPosition loc_b, unsigned int pos_b>
458 void
459 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::oper_checks() const
460 {
461 //
462 // Here we check basic HRR applicability requirements on the integral class
463 //
464
465#if CHECK_SAFETY
466 // part is within the range
467 typedef typename IntType::OperatorType Oper;
468 if (part < 0 || part >= Oper::Properties::np) {
469 assert(false);
470 }
471
472 // Cannot apply when a and b are the same
473 if (loc_a == loc_b && pos_a == pos_b) {
474 assert(false);
475 }
476#endif
477 }
478
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>
484 {
485 assert(i>=0 && i<nchildren_);
486
487 unsigned int nc=0;
488 for(unsigned int c=0; c<max_nchildren_; c++) {
489 if (children_[c]) {
490 if (nc == i)
491 return children_[c];
492 nc++;
493 }
494 }
495 abort(); // unreachable
496 }
497
498 template <class IntType, class F, int part,
499 FunctionPosition loc_a, unsigned int pos_a,
500 FunctionPosition loc_b, unsigned int pos_b>
501 std::string
503 {
504 std::ostringstream os;
505
506 os << "HRR Part " << part << " "
507 << (loc_a == InBra ? "bra" : "ket") << " " << pos_a << " "
508 << (loc_b == InBra ? "bra" : "ket") << " " << pos_b << " ";
509
510 if (loc_a == InBra) {
511 F sh_a(target_->bra(part,pos_a));
512 // HRR works for contracted and uncontracted non-differentiated functions
513 // thus only need to create the uncontracted instances
514 sh_a.uncontract();
515 os << sh_a.label() << " ";
516
517 if (loc_b == InBra) {
518 F sh_b(target_->bra(part,pos_b));
519 sh_b.uncontract();
520 os << sh_b.label();
521 }
522 else {
523 F sh_b(target_->ket(part,pos_b));
524 sh_b.uncontract();
525 os << sh_b.label();
526 }
527 }
528 else {
529 F sh_a(target_->ket(part,pos_a));
530 sh_a.uncontract();
531 os << sh_a.label() << " ";
532
533 if (loc_b == InBra) {
534 F sh_b(target_->bra(part,pos_b));
535 sh_b.uncontract();
536 os << sh_b.label();
537 }
538 else {
539 F sh_b(target_->ket(part,pos_b));
540 sh_b.uncontract();
541 os << sh_b.label();
542 }
543 }
544
545 return os.str();
546 }
547
548 template <class IntType, class F, int part,
549 FunctionPosition loc_a, unsigned int pos_a,
550 FunctionPosition loc_b, unsigned int pos_b>
551 std::string
553 const SafePtr<CodeContext>& context, const SafePtr<ImplicitDimensions>& dims) const
554 {
555 std::ostringstream os;
556 os << context->label_to_name(label_to_funcname(context->cparams()->api_prefix() + label()))
557 // First argument is the library object
558 << "(inteval, "
559 // Second is the target
560 << context->value_to_pointer(rr_target()->symbol());
561 // then come children
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());
565 }
566 // then dimensions of basis function sets not involved in the transfer
567 unsigned int hsr = 1;
568 // a cleaner way to count the number of function sets referring
569 // to some particles is to construct a dummy integral and
570 // use subiterator policy
571 // WARNING !!!
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);
576 hsr *= iter->num_iter();
577 delete iter;
578 }
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);
582 hsr *= iter->num_iter();
583 delete iter;
584 }
585 }
586 // Use TaskParameters to keep track of maximum hsr
588 taskmgr.current().params()->max_hrr_hsrank(hsr);
589
590 // can only do a simple bra->ket or ket->bra transfer so far
591 //unsigned int isr = 1;
592 if (loc_a == loc_b && pos_a != 0 && pos_b != 0)
593 throw CodeDoesNotExist("HRR::spfunction_call -- has not been generalized yet");
594
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);
602 lsr *= iter->num_iter();
603 delete iter;
604 }
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);
608 lsr *= iter->num_iter();
609 delete iter;
610 }
611 }
612 // Use TaskParameters to keep track of maximum hsr
613 taskmgr.current().params()->max_hrr_hsrank(hsr);
614
615 if (expl_high_dim())
616 os << "," << hsr;
617 if (expl_low_dim())
618 os << "," << lsr;
619 os << ")" << context->end_of_stat() << std::endl;
620 return os.str();
621 }
622
623 template <class IntType, class F, int part,
624 FunctionPosition loc_a, unsigned int pos_a,
625 FunctionPosition loc_b, unsigned int pos_b>
626 bool
628 {
629 bool high = true;
630 if (part == 0)
631 high = false;
632 return high;
633 }
634
635 template <class IntType, class F, int part,
636 FunctionPosition loc_a, unsigned int pos_a,
637 FunctionPosition loc_b, unsigned int pos_b>
638 bool
639 HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::expl_low_dim() const
640 {
641 unsigned int np = IntType::OperType::Properties::np;
642 bool low = true;
643 if (part == np - 1)
644 low = false;
645 // corner case: # of particles == 1
646 if (np == 1) { // to match the interface of np != 1 need to add insert dummy argument
647 low = true;
648 }
649 return low;
650 }
651
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
657 {
658 bool high_rank = expl_high_dim();
659 bool low_rank = expl_low_dim();
660
661 SafePtr<Entity> high_dim, low_dim;
662 if (high_rank) {
663 high_dim = SafePtr<Entity>(new RTimeEntity<EntityTypes::Int>("highdim"));
664 }
665 else {
666 high_dim = dims->high();
667 }
668 if (low_rank) {
669 low_dim = SafePtr<Entity>(new RTimeEntity<EntityTypes::Int>("lowdim"));
670 }
671 else {
672 low_dim = dims->low();
673 }
674
675 SafePtr<ImplicitDimensions> localdims(new ImplicitDimensions(high_dim,low_dim,dims->vecdim()));
676 return localdims;
677 }
678
679 };
680
681#endif
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).
Definition: rr.h:250
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