21#ifndef _libint2_src_bin_libint_oper_h_
22#define _libint2_src_bin_libint_oper_h_
24#include <contractable.h>
25#include <global_macros.h>
32#include <boost/preprocessor/list/for_each.hpp>
40 typedef enum { anti = -1, symm = 1, nonsymm = 0, nonstd = -2 } type;
50template <
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;
76 virtual int psymm(
int i,
int j)
const = 0;
93 typedef Props Properties;
97 int psymm(
int i,
int j)
const override;
103 bool operator==(
const Oper&)
const;
112 virtual int nonstd_psymm(
int i,
int j)
const {
116 virtual int nonstd_hermitian(
int p)
const {
117 throw ProgrammingError(
"nonstd_hermitian is not overloaded");
121template <
class Props>
123 if (i < 0 || i >=
static_cast<int>(Props::np))
124 throw std::runtime_error(
125 "Oper<Props>::psymm(i,j) -- index i out of bounds");
126 if (j < 0 || j >=
static_cast<int>(Props::np))
127 throw std::runtime_error(
128 "Oper<Props>::psymm(i,j) -- index j out of bounds");
129 if (i == j)
return 1;
131 switch (Props::psymm) {
132 case PermutationalSymmetry::anti:
134 case PermutationalSymmetry::symm:
136 case PermutationalSymmetry::nonsymm:
138 case PermutationalSymmetry::nonstd:
139 return nonstd_psymm(i, j);
145template <
class Props>
147 if (Props::multiplicative)
150 return nonstd_hermitian(p);
153template <
class Props>
162template <
class Descr>
164 public Hashable<unsigned, ComputeKey> {
166 typedef Descr Descriptor;
167 typedef typename Descr::Properties Properties;
172 unsigned int num_oper()
const override {
return 1; }
174 unsigned int key()
const override {
return descr_.key(); }
176 static const unsigned int max_key = Descr::max_key;
178 std::string
description()
const override {
return descr_.description(); }
180 std::string
label()
const override {
return descr_.label(); }
184 const Descr&
descr()
const {
return descr_; }
187 GenOper(
const std::shared_ptr<GenOper>& o) : descr_(o->descr_) {}
188 GenOper(
const std::shared_ptr<OperSet>& o)
189 : descr_(require_dynamic_cast<GenOper, OperSet>(o)->descr_) {}
190 GenOper(
const std::shared_ptr<ConstructablePolymorphically>& o)
191 : descr_(require_dynamic_cast<GenOper, ConstructablePolymorphically>(o)
193 explicit GenOper(
const ConstructablePolymorphically& o)
194 : descr_(require_dynamic_cast<GenOper, ConstructablePolymorphically>(&o)
196 virtual ~GenOper() {}
202 int nonstd_psymm(
int i,
int j)
const override {
205 if (Descr::Properties::psymm == PermutationalSymmetry::nonstd)
206 return descr_.psymm(i, j);
208 throw ProgrammingError(
209 "GenOper::nonstd_psymm -- descriptor is not nonstd");
213 int nonstd_hermitian(
int i)
const override {
216 if (!Descr::Properties::multiplicative)
217 return descr_.hermitian(i);
219 throw ProgrammingError(
220 "GenOper::nonstd_hermitian -- this operator is multiplicative");
226typedef OperatorProperties<1, false, PermutationalSymmetry::nonsymm>
227 Nonmultiplicative1Body_Props;
228typedef OperatorProperties<1, true, PermutationalSymmetry::nonsymm>
229 Multiplicative1Body_Props;
230typedef OperatorProperties<1, true, PermutationalSymmetry::nonsymm, true>
231 MultiplicativeODep1Body_Props;
232typedef OperatorProperties<2, true, PermutationalSymmetry::symm>
233 MultiplicativeSymm2Body_Props;
234typedef OperatorProperties<2, true, PermutationalSymmetry::nonsymm>
235 MultiplicativeNonsymm2Body_Props;
236typedef OperatorProperties<2, false, PermutationalSymmetry::symm>
237 NonmultiplicativeSymm2Body_Props;
238typedef OperatorProperties<2, false, PermutationalSymmetry::nonsymm>
239 NonmultiplicativeNonsymm2Body_Props;
243template <
unsigned int N>
246 static const unsigned int max_key = 1;
247 unsigned int key()
const {
return 0; }
248 std::string description()
const {
249 return "generic multiplicative symmetric operator";
251 std::string label()
const {
return "GenMultSymmOper"; }
252 int psymm(
int i,
int j)
const { abort(); }
253 int hermitian(
int i)
const { abort(); }
257#define BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR(r, propprefix, opname) \
258 struct opname##_Descr : public Contractable<opname##_Descr> { \
259 typedef propprefix##1Body_Props Properties; \
260 static const unsigned int max_key = 1; \
261 unsigned int key() const { return 0; } \
262 std::string description() const { return #opname; } \
263 std::string label() const { return #opname; } \
264 int psymm(int i, int j) const { abort(); } \
265 int hermitian(int i) const { return +1; } \
267 typedef GenOper<opname##_Descr> opname##Oper;
269#define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (Kinetic, BOOST_PP_NIL)
270BOOST_PP_LIST_FOR_EACH(BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR,
271 Nonmultiplicative, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
272#undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST
273#define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (Overlap, BOOST_PP_NIL)
274BOOST_PP_LIST_FOR_EACH(BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR,
275 Multiplicative, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
276#undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST
277#define BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST (ElecPot, BOOST_PP_NIL)
278BOOST_PP_LIST_FOR_EACH(BOOST_PP_DECLARE_HERMITIAN_ONEBODY_DESCRIPTOR,
279 MultiplicativeODep, BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST)
280#undef BOOST_PP_HERMITIAN_ONEBODY_OPER_LIST
292 σpVσp_Descr() : pauli_index_(0) {}
293 σpVσp_Descr(
int pauli_index) : pauli_index_(pauli_index) {
294 assert(pauli_index <= 3);
297 static const unsigned int max_key = 4;
298 unsigned int key()
const {
return pauli_index(); }
299 std::string description()
const {
300 std::string descr(
"opVop[");
301 if (pauli_index() == 0)
303 else if (pauli_index() == 1)
305 else if (pauli_index() == 2)
307 else if (pauli_index() == 3)
313 std::string label()
const {
return description(); }
314 int psymm(
int i,
int j)
const { abort(); }
315 int hermitian(
int i)
const {
return +1; }
317 int pauli_index()
const {
return pauli_index_; }
320 const int pauli_index_ = -1;
322typedef GenOper<σpVσp_Descr> σpVσpOper;
328template <
unsigned int NDIM>
340 std::string description()
const {
341 std::string descr(
"CartesianMultipole[");
342 std::ostringstream oss;
343 for (
unsigned i = 0; i != NDIM; ++i) {
345 if (i + 1 != NDIM) oss <<
",";
347 return descr + oss.str() +
"]";
349 std::string label()
const {
return description(); }
350 int psymm(
int i,
int j)
const { abort(); }
351 int hermitian(
int i)
const {
return +1; }
353template <
unsigned int NDIM>
364 using SphericalMultipoleQuanta::max_key;
365 using SphericalMultipoleQuanta::Sign;
377 std::string description()
const {
379 std::string(
"SphericalMultipole[") + std::to_string(this->l()) +
"," +
380 std::to_string((this->sign() == Sign::plus ? 1 : -1) * this->m()) +
"]";
383 std::string label()
const {
return description(); }
384 int psymm(
int i,
int j)
const { abort(); }
385 int hermitian(
int i)
const {
return +1; }
387using SphericalMultipoleOper = GenOper<SphericalMultipole_Descr>;
393 static const unsigned int max_key = 1;
394 unsigned int key()
const {
return 0; }
395 std::string description()
const {
return "1/r_{12}"; }
396 std::string label()
const {
return "TwoPRep"; }
397 int psymm(
int i,
int j)
const { abort(); }
398 int hermitian(
int i)
const {
return +1; }
406 static const unsigned int max_key = 1;
407 unsigned int key()
const {
return 0; }
408 std::string description()
const {
return "GTG_1d"; }
409 std::string label()
const {
return "GTG_1d"; }
410 int psymm(
int i,
int j)
const { abort(); }
411 int hermitian(
int i)
const {
return +1; }
425 static const unsigned int max_key = 5;
426 unsigned int key()
const {
return K_ + 1; }
427 std::string description()
const {
return label_(K_, this->contracted()); }
428 std::string label()
const {
return symbol_(K_, this->contracted()); }
429 int K()
const {
return K_; }
430 int psymm(
int i,
int j)
const { abort(); }
431 int hermitian(
int i)
const { abort(); }
435 static std::string label_(
int K,
bool contracted);
436 static std::string symbol_(
int K,
bool contracted);
439typedef GenOper<R12_k_G12_Descr> R12kG12;
448 static const int kmax = 4;
452 const IntVec3& K()
const {
return K_; }
453 const IntVec3& L()
const {
return L_; }
454 static const unsigned int max_key = kmax * kmax * kmax * kmax * kmax * kmax;
455 unsigned int key()
const;
456 std::string description()
const {
return label_(K_, L_, this->contracted()); }
457 std::string label()
const {
return symbol_(K_, L_, this->contracted()); }
458 int psymm(
int i,
int j)
const { abort(); }
459 int hermitian(
int i)
const { abort(); }
480 Ti_G12_Descr(
int K) : K_(K) { assert(K >= 0 && K <= 1); }
483 unsigned int key()
const {
return K_; }
484 std::string description()
const {
return label_(K_, this->contracted()); }
485 std::string label()
const {
return symbol_(K_, this->contracted()); }
486 int K()
const {
return K_; }
487 int psymm(
int i,
int j)
const { abort(); }
488 int hermitian(
int i)
const {
497 static std::string label_(
int K,
bool contracted);
498 static std::string symbol_(
int K,
bool contracted);
501typedef GenOper<Ti_G12_Descr> TiG12;
507class G12_Ti_G12_Descr :
public Contractable<G12_Ti_G12_Descr> {
509 typedef MultiplicativeSymm2Body_Props Properties;
511 static const unsigned int max_key = 2;
512 G12_Ti_G12_Descr(
int K) : K_(K) { assert(K >= 0 && K <= 1); }
513 G12_Ti_G12_Descr(
const G12_Ti_G12_Descr& a)
514 : Contractable<G12_Ti_G12_Descr>(a), K_(a.K_) {}
515 unsigned int key()
const {
return K_; }
516 std::string description()
const {
return label_(K_, this->contracted()); }
517 std::string label()
const {
return symbol_(K_, this->contracted()); }
518 int K()
const {
return K_; }
519 int psymm(
int i,
int j)
const { abort(); }
520 int hermitian(
int i)
const {
return +1; }
524 static std::string label_(
int K,
bool contracted);
525 static std::string symbol_(
int K,
bool contracted);
528typedef GenOper<G12_Ti_G12_Descr> G12TiG12;
533struct R1dotR1_G12_Descr :
public Contractable<R1dotR1_G12_Descr> {
534 typedef MultiplicativeNonsymm2Body_Props Properties;
535 static const unsigned int max_key = 1;
536 unsigned int key()
const {
return 0; }
537 std::string description()
const {
return "r_1.r_1 x G12"; }
538 std::string label()
const {
return "R1dotR1_G12"; }
539 int psymm(
int i,
int j)
const { abort(); }
540 int hermitian(
int i)
const { abort(); }
542typedef GenOper<R1dotR1_G12_Descr> R1dotR1_G12;
547struct R2dotR2_G12_Descr :
public Contractable<R2dotR2_G12_Descr> {
548 typedef MultiplicativeNonsymm2Body_Props Properties;
549 static const unsigned int max_key = 1;
550 unsigned int key()
const {
return 0; }
551 std::string description()
const {
return "r_2.r_2 x G12"; }
552 std::string label()
const {
return "R2dotR2_G12"; }
553 int psymm(
int i,
int j)
const { abort(); }
554 int hermitian(
int i)
const { abort(); }
556typedef GenOper<R2dotR2_G12_Descr> R2dotR2_G12;
561struct R1dotR2_G12_Descr :
public Contractable<R1dotR2_G12_Descr> {
562 typedef MultiplicativeSymm2Body_Props Properties;
563 static const unsigned int max_key = 1;
564 unsigned int key()
const {
return 0; }
565 std::string description()
const {
return "r_1.r_2 x G12"; }
566 std::string label()
const {
return "R1dotR2_G12"; }
567 int psymm(
int i,
int j)
const { abort(); }
568 int hermitian(
int i)
const { abort(); }
570typedef GenOper<R1dotR2_G12_Descr> R1dotR2_G12;
575struct DivG12prime_xTx_Descr :
public Contractable<DivG12prime_xTx_Descr> {
576 typedef NonmultiplicativeNonsymm2Body_Props Properties;
577 static const unsigned int max_key = 2;
578 DivG12prime_xTx_Descr(
int I) : I_(I) { assert(I >= 0 && I <= 1); }
579 DivG12prime_xTx_Descr(
const DivG12prime_xTx_Descr& a)
580 : Contractable<DivG12prime_xTx_Descr>(a), I_(a.I_) {}
581 unsigned int key()
const {
return I_; }
582 std::string description()
const {
return label_(I_); }
583 std::string label()
const {
return symbol_(I_); }
584 int I()
const {
return I_; }
585 int psymm(
int i,
int j)
const { abort(); }
586 int hermitian(
int i)
const {
594 DivG12prime_xTx_Descr();
595 static std::string label_(
int I);
596 static std::string symbol_(
int I);
599typedef GenOper<DivG12prime_xTx_Descr> DivG12prime_xTx;
Represents quantum numbers of cartesian multipole operator.
Definition multipole.h:43
static const unsigned max_key
The range of keys is [0,max_key).
Definition multipole.h:136
void inc(unsigned int xyz, unsigned int c=1u)
Add c quanta along xyz.
Definition multipole.h:79
ConstructablePolymorphically is a base for all objects which can be constructed using a std::shared_p...
Definition polyconstr.h:30
use this as a base to add to Derived a "contracted()" attribute
Definition contractable.h:28
GenOper is a single operator described by descriptor Descr.
Definition oper.h:164
GenOper iter_type
GenOper is not a set.
Definition oper.h:170
Descr & descr()
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:176
std::string description() const override
Implementation of OperSet::description()
Definition oper.h:178
std::string label() const override
Implementation of OperSet::label()
Definition oper.h:180
const Descr & descr() const
Return the descriptor object.
Definition oper.h:184
unsigned int num_oper() const override
Number of operators in the set.
Definition oper.h:172
unsigned int key() const override
Implementation of Hashable::key()
Definition oper.h:174
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition hashable.h:79
OperSet is the base class for all (sets of) operators.
Definition oper.h:64
virtual std::string label() const =0
Returns short label for the operator.
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....
virtual unsigned int num_oper() const =0
Number of operators in the set.
virtual bool origin_dependent() const =0
is operator origin-dependent?
virtual std::string description() const =0
Returns full human-readable description of the operator.
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...
Oper is OperSet characterized by properties Props.
Definition oper.h:91
int psymm(int i, int j) const override
Implementation of OperSet::psymm()
Definition oper.h:122
bool origin_dependent() const override
Implementation of OperSet::origin_dependent()
Definition oper.h:101
Oper()
The only declared constructor is only useable by derived classes.
Definition oper.h:107
int hermitian(int p) const override
Implementation of OperSet::hermitian()
Definition oper.h:146
OperatorProperties describes various properties of an operator or operator set.
Definition oper.h:52
This exception used to indicate some programming error.
Definition exception.h:85
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:418
R12_k_G12_Descr(int K)
K can range from -1 to 4.
Definition oper.h:422
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:445
Represents quantum numbers of real spherical multipole operator defined in Eqs.
Definition multipole.h:197
SphericalMultipoleQuanta()
constructs an object in default (unusable) state
Definition multipole.h:203
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:475
static const unsigned int max_key
K can range from 0 to 1.
Definition oper.h:479
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
cartesian multipole operator in NDIM dimensions
Definition oper.h:331
GTG_1d is the two-body 1-dimensional Gaussian geminal.
Definition oper.h:404
GenMultSymmOper is a generic multiplicative symmetric N-body operator.
Definition oper.h:244
Permutational symmetries: antisymmetric(anti), symmetric(symm), nonsymmetric (nonsymm),...
Definition oper.h:39
Represents quantum numbers of real spherical multipole operator defined in Eqs.
Definition oper.h:362
SphericalMultipole_Descr(int l, int m)
constructs if , otherwise constructs
Definition oper.h:371
SphericalMultipole_Descr()
Default ctor makes a 0th-order multipole.
Definition oper.h:368
TwoPRep is the two-body repulsion operator.
Definition oper.h:391