LIBINT 2.7.2
quanta.h
1/*
2 * Copyright (C) 2004-2021 Edward F. Valeev
3 *
4 * This file is part of Libint.
5 *
6 * Libint is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Libint is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Libint. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef _libint2_src_bin_libint_quanta_h_
22#define _libint2_src_bin_libint_quanta_h_
23
24#include <cassert>
25#include <vector>
26#include <smart_ptr.h>
27#include <global_macros.h>
28#include <iter.h>
29
30namespace libint2 {
31
37 public Hashable<LIBINT2_UINT_LEAST64,ComputeKey> {
38 public:
39 typedef DummyIterator iter_type;
41 static const LIBINT2_UINT_LEAST64 max_quantum_number = 100;
42
43 virtual ~QuantumSet() {}
44 virtual std::string label() const =0;
45
47 virtual unsigned int num_quanta() const =0;
49 virtual void inc(unsigned int i) =0;
51 virtual void dec(unsigned int i) =0;
52 };
53
56 template<typename T, unsigned int N> class QuantumNumbers : public QuantumSet {
57
58 std::vector<T> qn_;
59
60 public:
61 typedef QuantumSet parent_type;
64
65 QuantumNumbers(const std::vector<T>& qn);
66 QuantumNumbers(const SafePtr<QuantumNumbers>&);
67 QuantumNumbers(const SafePtr<QuantumSet>&);
68 QuantumNumbers(const SafePtr<ConstructablePolymorphically>&);
71
72 bool operator==(const QuantumNumbers&) const;
73 std::string label() const override;
74
76 void inc(unsigned int i) override { ++qn_.at(i); }
78 void dec(unsigned int i) override {
79#if CHECK_SAFETY
80 if (qn_.at(i) == T(0))
81 throw std::runtime_error("QuantumNumbers::dec -- quantum number already zero");
82#endif
83 --qn_.at(i);
84 }
85
87 const T elem(unsigned int i) const {
88 return qn_.at(i);
89 }
90
92 unsigned int num_quanta() const {
93 return qn_.size();
94 }
95
97 LIBINT2_UINT_LEAST64 key() const override {
98 LIBINT2_UINT_LEAST64 key = 0;
99 LIBINT2_UINT_LEAST64 pfac = 1;
100 const int maxi = ((int)num_quanta()) - 1;
101 for(int i=maxi; i>=0; i--) {
102 key += pfac*qn_[i];
104 }
105 assert(key < this->max_key());
106 return key;
107 }
108
110 LIBINT2_UINT_LEAST64 max_key() const {
111 LIBINT2_UINT_LEAST64 max_key = 1;
112 const int maxi = ((int)num_quanta()) - 1;
113 for(int i=maxi; i>=0; i--) {
115 }
116 return max_key;
117 }
118
119 };
120
121 template<typename T, unsigned int N>
122 QuantumNumbers<T,N>::QuantumNumbers(const std::vector<T>& qn) :
123 qn_(qn)
124 {
125 }
126
127 template<typename T, unsigned int N>
128 QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<QuantumNumbers>& sptr) :
129 qn_(sptr->qn_)
130 {
131 }
132
133 template<typename T, unsigned int N>
134 QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<QuantumSet>& sptr)
135 {
136 const SafePtr< QuantumNumbers<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbers,QuantumSet>(sptr);
137#if CHECK_SAFETY
138 if (sptr_cast == 0)
139 throw std::runtime_error("QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<QuantumSet>& sptr) -- type of sptr is incompatible with QuantumNumbers");
140#endif
141
142 qn_ = sptr_cast->qn_;
143 }
144
145 template<typename T, unsigned int N>
146 QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<ConstructablePolymorphically>& sptr)
147 {
148 const SafePtr< QuantumNumbers<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbers,ConstructablePolymorphically>(sptr);
149#if CHECK_SAFETY
150 if (sptr_cast == 0)
151 throw std::runtime_error("QuantumNumbers<T,N>::QuantumNumbers(const SafePtr<ConstructablePolymorphically>& sptr) -- type of sptr is incompatible with QuantumNumbers");
152#endif
153
154 qn_ = sptr_cast->qn_;
155 }
156
157 template<typename T, unsigned int N>
158 QuantumNumbers<T,N>::QuantumNumbers(const ConstructablePolymorphically& sptr)
159 {
160 const QuantumNumbers<T,N>& sptr_cast = dynamic_cast<const QuantumNumbers&>(sptr);
161 qn_ = sptr_cast.qn_;
162 }
163
164 template<typename T, unsigned int N>
165 QuantumNumbers<T,N>::~QuantumNumbers()
166 {
167 }
168
169 template<typename T, unsigned int N>
170 bool
171 QuantumNumbers<T,N>::operator==(const QuantumNumbers& a) const
172 {
173 return qn_ == a.qn_;
174 }
175
176 template<typename T, unsigned int N>
177 std::string
178 QuantumNumbers<T,N>::label() const
179 {
180 std::ostringstream oss;
181 oss << "{";
182 if (qn_.size() > 0)
183 oss << qn_[0];
184 for(int i=1; i<qn_.size(); i++)
185 oss << "," << qn_[i];
186 oss << "}";
187 return oss.str();
188 }
189
190 //typedef QuantumNumbers<unsigned int,0> NullQuantumSet;
191
192
197 template<typename T, unsigned int N> class QuantumNumbersA : public QuantumSet {
198
199 T qn_[N];
200
201 public:
202 typedef QuantumSet parent_type;
205
206 // Set all quanta to val
207 QuantumNumbersA(const T& val);
208 QuantumNumbersA(const T* qn);
209 QuantumNumbersA(const std::vector<T>& qn);
210 QuantumNumbersA(const SafePtr<QuantumNumbersA>&);
211 QuantumNumbersA(const SafePtr<QuantumSet>&);
212 QuantumNumbersA(const SafePtr<ConstructablePolymorphically>&);
214
215 bool operator==(const QuantumNumbersA&) const;
216 std::string label() const override;
217
219 void inc(unsigned int i) override { ++qn_[i]; }
221 void dec(unsigned int i) override {
222#if CHECK_SAFETY
223 if (qn_[i] == T(0))
224 throw std::runtime_error("QuantumNumbersA::dec -- quantum number already zero");
225#endif
226 --qn_[i];
227 }
228
230 const T elem(unsigned int i) const {
231 return qn_[i];
232 }
233
235 void set_elem(unsigned int i, const T& value) {
236 qn_[i] = value;
237 }
238
240 unsigned int num_quanta() const override {
241 return N;
242 }
243
245 LIBINT2_UINT_LEAST64 key() const override {
246 LIBINT2_UINT_LEAST64 key = 0;
247 LIBINT2_UINT_LEAST64 pfac = 1;
248 const int maxi = ((int)num_quanta()) - 1;
249 for(int i=maxi; i>=0; i--) {
250 key += pfac*qn_[i];
252 }
253 assert(key < this->max_key());
254 return key;
255 }
256
258 LIBINT2_UINT_LEAST64 max_key() const {
259 LIBINT2_UINT_LEAST64 max_key = 1;
260 const int maxi = ((int)num_quanta()) - 1;
261 for(int i=maxi; i>=0; i--) {
263 }
264 return max_key;
265 }
266
267 };
268
269 template<typename T, unsigned int N>
270 QuantumNumbersA<T,N>::QuantumNumbersA(const T& val)
271 {
272 for(unsigned int i=0; i<N; i++)
273 qn_[i] = val;
274 }
275
276 template<typename T, unsigned int N>
277 QuantumNumbersA<T,N>::QuantumNumbersA(const T* qn)
278 {
279 for(int i=0; i<N; i++)
280 qn_[i] = qn[i];
281 }
282
283 template<typename T, unsigned int N>
284 QuantumNumbersA<T,N>::QuantumNumbersA(const std::vector<T>& qn)
285 {
286 for(int i=0; i<N; i++)
287 qn_[i] = qn[i];
288 }
289
290 template<typename T, unsigned int N>
291 QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<QuantumNumbersA>& sptr)
292 {
293 T* qn = sptr->qn_;
294 for(unsigned int i=0; i<N; i++)
295 qn_[i] = qn[i];
296 }
297
298 template<typename T, unsigned int N>
299 QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<QuantumSet>& sptr)
300 {
301 const SafePtr< QuantumNumbersA<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbersA,QuantumSet>(sptr);
302#if CHECK_SAFETY
303 if (sptr_cast == 0)
304 throw std::runtime_error("QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<QuantumSet>& sptr) -- type of sptr is incompatible with QuantumNumbersA");
305#endif
306
307 T* qn = sptr_cast->qn_;
308 for(int i=0; i<N; i++)
309 qn_[i] = qn[i];
310 }
311
312 template<typename T, unsigned int N>
313 QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<ConstructablePolymorphically>& sptr)
314 {
315 const SafePtr< QuantumNumbersA<T,N> > sptr_cast = dynamic_pointer_cast<QuantumNumbersA,ConstructablePolymorphically>(sptr);
316#if CHECK_SAFETY
317 if (sptr_cast == 0)
318 throw std::runtime_error("QuantumNumbersA<T,N>::QuantumNumbersA(const SafePtr<ConstructablePolymorphically>& sptr) -- type of sptr is incompatible with QuantumNumbersA");
319#endif
320 T* qn = sptr_cast->qn_;
321 for(int i=0; i<N; i++)
322 qn_[i] = qn[i];
323 }
324
325 template<typename T, unsigned int N>
326 QuantumNumbersA<T,N>::~QuantumNumbersA()
327 {
328 }
329
330 template<typename T, unsigned int N>
331 bool
332 QuantumNumbersA<T,N>::operator==(const QuantumNumbersA& a) const
333 {
334 const T* qn0 = qn_;
335 const T* qn1 = a.qn_;
336 for(int i=0; i<N; i++, ++qn0, ++qn1)
337 if (*qn0 != *qn1)
338 return false;
339
340 return true;
341 }
342
343 template<typename T, unsigned int N>
344 std::string
345 QuantumNumbersA<T,N>::label() const
346 {
347 std::ostringstream oss;
348 oss << "{";
349 if (N > 0)
350 oss << qn_[0];
351 for(unsigned int i=1; i<N; i++)
352 oss << "," << qn_[i];
353 oss << "}";
354 return oss.str();
355 }
356
358 template<typename T> class QuantumNumbersA<T,0> : public QuantumSet {
359
360 public:
361 typedef QuantumSet parent_type;
364
365 QuantumNumbersA() {}
366 QuantumNumbersA(const T* qn) {}
367 QuantumNumbersA(const std::vector<T>& qn) {}
368 QuantumNumbersA(const SafePtr<QuantumNumbersA>&) {}
369 QuantumNumbersA(const SafePtr<QuantumSet>&) {}
370 QuantumNumbersA(const SafePtr<ConstructablePolymorphically>&) {}
371 ~QuantumNumbersA() {}
372
373 bool operator==(const QuantumNumbersA&) const { return true; }
374 std::string label() const override { return "{}"; }
375
377 void inc(unsigned int i) override { throw std::runtime_error("QuantumNumbersA<T,0>::inc -- no quantum numbers to increment"); }
379 void dec(unsigned int i) override {
380 throw std::runtime_error("QuantumNumbersA<T,0>::inc -- no quantum numbers to decrement");
381 }
383 const T elem(unsigned int i) const { throw std::runtime_error("QuantumNumbersA<T,0>::inc -- no quantum numbers to return"); }
385 unsigned int num_quanta() const override { return 0; }
386
388 LIBINT2_UINT_LEAST64 key() const override { return 0; }
389
391 LIBINT2_UINT_LEAST64 max_key() const { return 1; }
392
393 };
394
396 template <typename T, unsigned int N>
400 };
409
410};
411
412#endif
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:31
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition: hashable.h:74
unsigned int num_quanta() const override
Implementation of QuantumSet::num_quanta()
Definition: quanta.h:385
void dec(unsigned int i) override
Decrement quantum number i.
Definition: quanta.h:379
void inc(unsigned int i) override
Increment quantum number i.
Definition: quanta.h:377
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition: quanta.h:391
QuantumNumbersA iter_type
QuantumSet is a set of one QuantumSet.
Definition: quanta.h:363
const T elem(unsigned int i) const
Return i-th quantum number.
Definition: quanta.h:383
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable::key()
Definition: quanta.h:388
QuantumNumbersA<T,N> is a set of N quantum numbers of type T implemented in terms of a C-style array.
Definition: quanta.h:197
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable::key()
Definition: quanta.h:245
void dec(unsigned int i) override
Decrement quantum number i.
Definition: quanta.h:221
QuantumNumbersA iter_type
QuantumSet is a set of one QuantumSet.
Definition: quanta.h:204
const T elem(unsigned int i) const
Return i-th quantum number.
Definition: quanta.h:230
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition: quanta.h:258
void inc(unsigned int i) override
Increment quantum number i.
Definition: quanta.h:219
void set_elem(unsigned int i, const T &value)
Return i-th quantum number.
Definition: quanta.h:235
unsigned int num_quanta() const override
Implementation of QuantumSet::num_quanta()
Definition: quanta.h:240
QuantumNumbers<T,N> is a set of N quantum numbers of type T implemented in terms of std::vector.
Definition: quanta.h:56
unsigned int num_quanta() const
Return i-th quantum number.
Definition: quanta.h:92
void inc(unsigned int i) override
Increment quantum number i.
Definition: quanta.h:76
void dec(unsigned int i) override
Decrement quantum number i.
Definition: quanta.h:78
LIBINT2_UINT_LEAST64 max_key() const
key is in range [0,max_key())
Definition: quanta.h:110
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable::key()
Definition: quanta.h:97
QuantumNumbers iter_type
QuantumSet is a set of one QuantumSet.
Definition: quanta.h:63
const T elem(unsigned int i) const
Return i-th quantum number.
Definition: quanta.h:87
QuantumSet is the base class for all (sets of) quantum numbers.
Definition: quanta.h:37
virtual unsigned int num_quanta() const =0
Number of quantum numbers in the set.
virtual void dec(unsigned int i)=0
Decrement i-th quantum number.
static const LIBINT2_UINT_LEAST64 max_quantum_number
Quantum numbers lie in range [0,max_quantum_number)
Definition: quanta.h:41
virtual void inc(unsigned int i)=0
Increment i-th quantum number.
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
DefaultQuantumNumbers< unsignedint, 1 >::Result mType
mType is the type that describes the auxiliary index of standard 2-body repulsion integrals
Definition: quanta.h:408
DefaultQuantumNumbers< int, 0 >::Result EmptySet
EmptySet is the type that describes null set of auxiliary indices.
Definition: quanta.h:404
Default implementation of QuantumNumbers.
Definition: quanta.h:397
QuantumNumbersA< T, N > Result
This defines which QuantumNumbers implementation to use.
Definition: quanta.h:399