LIBINT  2.1.0-stable
oper.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_oper_h_
21 #define _libint2_src_bin_libint_oper_h_
22 
23 #include <string>
24 
25 #include <boost/preprocessor/list/for_each.hpp>
26 
27 #include <hashable.h>
28 #include <global_macros.h>
29 #include <util.h>
30 #include <iter.h>
31 #include <vectorn.h>
32 #include <contractable.h>
33 
34 namespace libint2 {
35 
38  typedef struct {
39  typedef enum {anti=-1, symm=1, nonsymm=0, nonstd=-2} type;
41 
47  template <unsigned int NP, bool multi, PermutationalSymmetry::type psymmetry>
49  public:
50  static const unsigned int np = NP;
51  static const bool multiplicative = multi;
52  static const PermutationalSymmetry::type psymm = psymmetry;
53  };
54 
60  public:
61  typedef DummyIterator iter_type;
62  virtual ~OperSet() {};
63 
65  virtual std::string description() const =0;
67  virtual std::string label() const =0;
70  virtual int psymm(int i, int j) const =0;
73  virtual int hermitian(int p) const =0;
74 
76  virtual unsigned int num_oper() const =0;
77  };
78 
81  template <class Props>
82  class Oper : public OperSet {
83  public:
84  typedef Props Properties;
85  virtual ~Oper() {}
86 
88  int psymm(int i, int j) const;
90  int hermitian(int p) const;
91 
92  bool operator==(const Oper&) const;
93 
94  protected:
96  Oper() {}
97 
98  private:
100  virtual int nonstd_psymm(int i, int j) const { throw ProgrammingError("nonstd_psymm is not overloaded"); }
102  virtual int nonstd_hermitian(int p) const { throw ProgrammingError("nonstd_hermitian is not overloaded"); }
103  };
104 
105  template <class Props>
106  int
107  Oper<Props>::psymm(int i, int j) const
108  {
109  if (i<0 || i>=static_cast<int>(Props::np))
110  throw std::runtime_error("Oper<Props>::psymm(i,j) -- index i out of bounds");
111  if (j<0 || j>=static_cast<int>(Props::np))
112  throw std::runtime_error("Oper<Props>::psymm(i,j) -- index j out of bounds");
113  if (i == j)
114  return 1;
115 
116  switch(Props::psymm) {
117  case PermutationalSymmetry::anti:
118  return -1;
119  case PermutationalSymmetry::symm:
120  return 1;
121  case PermutationalSymmetry::nonsymm:
122  return 0;
123  case PermutationalSymmetry::nonstd:
124  return nonstd_psymm(i,j);
125  default:
126  abort();
127  }
128  }
129 
130  template <class Props>
131  int
133  {
134  if (Props::multiplicative)
135  return +1;
136  else
137  return nonstd_hermitian(p);
138  }
139 
140  template <class Props>
141  bool
142  Oper<Props>::operator==(const Oper& a) const
143  {
144  return true;
145  }
146 
148 
151  template <class Descr>
152  class GenOper : public Oper<typename Descr::Properties>, public Hashable<unsigned,ComputeKey> {
153  public:
154  typedef Descr Descriptor;
155  typedef typename Descr::Properties Properties;
159 
160  unsigned int num_oper() const { return 1; };
162  unsigned int key() const { return descr_.key(); }
164  static const unsigned int max_key = Descr::max_key;
166  std::string description() const { return descr_.description(); }
168  std::string label() const { return descr_.label(); }
170  Descr& descr() { return descr_; }
172  const Descr& descr() const { return descr_; }
173 
174  GenOper(Descr descr = Descr()) : descr_(descr) {}
175  GenOper(const SafePtr<GenOper>& o) : descr_(o->descr_) {}
176  GenOper(const SafePtr<OperSet>& o) : descr_(require_dynamic_cast<GenOper,OperSet>(o)->descr_) {}
177  GenOper(const SafePtr<ConstructablePolymorphically>& o) : descr_(require_dynamic_cast<GenOper,ConstructablePolymorphically>(o)->descr_) {}
178  explicit GenOper(const ConstructablePolymorphically& o) : descr_(require_dynamic_cast<GenOper,ConstructablePolymorphically>(&o)->descr_) {}
179  virtual ~GenOper() {}
180 
181  private:
182  Descr descr_;
183 
185  int nonstd_psymm(int i, int j) const {
186  // TODO: figure out how to call this only if Desc::Properties::psymm == PermutationalSymmetry::nonstd
187  if (Descr::Properties::psymm == PermutationalSymmetry::nonstd)
188  return descr_.psymm(i,j);
189  else throw ProgrammingError("GenOper::nonstd_psymm -- descriptor is not nonstd");
190  }
191 
193  int nonstd_hermitian(int i) const {
194  // TODO: figure out how to call this only if Desc::Properties::psymm == PermutationalSymmetry::nonstd
195  if (!Descr::Properties::multiplicative)
196  return descr_.hermitian(i);
197  else throw ProgrammingError("GenOper::nonstd_hermitian -- this operator is multiplicative");
198  }
199 
200  };
201 
203 
210 
213  template <unsigned int N>
214  struct GenMultSymmOper_Descr : public Contractable<GenMultSymmOper_Descr<N> > {
216  static const unsigned int max_key = 1;
217  unsigned int key() const { return 0; }
218  std::string description() const { return "generic multiplicative symmetric operator"; }
219  std::string label() const { return "GenMultSymmOper"; }
220  int psymm(int i, int j) const { assert(false); }
221  int hermitian(int i) const { assert(false); }
222  };
224 
225 #define BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR(r,mult,prefix) \
226  struct prefix ## _Descr : public Contractable<prefix ## _Descr> { \
227  typedef mult ## 1Body_Props Properties; \
228  static const unsigned int max_key = 1; \
229  unsigned int key() const { return 0; } \
230  std::string description() const { return #prefix; } \
231  std::string label() const { return #prefix; } \
232  int psymm(int i, int j) const { assert(false); } \
233  int hermitian(int i) const { return +1; } \
234  }; \
235  typedef GenOper<prefix ## _Descr> prefix ## Oper; \
236 
237 #define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (Kinetic, BOOST_PP_NIL)
238 BOOST_PP_LIST_FOR_EACH ( BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR, Nonmultiplicative, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
239 #undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST
240 #define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (Overlap, (ElecPot, BOOST_PP_NIL))
241 BOOST_PP_LIST_FOR_EACH ( BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR, Multiplicative, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
242 #undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST
243 
246 template <unsigned int NDIM>
247 struct CartesianMultipole_Descr : public Contractable<CartesianMultipole_Descr<NDIM>>,
248  public OriginDerivative<NDIM> {
249  typedef Multiplicative1Body_Props Properties;
251 
253  CartesianMultipole_Descr(unsigned int k) { assert(NDIM==1u); this->inc(0,k); }
254  std::string description() const {
255  std::string descr("CartesianMultipole[");
256  std::ostringstream oss;
257  for(unsigned i=0; i!=NDIM; ++i) {
258  oss << this->d(i);
259  if (i+1 != NDIM) oss << ",";
260  }
261  return descr + oss.str() + "]";
262  }
263  std::string label() const { return description(); }
264  int psymm(int i, int j) const { assert(false); }
265  int hermitian(int i) const { return +1; }
266 };
267 template <unsigned int NDIM> using CartesianMultipoleOper = GenOper<CartesianMultipole_Descr<NDIM>>;
268 
271  struct TwoPRep_Descr : public Contractable<TwoPRep_Descr> {
272  typedef MultiplicativeSymm2Body_Props Properties;
273  static const unsigned int max_key = 1;
274  unsigned int key() const { return 0; }
275  std::string description() const { return "1/r_{12}"; }
276  std::string label() const { return "TwoPRep"; }
277  int psymm(int i, int j) const { assert(false); }
278  int hermitian(int i) const { return +1; }
279  };
281 
284  struct GTG_1d_Descr : public Contractable<GTG_1d_Descr> {
285  typedef MultiplicativeSymm2Body_Props Properties;
286  static const unsigned int max_key = 1;
287  unsigned int key() const { return 0; }
288  std::string description() const { return "GTG_1d"; }
289  std::string label() const { return "GTG_1d"; }
290  int psymm(int i, int j) const { assert(false); }
291  int hermitian(int i) const { return +1; }
292  };
294 
298  class R12_k_G12_Descr : public Contractable<R12_k_G12_Descr> {
299  public:
300  typedef MultiplicativeSymm2Body_Props Properties;
302  R12_k_G12_Descr(int K) : K_(K) { assert(K >= -1 && K <= 4); }
304  static const unsigned int max_key = 5;
305  unsigned int key() const { return K_ + 1; }
306  std::string description() const { return label_(K_, this->contracted()); }
307  std::string label() const { return symbol_(K_, this->contracted()); }
308  int K() const { return K_; }
309  int psymm(int i, int j) const { assert(false); }
310  int hermitian(int i) const { assert(false); }
311  private:
312  R12_k_G12_Descr();
313  static std::string label_(int K, bool contracted);
314  static std::string symbol_(int K, bool contracted);
315  int K_;
316  };
318 
322  class R12k_R12l_G12_Descr : public Contractable<R12k_R12l_G12_Descr> {
323  public:
324  typedef MultiplicativeSymm2Body_Props Properties;
325  static const int kmax = 4;
326  R12k_R12l_G12_Descr(const IntVec3& K, const IntVec3& L) : K_(K), L_(L) { }
328  const IntVec3& K() const { return K_; }
329  const IntVec3& L() const { return L_; }
330  static const unsigned int max_key = kmax * kmax * kmax * kmax * kmax * kmax;
331  unsigned int key() const;
332  std::string description() const { return label_(K_,L_, this->contracted()); }
333  std::string label() const { return symbol_(K_,L_, this->contracted()); }
334  int psymm(int i, int j) const { assert(false); }
335  int hermitian(int i) const { assert(false); }
336  private:
338  static std::string label_(const IntVec3& K, const IntVec3& L, bool contracted);
339  static std::string symbol_(const IntVec3& K, const IntVec3& L, bool contracted);
340  IntVec3 K_;
341  IntVec3 L_;
342  };
344 
348  class Ti_G12_Descr : public Contractable<Ti_G12_Descr> {
349  public:
350  typedef NonmultiplicativeNonsymm2Body_Props Properties;
352  static const unsigned int max_key = 2;
353  Ti_G12_Descr(int K) : K_(K) { assert(K >= 0 && K <= 1); }
354  Ti_G12_Descr(const Ti_G12_Descr& a) : Contractable<Ti_G12_Descr>(a), K_(a.K_) {}
355  unsigned int key() const { return K_; }
356  std::string description() const { return label_(K_, this->contracted()); }
357  std::string label() const { return symbol_(K_, this->contracted()); }
358  int K() const { return K_; }
359  int psymm(int i, int j) const { assert(false); }
360  int hermitian(int i) const { if (i != K_) return +1; else return -1; }
361  private:
362  Ti_G12_Descr();
363  static std::string label_(int K, bool contracted);
364  static std::string symbol_(int K, bool contracted);
365  int K_;
366  };
368 
373  class G12_Ti_G12_Descr : public Contractable<G12_Ti_G12_Descr> {
374  public:
375  typedef MultiplicativeSymm2Body_Props Properties;
377  static const unsigned int max_key = 2;
378  G12_Ti_G12_Descr(int K) : K_(K) { assert(K >= 0 && K <= 1); }
379  G12_Ti_G12_Descr(const G12_Ti_G12_Descr& a) : Contractable<G12_Ti_G12_Descr>(a), K_(a.K_) {}
380  unsigned int key() const { return K_; }
381  std::string description() const { return label_(K_, this->contracted()); }
382  std::string label() const { return symbol_(K_, this->contracted()); }
383  int K() const { return K_; }
384  int psymm(int i, int j) const { assert(false); }
385  int hermitian(int i) const { return +1; }
386  private:
387  G12_Ti_G12_Descr();
388  static std::string label_(int K, bool contracted);
389  static std::string symbol_(int K, bool contracted);
390  int K_;
391  };
392  typedef GenOper<G12_Ti_G12_Descr> G12TiG12;
393 
396  struct R1dotR1_G12_Descr : public Contractable<R1dotR1_G12_Descr> {
397  typedef MultiplicativeNonsymm2Body_Props Properties;
398  static const unsigned int max_key = 1;
399  unsigned int key() const { return 0; }
400  std::string description() const { return "r_1.r_1 x G12"; }
401  std::string label() const { return "R1dotR1_G12"; }
402  int psymm(int i, int j) const { assert(false); }
403  int hermitian(int i) const { assert(false); }
404  };
405  typedef GenOper< R1dotR1_G12_Descr > R1dotR1_G12;
406 
409  struct R2dotR2_G12_Descr : public Contractable<R2dotR2_G12_Descr> {
410  typedef MultiplicativeNonsymm2Body_Props Properties;
411  static const unsigned int max_key = 1;
412  unsigned int key() const { return 0; }
413  std::string description() const { return "r_2.r_2 x G12"; }
414  std::string label() const { return "R2dotR2_G12"; }
415  int psymm(int i, int j) const { assert(false); }
416  int hermitian(int i) const { assert(false); }
417  };
418  typedef GenOper< R2dotR2_G12_Descr > R2dotR2_G12;
419 
422  struct R1dotR2_G12_Descr : public Contractable<R1dotR2_G12_Descr> {
423  typedef MultiplicativeSymm2Body_Props Properties;
424  static const unsigned int max_key = 1;
425  unsigned int key() const { return 0; }
426  std::string description() const { return "r_1.r_2 x G12"; }
427  std::string label() const { return "R1dotR2_G12"; }
428  int psymm(int i, int j) const { assert(false); }
429  int hermitian(int i) const { assert(false); }
430  };
431  typedef GenOper< R1dotR2_G12_Descr > R1dotR2_G12;
432 
436  struct DivG12prime_xTx_Descr : public Contractable<DivG12prime_xTx_Descr> {
437  typedef NonmultiplicativeNonsymm2Body_Props Properties;
438  static const unsigned int max_key = 2;
439  DivG12prime_xTx_Descr(int I) : I_(I) { assert(I >= 0 && I <= 1); }
440  DivG12prime_xTx_Descr(const DivG12prime_xTx_Descr& a) : Contractable<DivG12prime_xTx_Descr>(a), I_(a.I_) {}
441  unsigned int key() const { return I_; }
442  std::string description() const { return label_(I_); }
443  std::string label() const { return symbol_(I_); }
444  int I() const { return I_; }
445  int psymm(int i, int j) const { assert(false); }
446  int hermitian(int i) const { if (i != I_) return +1; else return -1; }
447  private:
448  DivG12prime_xTx_Descr();
449  static std::string label_(int I);
450  static std::string symbol_(int I);
451  int I_;
452  };
453  typedef GenOper< DivG12prime_xTx_Descr > DivG12prime_xTx;
454 
455 };
456 
457 #endif
458 
R12_k_G12 is a two-body operator of form r_{12}^k * exp(- * r_{12}), where k is an integer and is a ...
Definition: oper.h:298
use this as a base to add to Derived a "contracted()" attribute
Definition: contractable.h:26
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:30
GenMultSymmOper is a generic multiplicative symmetric N-body operator.
Definition: oper.h:214
TwoPRep is the two-body repulsion operator.
Definition: oper.h:271
GenOper iter_type
GenOper is not a set.
Definition: oper.h:158
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:23
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType...
Definition: hashable.h:72
unsigned int num_oper() const
Number of operators in the set.
Definition: oper.h:160
unsigned int key() const
Implementation of Hashable::key()
Definition: oper.h:162
Oper()
The only declared constructor is only useable by derived classes.
Definition: oper.h:96
GenOper is a single operator described by descriptor Descr.
Definition: oper.h:152
std::string label() const
Implementation of OperSet::label()
Definition: oper.h:168
OperatorProperties describes various properties of an operator or operator set np – number of partic...
Definition: oper.h:48
const Descr & descr() const
Return the descriptor object.
Definition: oper.h:172
R12_k_G12_Descr(int K)
K can range from -1 to 4.
Definition: oper.h:302
Ti_G12 is a two-body operator of form [T_i, G12], where i is particle index (0 or 1) and G12 is a Gau...
Definition: oper.h:348
cartesian multipole operator:
Definition: oper.h:247
int hermitian(int p) const
Implementation of OperSet::hermitian()
Definition: oper.h:132
Oper is OperSet characterized by properties Props.
Definition: oper.h:82
int psymm(int i, int j) const
Implementation of OperSet::psymm()
Definition: oper.h:107
R12k_R12l_G12 is a two-body operator of form ( r_{12x}^kx * r_{12y}^ky * r_{12z}^kz ) * (r_{12x}^lx *...
Definition: oper.h:322
GTG_1d is the two-body 1-dimensional Gaussian geminal.
Definition: oper.h:284
Descr & descr()
Return the descriptor object.
Definition: oper.h:170
OperSet is the base class for all (sets of) operators.
Definition: oper.h:59
std::string description() const
Implementation of OperSet::description()
Definition: oper.h:166
Permutational symmetries: antisymmetric(anti), symmetric(symm), nonsymmetric (nonsymm), some more complicated symmetry (nonstd)
Definition: oper.h:38
Represents cartesian derivatives of atom-centered basis functions.
Definition: bfset.h:96
This exception used to indicate some programming error.
Definition: exception.h:94