LIBINT 2.9.0
bfset.h
1/*
2 * Copyright (C) 2004-2024 Edward F. Valeev
3 *
4 * This file is part of Libint compiler.
5 *
6 * Libint compiler 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 compiler 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 compiler. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef _libint2_src_bin_libint_bfset_h_
22#define _libint2_src_bin_libint_bfset_h_
23
24#include <contractable.h>
25#include <global_macros.h>
26#include <hashable.h>
27#include <polyconstr.h>
28#include <smart_ptr.h>
29#include <util_types.h>
30
31#include <array>
32#include <cassert>
33#include <iostream>
34#include <numeric>
35#include <sstream>
36#include <string>
37
38namespace libint2 {
39
44 public:
45 virtual ~BFSet() {}
46 virtual unsigned int num_bf() const = 0;
47 virtual std::string label() const = 0;
48
49 protected:
50 BFSet() {}
51};
52
62class IncableBFSet : public BFSet {
63 public:
64 virtual ~IncableBFSet() {}
65
67 virtual void inc(unsigned int xyz, unsigned int c = 1u) = 0;
70 virtual void dec(unsigned int xyz, unsigned int c = 1u) = 0;
72 virtual unsigned int norm() const = 0;
74 bool zero() const { return norm() == 0; }
76 bool valid() const { return valid_; }
77
78 protected:
79 IncableBFSet() : valid_(true) {}
80
82 void invalidate() { valid_ = false; }
83
84 private:
85 bool valid_;
86};
87
89template <typename F>
90F unit(unsigned int X) {
91 F tmp;
92 tmp.inc(X, 1);
93 return tmp;
94}
96inline bool exists(const IncableBFSet& A) { return A.valid(); }
97
100template <unsigned NDIM = 3>
101class OriginDerivative : public Hashable<LIBINT2_UINT_LEAST64, ReferToKey> {
102 static_assert(NDIM == 1 || NDIM == 3,
103 "OriginDerivative<NDIM>: only NDIM=1 or NDIM=3 are supported");
104
105 public:
106 OriginDerivative() : valid_(true) {
107 for (auto d = 0u; d != NDIM; ++d) d_[d] = 0u;
108 }
109 OriginDerivative(const OriginDerivative& other) : valid_(true) {
110 std::copy(other.d_, other.d_ + NDIM, d_);
111 }
112 OriginDerivative& operator=(const OriginDerivative& other) {
113 valid_ = other.valid_;
114 std::copy(other.d_, other.d_ + NDIM, d_);
115 return *this;
116 }
117 OriginDerivative& operator+=(const OriginDerivative& other) {
118 assert(valid_);
119 for (auto d = 0u; d != NDIM; ++d) d_[d] += other.d_[d];
120 return *this;
121 }
122 OriginDerivative& operator-=(const OriginDerivative& other) {
123 assert(valid_);
124 for (auto d = 0u; d != NDIM; ++d) d_[d] -= other.d_[d];
125 return *this;
126 }
128 static_assert(NDIM == 3u || NDIM == 1u,
129 "OriginDerivative with NDIM=1,3 are implemented");
130 }
131
133 unsigned int d(unsigned int xyz) const {
134 assert(xyz < NDIM);
135 return d_[xyz];
136 }
138 unsigned int operator[](unsigned int xyz) const { return this->d(xyz); }
140 void inc(unsigned int xyz, unsigned int c = 1u) {
141 assert(xyz < NDIM);
142 assert(valid_);
143 d_[xyz] += c;
144 }
147 void dec(unsigned int xyz, unsigned int c = 1u) {
148 assert(xyz < NDIM);
149 // assert(valid_);
150 if (d_[xyz] >= c)
151 d_[xyz] -= c;
152 else
153 valid_ = false;
154 }
156 unsigned int norm() const { return std::accumulate(d_, d_ + NDIM, 0u); }
158 bool zero() const { return norm() == 0; }
160 bool valid() const { return valid_; }
162 LIBINT2_UINT_LEAST64 key() const override {
163 if (NDIM == 3u) {
164 unsigned nxy = d_[1] + d_[2];
165 unsigned l = nxy + d_[0];
166 LIBINT2_UINT_LEAST64 key = nxy * (nxy + 1) / 2 + d_[2];
167 const auto result = key + key_l_offset.at(l);
168 assert(result < max_key);
169 return result;
170 }
171 if (NDIM == 1u) {
172 const auto result = d_[0];
173 assert(result < max_key);
174 return result;
175 }
176 assert(false);
177 }
179 std::string label() const {
180 char result[NDIM + 1];
181 for (auto xyz = 0u; xyz < NDIM; ++xyz) result[xyz] = '0' + d_[xyz];
182 result[NDIM] = '\0';
183 return std::string(result);
184 }
185
186 /* ---------------
187 * key computation
188 * --------------- */
189 const static unsigned max_deriv = 4;
190
191 // nkeys_l[L] is the number of possible OriginDerivative's with \c norm() == L
192 // \note for NDIM=1 nkeys_l[L] = 1
193 // \note for NDIM=2 nkeys_l[L] = (L+1)
194 // \note for NDIM=3 nkeys_l[L] = (L+1)(L+2)/2
195 // static std::array<LIBINT2_UINT_LEAST64, OriginDerivative::max_deriv+1>
196 // nkeys;
197
201 const static unsigned max_key =
202 NDIM == 3 ? (1 + max_deriv) * (2 + max_deriv) * (3 + max_deriv) / 6
203 : (1 + max_deriv);
204
206 void print(std::ostream& os = std::cout) const;
207
208 protected:
210 void invalidate() { valid_ = false; }
211
212 private:
213 unsigned int d_[NDIM];
214 bool valid_; // indicates valid/invalid state
217 static std::array<LIBINT2_UINT_LEAST64, OriginDerivative::max_deriv + 1>
218 key_l_offset;
219};
220
221// explicit instantiation declaration, definitions are gauss.cc
222template <>
223std::array<LIBINT2_UINT_LEAST64, OriginDerivative<1u>::max_deriv + 1>
224 OriginDerivative<1u>::key_l_offset;
225template <>
226std::array<LIBINT2_UINT_LEAST64, OriginDerivative<3u>::max_deriv + 1>
227 OriginDerivative<3u>::key_l_offset;
228
229template <unsigned NDIM>
230OriginDerivative<NDIM> operator-(const OriginDerivative<NDIM>& A,
231 const OriginDerivative<NDIM>& B) {
232 OriginDerivative<NDIM> Diff(A);
233 for (unsigned int xyz = 0; xyz < 3; ++xyz) Diff.dec(xyz, B.d(xyz));
234 return Diff;
235}
236
237template <unsigned NDIM>
238bool operator==(const OriginDerivative<NDIM>& A,
239 const OriginDerivative<NDIM>& B) {
240 for (unsigned d = 0; d != NDIM; ++d)
241 if (A.d(d) != B.d(d)) return false;
242 return true;
243}
244
246template <unsigned NDIM>
247inline bool exists(const OriginDerivative<NDIM>& A) {
248 return A.valid();
249}
250
251class CGF; // forward declaration of CGF
252
254class CGShell : public IncableBFSet,
255 public Hashable<LIBINT2_UINT_LEAST64, ReferToKey>,
256 public Contractable<CGShell> {
257 unsigned int qn_[1];
258 OriginDerivative<3> deriv_;
259 bool pure_sh_; //< if true, assumed to contain solid harmonics with quantum
260 // number qn_[0] only
262 bool unit_;
263
264 friend CGShell operator+(const CGShell& A, const CGShell& B);
265 friend CGShell operator-(const CGShell& A, const CGShell& B);
266
267 public:
269 typedef CGF iter_type;
271
273 CGShell();
274 CGShell(unsigned int qn, bool pure_sh = false);
275 CGShell(const CGShell&);
276 virtual ~CGShell();
277 CGShell& operator=(const CGShell&);
278
279 const OriginDerivative<3u>& deriv() const { return deriv_; }
280 OriginDerivative<3u>& deriv() { return deriv_; }
281
283 std::string label() const override;
285 unsigned int num_bf() const override {
286 return (qn_[0] + 1) * (qn_[0] + 2) / 2;
287 }
289 unsigned int qn(unsigned int xyz = 0) const { return qn_[0]; }
291 unsigned int operator[](unsigned int xyz) const { return this->qn(xyz); }
292
294 bool operator==(const CGShell&) const;
295
299 bool pure_sh() const { return pure_sh_; }
302 void pure_sh(bool p) { pure_sh_ = p; }
303
305 void inc(unsigned int xyz, unsigned int c = 1u) override;
307 void dec(unsigned int xyz, unsigned int c = 1u) override;
309 unsigned int norm() const override;
311 LIBINT2_UINT_LEAST64 key() const override {
312 if (is_unit()) return max_key - 1;
313 const LIBINT2_UINT_LEAST64 result =
314 ((deriv().key() * 2 + (contracted() ? 1 : 0)) * (max_qn + 1) + qn_[0]) *
315 2 +
316 (pure_sh() ? 1 : 0);
317 assert(result < max_key - 1);
318 return result;
319 }
320 const static LIBINT2_UINT_LEAST64 max_qn = LIBINT_CARTGAUSS_MAX_AM;
328 const static LIBINT2_UINT_LEAST64 max_key =
329 OriginDerivative<3u>::max_key * 2 * (max_qn + 1) * 2 + 1;
330
332 void print(std::ostream& os = std::cout) const;
333
335 static CGShell unit();
336 bool is_unit() const { return unit_; }
337};
338
339CGShell operator+(const CGShell& A, const CGShell& B);
340CGShell operator-(const CGShell& A, const CGShell& B);
341
343class CGF : public IncableBFSet,
344 public Hashable<LIBINT2_UINT_LEAST64, ComputeKey>,
345 public Contractable<CGF> {
346 unsigned int qn_[3];
348 bool pure_sh_; //< if true, assumed to contain solid harmonics with quantum
349 // number qn_[0] only
350 bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
351
352 friend CGF operator+(const CGF& A, const CGF& B);
353 friend CGF operator-(const CGF& A, const CGF& B);
354
355 public:
357 typedef CGF iter_type;
360 // typedef typename Hashable<unsigned,ComputeKey>::KeyReturnType
361 // KeyReturnType;
362
364 CGF();
365 CGF(unsigned int qn[3], bool pure_sh = false);
366 CGF(const CGF&);
367 explicit CGF(const ConstructablePolymorphically&);
368 virtual ~CGF();
370 CGF& operator=(const CGF&);
371
372 const OriginDerivative<3u>& deriv() const { return deriv_; }
373 OriginDerivative<3u>& deriv() { return deriv_; }
374
376 std::string label() const override;
378 unsigned int num_bf() const override { return 1; }
380 unsigned int qn(unsigned int axis) const;
381 unsigned int operator[](unsigned int axis) const { return qn(axis); }
382
386 bool pure_sh() const { return pure_sh_; }
389 void pure_sh(bool p) { pure_sh_ = p; }
390
392 bool operator==(const CGF&) const;
393
395 void inc(unsigned int xyz, unsigned int c = 1u) override;
397 void dec(unsigned int xyz, unsigned int c = 1u) override;
399 unsigned int norm() const override;
401 LIBINT2_UINT_LEAST64 key() const override {
402 if (is_unit()) return max_key - 1;
403 unsigned nxy = qn_[1] + qn_[2];
404 unsigned l = nxy + qn_[0];
405 LIBINT2_UINT_LEAST64 key = nxy * (nxy + 1) / 2 + qn_[2];
406 const LIBINT2_UINT_LEAST64 result =
407 ((deriv().key() * 2 + (contracted() ? 1 : 0)) * max_num_qn + key +
408 key_l_offset.at(l)) *
409 2 +
410 (pure_sh() ? 1 : 0);
411 if (result >= max_key - 1) {
412 this->print(std::cout);
413 std::cout << "result,max_key-1 = " << result << "," << max_key - 1
414 << std::endl;
415 assert(result < max_key - 1);
416 }
417 return result;
418 }
423 const static LIBINT2_UINT_LEAST64 max_num_qn =
424 ((1 + (CGShell::max_qn + 1)) * (2 + (CGShell::max_qn + 1)) *
425 (3 + (CGShell::max_qn + 1)) / 6);
426 // deriv_key_range = OriginDerivative<3u>::max_key
427 // contracted = 2 (yes or no)
428 // qn_range = max_num_qn
429 // puresh_key_range = 2
430 // +1 to account for unit function
431 const static LIBINT2_UINT_LEAST64 max_key =
433
435 void print(std::ostream& os = std::cout) const;
436
438 static CGF unit();
439 bool is_unit() const { return unit_; }
440
441 private:
444 static std::array<LIBINT2_UINT_LEAST64, CGShell::max_qn + 1> key_l_offset;
445};
446
447CGF operator+(const CGF& A, const CGF& B);
448CGF operator-(const CGF& A, const CGF& B);
449
450#if 1
454template <CartesianAxis Axis>
455class CGF1d : public IncableBFSet,
456 public Hashable<LIBINT2_UINT_LEAST64, ComputeKey>,
457 public Contractable<CGF1d<Axis> > {
458 unsigned int qn_[1];
460 bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
461
462 public:
463 static constexpr auto axis = Axis;
464
468
470 CGF1d() : unit_(false) { qn_[0] = 0; }
471 CGF1d(unsigned int qn) : unit_(false) { qn_[0] = qn; }
472 CGF1d(unsigned int qn[1]) : unit_(false) { qn_[0] = qn[0]; }
473 CGF1d(const CGF1d& source)
474 : Contractable<CGF1d>(source),
475 deriv_(source.deriv_),
476 unit_(source.unit_) {
477 qn_[0] = source.qn_[0];
478 }
479 explicit CGF1d(const ConstructablePolymorphically& sptr)
480 : Contractable<CGF1d>(dynamic_cast<const CGF1d&>(sptr)) {
481 const CGF1d& sptr_cast = dynamic_cast<const CGF1d&>(sptr);
482 qn_[0] = sptr_cast.qn_[0];
483 deriv_ = sptr_cast.deriv_;
484 unit_ = sptr_cast.unit_;
485 }
486 virtual ~CGF1d() {}
487
489 CGF1d& operator=(const CGF1d& source) {
490 qn_[0] = source.qn_[0];
491 deriv_ = source.deriv_;
492 unit_ = source.unit_;
494 if (!source.valid()) invalidate();
495 return *this;
496 }
497
498 CGF1d operator+(const CGF1d& B) const {
499 // assert(this->is_unit() == false && B.is_unit() == false);
500 CGF1d<Axis> Sum(*this);
501 Sum.inc(0, B.qn(0));
502 Sum.deriv_ += B.deriv_;
503 return Sum;
504 }
505 CGF1d operator-(const CGF1d& B) const {
506 // assert(A.is_unit() == false && B.is_unit() == false);
507 CGF1d Diff(*this);
508 Diff.dec(0, B.qn(0));
509 Diff.deriv_ -= B.deriv_;
510 return Diff;
511 }
512
513 const OriginDerivative<1u>& deriv() const { return deriv_; }
514 OriginDerivative<1u>& deriv() { return deriv_; }
515
517 std::string label() const override {
518 // unit *functions* are treated as regular qn-0 functions so that
519 // (00|00)^(m) = (unit 0|00)^(m)
520 std::ostringstream oss;
521 oss << to_string(Axis) << qn_[0];
522 if (!deriv_.zero()) oss << "_" << deriv_.label();
523
524 // I don't handle labels of contracted CGF1d because I don't think I need
525 // them make sure just in case
526 assert(!this->contracted());
527
528 return oss.str();
529 }
530
532 unsigned int num_bf() const override { return 1; }
534 unsigned int qn(unsigned int dir = 0) const {
535 assert(dir == 0);
536 return qn_[0];
537 }
538 unsigned int operator[](unsigned int dir) const { return this->qn(dir); }
539
541 bool operator==(const CGF1d& a) const {
542 return (qn_[0] == a.qn_[0] && this->contracted() == a.contracted() &&
543 deriv_ == a.deriv_ && unit_ == a.unit_);
544 }
545
547 void inc(unsigned int dir, unsigned int c = 1u) override {
548 assert(!is_unit());
549 assert(dir == 0);
550 if (valid()) qn_[0] += c;
551 }
553 void dec(unsigned int dir, unsigned int c = 1u) override {
554 if (is_unit()) {
555 invalidate();
556 return;
557 }
558 assert(dir == 0);
559 if (valid()) {
560 if (qn_[0] < c) {
561 invalidate();
562 return;
563 }
564 qn_[0] -= c;
565 }
566 }
568 unsigned int norm() const override { return qn_[0]; }
570 LIBINT2_UINT_LEAST64 key() const override {
571 if (is_unit()) return max_key - 1;
572 const LIBINT2_UINT_LEAST64 result =
573 (deriv().key() * 2ul + (this->contracted() ? 1ul : 0ul)) * max_num_qn +
574 qn_[0];
575 if (result >= max_key - 1) {
576 this->print(std::cout);
577 std::cout << "result,max_key-1 = " << result << "," << max_key - 1
578 << std::endl;
579 assert(result < max_key - 1);
580 }
581 return result;
582 }
587 const static LIBINT2_UINT_LEAST64 max_num_qn = CGShell::max_qn + 1;
588 // deriv_key_range = OriginDerivative<1u>::max_key
589 // contracted = 2 (yes or no)
590 // qn_range = max_num_qn
591 // +1 to account for unit function
592 const static LIBINT2_UINT_LEAST64 max_key =
594 max_num_qn +
595 1;
596
598 void print(std::ostream& os = std::cout) const {
599 os << "CGF1d<" << to_string(Axis) << ">: " << label() << std::endl;
600 }
601
603 static CGF1d unit() {
604 CGF1d result;
605 result.unit_ = true;
606 result.uncontract();
607 return result;
608 }
609 bool is_unit() const { return unit_; }
610
611 private:
614 static std::array<LIBINT2_UINT_LEAST64, CGShell::max_qn + 1> key_l_offset;
615};
616
617// template <CartesianAxis Axis>
618// inline CGF1d<Axis> operator+(const CGF1d<Axis>& A, const CGF1d<Axis>& B) {
619// assert(A.is_unit() == false && B.is_unit() == false);
620// CGF1d<Axis> Sum(A);
621// Sum.inc(0,B.qn(0));
622// Sum.deriv_ += B.deriv_;
623// return Sum;
624// }
625// template <CartesianAxis Axis>
626// inline CGF1d<Axis> operator-(const CGF1d<Axis>& A, const CGF1d<Axis>& B) {
627// //assert(A.is_unit() == false && B.is_unit() == false);
628// CGF1d<Axis> Diff(A);
629// Diff.dec(0,B.qn(0));
630// Diff.deriv_ -= B.deriv_;
631//
632// return Diff;
633// }
634
644template <CartesianAxis Axis>
645class CGShell1d : public IncableBFSet,
646 public Hashable<LIBINT2_UINT_LEAST64, ComputeKey>,
647 public Contractable<CGShell1d<Axis> > {
648 unsigned int qn_[1];
650 bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
651
652 public:
653 static constexpr auto axis = Axis;
654
658
660 CGShell1d() : unit_(false) { qn_[0] = 0; }
661 CGShell1d(unsigned int qn) : unit_(false) { qn_[0] = qn; }
662 CGShell1d(unsigned int qn[1]) : unit_(false) { qn_[0] = qn[0]; }
663 CGShell1d(const CGShell1d& source)
664 : Contractable<CGShell1d>(source),
665 deriv_(source.deriv_),
666 unit_(source.unit_) {
667 qn_[0] = source.qn_[0];
668 }
669 virtual ~CGShell1d() {}
670
672 CGShell1d& operator=(const CGShell1d& source) {
673 qn_[0] = source.qn_[0];
674 deriv_ = source.deriv_;
675 unit_ = source.unit_;
677 if (!source.valid()) invalidate();
678 return *this;
679 }
680
681 const OriginDerivative<1u>& deriv() const { return deriv_; }
682 OriginDerivative<1u>& deriv() { return deriv_; }
683
685 std::string label() const override {
686 // unit *functions* are treated as regular qn-0 functions so that
687 // (00|00)^(m) = (unit 0|00)^(m)
688 std::ostringstream oss;
689 auto axis_label = to_string(Axis);
690 axis_label[0] = std::toupper(axis_label[0]);
691 oss << axis_label << qn_[0];
692 if (!deriv_.zero()) oss << "_" << deriv_.label();
693
694 // I don't handle labels of contracted CGF1d because I don't think I need
695 // them make sure just in case
696 assert(!this->contracted());
697
698 return oss.str();
699 }
700
702 unsigned int num_bf() const override { return qn_[0] + 1; }
704 unsigned int qn(unsigned int dir = 0) const {
705 assert(dir == 0);
706 return qn_[0];
707 }
708
710 bool operator==(const CGShell1d& a) const {
711 return (qn_[0] == a.qn_[0] && this->contracted() == a.contracted() &&
712 deriv_ == a.deriv_ && unit_ == a.unit_);
713 }
714
716 void inc(unsigned int dir, unsigned int c = 1u) override { assert(false); }
718 void dec(unsigned int dir, unsigned int c = 1u) override { assert(false); }
720 unsigned int norm() const override { return qn_[0]; }
722 LIBINT2_UINT_LEAST64 key() const override {
723 if (is_unit()) return max_key - 1;
724 const LIBINT2_UINT_LEAST64 result =
725 (deriv().key() * 2ul + (this->contracted() ? 1ul : 0ul)) * max_num_qn +
726 qn_[0];
727 if (result >= max_key - 1) {
728 this->print(std::cout);
729 std::cout << "result,max_key-1 = " << result << "," << max_key - 1
730 << std::endl;
731 assert(result < max_key - 1);
732 }
733 return result;
734 }
739 const static LIBINT2_UINT_LEAST64 max_num_qn = CGShell::max_qn + 1;
740 // deriv_key_range = OriginDerivative<1u>::max_key
741 // contracted = 2 (yes or no)
742 // qn_range = max_num_qn
743 // +1 to account for unit function
744 const static LIBINT2_UINT_LEAST64 max_key =
746 max_num_qn +
747 1;
748
750 void print(std::ostream& os = std::cout) const {
751 os << "CGShell1d<" << to_string(Axis) << ">: " << label() << std::endl;
752 }
753
755 static CGShell1d unit() {
756 CGShell1d result;
757 result.unit_ = true;
758 result.uncontract();
759 return result;
760 }
761 bool is_unit() const { return unit_; }
762
763 private:
766 static std::array<LIBINT2_UINT_LEAST64, CGShell::max_qn + 1> key_l_offset;
767};
768
769#endif
770
771#if 0
772 class SHGF; // forward declaration
773
775 class SHGShell : public IncableBFSet, public Hashable<unsigned,ReferToKey>,
776 public Contractable<SHGShell> {
777
778 unsigned int qn_[1];
779 OriginDerivative deriv_;
780
781 friend SHGShell operator+(const SHGShell& A, const SHGShell& B);
782 friend SHGShell operator-(const SHGShell& A, const SHGShell& B);
783
784 public:
788
791 SHGShell(unsigned int qn);
792 SHGShell(const SHGShell&);
793 virtual ~SHGShell();
794 SHGShell& operator=(const SHGShell&);
795
796 const OriginDerivative& deriv() const { return deriv_; }
797 OriginDerivative& deriv() { return deriv_; }
798
800 std::string label() const;
802 unsigned int num_bf() const { return 2*qn_[0]+1; };
804 unsigned int qn(unsigned int m=0) const { return qn_[0]; }
805
807 bool operator==(const SHGShell&) const;
808
810 void inc(unsigned int xyz, unsigned int c = 1u);
812 void dec(unsigned int xyz, unsigned int c = 1u);
814 unsigned int norm() const;
816 unsigned key() const { return (deriv().key() * 2 + (contracted() ? 1 : 0)) * (max_qn+1) + qn_[0]; }
817 const static unsigned max_qn = LIBINT_CARTGAUSS_MAX_AM;
818 // The range of keys is [0,max_key]
819 const static unsigned max_key = 2 * (max_qn + 1) * OriginDerivative::max_key * 2; // deriv_key_range = 2
820 // qn_range = max_qn + 1
821 // puresh_key_range = 2
822
824 void print(std::ostream& os = std::cout) const;
825
826 };
827
828 SHGShell operator+(const SHGShell& A, const SHGShell& B);
829 SHGShell operator-(const SHGShell& A, const SHGShell& B);
830
832 class SHGF : public IncableBFSet, public Hashable<unsigned,ComputeKey>,
833 public Contractable<SHGF> {
834
835 unsigned int qn_[3];
836 OriginDerivative deriv_;
837
838 friend SHGF operator+(const SHGF& A, const SHGF& B);
839 friend SHGF operator-(const SHGF& A, const SHGF& B);
840
841 public:
846 //typedef typename Hashable<unsigned,ComputeKey>::KeyReturnType KeyReturnType;
847
850 SHGF(unsigned int qn[3]);
851 SHGF(const SHGF&);
853 virtual ~SHGF();
856
857 const OriginDerivative& deriv() const { return deriv_; }
858 OriginDerivative& deriv() { return deriv_; }
859
861 std::string label() const;
863 unsigned int num_bf() const { return 1; };
865 unsigned int qn(unsigned int xyz) const;
866
868 bool operator==(const SHGF&) const;
869
871 void inc(unsigned int xyz, unsigned int c = 1u);
873 void dec(unsigned int xyz, unsigned int c = 1u);
875 unsigned int norm() const;
877 unsigned key() const {
878 unsigned nxy = qn_[1] + qn_[2];
879 unsigned l = nxy + qn_[0];
880 unsigned key = nxy*(nxy+1)/2 + qn_[2];
881 return ( deriv().key() * 2 + (contracted() ? 1 : 0)) * max_num_qn + key + key_l_offset.at(l);
882 }
886 const static unsigned max_num_qn = ((1 + (SHGShell::max_qn+1)) * (2 + (SHGShell::max_qn+1)) * (3 + (SHGShell::max_qn+1)) /6);
887 const static unsigned max_key = 2 * OriginDerivative::max_key * max_num_qn;
888
890 void print(std::ostream& os = std::cout) const;
891
892 private:
894 static unsigned key_l_offset[SHGShell::max_key+2];
895 };
896
897 SHGF operator+(const SHGF& A, const SHGF& B);
898 SHGF operator-(const SHGF& A, const SHGF& B);
899#endif
900
905template <class T>
907template <>
909 static const bool result = false;
910};
911template <>
913 static const bool result = true;
914};
915template <CartesianAxis Axis>
916struct TrivialBFSet<CGShell1d<Axis> > {
917 static const bool result = false;
918};
919template <CartesianAxis Axis>
920struct TrivialBFSet<CGF1d<Axis> > {
921 static const bool result = true;
922};
923#if 0
924 template <>
926 static const bool result = false;
927 };
928 template <>
930 static const bool result = true;
931 };
932#endif
933
934}; // namespace libint2
935
936#endif
Set of basis functions.
Definition bfset.h:43
Cartesian components of 3D CGF = 1D CGF.
Definition bfset.h:457
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition bfset.h:570
CGF1d & operator=(const CGF1d &source)
assignment
Definition bfset.h:489
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition bfset.h:587
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition bfset.h:568
unsigned int num_bf() const override
Returns the number of basis functions in the set (always 1)
Definition bfset.h:532
void inc(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition bfset.h:547
static CGF1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition bfset.h:603
void print(std::ostream &os=std::cout) const
Print out the content.
Definition bfset.h:598
std::string label() const override
Return a compact label.
Definition bfset.h:517
CGF1d iter_type
As far as SetIterator is concerned, CGF1d is a set of one CGF1d.
Definition bfset.h:466
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition bfset.h:534
bool operator==(const CGF1d &a) const
Comparison operator.
Definition bfset.h:541
void dec(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition bfset.h:553
CGF1d()
Default constructor makes an qn=0 Gaussian.
Definition bfset.h:470
3D Cartesian Gaussian Function
Definition bfset.h:345
void print(std::ostream &os=std::cout) const
Print out the content.
Definition gauss.cc:176
unsigned int qn(unsigned int axis) const
Returns the quantum number along axis.
Definition gauss.cc:134
CGF & operator=(const CGF &)
assignment
Definition gauss.cc:145
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition gauss.cc:174
bool operator==(const CGF &) const
Comparison operator.
Definition gauss.cc:139
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition bfset.h:401
static CGF unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition gauss.cc:195
void dec(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition gauss.cc:155
CGF iter_type
As far as SetIterator is concerned, CGF is a set of one CGF.
Definition bfset.h:357
unsigned int num_bf() const override
Returns the number of basis functions in the set (always 1)
Definition bfset.h:378
CGF()
How to return key.
Definition gauss.cc:84
std::string label() const override
Return a compact label.
Definition gauss.cc:111
void pure_sh(bool p)
Definition bfset.h:389
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition bfset.h:423
bool pure_sh() const
contains only solid harmonics with the same quantum number as this shell? (this may permit simplified...
Definition bfset.h:386
void inc(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition gauss.cc:169
a "shell" of 1D CGFs with quantum number L is a set of 1D CGFs with quantum numbers 0 .
Definition bfset.h:647
void inc(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition bfset.h:716
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition bfset.h:739
bool operator==(const CGShell1d &a) const
Comparison operator.
Definition bfset.h:710
unsigned int num_bf() const override
Returns the number of basis functions in the set (always 1)
Definition bfset.h:702
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition bfset.h:704
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition bfset.h:722
CGShell1d()
Default constructor makes a qn=0 shell.
Definition bfset.h:660
std::string label() const override
Return a compact label.
Definition bfset.h:685
void print(std::ostream &os=std::cout) const
Print out the content.
Definition bfset.h:750
static CGShell1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition bfset.h:755
CGShell1d & operator=(const CGShell1d &source)
assignment
Definition bfset.h:672
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition bfset.h:720
void dec(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition bfset.h:718
CGF1d< Axis > iter_type
CGShell1d is a set CGF1d's.
Definition bfset.h:656
3D Cartesian Gaussian Shell
Definition bfset.h:256
bool operator==(const CGShell &) const
Comparison operator.
Definition gauss.cc:242
CGShell()
Default constructor creates an s-type shell.
Definition gauss.cc:205
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition bfset.h:311
std::string label() const override
Return a compact label.
Definition gauss.cc:224
bool pure_sh() const
contains only solid harmonics with the same quantum number as this shell? (this may permit simplified...
Definition bfset.h:299
void dec(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition gauss.cc:247
unsigned int qn(unsigned int xyz=0) const
Returns the angular momentum.
Definition bfset.h:289
unsigned int operator[](unsigned int xyz) const
returns the angular momentum
Definition bfset.h:291
static const LIBINT2_UINT_LEAST64 max_key
The range of keys is [0,max_key] deriv_key_range = OriginDerivative<3u>::max_key contracted = 2 (yes ...
Definition bfset.h:328
void pure_sh(bool p)
Definition bfset.h:302
void print(std::ostream &os=std::cout) const
Print out the content.
Definition gauss.cc:268
static CGShell unit()
returns the unit shell (exponent=0, am=0, indicated by pure_sh=true)
Definition gauss.cc:288
unsigned int num_bf() const override
Returns the number of basis functions in the set.
Definition bfset.h:285
void inc(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition gauss.cc:261
CGF iter_type
As far as SetIterator is concerned, CGShell is a set of CGFs.
Definition bfset.h:269
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition gauss.cc:266
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
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition hashable.h:79
Set of basis functions with incrementable/decrementable quantum numbers.
Definition bfset.h:62
bool valid() const
Return false if this object is invalid.
Definition bfset.h:76
virtual unsigned int norm() const =0
Returns the norm of the quantum numbers.
void invalidate()
make this object invalid
Definition bfset.h:82
virtual void inc(unsigned int xyz, unsigned int c=1u)=0
Add c quanta along xyz.
virtual void dec(unsigned int xyz, unsigned int c=1u)=0
Subtract c quanta along xyz.
bool zero() const
norm() == 0
Definition bfset.h:74
Represents cartesian derivatives of atom-centered basis functions.
Definition bfset.h:101
static const unsigned max_key
The range of keys is [0,max_key).
Definition bfset.h:201
unsigned int operator[](unsigned int xyz) const
returns the number of quanta along xyz
Definition bfset.h:138
bool zero() const
norm() == 0
Definition bfset.h:158
void dec(unsigned int xyz, unsigned int c=1u)
Subtract c quanta along xyz.
Definition bfset.h:147
bool valid() const
Return false if this object is invalid.
Definition bfset.h:160
unsigned int norm() const
Returns the norm of the quantum numbers.
Definition bfset.h:156
void print(std::ostream &os=std::cout) const
Print out the content.
unsigned int d(unsigned int xyz) const
returns the number of quanta along xyz
Definition bfset.h:133
std::string label() const
Return a compact label.
Definition bfset.h:179
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<unsigned>::key()
Definition bfset.h:162
void inc(unsigned int xyz, unsigned int c=1u)
Add c quanta along xyz.
Definition bfset.h:140
void invalidate()
make this object invalid
Definition bfset.h:210
Solid-Harmonic Gaussian Function.
Definition bfset.h:833
static const unsigned max_num_qn
The range of keys is [0,max_key).
Definition bfset.h:886
unsigned int qn(unsigned int xyz) const
Returns the angular momentum.
void print(std::ostream &os=std::cout) const
Print out the content.
bool operator==(const SHGF &) const
Comparison operator.
SHGF iter_type
As far as SetIterator is concerned, SHGF is a set of one SHGF.
Definition bfset.h:843
SHGF()
How to return key.
unsigned key() const
Implements Hashable<unsigned>::key()
Definition bfset.h:877
void inc(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::inc().
std::string label() const
Return a compact label.
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition bfset.h:863
void dec(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::dec().
unsigned int norm() const
Implements IncableBFSet::norm()
SHGF & operator=(const SHGF &)
assignment
Solid-Harmonic Gaussian Shell.
Definition bfset.h:776
unsigned int norm() const
Implements IncableBFSet::norm()
unsigned key() const
Implements Hashable<unsigned>::key()
Definition bfset.h:816
std::string label() const
Return a compact label.
SHGShell()
Default constructor creates an s-type shell.
bool operator==(const SHGShell &) const
Comparison operator.
unsigned int qn(unsigned int m=0) const
Returns the angular momentum.
Definition bfset.h:804
SHGF iter_type
As far as SetIterator is concerned, SHGShell is a set of SHGFs.
Definition bfset.h:786
void inc(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::inc().
unsigned int num_bf() const
Returns the number of basis functions in the set.
Definition bfset.h:802
void dec(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::dec().
void print(std::ostream &os=std::cout) const
Print out the content.
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
std::string to_string(const T &x)
Converts x to its string representation.
Definition entity.h:121
F unit(unsigned int X)
BF with unit quantum along X. F must behave like IncableBFSet.
Definition bfset.h:90
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition bfset.h:906