LIBINT  2.1.0-stable
generic_rr.h
1 /*
2  * This file is a part of Libint.
3  * Copyright (C) 2004-2014 Edward F. Valeev
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see http://www.gnu.org/licenses/.
17  *
18  */
19 
20 #ifndef _libint2_src_bin_libint_genericrr_h_
21 #define _libint2_src_bin_libint_genericrr_h_
22 
23 #include <iostream>
24 #include <sstream>
25 #include <string>
26 #include <vector>
27 #include <stdexcept>
28 #include <assert.h>
29 #include <boost/type_traits/is_same.hpp>
30 
31 #include <dgvertex.h>
32 #include <rr.h>
33 #include <integral.h>
34 #include <algebra.h>
35 #include <flop.h>
36 #include <prefactors.h>
37 #include <context.h>
38 #include <default_params.h>
39 #include <util.h>
40 
41 using namespace std;
42 
43 namespace libint2 {
44 
47  template <typename RRImpl, typename F, typename Target>
49  public:
50  typedef F BasisFunctionType;
51  typedef Target TargetType;
54 
56  static SafePtr<RRImpl> Instance(const SafePtr<TargetType>& Tint, unsigned int dir) {
57  // screen out calls with nondefault extra parameters
58  if (!RRImpl::directional() && dir != 0)
59  return SafePtr<RRImpl>();
60  // attempt to construct
61  SafePtr<RRImpl> this_ptr(new RRImpl(Tint,dir));
62  // if succeeded (nchildren > 0) do post-construction
63  if (this_ptr->num_children() != 0) {
64  this_ptr->template register_with_rrstack<RRImpl>();
65  return this_ptr;
66  }
67  // else return null pointer
68  return SafePtr<RRImpl>();
69  }
70 
72  unsigned int num_children() const { return children_.size(); };
74  SafePtr<DGVertex> rr_target() const { return static_pointer_cast<DGVertex,TargetType>(target_); }
76  SafePtr<DGVertex> rr_child(unsigned int i) const {
77  return children_.at(i);
78  }
80  bool is_simple() const {
82  }
83 
85  std::string generate_label() const
86  {
87  ostringstream os;
88  os << RRImpl::descr() << " " << target_->label();
89  return os.str();
90  }
91 
92  protected:
93  GenericRecurrenceRelation(const SafePtr<TargetType>& Tint, unsigned int dir) :
94  target_(Tint), dir_(dir) {
95  children_.reserve(RRImpl::max_nchildren);
96  }
100  static bool default_directional() {
101  if (boost::is_same<BasisFunctionType,CGF>::value)
102  return true;
103  return false;
104  }
105 
106  unsigned int dir() const { return dir_; }
107 
109  const SafePtr<DGVertex>& add_child(const SafePtr<DGVertex>& child) {
110  typedef std::vector< SafePtr<DGVertex> > cvector;
111  typedef typename cvector::const_iterator citer;
112  const citer pos = std::find(children_.begin(),children_.end(),child);
113  if (pos == children_.end()) {
114  children_.push_back(child);
115  return *(children_.rbegin());
116  }
117  else
118  return *pos;
119  }
120 
122  template<class RR, class C> friend class ChildFactory;
125 #if 0
126  template <class RealChildType>
127  const SafePtr<DGVertex>& make_child(const typename RealChildType::BasisFunctionType& A,
128  const typename RealChildType::BasisFunctionType& B,
129  const typename RealChildType::BasisFunctionType& C,
130  const typename RealChildType::BasisFunctionType& D,
131  const typename RealChildType::AuxIndexType& aux = typename RealChildType::AuxIndexType(),
132  const typename RealChildType::OperType& oper = typename RealChildType::OperType()) {
133  const SafePtr<DGVertex>& i = static_pointer_cast<DGVertex,RealChildType>(ChildType::Instance(A,B,C,D,aux,oper));
134  return add_child(i);
135  }
136 #endif
137 
138  SafePtr<TargetType> target_;
139 
140  private:
141  unsigned int dir_;
142  std::vector< SafePtr<DGVertex> > children_;
143 
144  };
145 
147  template <class GenRR, class ChildType>
148  class ChildFactory {
149  public:
150  typedef typename ChildType::BasisFunctionType F;
151  typedef typename ChildType::AuxIndexType AuxIndexType;
152  typedef typename ChildType::OperType OperType;
153 
154  ChildFactory(GenRR* rr) : rr_(rr) {}
155 
157  const SafePtr<DGVertex>& make_child(const F& A,
158  const F& B,
159  const F& C,
160  const F& D,
161  const AuxIndexType& aux = AuxIndexType(),
162  const OperType& oper = OperType()) {
163  auto i = static_pointer_cast<DGVertex,ChildType>(ChildType::Instance(A,B,C,D,aux,oper));
164  return rr_->add_child(i);
165  }
167  const SafePtr<DGVertex>& make_child(const F& A,
168  const F& B,
169  const AuxIndexType& aux = AuxIndexType(),
170  const OperType& oper = OperType()) {
171  auto i = static_pointer_cast<DGVertex,ChildType>(ChildType::Instance(A,B,aux,oper));
172  return rr_->add_child(i);
173  }
175  const SafePtr<DGVertex>&
177  const AuxIndexType& aux = AuxIndexType(),
178  const OperType& oper = OperType()) {
179  auto i = static_pointer_cast<DGVertex,ChildType>(ChildType::Instance(braket_wedge,aux,oper));
180  return rr_->add_child(i);
181  }
183  const SafePtr<DGVertex>&
185  const AuxIndexType& aux = AuxIndexType(),
186  const OperType& oper = OperType()) {
187  auto i = static_pointer_cast<DGVertex,ChildType>(ChildType::Instance(braket_wedge,aux,oper));
188  return rr_->add_child(i);
189  }
191  void wedge(const LinearCombination< SafePtr<DGVertex>, BraketPair<F,PBra> >& bra_lc,
192  const LinearCombination< SafePtr<DGVertex>, BraketPair<F,PKet> >& ket_lc,
193  const AuxIndexType& aux = AuxIndexType(),
194  const OperType& oper = OperType()) {
195  using namespace libint2::algebra;
199  >
200  > ProductLC;
201  const ProductLC& product_lc = bra_lc ^ ket_lc;
202  const size_t nprod = product_lc.size();
203  for(unsigned int t=0; t<nprod; ++t) {
204  const typename ProductLC::term_t& term = product_lc[t];
205  auto child = make_child(term.second,aux,oper);
206  if (rr_->is_simple()) {
207  if (rr_->expr_)
208  rr_->expr_ += term.first * child;
209  else
210  rr_->expr_ = term.first * child;
211  }
212  }
213  }
214  void wedge(const BraketPair<F,PBra>& bra,
215  const LinearCombination< SafePtr<DGVertex>, BraketPair<F,PKet> >& ket_lc,
216  const AuxIndexType& aux = AuxIndexType(),
217  const OperType& oper = OperType()) {
218  using namespace libint2::prefactor;
220  bra_lc += make_pair(Scalar(1.0),bra);
221  wedge(bra_lc,ket_lc,aux,oper);
222  }
223  void wedge(const LinearCombination< SafePtr<DGVertex>, BraketPair<F,PBra> >& bra_lc,
224  const BraketPair<F,PKet>& ket,
225  const AuxIndexType& aux = AuxIndexType(),
226  const OperType& oper = OperType()) {
227  using namespace libint2::prefactor;
229  ket_lc += make_pair(Scalar(1.0),ket);
230  wedge(bra_lc,ket_lc,aux,oper);
231  }
232 
233  private:
234  GenRR* rr_;
235  };
236 
237 };
238 
239 #endif
static bool default_directional()
is this recurrence relation parameterized by a direction (x, y, or z).
Definition: generic_rr.h:100
SafePtr< DGVertex > rr_target() const
Implementation of RecurrenceRelation::rr_target()
Definition: generic_rr.h:74
const SafePtr< DGVertex > & make_child(const F &A, const F &B, const F &C, const F &D, const AuxIndexType &aux=AuxIndexType(), const OperType &oper=OperType())
make_child
Definition: generic_rr.h:157
static SafePtr< RRImpl > Instance(const SafePtr< TargetType > &Tint, unsigned int dir)
Return an instance if applicable, or a null pointer otherwise.
Definition: generic_rr.h:56
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition: bfset.h:879
const SafePtr< DGVertex > & make_child(const algebra::Wedge< BraketPair< F, CBra >, BraketPair< F, CKet > > &braket_wedge, const AuxIndexType &aux=AuxIndexType(), const OperType &oper=OperType())
make a child from a wedge of chemists&#39; brackets
Definition: generic_rr.h:184
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:23
Definition: stdarray.h:18
Wedge is a typeholder for the result of a wedge product.
Definition: algebra.h:245
Definition: prefactors.h:159
This is a vertex of a Directed Graph (DG)
Definition: dgvertex.h:42
void wedge(const LinearCombination< SafePtr< DGVertex >, BraketPair< F, PBra > > &bra_lc, const LinearCombination< SafePtr< DGVertex >, BraketPair< F, PKet > > &ket_lc, const AuxIndexType &aux=AuxIndexType(), const OperType &oper=OperType())
take a wedge product of various (linear combinations of) brakets
Definition: generic_rr.h:191
RRImpl must inherit GenericRecurrenceRelation<RRImpl>
Definition: generic_rr.h:48
represents linear combination of objects of type T with coefficients of type C
Definition: algebra.h:222
AlgebraicOperator is an algebraic operator that acts on objects of type T.
Definition: algebra.h:47
Definition: algebra.h:32
bool is_simple() const
Implementation of RecurrenceRelation::is_simple()
Definition: generic_rr.h:80
std::string generate_label() const
Implementation of RecurrenceRelation::generate_label()
Definition: generic_rr.h:85
unsigned int num_children() const
Implementation of RecurrenceRelation::num_children()
Definition: generic_rr.h:72
const SafePtr< DGVertex > & make_child(const algebra::Wedge< BraketPair< F, PBra >, BraketPair< F, PKet > > &braket_wedge, const AuxIndexType &aux=AuxIndexType(), const OperType &oper=OperType())
make a child from a wedge of physicists&#39; brackets
Definition: generic_rr.h:176
RecurrenceRelation describes all recurrence relations.
Definition: rr.h:100
const SafePtr< DGVertex > & add_child(const SafePtr< DGVertex > &child)
add child
Definition: generic_rr.h:109
BraketPair is a trimmed down version of ArrayBraket specialized for same-particle or different-partic...
Definition: braket.h:416
Helps GenericRecurrenceRelation to work around the compiler problem with make_child.
Definition: generic_rr.h:148
const SafePtr< DGVertex > & make_child(const typename RealChildType::BasisFunctionType &A, const typename RealChildType::BasisFunctionType &B, const typename RealChildType::BasisFunctionType &C, const typename RealChildType::BasisFunctionType &D, const typename RealChildType::AuxIndexType &aux=typename RealChildType::AuxIndexType(), const typename RealChildType::OperType &oper=typename RealChildType::OperType())
make_child should really looks something like this, but gcc 4.3.0 craps out TODO test is this works ...
Definition: generic_rr.h:127
SafePtr< DGVertex > rr_child(unsigned int i) const
Implementation of RecurrenceRelation::rr_child()
Definition: generic_rr.h:76
const SafePtr< DGVertex > & make_child(const F &A, const F &B, const AuxIndexType &aux=AuxIndexType(), const OperType &oper=OperType())
make_child
Definition: generic_rr.h:167