21#ifndef _libint2_src_bin_libint_multipole_h_
22#define _libint2_src_bin_libint_multipole_h_
24#include <global_macros.h>
26#include <polyconstr.h>
28#include <util_types.h>
41template <
unsigned NDIM = 3>
43 :
public Hashable<LIBINT2_UINT_LEAST64, ReferToKey> {
45 NDIM == 1 || NDIM == 3,
46 "CartesianMultipoleQuanta<NDIM>: only NDIM=1 or NDIM=3 are supported");
50 for (
auto d = 0u; d != NDIM; ++d) n_[d] = 0u;
54 std::copy(other.n_, other.n_ + NDIM, n_);
57 valid_ = other.valid_;
58 std::copy(other.n_, other.n_ + NDIM, n_);
63 for (
auto d = 0u; d != NDIM; ++d) n_[d] += other.n_[d];
68 for (
auto d = 0u; d != NDIM; ++d) n_[d] -= other.n_[d];
79 void inc(
unsigned int xyz,
unsigned int c = 1u) {
86 void dec(
unsigned int xyz,
unsigned int c = 1u) {
95 unsigned int norm()
const {
return std::accumulate(n_, n_ + NDIM, 0u); }
99 bool valid()
const {
return valid_; }
101 LIBINT2_UINT_LEAST64
key()
const {
103 unsigned nxy = n_[1] + n_[2];
104 unsigned l = nxy + n_[0];
105 LIBINT2_UINT_LEAST64
key = nxy * (nxy + 1) / 2 + n_[2];
106 const auto result =
key + key_l_offset.at(l);
111 const auto result = n_[0];
119 char result[NDIM + 1];
120 for (
auto xyz = 0u; xyz < NDIM; ++xyz) result[xyz] =
'0' + n_[xyz];
122 return std::string(result);
128 constexpr static unsigned max_qn = LIBINT_CARTGAUSS_MAX_AM;
137 NDIM == 3 ? (1 + max_qn) * (2 + max_qn) * (3 + max_qn) / 6 : (1 + max_qn);
140 void print(std::ostream& os = std::cout)
const;
147 unsigned int n_[NDIM];
151 static std::array<LIBINT2_UINT_LEAST64, CartesianMultipoleQuanta::max_qn + 1>
157std::array<LIBINT2_UINT_LEAST64, CartesianMultipoleQuanta<1u>::max_qn + 1>
158 CartesianMultipoleQuanta<1u>::key_l_offset;
160std::array<LIBINT2_UINT_LEAST64, CartesianMultipoleQuanta<3u>::max_qn + 1>
161 CartesianMultipoleQuanta<3u>::key_l_offset;
163template <
unsigned NDIM>
164CartesianMultipoleQuanta<NDIM> operator-(
165 const CartesianMultipoleQuanta<NDIM>& A,
166 const CartesianMultipoleQuanta<NDIM>& B) {
167 CartesianMultipoleQuanta<NDIM> Diff(A);
168 for (
unsigned int xyz = 0; xyz < 3; ++xyz) Diff.dec(xyz, B[xyz]);
172template <
unsigned NDIM>
173bool operator==(
const CartesianMultipoleQuanta<NDIM>& A,
174 const CartesianMultipoleQuanta<NDIM>& B) {
175 for (
unsigned d = 0; d != NDIM; ++d)
176 if (A[d] != B[d])
return false;
181template <
unsigned NDIM>
197 :
public Hashable<LIBINT2_UINT_LEAST64, ReferToKey> {
199 enum Sign { plus, minus };
200 constexpr static unsigned max_qn = LIBINT_CARTGAUSS_MAX_AM;
214 phase_(sign == Sign::plus && m < 0 ? -1 : 1) {
215 if (l < 0) valid_ =
false;
216 if (m_ > l_) valid_ =
false;
218 if (sign_ == Sign::minus && m_ == 0) valid_ =
false;
223 return static_cast<int>(l_);
227 return static_cast<int>(m_);
233 bool valid()
const {
return valid_; }
241 return sign_ == Sign::plus && l_ == 0 && m_ == 0;
248 const static unsigned max_key = (1 + max_qn) * (1 + max_qn);
251 LIBINT2_UINT_LEAST64
key()
const {
253 const auto result = l_ * l_ + (sign_ == Sign::plus ? (l_ + m_) : (l_ - m_));
254 assert(result < max_key);
271inline SphericalMultipoleQuanta::Sign
flip(
272 const SphericalMultipoleQuanta::Sign& s) {
273 return s == SphericalMultipoleQuanta::Sign::minus
274 ? SphericalMultipoleQuanta::Sign::plus
275 : SphericalMultipoleQuanta::Sign::minus;
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
unsigned int operator[](unsigned int xyz) const
returns the number of quanta along xyz
Definition multipole.h:74
unsigned int norm() const
Returns the sum of quantum numbers.
Definition multipole.h:95
bool valid() const
Return false if this object is invalid.
Definition multipole.h:99
void dec(unsigned int xyz, unsigned int c=1u)
Subtract c quanta along xyz.
Definition multipole.h:86
void inc(unsigned int xyz, unsigned int c=1u)
Add c quanta along xyz.
Definition multipole.h:79
void print(std::ostream &os=std::cout) const
Print out the content.
bool zero() const
norm() == 0
Definition multipole.h:97
std::string label() const
Return a compact label.
Definition multipole.h:118
void invalidate()
make this object invalid
Definition multipole.h:144
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<unsigned>::key()
Definition multipole.h:101
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition hashable.h:79
Represents quantum numbers of real spherical multipole operator defined in Eqs.
Definition multipole.h:197
bool is_precomputed() const
Definition multipole.h:239
SphericalMultipoleQuanta(int l, int m)
constructs if , otherwise constructs
Definition multipole.h:206
SphericalMultipoleQuanta()
constructs an object in default (unusable) state
Definition multipole.h:203
SphericalMultipoleQuanta(int l, int m, Sign sign)
constructs
Definition multipole.h:209
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<unsigned>::key()
Definition multipole.h:251
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24
bool exists(const IncableBFSet &A)
Return true if A is valid.
Definition bfset.h:96
SphericalMultipoleQuanta::Sign flip(const SphericalMultipoleQuanta::Sign &s)
plus <-> minus
Definition multipole.h:271