21 #ifndef _libint2_src_bin_libint_oper_h_ 22 #define _libint2_src_bin_libint_oper_h_ 26 #include <boost/preprocessor/list/for_each.hpp> 29 #include <global_macros.h> 33 #include <contractable.h> 34 #include <multipole.h> 41 typedef enum {anti=-1, symm=1, nonsymm=0, nonstd=-2} type;
50 template <
unsigned int NP,
bool multi, PermutationalSymmetry::type psymmetry,
51 bool origin_dependent =
false>
54 static constexpr
auto np = NP;
55 static constexpr
auto multiplicative = multi;
56 static constexpr
auto psymm = psymmetry;
57 static constexpr
auto odep = origin_dependent;
66 typedef DummyIterator iter_type;
72 virtual std::string
label()
const =0;
75 virtual int psymm(
int i,
int j)
const =0;
84 virtual unsigned int num_oper()
const =0;
89 template <
class Props>
92 typedef Props Properties;
96 int psymm(
int i,
int j)
const;
102 bool operator==(
const Oper&)
const;
110 virtual int nonstd_psymm(
int i,
int j)
const {
throw ProgrammingError(
"nonstd_psymm is not overloaded"); }
112 virtual int nonstd_hermitian(
int p)
const {
throw ProgrammingError(
"nonstd_hermitian is not overloaded"); }
115 template <
class Props>
119 if (i<0 || i>=static_cast<int>(Props::np))
120 throw std::runtime_error(
"Oper<Props>::psymm(i,j) -- index i out of bounds");
121 if (j<0 || j>=static_cast<int>(Props::np))
122 throw std::runtime_error(
"Oper<Props>::psymm(i,j) -- index j out of bounds");
126 switch(Props::psymm) {
127 case PermutationalSymmetry::anti:
129 case PermutationalSymmetry::symm:
131 case PermutationalSymmetry::nonsymm:
133 case PermutationalSymmetry::nonstd:
134 return nonstd_psymm(i,j);
140 template <
class Props>
144 if (Props::multiplicative)
147 return nonstd_hermitian(p);
150 template <
class Props>
161 template <
class Descr>
164 typedef Descr Descriptor;
165 typedef typename Descr::Properties Properties;
172 unsigned int key()
const {
return descr_.key(); }
174 static const unsigned int max_key = Descr::max_key;
178 std::string
label()
const {
return descr_.label(); }
182 const Descr&
descr()
const {
return descr_; }
185 GenOper(
const SafePtr<GenOper>& o) : descr_(o->descr_) {}
186 GenOper(
const SafePtr<OperSet>& o) : descr_(require_dynamic_cast<GenOper,OperSet>(o)->descr_) {}
187 GenOper(
const SafePtr<ConstructablePolymorphically>& o) : descr_(require_dynamic_cast<GenOper,ConstructablePolymorphically>(o)->descr_) {}
188 explicit GenOper(
const ConstructablePolymorphically& o) : descr_(require_dynamic_cast<GenOper,ConstructablePolymorphically>(&o)->descr_) {}
189 virtual ~GenOper() {}
195 int nonstd_psymm(
int i,
int j)
const {
197 if (Descr::Properties::psymm == PermutationalSymmetry::nonstd)
198 return descr_.psymm(i,j);
199 else throw ProgrammingError(
"GenOper::nonstd_psymm -- descriptor is not nonstd");
203 int nonstd_hermitian(
int i)
const {
205 if (!Descr::Properties::multiplicative)
206 return descr_.hermitian(i);
207 else throw ProgrammingError(
"GenOper::nonstd_hermitian -- this operator is multiplicative");
214 typedef OperatorProperties<1,false,PermutationalSymmetry::nonsymm> Nonmultiplicative1Body_Props;
215 typedef OperatorProperties<1,true, PermutationalSymmetry::nonsymm> Multiplicative1Body_Props;
216 typedef OperatorProperties<1,true, PermutationalSymmetry::nonsymm, true> MultiplicativeODep1Body_Props;
217 typedef OperatorProperties<2,true, PermutationalSymmetry::symm> MultiplicativeSymm2Body_Props;
218 typedef OperatorProperties<2,true, PermutationalSymmetry::nonsymm> MultiplicativeNonsymm2Body_Props;
219 typedef OperatorProperties<2,false,PermutationalSymmetry::symm> NonmultiplicativeSymm2Body_Props;
220 typedef OperatorProperties<2,false,PermutationalSymmetry::nonsymm> NonmultiplicativeNonsymm2Body_Props;
224 template <
unsigned int N>
227 static const unsigned int max_key = 1;
228 unsigned int key()
const {
return 0; }
229 std::string description()
const {
return "generic multiplicative symmetric operator"; }
230 std::string label()
const {
return "GenMultSymmOper"; }
231 int psymm(
int i,
int j)
const { assert(
false); }
232 int hermitian(
int i)
const { assert(
false); }
236 #define BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR(r,propprefix,opname) \ 237 struct opname ## _Descr : public Contractable<opname ## _Descr> { \ 238 typedef propprefix ## 1Body_Props Properties; \ 239 static const unsigned int max_key = 1; \ 240 unsigned int key() const { return 0; } \ 241 std::string description() const { return #opname; } \ 242 std::string label() const { return #opname; } \ 243 int psymm(int i, int j) const { assert(false); } \ 244 int hermitian(int i) const { return +1; } \ 246 typedef GenOper<opname ## _Descr> opname ## Oper; \ 248 #define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (Kinetic, BOOST_PP_NIL) 249 BOOST_PP_LIST_FOR_EACH ( BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR, Nonmultiplicative, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
250 #undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST 251 #define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (Overlap, BOOST_PP_NIL) 252 BOOST_PP_LIST_FOR_EACH ( BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR, Multiplicative, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
253 #undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST 254 #define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (ElecPot, BOOST_PP_NIL) 255 BOOST_PP_LIST_FOR_EACH ( BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR, MultiplicativeODep, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
256 #undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST 261 template <
unsigned int NDIM>
262 struct CartesianMultipole_Descr :
public Contractable<CartesianMultipole_Descr<NDIM>>,
267 CartesianMultipole_Descr() { }
268 CartesianMultipole_Descr(
unsigned int k) { assert(NDIM==1u); this->inc(0,k); }
269 std::string description()
const {
270 std::string descr(
"CartesianMultipole[");
271 std::ostringstream oss;
272 for(
unsigned i=0; i!=NDIM; ++i) {
274 if (i+1 != NDIM) oss <<
",";
276 return descr + oss.str() +
"]";
278 std::string label()
const {
return description(); }
279 int psymm(
int i,
int j)
const { assert(
false); }
280 int hermitian(
int i)
const {
return +1; }
290 using SphericalMultipoleQuanta::max_key;
291 using SphericalMultipoleQuanta::Sign;
300 std::string description()
const {
301 std::string descr = std::string(
"SphericalMultipole[") + std::to_string(this->l()) +
"," + std::to_string((this->sign() == Sign::plus ? 1 : -1) * this->m()) +
"]";
304 std::string label()
const {
return description(); }
305 int psymm(
int i,
int j)
const { assert(
false); }
306 int hermitian(
int i)
const {
return +1; }
308 using SphericalMultipoleOper = GenOper<SphericalMultipole_Descr>;
314 static const unsigned int max_key = 1;
315 unsigned int key()
const {
return 0; }
316 std::string description()
const {
return "1/r_{12}"; }
317 std::string label()
const {
return "TwoPRep"; }
318 int psymm(
int i,
int j)
const { assert(
false); }
319 int hermitian(
int i)
const {
return +1; }
327 static const unsigned int max_key = 1;
328 unsigned int key()
const {
return 0; }
329 std::string description()
const {
return "GTG_1d"; }
330 std::string label()
const {
return "GTG_1d"; }
331 int psymm(
int i,
int j)
const { assert(
false); }
332 int hermitian(
int i)
const {
return +1; }
345 static const unsigned int max_key = 5;
346 unsigned int key()
const {
return K_ + 1; }
347 std::string description()
const {
return label_(K_, this->contracted()); }
348 std::string label()
const {
return symbol_(K_, this->contracted()); }
349 int K()
const {
return K_; }
350 int psymm(
int i,
int j)
const { assert(
false); }
351 int hermitian(
int i)
const { assert(
false); }
354 static std::string label_(
int K,
bool contracted);
355 static std::string symbol_(
int K,
bool contracted);
358 typedef GenOper<R12_k_G12_Descr> R12kG12;
366 static const int kmax = 4;
369 const IntVec3& K()
const {
return K_; }
370 const IntVec3& L()
const {
return L_; }
371 static const unsigned int max_key = kmax * kmax * kmax * kmax * kmax * kmax;
372 unsigned int key()
const;
373 std::string description()
const {
return label_(K_,L_, this->contracted()); }
374 std::string label()
const {
return symbol_(K_,L_, this->contracted()); }
375 int psymm(
int i,
int j)
const { assert(
false); }
376 int hermitian(
int i)
const { assert(
false); }
379 static std::string label_(
const IntVec3& K,
const IntVec3& L,
bool contracted);
380 static std::string symbol_(
const IntVec3& K,
const IntVec3& L,
bool contracted);
394 Ti_G12_Descr(
int K) : K_(K) { assert(K >= 0 && K <= 1); }
396 unsigned int key()
const {
return K_; }
397 std::string description()
const {
return label_(K_, this->contracted()); }
398 std::string label()
const {
return symbol_(K_, this->contracted()); }
399 int K()
const {
return K_; }
400 int psymm(
int i,
int j)
const { assert(
false); }
401 int hermitian(
int i)
const {
if (i != K_)
return +1;
else return -1; }
404 static std::string label_(
int K,
bool contracted);
405 static std::string symbol_(
int K,
bool contracted);
408 typedef GenOper<Ti_G12_Descr> TiG12;
414 class G12_Ti_G12_Descr :
public Contractable<G12_Ti_G12_Descr> {
416 typedef MultiplicativeSymm2Body_Props Properties;
418 static const unsigned int max_key = 2;
419 G12_Ti_G12_Descr(
int K) : K_(K) { assert(K >= 0 && K <= 1); }
420 G12_Ti_G12_Descr(
const G12_Ti_G12_Descr& a) : Contractable<G12_Ti_G12_Descr>(a), K_(a.K_) {}
421 unsigned int key()
const {
return K_; }
422 std::string description()
const {
return label_(K_, this->contracted()); }
423 std::string label()
const {
return symbol_(K_, this->contracted()); }
424 int K()
const {
return K_; }
425 int psymm(
int i,
int j)
const { assert(
false); }
426 int hermitian(
int i)
const {
return +1; }
429 static std::string label_(
int K,
bool contracted);
430 static std::string symbol_(
int K,
bool contracted);
433 typedef GenOper<G12_Ti_G12_Descr> G12TiG12;
437 struct R1dotR1_G12_Descr :
public Contractable<R1dotR1_G12_Descr> {
438 typedef MultiplicativeNonsymm2Body_Props Properties;
439 static const unsigned int max_key = 1;
440 unsigned int key()
const {
return 0; }
441 std::string description()
const {
return "r_1.r_1 x G12"; }
442 std::string label()
const {
return "R1dotR1_G12"; }
443 int psymm(
int i,
int j)
const { assert(
false); }
444 int hermitian(
int i)
const { assert(
false); }
446 typedef GenOper< R1dotR1_G12_Descr > R1dotR1_G12;
450 struct R2dotR2_G12_Descr :
public Contractable<R2dotR2_G12_Descr> {
451 typedef MultiplicativeNonsymm2Body_Props Properties;
452 static const unsigned int max_key = 1;
453 unsigned int key()
const {
return 0; }
454 std::string description()
const {
return "r_2.r_2 x G12"; }
455 std::string label()
const {
return "R2dotR2_G12"; }
456 int psymm(
int i,
int j)
const { assert(
false); }
457 int hermitian(
int i)
const { assert(
false); }
459 typedef GenOper< R2dotR2_G12_Descr > R2dotR2_G12;
463 struct R1dotR2_G12_Descr :
public Contractable<R1dotR2_G12_Descr> {
464 typedef MultiplicativeSymm2Body_Props Properties;
465 static const unsigned int max_key = 1;
466 unsigned int key()
const {
return 0; }
467 std::string description()
const {
return "r_1.r_2 x G12"; }
468 std::string label()
const {
return "R1dotR2_G12"; }
469 int psymm(
int i,
int j)
const { assert(
false); }
470 int hermitian(
int i)
const { assert(
false); }
472 typedef GenOper< R1dotR2_G12_Descr > R1dotR2_G12;
477 struct DivG12prime_xTx_Descr :
public Contractable<DivG12prime_xTx_Descr> {
478 typedef NonmultiplicativeNonsymm2Body_Props Properties;
479 static const unsigned int max_key = 2;
480 DivG12prime_xTx_Descr(
int I) : I_(I) { assert(I >= 0 && I <= 1); }
481 DivG12prime_xTx_Descr(
const DivG12prime_xTx_Descr& a) : Contractable<DivG12prime_xTx_Descr>(a), I_(a.I_) {}
482 unsigned int key()
const {
return I_; }
483 std::string description()
const {
return label_(I_); }
484 std::string label()
const {
return symbol_(I_); }
485 int I()
const {
return I_; }
486 int psymm(
int i,
int j)
const { assert(
false); }
487 int hermitian(
int i)
const {
if (i != I_)
return +1;
else return -1; }
489 DivG12prime_xTx_Descr();
490 static std::string label_(
int I);
491 static std::string symbol_(
int I);
494 typedef GenOper< DivG12prime_xTx_Descr > DivG12prime_xTx;
R12_k_G12 is a two-body operator of form r_{12}^k * exp(-\gamma * r_{12}), where k is an integer and ...
Definition: oper.h:339
virtual std::string description() const =0
Returns full human-readable description of the operator.
use this as a base to add to Derived a "contracted()" attribute
Definition: contractable.h:27
virtual int hermitian(int p) const =0
Returns 1, 0, or -1, if each operator in the set is Hermitian, non-Hermitian, or anti-Hermitian w....
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:31
std::string label() const
Implementation of OperSet::label()
Definition: oper.h:178
GenMultSymmOper is a generic multiplicative symmetric N-body operator.
Definition: oper.h:225
TwoPRep is the two-body repulsion operator.
Definition: oper.h:312
std::string description() const
Implementation of OperSet::description()
Definition: oper.h:176
Represents quantum numbers of cartesian multipole operator.
Definition: multipole.h:41
GenOper iter_type
GenOper is not a set.
Definition: oper.h:168
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition: hashable.h:73
Represents quantum numbers of real spherical multipole operator defined in Eqs.
Definition: multipole.h:185
unsigned int num_oper() const
Number of operators in the set.
Definition: oper.h:170
virtual int psymm(int i, int j) const =0
Returns 1, 0, or -1, if each operator in the set is symmetric, nonsymmetric, or antisymmetric with re...
virtual std::string label() const =0
Returns short label for the operator.
Oper()
The only declared constructor is only useable by derived classes.
Definition: oper.h:106
GenOper is a single operator described by descriptor Descr.
Definition: oper.h:162
OperatorProperties describes various properties of an operator or operator set.
Definition: oper.h:52
static const unsigned int max_key
K can range from 0 to 1.
Definition: oper.h:393
R12_k_G12_Descr(int K)
K can range from -1 to 4.
Definition: oper.h:343
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:389
SphericalMultipole_Descr()
Default ctor makes a 0th-order multipole.
Definition: oper.h:294
Oper is OperSet characterized by properties Props.
Definition: oper.h:90
(BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR, MultiplicativeODep, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST) template< unsigned int NDIM > struct CartesianMultipole_Descr GenOper< CartesianMultipole_Descr< NDIM > > CartesianMultipoleOper
cartesian multipole operator in NDIM dimensions
Definition: oper.h:282
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:363
SphericalMultipole_Descr(int l, int m)
constructs if , otherwise constructs
Definition: oper.h:296
GTG_1d is the two-body 1-dimensional Gaussian geminal.
Definition: oper.h:325
Descr & descr()
Return the descriptor object.
Definition: oper.h:180
OperSet is the base class for all (sets of) operators.
Definition: oper.h:64
int hermitian(int p) const
Implementation of OperSet::hermitian()
Definition: oper.h:142
int psymm(int i, int j) const
Implementation of OperSet::psymm()
Definition: oper.h:117
bool origin_dependent() const
Implementation of OperSet::origin_dependent()
Definition: oper.h:100
virtual unsigned int num_oper() const =0
Number of operators in the set.
virtual bool origin_dependent() const =0
is operator origin-dependent?
Represents quantum numbers of real spherical multipole operator defined in Eqs.
Definition: oper.h:288
const Descr & descr() const
Return the descriptor object.
Definition: oper.h:182
static const unsigned int max_key
Range of key is [0,Descr::max_key)
Definition: oper.h:174
unsigned int key() const
Implementation of Hashable::key()
Definition: oper.h:172
Permutational symmetries: antisymmetric(anti), symmetric(symm), nonsymmetric (nonsymm),...
Definition: oper.h:40
This exception used to indicate some programming error.
Definition: exception.h:95
SphericalMultipoleQuanta()
constructs an object in default (unusable) state
Definition: multipole.h:191