LIBINT 2.7.2
bfset.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_bfset_h_
22#define _libint2_src_bin_libint_bfset_h_
23
24#include <iostream>
25#include <string>
26#include <cassert>
27#include <numeric>
28#include <sstream>
29#include <stdarray.h>
30#include <smart_ptr.h>
31#include <polyconstr.h>
32#include <hashable.h>
33#include <contractable.h>
34#include <global_macros.h>
35#include <util_types.h>
36
37namespace libint2 {
38
43
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 };
53
62 class IncableBFSet : public BFSet {
63
64 public:
65 virtual ~IncableBFSet() {}
66
68 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
89 template <typename F>
90 F unit(unsigned int X) { F tmp; tmp.inc(X,1); return tmp; }
92 inline bool exists(const IncableBFSet& A) { return A.valid(); }
93
96 template <unsigned NDIM = 3>
97 class OriginDerivative : public Hashable<LIBINT2_UINT_LEAST64,ReferToKey> {
98
99 static_assert(NDIM == 1 || NDIM == 3, "OriginDerivative<NDIM>: only NDIM=1 or NDIM=3 are supported");
100 public:
101 OriginDerivative() : valid_(true) {
102 for(auto d=0u; d!=NDIM; ++d) d_[d] = 0u;
103 }
104 OriginDerivative(const OriginDerivative& other) : valid_(true) {
105 std::copy(other.d_, other.d_ + NDIM, d_);
106 }
107 OriginDerivative& operator=(const OriginDerivative& other) {
108 valid_ = other.valid_;
109 std::copy(other.d_, other.d_ + NDIM, d_);
110 return *this;
111 }
112 OriginDerivative& operator+=(const OriginDerivative& other) {
113 assert(valid_);
114 for(auto d=0u; d!=NDIM; ++d) d_[d] += other.d_[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 }
123 static_assert(NDIM == 3u || NDIM == 1u, "OriginDerivative with NDIM=1,3 are implemented");
124 }
125
127 unsigned int d(unsigned int xyz) const {
128 assert(xyz < NDIM);
129 return d_[xyz];
130 }
132 unsigned int operator[](unsigned int xyz) const {
133 return this->d(xyz);
134 }
136 void inc(unsigned int xyz, unsigned int c = 1u) {
137 assert(xyz < NDIM);
138 assert(valid_);
139 d_[xyz] += c;
140 }
142 void dec(unsigned int xyz, unsigned int c = 1u) {
143 assert(xyz < NDIM);
144 //assert(valid_);
145 if (d_[xyz] >= c)
146 d_[xyz] -= c;
147 else
148 valid_ = false;
149 }
151 unsigned int norm() const {
152 return std::accumulate(d_, d_+NDIM, 0u);
153 }
155 bool zero() const { return norm() == 0; }
157 bool valid() const { return valid_; }
159 LIBINT2_UINT_LEAST64 key() const override {
160 if (NDIM == 3u) {
161 unsigned nxy = d_[1] + d_[2];
162 unsigned l = nxy + d_[0];
163 LIBINT2_UINT_LEAST64 key = nxy*(nxy+1)/2 + d_[2];
164 const auto result = key + key_l_offset.at(l);
165 assert(result < max_key);
166 return result;
167 }
168 if (NDIM == 1u) {
169 const auto result = d_[0];
170 assert(result < max_key);
171 return result;
172 }
173 assert(false);
174 }
176 std::string label() const {
177 char result[NDIM+1];
178 for(auto xyz=0u; xyz<NDIM; ++xyz) result[xyz] = '0' + d_[xyz];
179 result[NDIM] = '\0';
180 return std::string(result);
181 }
182
183 /* ---------------
184 * key computation
185 * --------------- */
186 const static unsigned max_deriv = 4;
187
188 // nkeys_l[L] is the number of possible OriginDerivative's with \c norm() == L
189 // \note for NDIM=1 nkeys_l[L] = 1
190 // \note for NDIM=2 nkeys_l[L] = (L+1)
191 // \note for NDIM=3 nkeys_l[L] = (L+1)(L+2)/2
192 //static std::array<LIBINT2_UINT_LEAST64, OriginDerivative::max_deriv+1> nkeys;
193
196 const static unsigned max_key = NDIM == 3 ? (1 + max_deriv)*(2 + max_deriv)*(3 + max_deriv)/6 : (1+max_deriv);
197
199 void print(std::ostream& os = std::cout) const;
200
201 protected:
202
204 void invalidate() { valid_ = false; }
205
206 private:
207 unsigned int d_[NDIM];
208 bool valid_; // indicates valid/invalid state
212
213 };
214
215 // explicit instantiation declaration, definitions are gauss.cc
216 template<>
217 std::array<LIBINT2_UINT_LEAST64, OriginDerivative<1u>::max_deriv+1> OriginDerivative<1u>::key_l_offset;
218 template<>
219 std::array<LIBINT2_UINT_LEAST64, OriginDerivative<3u>::max_deriv+1> OriginDerivative<3u>::key_l_offset;
220
221 template <unsigned NDIM>
222 OriginDerivative<NDIM> operator-(const OriginDerivative<NDIM>& A, const OriginDerivative<NDIM>& B) {
223 OriginDerivative<NDIM> Diff(A);
224 for(unsigned int xyz=0; xyz<3; ++xyz)
225 Diff.dec(xyz,B.d(xyz));
226 return Diff;
227 }
228
229 template <unsigned NDIM>
230 bool operator==(const OriginDerivative<NDIM>& A, const OriginDerivative<NDIM>& B) {
231 for(unsigned d=0; d!=NDIM; ++d)
232 if (A.d(d) != B.d(d))
233 return false;
234 return true;
235 }
236
238 template <unsigned NDIM> inline bool exists(const OriginDerivative<NDIM>& A) { return A.valid(); }
239
240 class CGF; // forward declaration of CGF
241
243 class CGShell : public IncableBFSet, public Hashable<LIBINT2_UINT_LEAST64,ReferToKey>,
244 public Contractable<CGShell> {
245
246 unsigned int qn_[1];
247 OriginDerivative<3> deriv_;
248 bool pure_sh_; //< if true, assumed to contain solid harmonics with quantum number qn_[0] only
250 bool unit_;
251
252 friend CGShell operator+(const CGShell& A, const CGShell& B);
253 friend CGShell operator-(const CGShell& A, const CGShell& B);
254
255 public:
257 typedef CGF iter_type;
259
261 CGShell();
262 CGShell(unsigned int qn, bool pure_sh = false);
263 CGShell(const CGShell&);
264 virtual ~CGShell();
265 CGShell& operator=(const CGShell&);
266
267 const OriginDerivative<3u>& deriv() const { return deriv_; }
268 OriginDerivative<3u>& deriv() { return deriv_; }
269
271 std::string label() const override;
273 unsigned int num_bf() const override { return (qn_[0]+1)*(qn_[0]+2)/2; }
275 unsigned int qn(unsigned int xyz=0) const { return qn_[0]; }
277 unsigned int operator[](unsigned int xyz) const {
278 return this->qn(xyz);
279 }
280
282 bool operator==(const CGShell&) const;
283
286 bool pure_sh() const { return pure_sh_; }
288 void pure_sh(bool p) { pure_sh_ = p; }
289
291 void inc(unsigned int xyz, unsigned int c = 1u) override;
293 void dec(unsigned int xyz, unsigned int c = 1u) override;
295 unsigned int norm() const override;
297 LIBINT2_UINT_LEAST64 key() const override {
298 if (is_unit()) return max_key-1;
299 const LIBINT2_UINT_LEAST64 result =
300 ((deriv().key() * 2 +
301 (contracted() ? 1 : 0)
302 ) * (max_qn+1) +
303 qn_[0]
304 ) * 2 +
305 (pure_sh() ? 1 : 0);
306 assert(result < max_key-1);
307 return result;
308 }
309 const static LIBINT2_UINT_LEAST64 max_qn = LIBINT_CARTGAUSS_MAX_AM;
317 const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<3u>::max_key * 2 * (max_qn + 1) * 2 + 1;
318
320 void print(std::ostream& os = std::cout) const;
321
323 static CGShell unit();
324 bool is_unit() const { return unit_; }
325
326 };
327
328 CGShell operator+(const CGShell& A, const CGShell& B);
329 CGShell operator-(const CGShell& A, const CGShell& B);
330
332 class CGF : public IncableBFSet, public Hashable<LIBINT2_UINT_LEAST64,ComputeKey>,
333 public Contractable<CGF> {
334
335 unsigned int qn_[3];
337 bool pure_sh_; //< if true, assumed to contain solid harmonics with quantum number qn_[0] only
338 bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
339
340 friend CGF operator+(const CGF& A, const CGF& B);
341 friend CGF operator-(const CGF& A, const CGF& B);
342
343 public:
345 typedef CGF iter_type;
348 //typedef typename Hashable<unsigned,ComputeKey>::KeyReturnType KeyReturnType;
349
351 CGF();
352 CGF(unsigned int qn[3], bool pure_sh = false);
353 CGF(const CGF&);
354 explicit CGF(const ConstructablePolymorphically&);
355 virtual ~CGF();
357 CGF& operator=(const CGF&);
358
359 const OriginDerivative<3u>& deriv() const { return deriv_; }
360 OriginDerivative<3u>& deriv() { return deriv_; }
361
363 std::string label() const override;
365 unsigned int num_bf() const override { return 1; }
367 unsigned int qn(unsigned int axis) const;
368 unsigned int operator[](unsigned int axis) const {
369 return qn(axis);
370 }
371
374 bool pure_sh() const { return pure_sh_; }
376 void pure_sh(bool p) { pure_sh_ = p; }
377
379 bool operator==(const CGF&) const;
380
382 void inc(unsigned int xyz, unsigned int c = 1u) override;
384 void dec(unsigned int xyz, unsigned int c = 1u) override;
386 unsigned int norm() const override;
388 LIBINT2_UINT_LEAST64 key() const override {
389 if (is_unit()) return max_key-1;
390 unsigned nxy = qn_[1] + qn_[2];
391 unsigned l = nxy + qn_[0];
392 LIBINT2_UINT_LEAST64 key = nxy*(nxy+1)/2 + qn_[2];
393 const LIBINT2_UINT_LEAST64 result =
394 ( ( deriv().key() * 2 +
395 (contracted() ? 1 : 0)
396 ) * max_num_qn +
397 key + key_l_offset.at(l)
398 ) * 2
399 + (pure_sh() ? 1 : 0);
400 if (result >= max_key-1) {
401 this->print(std::cout);
402 std::cout << "result,max_key-1 = " << result << "," << max_key-1 << std::endl;
403 assert(result < max_key-1);
404 }
405 return result;
406 }
410 const static LIBINT2_UINT_LEAST64 max_num_qn = ((1 + (CGShell::max_qn+1)) * (2 + (CGShell::max_qn+1)) * (3 + (CGShell::max_qn+1)) /6);
411 // deriv_key_range = OriginDerivative<3u>::max_key
412 // contracted = 2 (yes or no)
413 // qn_range = max_num_qn
414 // puresh_key_range = 2
415 // +1 to account for unit function
416 const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<3u>::max_key * 2ul * max_num_qn * 2ul + 1;
417
419 void print(std::ostream& os = std::cout) const;
420
422 static CGF unit();
423 bool is_unit() const { return unit_; }
424
425 private:
428 };
429
430 CGF operator+(const CGF& A, const CGF& B);
431 CGF operator-(const CGF& A, const CGF& B);
432
433#if 1
437 template <CartesianAxis Axis>
438 class CGF1d : public IncableBFSet,
439 public Hashable<LIBINT2_UINT_LEAST64, ComputeKey>,
440 public Contractable<CGF1d<Axis> > {
441 unsigned int qn_[1];
443 bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
444
445 public:
446
447 static constexpr auto axis = Axis;
448
452
454 CGF1d() : unit_(false) { qn_[0] = 0; }
455 CGF1d(unsigned int qn) : unit_(false) { qn_[0] = qn; }
456 CGF1d(unsigned int qn[1]) : unit_(false) { qn_[0] = qn[0]; }
457 CGF1d(const CGF1d& source) : Contractable<CGF1d>(source),
458 deriv_(source.deriv_), unit_(source.unit_)
459 {
460 qn_[0] = source.qn_[0];
461 }
462 explicit CGF1d(const ConstructablePolymorphically& sptr) :
463 Contractable<CGF1d>(dynamic_cast<const CGF1d&>(sptr))
464 {
465 const CGF1d& sptr_cast = dynamic_cast<const CGF1d&>(sptr);
466 qn_[0] = sptr_cast.qn_[0];
467 deriv_ = sptr_cast.deriv_;
468 unit_ = sptr_cast.unit_;
469 }
470 virtual ~CGF1d() {
471 }
472
474 CGF1d& operator=(const CGF1d& source)
475 {
476 qn_[0] = source.qn_[0];
477 deriv_ = source.deriv_;
478 unit_ = source.unit_;
480 if (!source.valid()) invalidate();
481 return *this;
482 }
483
484 CGF1d operator+(const CGF1d& B) const {
485 //assert(this->is_unit() == false && B.is_unit() == false);
486 CGF1d<Axis> Sum(*this);
487 Sum.inc(0,B.qn(0));
488 Sum.deriv_ += B.deriv_;
489 return Sum;
490 }
491 CGF1d operator-(const CGF1d& B) const {
492 //assert(A.is_unit() == false && B.is_unit() == false);
493 CGF1d Diff(*this);
494 Diff.dec(0,B.qn(0));
495 Diff.deriv_ -= B.deriv_;
496 return Diff;
497 }
498
499 const OriginDerivative<1u>& deriv() const { return deriv_; }
500 OriginDerivative<1u>& deriv() { return deriv_; }
501
503 std::string label() const override {
504 // unit *functions* are treated as regular qn-0 functions so that (00|00)^(m) = (unit 0|00)^(m)
505 std::ostringstream oss;
506 oss << to_string(Axis) << qn_[0];
507 if (!deriv_.zero()) oss << "_" << deriv_.label();
508
509 // I don't handle labels of contracted CGF1d because I don't think I need them
510 // make sure just in case
511 assert(!this->contracted());
512
513 return oss.str();
514 }
515
516
518 unsigned int num_bf() const override { return 1; }
520 unsigned int qn(unsigned int dir = 0) const {
521 assert(dir == 0);
522 return qn_[0];
523 }
524 unsigned int operator[](unsigned int dir) const {
525 return this->qn(dir);
526 }
527
529 bool operator==(const CGF1d& a) const {
530 return ( qn_[0] == a.qn_[0] &&
531 this->contracted() == a.contracted() &&
532 deriv_ == a.deriv_ &&
533 unit_ == a.unit_);
534 }
535
537 void inc(unsigned int dir, unsigned int c = 1u) override {
538 assert(!is_unit());
539 assert(dir==0);
540 if (valid())
541 qn_[0] += c;
542 }
544 void dec(unsigned int dir, unsigned int c = 1u) override {
545 if (is_unit()) { invalidate(); return; }
546 assert(dir==0);
547 if (valid()) {
548 if (qn_[0] < c) {
549 invalidate();
550 return;
551 }
552 qn_[0] -= c;
553 }
554 }
556 unsigned int norm() const override { return qn_[0]; }
558 LIBINT2_UINT_LEAST64 key() const override {
559 if (is_unit()) return max_key-1;
560 const LIBINT2_UINT_LEAST64 result =
561 ( deriv().key() * 2ul +
562 (this->contracted() ? 1ul : 0ul)
563 ) * max_num_qn +
564 qn_[0];
565 if (result >= max_key-1) {
566 this->print(std::cout);
567 std::cout << "result,max_key-1 = " << result << "," << max_key-1 << std::endl;
568 assert(result < max_key-1);
569 }
570 return result;
571 }
575 const static LIBINT2_UINT_LEAST64 max_num_qn = CGShell::max_qn+1;
576 // deriv_key_range = OriginDerivative<1u>::max_key
577 // contracted = 2 (yes or no)
578 // qn_range = max_num_qn
579 // +1 to account for unit function
580 const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<1u>::max_key * OriginDerivative<1u>::max_key * max_num_qn + 1;
581
583 void print(std::ostream& os = std::cout) const {
584 os << "CGF1d<" << to_string(Axis) << ">: " << label() << std::endl;
585 }
586
588 static CGF1d unit() {
589 CGF1d result;
590 result.unit_ = true;
591 result.uncontract();
592 return result;
593 }
594 bool is_unit() const { return unit_; }
595
596 private:
599 };
600
601// template <CartesianAxis Axis>
602// inline CGF1d<Axis> operator+(const CGF1d<Axis>& A, const CGF1d<Axis>& B) {
603// assert(A.is_unit() == false && B.is_unit() == false);
604// CGF1d<Axis> Sum(A);
605// Sum.inc(0,B.qn(0));
606// Sum.deriv_ += B.deriv_;
607// return Sum;
608// }
609// template <CartesianAxis Axis>
610// inline CGF1d<Axis> operator-(const CGF1d<Axis>& A, const CGF1d<Axis>& B) {
611// //assert(A.is_unit() == false && B.is_unit() == false);
612// CGF1d<Axis> Diff(A);
613// Diff.dec(0,B.qn(0));
614// Diff.deriv_ -= B.deriv_;
615//
616// return Diff;
617// }
618
619
626 template <CartesianAxis Axis>
627 class CGShell1d : public IncableBFSet, public Hashable<LIBINT2_UINT_LEAST64,ComputeKey>,
628 public Contractable< CGShell1d<Axis> > {
629
630 unsigned int qn_[1];
632 bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
633
634 public:
635
636 static constexpr auto axis = Axis;
637
641
643 CGShell1d() : unit_(false) { qn_[0] = 0; }
644 CGShell1d(unsigned int qn) : unit_(false) { qn_[0] = qn; }
645 CGShell1d(unsigned int qn[1]) : unit_(false) { qn_[0] = qn[0]; }
646 CGShell1d(const CGShell1d& source) : Contractable<CGShell1d>(source),
647 deriv_(source.deriv_), unit_(source.unit_)
648 {
649 qn_[0] = source.qn_[0];
650 }
651 virtual ~CGShell1d() {
652 }
653
656 {
657 qn_[0] = source.qn_[0];
658 deriv_ = source.deriv_;
659 unit_ = source.unit_;
661 if (!source.valid()) invalidate();
662 return *this;
663 }
664
665 const OriginDerivative<1u>& deriv() const { return deriv_; }
666 OriginDerivative<1u>& deriv() { return deriv_; }
667
669 std::string label() const override {
670 // unit *functions* are treated as regular qn-0 functions so that (00|00)^(m) = (unit 0|00)^(m)
671 std::ostringstream oss;
672 auto axis_label = to_string(Axis);
673 axis_label[0] = std::toupper(axis_label[0]);
674 oss << axis_label << qn_[0];
675 if (!deriv_.zero()) oss << "_" << deriv_.label();
676
677 // I don't handle labels of contracted CGF1d because I don't think I need them
678 // make sure just in case
679 assert(!this->contracted());
680
681 return oss.str();
682 }
683
684
686 unsigned int num_bf() const override { return qn_[0]+1; }
688 unsigned int qn(unsigned int dir=0) const {
689 assert(dir == 0);
690 return qn_[0];
691 }
692
694 bool operator==(const CGShell1d& a) const {
695 return ( qn_[0] == a.qn_[0] &&
696 this->contracted() == a.contracted() &&
697 deriv_ == a.deriv_ &&
698 unit_ == a.unit_);
699 }
700
702 void inc(unsigned int dir, unsigned int c = 1u) override {
703 assert(false);
704 }
706 void dec(unsigned int dir, unsigned int c = 1u) override {
707 assert(false);
708 }
710 unsigned int norm() const override { return qn_[0]; }
712 LIBINT2_UINT_LEAST64 key() const override {
713 if (is_unit()) return max_key-1;
714 const LIBINT2_UINT_LEAST64 result =
715 ( deriv().key() * 2ul +
716 (this->contracted() ? 1ul : 0ul)
717 ) * max_num_qn +
718 qn_[0];
719 if (result >= max_key-1) {
720 this->print(std::cout);
721 std::cout << "result,max_key-1 = " << result << "," << max_key-1 << std::endl;
722 assert(result < max_key-1);
723 }
724 return result;
725 }
729 const static LIBINT2_UINT_LEAST64 max_num_qn = CGShell::max_qn+1;
730 // deriv_key_range = OriginDerivative<1u>::max_key
731 // contracted = 2 (yes or no)
732 // qn_range = max_num_qn
733 // +1 to account for unit function
734 const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<1u>::max_key * OriginDerivative<1u>::max_key * max_num_qn + 1;
735
737 void print(std::ostream& os = std::cout) const {
738 os << "CGShell1d<" << to_string(Axis) << ">: " << label() << std::endl;
739 }
740
742 static CGShell1d unit() {
743 CGShell1d result;
744 result.unit_ = true;
745 result.uncontract();
746 return result;
747 }
748 bool is_unit() const { return unit_; }
749
750 private:
753 };
754
755#endif
756
757#if 0
758 class SHGF; // forward declaration
759
761 class SHGShell : public IncableBFSet, public Hashable<unsigned,ReferToKey>,
762 public Contractable<SHGShell> {
763
764 unsigned int qn_[1];
765 OriginDerivative deriv_;
766
767 friend SHGShell operator+(const SHGShell& A, const SHGShell& B);
768 friend SHGShell operator-(const SHGShell& A, const SHGShell& B);
769
770 public:
774
777 SHGShell(unsigned int qn);
778 SHGShell(const SHGShell&);
779 virtual ~SHGShell();
780 SHGShell& operator=(const SHGShell&);
781
782 const OriginDerivative& deriv() const { return deriv_; }
783 OriginDerivative& deriv() { return deriv_; }
784
786 std::string label() const;
788 unsigned int num_bf() const { return 2*qn_[0]+1; };
790 unsigned int qn(unsigned int m=0) const { return qn_[0]; }
791
793 bool operator==(const SHGShell&) const;
794
796 void inc(unsigned int xyz, unsigned int c = 1u);
798 void dec(unsigned int xyz, unsigned int c = 1u);
800 unsigned int norm() const;
802 unsigned key() const { return (deriv().key() * 2 + (contracted() ? 1 : 0)) * (max_qn+1) + qn_[0]; }
803 const static unsigned max_qn = LIBINT_CARTGAUSS_MAX_AM;
804 // The range of keys is [0,max_key]
805 const static unsigned max_key = 2 * (max_qn + 1) * OriginDerivative::max_key * 2; // deriv_key_range = 2
806 // qn_range = max_qn + 1
807 // puresh_key_range = 2
808
810 void print(std::ostream& os = std::cout) const;
811
812 };
813
814 SHGShell operator+(const SHGShell& A, const SHGShell& B);
815 SHGShell operator-(const SHGShell& A, const SHGShell& B);
816
818 class SHGF : public IncableBFSet, public Hashable<unsigned,ComputeKey>,
819 public Contractable<SHGF> {
820
821 unsigned int qn_[3];
822 OriginDerivative deriv_;
823
824 friend SHGF operator+(const SHGF& A, const SHGF& B);
825 friend SHGF operator-(const SHGF& A, const SHGF& B);
826
827 public:
832 //typedef typename Hashable<unsigned,ComputeKey>::KeyReturnType KeyReturnType;
833
836 SHGF(unsigned int qn[3]);
837 SHGF(const SHGF&);
839 virtual ~SHGF();
842
843 const OriginDerivative& deriv() const { return deriv_; }
844 OriginDerivative& deriv() { return deriv_; }
845
847 std::string label() const;
849 unsigned int num_bf() const { return 1; };
851 unsigned int qn(unsigned int xyz) const;
852
854 bool operator==(const SHGF&) const;
855
857 void inc(unsigned int xyz, unsigned int c = 1u);
859 void dec(unsigned int xyz, unsigned int c = 1u);
861 unsigned int norm() const;
863 unsigned key() const {
864 unsigned nxy = qn_[1] + qn_[2];
865 unsigned l = nxy + qn_[0];
866 unsigned key = nxy*(nxy+1)/2 + qn_[2];
867 return ( deriv().key() * 2 + (contracted() ? 1 : 0)) * max_num_qn + key + key_l_offset.at(l);
868 }
872 const static unsigned max_num_qn = ((1 + (SHGShell::max_qn+1)) * (2 + (SHGShell::max_qn+1)) * (3 + (SHGShell::max_qn+1)) /6);
873 const static unsigned max_key = 2 * OriginDerivative::max_key * max_num_qn;
874
876 void print(std::ostream& os = std::cout) const;
877
878 private:
880 static unsigned key_l_offset[SHGShell::max_key+2];
881 };
882
883 SHGF operator+(const SHGF& A, const SHGF& B);
884 SHGF operator-(const SHGF& A, const SHGF& B);
885#endif
886
891 template <class T>
893 template <>
895 static const bool result = false;
896 };
897 template <>
899 static const bool result = true;
900 };
901 template <CartesianAxis Axis>
902 struct TrivialBFSet< CGShell1d<Axis> > {
903 static const bool result = false;
904 };
905 template <CartesianAxis Axis>
906 struct TrivialBFSet< CGF1d<Axis> > {
907 static const bool result = true;
908 };
909#if 0
910 template <>
912 static const bool result = false;
913 };
914 template <>
916 static const bool result = true;
917 };
918#endif
919
920};
921
922#endif
923
Set of basis functions.
Definition: bfset.h:42
Cartesian components of 3D CGF = 1D CGF.
Definition: bfset.h:440
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:558
CGF1d & operator=(const CGF1d &source)
assignment
Definition: bfset.h:474
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:575
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition: bfset.h:556
unsigned int num_bf() const override
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:518
void inc(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition: bfset.h:537
static CGF1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: bfset.h:588
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: bfset.h:583
std::string label() const override
Return a compact label.
Definition: bfset.h:503
CGF1d iter_type
As far as SetIterator is concerned, CGF1d is a set of one CGF1d.
Definition: bfset.h:450
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition: bfset.h:520
bool operator==(const CGF1d &a) const
Comparison operator.
Definition: bfset.h:529
void dec(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition: bfset.h:544
CGF1d()
Default constructor makes an qn=0 Gaussian.
Definition: bfset.h:454
3D Cartesian Gaussian Function
Definition: bfset.h:333
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: gauss.cc:202
unsigned int qn(unsigned int axis) const
Returns the quantum number along axis.
Definition: gauss.cc:143
CGF & operator=(const CGF &)
assignment
Definition: gauss.cc:162
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition: gauss.cc:196
bool operator==(const CGF &) const
Comparison operator.
Definition: gauss.cc:150
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:388
static CGF unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: gauss.cc:228
void dec(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition: gauss.cc:175
CGF iter_type
As far as SetIterator is concerned, CGF is a set of one CGF.
Definition: bfset.h:345
unsigned int num_bf() const override
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:365
CGF()
How to return key.
Definition: gauss.cc:81
std::string label() const override
Return a compact label.
Definition: gauss.cc:119
void pure_sh(bool p)
Definition: bfset.h:376
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:410
bool pure_sh() const
contains only solid harmonics with the same quantum number as this shell? (this may permit simplified...
Definition: bfset.h:374
void inc(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition: gauss.cc:188
a "shell" of 1D CGFs with quantum number L is a set of 1D CGFs with quantum numbers 0 .
Definition: bfset.h:628
void inc(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition: bfset.h:702
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:729
bool operator==(const CGShell1d &a) const
Comparison operator.
Definition: bfset.h:694
unsigned int num_bf() const override
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:686
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition: bfset.h:688
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:712
CGShell1d()
Default constructor makes a qn=0 shell.
Definition: bfset.h:643
std::string label() const override
Return a compact label.
Definition: bfset.h:669
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: bfset.h:737
static CGShell1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: bfset.h:742
CGShell1d & operator=(const CGShell1d &source)
assignment
Definition: bfset.h:655
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition: bfset.h:710
void dec(unsigned int dir, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition: bfset.h:706
CGF1d< Axis > iter_type
CGShell1d is a set CGF1d's.
Definition: bfset.h:639
3D Cartesian Gaussian Shell
Definition: bfset.h:244
bool operator==(const CGShell &) const
Comparison operator.
Definition: gauss.cc:285
CGShell()
Default constructor creates an s-type shell.
Definition: gauss.cc:238
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:297
std::string label() const override
Return a compact label.
Definition: gauss.cc:262
bool pure_sh() const
contains only solid harmonics with the same quantum number as this shell? (this may permit simplified...
Definition: bfset.h:286
void dec(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::dec().
Definition: gauss.cc:295
unsigned int qn(unsigned int xyz=0) const
Returns the angular momentum.
Definition: bfset.h:275
unsigned int operator[](unsigned int xyz) const
returns the angular momentum
Definition: bfset.h:277
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:317
void pure_sh(bool p)
Definition: bfset.h:288
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: gauss.cc:322
static CGShell unit()
returns the unit shell (exponent=0, am=0, indicated by pure_sh=true)
Definition: gauss.cc:345
unsigned int num_bf() const override
Returns the number of basis functions in the set.
Definition: bfset.h:273
void inc(unsigned int xyz, unsigned int c=1u) override
Implementation of IncableBFSet::inc().
Definition: gauss.cc:308
CGF iter_type
As far as SetIterator is concerned, CGShell is a set of CGFs.
Definition: bfset.h:257
unsigned int norm() const override
Implements IncableBFSet::norm()
Definition: gauss.cc:316
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:31
use this as a base to add to Derived a "contracted()" attribute
Definition: contractable.h:27
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition: hashable.h:74
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. If impossible, invalidate the object, but do not change its quanta!
bool zero() const
norm() == 0
Definition: bfset.h:74
Represents cartesian derivatives of atom-centered basis functions.
Definition: bfset.h:97
static const unsigned max_key
The range of keys is [0,max_key).
Definition: bfset.h:196
unsigned int operator[](unsigned int xyz) const
returns the number of quanta along xyz
Definition: bfset.h:132
bool zero() const
norm() == 0
Definition: bfset.h:155
void dec(unsigned int xyz, unsigned int c=1u)
Subtract c quanta along xyz. If impossible, invalidate the object, but do not change its quanta!
Definition: bfset.h:142
bool valid() const
Return false if this object is invalid.
Definition: bfset.h:157
unsigned int norm() const
Returns the norm of the quantum numbers.
Definition: bfset.h:151
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:127
std::string label() const
Return a compact label.
Definition: bfset.h:176
LIBINT2_UINT_LEAST64 key() const override
Implements Hashable<unsigned>::key()
Definition: bfset.h:159
void inc(unsigned int xyz, unsigned int c=1u)
Add c quanta along xyz.
Definition: bfset.h:136
void invalidate()
make this object invalid
Definition: bfset.h:204
Solid-Harmonic Gaussian Function.
Definition: bfset.h:819
static const unsigned max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:872
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:829
SHGF()
How to return key.
unsigned key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:863
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:849
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:762
unsigned int norm() const
Implements IncableBFSet::norm()
unsigned key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:802
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:790
SHGF iter_type
As far as SetIterator is concerned, SHGShell is a set of SHGFs.
Definition: bfset.h:772
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:788
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:92
std::string to_string(const T &x)
Converts x to its string representation.
Definition: entity.h:74
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:892