LIBINT  2.6.0
bfset.h
1 /*
2  * Copyright (C) 2004-2019 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 
37 namespace 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  }
122  ~OriginDerivative() {
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 {
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;
258  typedef IncableBFSet parent_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;
273  unsigned int num_bf() const { 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);
293  void dec(unsigned int xyz, unsigned int c = 1u);
295  unsigned int norm() const;
297  LIBINT2_UINT_LEAST64 key() const {
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];
336  OriginDerivative<3u> deriv_;
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;
346  typedef IncableBFSet parent_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;
365  unsigned int num_bf() const { 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);
384  void dec(unsigned int xyz, unsigned int c = 1u);
386  unsigned int norm() const;
388  LIBINT2_UINT_LEAST64 key() const {
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
434  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];
442  OriginDerivative<1u> deriv_;
443  bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
444 
445  public:
446 
447  static constexpr auto axis = Axis;
448 
450  typedef CGF1d iter_type;
451  typedef IncableBFSet parent_type;
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 {
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() == false) 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() == false);
512 
513  return oss.str();
514  }
515 
516 
518  unsigned int num_bf() const { 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) {
538  assert(is_unit() == false);
539  assert(dir==0);
540  if (valid())
541  qn_[0] += c;
542  }
544  void dec(unsigned int dir, unsigned int c = 1u) {
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 { return qn_[0]; }
558  LIBINT2_UINT_LEAST64 key() const {
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];
631  OriginDerivative<1u> deriv_;
632  bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
633 
634  public:
635 
636  static constexpr auto axis = Axis;
637 
640  typedef IncableBFSet parent_type;
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 
655  CGShell1d& operator=(const CGShell1d& source)
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 {
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() == false) 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() == false);
680 
681  return oss.str();
682  }
683 
684 
686  unsigned int num_bf() const { 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) {
703  assert(false);
704  }
706  void dec(unsigned int dir, unsigned int c = 1u) {
707  assert(false);
708  }
710  unsigned int norm() const { return qn_[0]; }
712  LIBINT2_UINT_LEAST64 key() const {
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:
772  typedef SHGF iter_type;
773  typedef IncableBFSet parent_type;
774 
776  SHGShell();
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:
829  typedef SHGF iter_type;
830  typedef IncableBFSet parent_type;
832  //typedef typename Hashable<unsigned,ComputeKey>::KeyReturnType KeyReturnType;
833 
835  SHGF();
836  SHGF(unsigned int qn[3]);
837  SHGF(const SHGF&);
839  virtual ~SHGF();
841  SHGF& operator=(const 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>
892  struct TrivialBFSet;
893  template <>
895  static const bool result = false;
896  };
897  template <>
898  struct TrivialBFSet<CGF> {
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 <>
915  struct TrivialBFSet<SHGF> {
916  static const bool result = true;
917  };
918 #endif
919 
920 };
921 
922 #endif
923 
bool operator==(const CGShell1d &a) const
Comparison operator.
Definition: bfset.h:694
std::string label() const
Return a compact label.
Definition: bfset.h:176
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: bfset.h:583
std::string label() const
Return a compact label.
Definition: bfset.h:503
use this as a base to add to Derived a "contracted()" attribute
Definition: contractable.h:27
Cartesian components of 3D CGF = 1D CGF.
Definition: bfset.h:438
void dec(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::dec().
Definition: gauss.cc:295
unsigned key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:863
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition: bfset.h:892
Set of basis functions with incrementable/decrementable quantum numbers.
Definition: bfset.h:62
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition: bfset.h:520
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:31
3D Cartesian Gaussian Shell
Definition: bfset.h:243
static CGF1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: bfset.h:588
void dec(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::dec().
Definition: bfset.h:544
std::string label() const
Return a compact label.
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType.
Definition: hashable.h:73
a "shell" of 1D CGFs with quantum number L is a set of 1D CGFs with quantum numbers 0 .
Definition: bfset.h:627
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
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:849
virtual void inc(unsigned int xyz, unsigned int c=1u)=0
Add c quanta along xyz.
CGF1d & operator=(const CGF1d &source)
assignment
Definition: bfset.h:474
CGShell()
Default constructor creates an s-type shell.
Definition: gauss.cc:238
unsigned int norm() const
Returns the norm of the quantum numbers.
Definition: bfset.h:151
unsigned int num_bf() const
Returns the number of basis functions in the set.
Definition: bfset.h:273
void dec(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::dec().
Definition: gauss.cc:175
void dec(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::dec().
Definition: bfset.h:706
CGF iter_type
As far as SetIterator is concerned, CGShell is a set of CGFs.
Definition: bfset.h:257
unsigned int norm() const
Implements IncableBFSet::norm()
Definition: bfset.h:710
SHGF iter_type
As far as SetIterator is concerned, SHGShell is a set of SHGFs.
Definition: bfset.h:772
unsigned int qn(unsigned int xyz) const
Returns the angular momentum.
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:686
CGF1d iter_type
As far as SetIterator is concerned, CGF1d is a set of one CGF1d.
Definition: bfset.h:450
std::string label() const
Return a compact label.
Definition: gauss.cc:262
SHGF & operator=(const SHGF &)
assignment
Solid-Harmonic Gaussian Shell.
Definition: bfset.h:761
unsigned int norm() const
Implements IncableBFSet::norm()
Definition: bfset.h:556
CGF()
How to return key.
Definition: gauss.cc:81
virtual unsigned int norm() const =0
Returns the norm of the quantum numbers.
bool operator==(const SHGShell &) const
Comparison operator.
CGF1d()
Default constructor makes an qn=0 Gaussian.
Definition: bfset.h:454
unsigned int norm() const
Implements IncableBFSet::norm()
Definition: gauss.cc:196
unsigned int d(unsigned int xyz) const
returns the number of quanta along xyz
Definition: bfset.h:127
bool zero() const
norm() == 0
Definition: bfset.h:74
bool pure_sh() const
contains only solid harmonics with the same quantum number as this shell? (this may permit simplified...
Definition: bfset.h:374
bool operator==(const SHGF &) const
Comparison operator.
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:365
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:518
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:159
void inc(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::inc().
Definition: gauss.cc:188
unsigned int qn(unsigned int m=0) const
Returns the angular momentum.
Definition: bfset.h:790
std::string to_string(const T &x)
Converts x to its string representation.
Definition: entity.h:74
static CGF unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: gauss.cc:228
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:712
unsigned int norm() const
Implements IncableBFSet::norm()
void inc(unsigned int xyz, unsigned int c=1u)
Add c quanta along xyz.
Definition: bfset.h:136
void dec(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::dec().
CGF1d< Axis > iter_type
CGShell1d is a set CGF1d's.
Definition: bfset.h:639
std::string label() const
Return a compact label.
Definition: bfset.h:669
void inc(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::inc().
bool valid() const
Return false if this object is invalid.
Definition: bfset.h:157
static const unsigned max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:872
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
F unit(unsigned int X)
BF with unit quantum along X. F must behave like IncableBFSet.
Definition: bfset.h:90
bool operator==(const CGShell &) const
Comparison operator.
Definition: gauss.cc:285
void inc(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::inc().
Definition: bfset.h:537
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.
Definition: gauss.cc:322
void inc(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::inc().
Definition: gauss.cc:308
unsigned int num_bf() const
Returns the number of basis functions in the set.
Definition: bfset.h:788
CGF & operator=(const CGF &)
assignment
Definition: gauss.cc:162
bool zero() const
norm() == 0
Definition: bfset.h:155
SHGShell()
Default constructor creates an s-type shell.
void print(std::ostream &os=std::cout) const
Print out the content.
bool exists(const IncableBFSet &A)
Return true if A is valid.
Definition: bfset.h:92
void inc(unsigned int xyz, unsigned int c=1u)
Implementation of IncableBFSet::inc().
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:558
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:410
std::string label() const
Return a compact label.
Definition: gauss.cc:119
void print(std::ostream &os=std::cout) const
Print out the content.
unsigned int qn(unsigned int axis) const
Returns the quantum number along axis.
Definition: gauss.cc:143
unsigned int qn(unsigned int xyz=0) const
Returns the angular momentum.
Definition: bfset.h:275
SHGF iter_type
As far as SetIterator is concerned, SHGF is a set of one SHGF.
Definition: bfset.h:829
void inc(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::inc().
Definition: bfset.h:702
SHGF()
How to return key.
bool operator==(const CGF1d &a) const
Comparison operator.
Definition: bfset.h:529
Set of basis functions.
Definition: bfset.h:42
unsigned int norm() const
Implements IncableBFSet::norm()
Definition: gauss.cc:316
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:729
static CGShell unit()
returns the unit shell (exponent=0, am=0, indicated by pure_sh=true)
Definition: gauss.cc:345
CGShell1d()
Default constructor makes a qn=0 shell.
Definition: bfset.h:643
unsigned int norm() const
Implements IncableBFSet::norm()
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
Solid-Harmonic Gaussian Function.
Definition: bfset.h:818
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition: bfset.h:688
void invalidate()
make this object invalid
Definition: bfset.h:82
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: gauss.cc:202
unsigned key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:802
void pure_sh(bool p)
Definition: bfset.h:288
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!
CGShell1d & operator=(const CGShell1d &source)
assignment
Definition: bfset.h:655
static CGShell1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: bfset.h:742
static const LIBINT2_UINT_LEAST64 max_num_qn
The range of keys is [0,max_key).
Definition: bfset.h:575
3D Cartesian Gaussian Function
Definition: bfset.h:332
Represents cartesian derivatives of atom-centered basis functions.
Definition: bfset.h:97
CGF iter_type
As far as SetIterator is concerned, CGF is a set of one CGF.
Definition: bfset.h:345
void pure_sh(bool p)
Definition: bfset.h:376
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 print(std::ostream &os=std::cout) const
Print out the content.
Definition: bfset.h:737
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:297
std::string label() const
Return a compact label.
void print(std::ostream &os=std::cout) const
Print out the content.
unsigned int operator[](unsigned int xyz) const
returns the angular momentum
Definition: bfset.h:277
bool operator==(const CGF &) const
Comparison operator.
Definition: gauss.cc:150
void invalidate()
make this object invalid
Definition: bfset.h:204
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:388
bool valid() const
Return false if this object is invalid.
Definition: bfset.h:76