LIBINT  2.6.0
hrr.h
1 /*
2  * Copyright (C) 2004-2019 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 
40 using namespace std;
41 
42 namespace libint2 {
43 
56  template<class IntType, class BFSet, int part, FunctionPosition loc_a,
57  unsigned int pos_a, FunctionPosition loc_b, unsigned int pos_b>
58  class HRR: public RecurrenceRelation {
59 
60  public:
62  typedef BFSet BasisFunctionType;
64  typedef IntType TargetType;
65  typedef IntType ChildType;
68 
76  static SafePtr<ThisType> Instance(const SafePtr<TargetType>&, unsigned int dir = 0);
77  virtual ~HRR();
78 
80  BraketDirection braket_direction() const {
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;
85  else
86  return BraketDirection::None;
87  }
88 
92  static bool directional() {
93  if (boost::is_same<BasisFunctionType,CGShell>::value)
94  return false;
95  return true;
96  }
97 
99  unsigned int num_children() const {return nchildren_;};
101  SafePtr<TargetType> target() const {return target_;};
103  SafePtr<ChildType> child(unsigned int i) const;
105  SafePtr<DGVertex> rr_target() const {return static_pointer_cast<DGVertex,TargetType>(target());}
107  SafePtr<DGVertex> rr_child(unsigned int i) const {return static_pointer_cast<DGVertex,ChildType>(child(i));}
109  bool is_simple() const {
111  }
113  std::string spfunction_call(const SafePtr<CodeContext>& context,
114  const SafePtr<ImplicitDimensions>& dims) const;
115 
116  private:
122  HRR(const SafePtr<TargetType>&, unsigned int dir);
123 
124  unsigned int dir_;
125  SafePtr<TargetType> target_;
126  static const unsigned int max_nchildren_ = 8;
127  SafePtr<ChildType> children_[max_nchildren_];
128  unsigned int nchildren_;
129 
130  void oper_checks() const;
131 
133  std::string generate_label() const;
135  SafePtr<ImplicitDimensions> adapt_dims_(const SafePtr<ImplicitDimensions>& dims) const;
137  bool register_with_rrstack() const;
142  bool expl_high_dim() const;
143  bool expl_low_dim() const;
144  };
145 
146  template <class IntType, class F, int part,
147  FunctionPosition loc_a, unsigned int pos_a,
148  FunctionPosition loc_b, unsigned int pos_b>
149  SafePtr< HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b> >
150  HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::Instance(const SafePtr<TargetType>& Tint, unsigned int dir)
151  {
152  SafePtr<ThisType> this_ptr(new ThisType(Tint,dir));
153  // Do post-construction duties
154  if (this_ptr->num_children() != 0) {
155  this_ptr->register_with_rrstack();
156  return this_ptr;
157  }
158  return SafePtr<ThisType>();
159  }
160 
161  template <class IntType, class F, int part,
162  FunctionPosition loc_a, unsigned int pos_a,
163  FunctionPosition loc_b, unsigned int pos_b>
164  HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::HRR(const SafePtr<TargetType>& Tint, unsigned int dir) :
165  dir_(dir), target_(Tint), nchildren_(0)
166  {
167  using namespace libint2::algebra;
168  using namespace libint2::prefactor;
169 
170  // assume that always transfering from Bra to Ket and vice versa
171  assert(loc_a != loc_b);
172 
173  target_ = Tint;
174  const typename IntType::AuxQuantaType& aux = Tint->aux();
175  const typename IntType::OperType& oper = Tint->oper();
176 
177  // can move across operator only if it's multiplicative
178  if (loc_a != loc_b && oper.hermitian(part) != +1) {
179  return;
180  }
181 
182  typedef typename IntType::BraType IBraType;
183  typedef typename IntType::KetType IKetType;
184  IBraType* bra = new IBraType(Tint->bra());
185  IKetType* ket = new IKetType(Tint->ket());
186 
187  //
188  // InBra and InKet cases have to be treated explicitly since BraType and KetType don't have to match
189  //
190  if (loc_a == InKet && loc_b == InBra) {
191  F a(ket->member(part,pos_a));
192  F b(bra->member(part,pos_b));
193 
194  // See if b-1 exists
195  F bm1(b); bm1.dec(dir_);
196  if (!exists(bm1)) {
197  delete bra;
198  delete ket;
199  return;
200  }
201  bra->set_member(bm1,part,pos_b); // set b permanently to b-1_i
202 
203  {
204  F ap1(a); ap1.inc(dir_);
205  ket->set_member(ap1,part,pos_a);
206  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
207  ket->set_member(a,part,pos_a);
208  }
209 
210  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
211 
212  if (!is_simple()) { // treatment of derivative terms differs for shell sets and integrals
213  // since in computing shell sets transfer/build will occur in all 3 directions
214  // change in up to all three derivative indices will occur
215 
216  for(unsigned int xyz=0; xyz<3; ++xyz) {
217  // is a differentiated in this direction? add another term
218  if (a.deriv().d(xyz) > 0) {
219  F a_der_m1(a);
220  a_der_m1.deriv().dec(xyz);
221  ket->set_member(a_der_m1,part,pos_a);
222  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
223  ket->set_member(a,part,pos_a);
224  }
225  // is b differentiated in this direction? add another term
226  if (bm1.deriv().d(xyz) > 0) {
227  F bm1_der_m1(bm1);
228  bm1_der_m1.deriv().dec(xyz);
229  bra->set_member(bm1_der_m1,part,pos_b);
230  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
231  bra->set_member(bm1,part,pos_b);
232  }
233  }
234  }
235 
236  if (is_simple()) {
237  // ( 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 )
238  // the latter is amenable to generate fmadd instruction
239  expr_ = children_[0] + prefactors.Y_X[part][dir] * children_[1];
240 
241  // is a differentiated in this direction? add another term
242  const bool aderiv = a.deriv().d(dir_) > 0;
243  if (aderiv) {
244  F a_der_m1(a);
245  a_der_m1.deriv().dec(dir_);
246  ket->set_member(a_der_m1,part,pos_a);
247  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
248  ket->set_member(a,part,pos_a);
249  }
250 
251  // is b differentiated in this direction? add another term
252  const bool bderiv = bm1.deriv().d(dir_) > 0;
253  if (bderiv) {
254  F bm1_der_m1(bm1);
255  bm1_der_m1.deriv().dec(dir_);
256  bra->set_member(bm1_der_m1,part,pos_b);
257  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
258  bra->set_member(bm1,part,pos_b);
259  }
260 
261  if (aderiv)
262  expr_ += Vector(a.deriv())[dir_] * children_[2];
263  if (bderiv)
264  expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
265  }
266  } // a in ket, b in bra
267 
268  if (loc_a == InBra && loc_b == InKet) {
269  F a(bra->member(part,pos_a));
270  F b(ket->member(part,pos_b));
271 
272  // See if b-1 exists
273  F bm1(b); bm1.dec(dir_);
274  if (!exists(bm1)) {
275  delete bra;
276  delete ket;
277  return;
278  }
279  ket->set_member(bm1,part,pos_b); // set b permanently to b-1_i
280 
281  {
282  F ap1(a); ap1.inc(dir_);
283  bra->set_member(ap1,part,pos_a);
284  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
285  bra->set_member(a,part,pos_a);
286  }
287 
288  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
289 
290  if (!is_simple()) { // treatment of derivative terms differs for shell sets and integrals
291  // since in computing shell sets transfer/build will occur in all 3 directions
292  // change in up to all three derivative indices will occur
293 
294  for(unsigned int xyz=0; xyz<3; ++xyz) {
295  // is a differentiated in this direction? add another term
296  if (a.deriv().d(xyz) > 0) {
297  F a_der_m1(a);
298  a_der_m1.deriv().dec(xyz);
299  bra->set_member(a_der_m1,part,pos_a);
300  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
301  bra->set_member(a,part,pos_a);
302  }
303  // is b differentiated in this direction? add another term
304  if (bm1.deriv().d(xyz) > 0) {
305  F bm1_der_m1(bm1);
306  bm1_der_m1.deriv().dec(xyz);
307  ket->set_member(bm1_der_m1,part,pos_b);
308  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
309  ket->set_member(bm1,part,pos_b);
310  }
311  }
312  }
313 
314  if (is_simple()) {
315  // ( a | b) = ( a+1_i | b-1_i ) + AB_i ( a | b-1_i )
316  expr_ = children_[0] + prefactors.X_Y[part][dir] * children_[1];
317 
318  // is a differentiated in this direction? add another term
319  const bool aderiv = a.deriv().d(dir_) > 0;
320  if (aderiv) {
321  F a_der_m1(a);
322  a_der_m1.deriv().dec(dir_);
323  bra->set_member(a_der_m1,part,pos_a);
324  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
325  bra->set_member(a,part,pos_a);
326  }
327 
328  // is b differentiated in this direction? add another term
329  const bool bderiv = bm1.deriv().d(dir_) > 0;
330  if (bderiv) {
331  F bm1_der_m1(bm1);
332  bm1_der_m1.deriv().dec(dir_);
333  ket->set_member(bm1_der_m1,part,pos_b);
334  children_[nchildren_++] = IntType::Instance(*bra,*ket,aux,oper);
335  ket->set_member(bm1,part,pos_b);
336  }
337 
338  if (aderiv)
339  expr_ += Vector(a.deriv())[dir_] * children_[2];
340  if (bderiv)
341  expr_ -= Vector(b.deriv())[dir_] * children_[aderiv ? 3 : 2];
342  }
343 
344  } // a in bra, b in ket
345 
346  delete bra;
347  delete ket;
348  }
349 
350  template <class IntType, class F, int part,
351  FunctionPosition loc_a, unsigned int pos_a,
352  FunctionPosition loc_b, unsigned int pos_b>
353  bool
354  HRR<IntType,F,part,loc_a,pos_a,loc_b,pos_b>::register_with_rrstack() const
355  {
356  // This is an ugly hack -- add HRR's to the RRStack preemptively for targets in which all functions not involved
357  // in transfer have zero quanta. The reason is that for the HRR quartet level code to work correctly
358  // I must use these particular instances of HRR to generate the source.
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  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  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() << 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
BraketDirection braket_direction() const
overrides RecurrenceRelation::braket_direction()
Definition: hrr.h:80
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
Manages tasks. This is a Singleton.
Definition: task.h:63
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition: bfset.h:892
SafePtr< rdouble > Y_X[np][3]
Cartesian components of Y_X vectors.
Definition: prefactors.h:66
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
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
Implementation of RecurrenceRelation::spfunction_call()
Definition: hrr.h:552
void current(const std::string &task_label)
Makes this task current (must have been added already)
Definition: task.cc:76
RecurrenceRelation::ExprType ExprType
A short alias.
Definition: hrr.h:67
bool is_simple() const
Implementation of RecurrenceRelation::is_simple()
Definition: hrr.h:109
AlgebraicOperator is an algebraic operator that acts on objects of type T.
Definition: algebra.h:48
const std::string & label() const
label() returns a unique, short, descriptive label of this RR (e.g.
Definition: rr.cc:292
bool exists(const IncableBFSet &A)
Return true if A is valid.
Definition: bfset.h:92
SafePtr< DGVertex > rr_target() const
Implementation of RecurrenceRelation::target()
Definition: hrr.h:105
Iterator provides a base class for all object iterator classes.
Definition: iter.h:45
virtual unsigned int num_iter() const =0
Returns a number of iterations (number of elements in a set over which to iterate).
unsigned int num_children() const
Implementation of RecurrenceRelation::num_children()
Definition: hrr.h:99
RecurrenceRelation describes all recurrence relations.
Definition: rr.h:101
SafePtr< DGVertex > rr_child(unsigned int i) const
Implementation of RecurrenceRelation::child()
Definition: hrr.h:107
Set of basis functions.
Definition: bfset.h:42
static LibraryTaskManager & Instance()
LibraryTaskManager is a Singleton.
Definition: task.cc:34
Definition: rr.h:252
static bool directional()
is this recurrence relation parameterized by a direction.
Definition: hrr.h:92
A generic Horizontal Recurrence Relation:
Definition: hrr.h:58
SafePtr< TargetType > target() const
returns pointer to the target
Definition: hrr.h:101
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:71
DefaultQuantumNumbers< int, 0 >::Result EmptySet
EmptySet is the type that describes null set of auxiliary indices.
Definition: quanta.h:407
This exception used to indicate that some code hasn't been developed or generalized yet.
Definition: exception.h:87