LIBINT  2.1.0-stable
bfset.h
1 /*
2  * This file is a part of Libint.
3  * Copyright (C) 2004-2014 Edward F. Valeev
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see http://www.gnu.org/licenses/.
17  *
18  */
19 
20 #ifndef _libint2_src_bin_libint_bfset_h_
21 #define _libint2_src_bin_libint_bfset_h_
22 
23 #include <iostream>
24 #include <string>
25 #include <cassert>
26 #include <numeric>
27 #include <sstream>
28 #include <libint2/stdarray.h>
29 #include <smart_ptr.h>
30 #include <polyconstr.h>
31 #include <hashable.h>
32 #include <contractable.h>
33 #include <global_macros.h>
34 #include <util_types.h>
35 
36 namespace libint2 {
37 
42 
43  public:
44  virtual ~BFSet() {}
45  virtual unsigned int num_bf() const =0;
46  virtual const std::string label() const =0;
47 
48  protected:
49  BFSet() {}
50 
51  };
52 
61  class IncableBFSet : public BFSet {
62 
63  public:
64  virtual ~IncableBFSet() {}
65 
67  virtual void inc(unsigned int xyz, unsigned int c = 1u) =0;
69  virtual void dec(unsigned int xyz, unsigned int c = 1u) =0;
71  virtual unsigned int norm() const =0;
73  bool zero() const { return norm() == 0; }
75  bool valid() const { return valid_; }
76 
77  protected:
78  IncableBFSet() : valid_(true) {}
79 
81  void invalidate() { valid_ = false; }
82 
83  private:
84  bool valid_;
85  };
86 
88  template <typename F>
89  F unit(unsigned int X) { F tmp; tmp.inc(X,1); return tmp; }
91  inline bool exists(const IncableBFSet& A) { return A.valid(); }
92 
95  template <unsigned NDIM = 3>
96  class OriginDerivative : public Hashable<LIBINT2_UINT_LEAST64,ReferToKey> {
97 
98  public:
99  OriginDerivative() : valid_(true) {
100  for(auto d=0u; d!=NDIM; ++d) d_[d] = 0u;
101  }
102  OriginDerivative(const OriginDerivative& other) : valid_(true) {
103  std::copy(other.d_, other.d_ + NDIM, d_);
104  }
105  OriginDerivative& operator=(const OriginDerivative& other) {
106  valid_ = other.valid_;
107  std::copy(other.d_, other.d_ + NDIM, d_);
108  return *this;
109  }
110  OriginDerivative& operator+=(const OriginDerivative& other) {
111  assert(valid_);
112  for(auto d=0u; d!=NDIM; ++d) d_[d] += other.d_[d];
113  return *this;
114  }
115  OriginDerivative& operator-=(const OriginDerivative& other) {
116  assert(valid_);
117  for(auto d=0u; d!=NDIM; ++d) d_[d] -= other.d_[d];
118  return *this;
119  }
120  ~OriginDerivative() {
121  static_assert(NDIM == 3u || NDIM == 1u, "OriginDerivative with NDIM=1,3 are implemented");
122  }
123 
125  unsigned int d(unsigned int xyz) const {
126  assert(xyz < NDIM);
127  return d_[xyz];
128  }
130  unsigned int operator[](unsigned int xyz) const {
131  return this->d(xyz);
132  }
134  void inc(unsigned int xyz, unsigned int c = 1u) {
135  assert(xyz < NDIM);
136  assert(valid_);
137  d_[xyz] += c;
138  }
140  void dec(unsigned int xyz, unsigned int c = 1u) {
141  assert(xyz < NDIM);
142  //assert(valid_);
143  if (d_[xyz] >= c)
144  d_[xyz] -= c;
145  else
146  valid_ = false;
147  }
149  unsigned int norm() const {
150  return std::accumulate(d_, d_+NDIM, 0u);
151  }
153  bool zero() const { return norm() == 0; }
155  bool valid() const { return valid_; }
157  LIBINT2_UINT_LEAST64 key() const {
158  if (NDIM == 3u) {
159  unsigned nxy = d_[1] + d_[2];
160  unsigned l = nxy + d_[0];
161  LIBINT2_UINT_LEAST64 key = nxy*(nxy+1)/2 + d_[2];
162  return key + key_l_offset.at(l);
163  }
164  if (NDIM == 1u) {
165  return d_[0];
166  }
167  assert(false);
168  }
170  const std::string label() const {
171  char result[NDIM+1];
172  for(auto xyz=0u; xyz<NDIM; ++xyz) result[xyz] = '0' + d_[xyz];
173  result[NDIM] = '\0';
174  return std::string(result);
175  }
176 
177  /* ---------------
178  * key computation
179  * --------------- */
180  const static unsigned max_deriv = 4;
181 
182  // nkeys_l[L] is the number of possible OriginDerivative's with \c norm() == L
183  // \note for NDIM=1 nkeys_l[L] = 1
184  // \note for NDIM=2 nkeys_l[L] = (L+1)
185  // \note for NDIM=3 nkeys_l[L] = (L+1)(L+2)/2
186  //static std::array<LIBINT2_UINT_LEAST64, OriginDerivative::max_deriv+1> nkeys;
187 
190  const static unsigned max_key = NDIM == 3 ? (1 + max_deriv)*(2 + max_deriv)*(3 + max_deriv)/6 : (1+max_deriv);
191 
193  void print(std::ostream& os = std::cout) const;
194 
195  protected:
196 
198  void invalidate() { valid_ = false; }
199 
200  private:
201  unsigned int d_[NDIM];
202  bool valid_; // indicates valid/invalid state
206 
207  };
208 
209  template <unsigned NDIM>
211  OriginDerivative<NDIM> Diff(A);
212  for(unsigned int xyz=0; xyz<3; ++xyz)
213  Diff.dec(xyz,B.d(xyz));
214  return Diff;
215  }
216 
217  template <unsigned NDIM>
218  bool operator==(const OriginDerivative<NDIM>& A, const OriginDerivative<NDIM>& B) {
219  for(unsigned d=0; d!=NDIM; ++d)
220  if (A.d(d) != B.d(d))
221  return false;
222  return true;
223  }
224 
226  template <unsigned NDIM> inline bool exists(const OriginDerivative<NDIM>& A) { return A.valid(); }
227 
228  class CGF; // forward declaration of CGF
229 
231  class CGShell : public IncableBFSet, public Hashable<LIBINT2_UINT_LEAST64,ReferToKey>,
232  public Contractable<CGShell> {
233 
234  unsigned int qn_[1];
235  OriginDerivative<3> deriv_;
236  bool pure_sh_; //< if true, assumed to contain solid harmonics with quantum number qn_[0] only
238  bool unit_;
239 
240  friend CGShell operator+(const CGShell& A, const CGShell& B);
241  friend CGShell operator-(const CGShell& A, const CGShell& B);
242 
243  public:
245  typedef CGF iter_type;
246  typedef IncableBFSet parent_type;
247 
249  CGShell();
250  CGShell(unsigned int qn, bool pure_sh = false);
251  CGShell(const CGShell&);
252  virtual ~CGShell();
253  CGShell& operator=(const CGShell&);
254 
255  const OriginDerivative<3u>& deriv() const { return deriv_; }
256  OriginDerivative<3u>& deriv() { return deriv_; }
257 
259  const std::string label() const;
261  unsigned int num_bf() const { return (qn_[0]+1)*(qn_[0]+2)/2; };
263  unsigned int qn(unsigned int xyz=0) const { return qn_[0]; }
265  unsigned int operator[](unsigned int xyz) const {
266  return this->qn(xyz);
267  }
268 
270  bool operator==(const CGShell&) const;
271 
274  bool pure_sh() const { return pure_sh_; }
276  void pure_sh(bool p) { pure_sh_ = p; }
277 
279  void inc(unsigned int xyz, unsigned int c = 1u);
281  void dec(unsigned int xyz, unsigned int c = 1u);
283  unsigned int norm() const;
285  LIBINT2_UINT_LEAST64 key() const {
286  if (is_unit()) return max_key-1;
287  const LIBINT2_UINT_LEAST64 result =
288  ((deriv().key() * 2 +
289  (contracted() ? 1 : 0)
290  ) * (max_qn+1) +
291  qn_[0]
292  ) * 2 +
293  (pure_sh() ? 1 : 0);
294  assert(result < max_key-1);
295  return result;
296  }
297  const static LIBINT2_UINT_LEAST64 max_qn = LIBINT_CARTGAUSS_MAX_AM;
305  const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<3u>::max_key * 2 * (max_qn + 1) * 2 + 1;
306 
308  void print(std::ostream& os = std::cout) const;
309 
311  static CGShell unit();
312  bool is_unit() const { return unit_; }
313 
314  };
315 
316  CGShell operator+(const CGShell& A, const CGShell& B);
317  CGShell operator-(const CGShell& A, const CGShell& B);
318 
320  class CGF : public IncableBFSet, public Hashable<LIBINT2_UINT_LEAST64,ComputeKey>,
321  public Contractable<CGF> {
322 
323  unsigned int qn_[3];
324  OriginDerivative<3u> deriv_;
325  bool pure_sh_; //< if true, assumed to contain solid harmonics with quantum number qn_[0] only
326  bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
327 
328  friend CGF operator+(const CGF& A, const CGF& B);
329  friend CGF operator-(const CGF& A, const CGF& B);
330 
331  public:
333  typedef CGF iter_type;
334  typedef IncableBFSet parent_type;
336  //typedef typename Hashable<unsigned,ComputeKey>::KeyReturnType KeyReturnType;
337 
339  CGF();
340  CGF(unsigned int qn[3], bool pure_sh = false);
341  CGF(const CGF&);
342  explicit CGF(const ConstructablePolymorphically&);
343  virtual ~CGF();
345  CGF& operator=(const CGF&);
346 
347  const OriginDerivative<3u>& deriv() const { return deriv_; }
348  OriginDerivative<3u>& deriv() { return deriv_; }
349 
351  const std::string label() const;
353  unsigned int num_bf() const { return 1; };
355  unsigned int qn(unsigned int axis) const;
356  unsigned int operator[](unsigned int axis) const {
357  return qn(axis);
358  }
359 
362  bool pure_sh() const { return pure_sh_; }
364  void pure_sh(bool p) { pure_sh_ = p; }
365 
367  bool operator==(const CGF&) const;
368 
370  void inc(unsigned int xyz, unsigned int c = 1u);
372  void dec(unsigned int xyz, unsigned int c = 1u);
374  unsigned int norm() const;
376  LIBINT2_UINT_LEAST64 key() const {
377  if (is_unit()) return max_key-1;
378  unsigned nxy = qn_[1] + qn_[2];
379  unsigned l = nxy + qn_[0];
380  LIBINT2_UINT_LEAST64 key = nxy*(nxy+1)/2 + qn_[2];
381  const LIBINT2_UINT_LEAST64 result =
382  ( ( deriv().key() * 2 +
383  (contracted() ? 1 : 0)
384  ) * max_num_qn +
385  key + key_l_offset.at(l)
386  ) * 2
387  + (pure_sh() ? 1 : 0);
388  if (result >= max_key-1) {
389  this->print(std::cout);
390  std::cout << "result,max_key-1 = " << result << "," << max_key-1 << std::endl;
391  assert(result < max_key-1);
392  }
393  return result;
394  }
398  const static LIBINT2_UINT_LEAST64 max_num_qn = ((1 + (CGShell::max_qn+1)) * (2 + (CGShell::max_qn+1)) * (3 + (CGShell::max_qn+1)) /6);
399  // deriv_key_range = OriginDerivative<3u>::max_key
400  // contracted = 2 (yes or no)
401  // qn_range = max_num_qn
402  // puresh_key_range = 2
403  // +1 to account for unit function
404  const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<3u>::max_key * 2ul * max_num_qn * 2ul + 1;
405 
407  void print(std::ostream& os = std::cout) const;
408 
410  static CGF unit();
411  bool is_unit() const { return unit_; }
412 
413  private:
416  };
417 
418  CGF operator+(const CGF& A, const CGF& B);
419  CGF operator-(const CGF& A, const CGF& B);
420 
421 #if 1
422  template <CartesianAxis Axis>
425  class CGF1d : public IncableBFSet, public Hashable<LIBINT2_UINT_LEAST64,ComputeKey>,
426  public Contractable< CGF1d<Axis> > {
427 
428  unsigned int qn_[1];
429  OriginDerivative<1u> deriv_;
430  bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
431 
432  public:
433 
434  static constexpr CartesianAxis axis = Axis;
435 
437  typedef CGF1d iter_type;
438  typedef IncableBFSet parent_type;
439 
441  CGF1d() : unit_(false) { qn_[0] = 0; }
442  CGF1d(unsigned int qn) : unit_(false) { qn_[0] = qn; }
443  CGF1d(unsigned int qn[1]) : unit_(false) { qn_[0] = qn[0]; }
444  CGF1d(const CGF1d& source) : Contractable<CGF1d>(source),
445  deriv_(source.deriv_), unit_(source.unit_)
446  {
447  qn_[0] = source.qn_[0];
448  }
449  explicit CGF1d(const ConstructablePolymorphically& sptr) :
450  Contractable<CGF1d>(dynamic_cast<const CGF1d&>(sptr))
451  {
452  const CGF1d& sptr_cast = dynamic_cast<const CGF1d&>(sptr);
453  qn_[0] = sptr_cast.qn_[0];
454  deriv_ = sptr_cast.deriv_;
455  unit_ = sptr_cast.unit_;
456  }
457  virtual ~CGF1d() {
458  }
459 
461  CGF1d& operator=(const CGF1d& source)
462  {
463  qn_[0] = source.qn_[0];
464  deriv_ = source.deriv_;
465  unit_ = source.unit_;
467  if (!source.valid()) invalidate();
468  return *this;
469  }
470 
471  CGF1d operator+(const CGF1d& B) const {
472  //assert(this->is_unit() == false && B.is_unit() == false);
473  CGF1d<Axis> Sum(*this);
474  Sum.inc(0,B.qn(0));
475  Sum.deriv_ += B.deriv_;
476  return Sum;
477  }
478  CGF1d operator-(const CGF1d& B) const {
479  //assert(A.is_unit() == false && B.is_unit() == false);
480  CGF1d Diff(*this);
481  Diff.dec(0,B.qn(0));
482  Diff.deriv_ -= B.deriv_;
483  return Diff;
484  }
485 
486  const OriginDerivative<1u>& deriv() const { return deriv_; }
487  OriginDerivative<1u>& deriv() { return deriv_; }
488 
490  const std::string label() const {
491  // unit *functions* are treated as regular qn-0 functions so that (00|00)^(m) = (unit 0|00)^(m)
492  std::ostringstream oss;
493  oss << to_string(Axis) << qn_[0];
494  if (deriv_.zero() == false) oss << "_" << deriv_.label();
495 
496  // I don't handle labels of contracted CGF1d because I don't think I need them
497  // make sure just in case
498  assert(this->contracted() == false);
499 
500  return oss.str();
501  }
502 
503 
505  unsigned int num_bf() const { return 1; };
507  unsigned int qn(unsigned int dir = 0) const {
508  assert(dir == 0);
509  return qn_[0];
510  }
511  unsigned int operator[](unsigned int dir) const {
512  return this->qn(dir);
513  }
514 
516  bool operator==(const CGF1d& a) const {
517  return ( qn_[0] == a.qn_[0] &&
518  this->contracted() == a.contracted() &&
519  deriv_ == a.deriv_ &&
520  unit_ == a.unit_);
521  }
522 
524  void inc(unsigned int dir, unsigned int c = 1u) {
525  assert(is_unit() == false);
526  assert(dir==0);
527  if (valid())
528  qn_[0] += c;
529  }
531  void dec(unsigned int dir, unsigned int c = 1u) {
532  if (is_unit()) { invalidate(); return; }
533  assert(dir==0);
534  if (valid()) {
535  if (qn_[0] < c) {
536  invalidate();
537  return;
538  }
539  qn_[0] -= c;
540  }
541  }
543  unsigned int norm() const { return qn_[0]; }
545  LIBINT2_UINT_LEAST64 key() const {
546  if (is_unit()) return max_key-1;
547  const LIBINT2_UINT_LEAST64 result =
548  ( deriv().key() * 2ul +
549  (this->contracted() ? 1ul : 0ul)
550  ) * max_num_qn +
551  qn_[0];
552  if (result >= max_key-1) {
553  this->print(std::cout);
554  std::cout << "result,max_key-1 = " << result << "," << max_key-1 << std::endl;
555  assert(result < max_key-1);
556  }
557  return result;
558  }
562  const static LIBINT2_UINT_LEAST64 max_num_qn = CGShell::max_qn+1;
563  // deriv_key_range = OriginDerivative<1u>::max_key
564  // contracted = 2 (yes or no)
565  // qn_range = max_num_qn
566  // +1 to account for unit function
567  const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<1u>::max_key * OriginDerivative<1u>::max_key * max_num_qn + 1;
568 
570  void print(std::ostream& os = std::cout) const {
571  os << "CGF1d<" << to_string(Axis) << ">: " << label() << std::endl;
572  }
573 
575  static CGF1d unit() {
576  CGF1d result;
577  result.unit_ = true;
578  result.uncontract();
579  return result;
580  }
581  bool is_unit() const { return unit_; }
582 
583  private:
586  };
587 
588 // template <CartesianAxis Axis>
589 // inline CGF1d<Axis> operator+(const CGF1d<Axis>& A, const CGF1d<Axis>& B) {
590 // assert(A.is_unit() == false && B.is_unit() == false);
591 // CGF1d<Axis> Sum(A);
592 // Sum.inc(0,B.qn(0));
593 // Sum.deriv_ += B.deriv_;
594 // return Sum;
595 // }
596 // template <CartesianAxis Axis>
597 // inline CGF1d<Axis> operator-(const CGF1d<Axis>& A, const CGF1d<Axis>& B) {
598 // //assert(A.is_unit() == false && B.is_unit() == false);
599 // CGF1d<Axis> Diff(A);
600 // Diff.dec(0,B.qn(0));
601 // Diff.deriv_ -= B.deriv_;
602 //
603 // return Diff;
604 // }
605 
606 
613  template <CartesianAxis Axis>
614  class CGShell1d : public IncableBFSet, public Hashable<LIBINT2_UINT_LEAST64,ComputeKey>,
615  public Contractable< CGShell1d<Axis> > {
616 
617  unsigned int qn_[1];
618  OriginDerivative<1u> deriv_;
619  bool unit_; //< if true, this is a unit Gaussian (exponent = 0)
620 
621  public:
622 
623  static constexpr CartesianAxis axis = Axis;
624 
627  typedef IncableBFSet parent_type;
628 
630  CGShell1d() : unit_(false) { qn_[0] = 0; }
631  CGShell1d(unsigned int qn) : unit_(false) { qn_[0] = qn; }
632  CGShell1d(unsigned int qn[1]) : unit_(false) { qn_[0] = qn[0]; }
633  CGShell1d(const CGShell1d& source) : Contractable<CGShell1d>(source),
634  deriv_(source.deriv_), unit_(source.unit_)
635  {
636  qn_[0] = source.qn_[0];
637  }
638  virtual ~CGShell1d() {
639  }
640 
642  CGShell1d& operator=(const CGShell1d& source)
643  {
644  qn_[0] = source.qn_[0];
645  deriv_ = source.deriv_;
646  unit_ = source.unit_;
648  if (!source.valid()) invalidate();
649  return *this;
650  }
651 
652  const OriginDerivative<1u>& deriv() const { return deriv_; }
653  OriginDerivative<1u>& deriv() { return deriv_; }
654 
656  const std::string label() const {
657  // unit *functions* are treated as regular qn-0 functions so that (00|00)^(m) = (unit 0|00)^(m)
658  std::ostringstream oss;
659  auto axis_label = to_string(Axis);
660  axis_label[0] = std::toupper(axis_label[0]);
661  oss << axis_label << qn_[0];
662  if (deriv_.zero() == false) oss << "_" << deriv_.label();
663 
664  // I don't handle labels of contracted CGF1d because I don't think I need them
665  // make sure just in case
666  assert(this->contracted() == false);
667 
668  return oss.str();
669  }
670 
671 
673  unsigned int num_bf() const { return qn_[0]+1; };
675  unsigned int qn(unsigned int dir=0) const {
676  assert(dir == 0);
677  return qn_[0];
678  }
679 
681  bool operator==(const CGShell1d& a) const {
682  return ( qn_[0] == a.qn_[0] &&
683  this->contracted() == a.contracted() &&
684  deriv_ == a.deriv_ &&
685  unit_ == a.unit_);
686  }
687 
689  void inc(unsigned int dir, unsigned int c = 1u) {
690  assert(false);
691  }
693  void dec(unsigned int dir, unsigned int c = 1u) {
694  assert(false);
695  }
697  unsigned int norm() const { return qn_[0]; }
699  LIBINT2_UINT_LEAST64 key() const {
700  if (is_unit()) return max_key-1;
701  const LIBINT2_UINT_LEAST64 result =
702  ( deriv().key() * 2ul +
703  (this->contracted() ? 1ul : 0ul)
704  ) * max_num_qn +
705  qn_[0];
706  if (result >= max_key-1) {
707  this->print(std::cout);
708  std::cout << "result,max_key-1 = " << result << "," << max_key-1 << std::endl;
709  assert(result < max_key-1);
710  }
711  return result;
712  }
716  const static LIBINT2_UINT_LEAST64 max_num_qn = CGShell::max_qn+1;
717  // deriv_key_range = OriginDerivative<1u>::max_key
718  // contracted = 2 (yes or no)
719  // qn_range = max_num_qn
720  // +1 to account for unit function
721  const static LIBINT2_UINT_LEAST64 max_key = OriginDerivative<1u>::max_key * OriginDerivative<1u>::max_key * max_num_qn + 1;
722 
724  void print(std::ostream& os = std::cout) const {
725  os << "CGShell1d<" << to_string(Axis) << ">: " << label() << std::endl;
726  }
727 
729  static CGShell1d unit() {
730  CGShell1d result;
731  result.unit_ = true;
732  result.uncontract();
733  return result;
734  }
735  bool is_unit() const { return unit_; }
736 
737  private:
740  };
741 
742 #endif
743 
744 #if 0
745  class SHGF; // forward declaration
746 
748  class SHGShell : public IncableBFSet, public Hashable<unsigned,ReferToKey>,
749  public Contractable<SHGShell> {
750 
751  unsigned int qn_[1];
752  OriginDerivative deriv_;
753 
754  friend SHGShell operator+(const SHGShell& A, const SHGShell& B);
755  friend SHGShell operator-(const SHGShell& A, const SHGShell& B);
756 
757  public:
759  typedef SHGF iter_type;
760  typedef IncableBFSet parent_type;
761 
763  SHGShell();
764  SHGShell(unsigned int qn);
765  SHGShell(const SHGShell&);
766  virtual ~SHGShell();
767  SHGShell& operator=(const SHGShell&);
768 
769  const OriginDerivative& deriv() const { return deriv_; }
770  OriginDerivative& deriv() { return deriv_; }
771 
773  const std::string label() const;
775  unsigned int num_bf() const { return 2*qn_[0]+1; };
777  unsigned int qn(unsigned int m=0) const { return qn_[0]; }
778 
780  bool operator==(const SHGShell&) const;
781 
783  void inc(unsigned int xyz, unsigned int c = 1u);
785  void dec(unsigned int xyz, unsigned int c = 1u);
787  unsigned int norm() const;
789  unsigned key() const { return (deriv().key() * 2 + (contracted() ? 1 : 0)) * (max_qn+1) + qn_[0]; }
790  const static unsigned max_qn = LIBINT_CARTGAUSS_MAX_AM;
791  // The range of keys is [0,max_key]
792  const static unsigned max_key = 2 * (max_qn + 1) * OriginDerivative::max_key * 2; // deriv_key_range = 2
793  // qn_range = max_qn + 1
794  // puresh_key_range = 2
795 
797  void print(std::ostream& os = std::cout) const;
798 
799  };
800 
801  SHGShell operator+(const SHGShell& A, const SHGShell& B);
802  SHGShell operator-(const SHGShell& A, const SHGShell& B);
803 
805  class SHGF : public IncableBFSet, public Hashable<unsigned,ComputeKey>,
806  public Contractable<SHGF> {
807 
808  unsigned int qn_[3];
809  OriginDerivative deriv_;
810 
811  friend SHGF operator+(const SHGF& A, const SHGF& B);
812  friend SHGF operator-(const SHGF& A, const SHGF& B);
813 
814  public:
816  typedef SHGF iter_type;
817  typedef IncableBFSet parent_type;
819  //typedef typename Hashable<unsigned,ComputeKey>::KeyReturnType KeyReturnType;
820 
822  SHGF();
823  SHGF(unsigned int qn[3]);
824  SHGF(const SHGF&);
826  virtual ~SHGF();
828  SHGF& operator=(const SHGF&);
829 
830  const OriginDerivative& deriv() const { return deriv_; }
831  OriginDerivative& deriv() { return deriv_; }
832 
834  const std::string label() const;
836  unsigned int num_bf() const { return 1; };
838  unsigned int qn(unsigned int xyz) const;
839 
841  bool operator==(const SHGF&) const;
842 
844  void inc(unsigned int xyz, unsigned int c = 1u);
846  void dec(unsigned int xyz, unsigned int c = 1u);
848  unsigned int norm() const;
850  unsigned key() const {
851  unsigned nxy = qn_[1] + qn_[2];
852  unsigned l = nxy + qn_[0];
853  unsigned key = nxy*(nxy+1)/2 + qn_[2];
854  return ( deriv().key() * 2 + (contracted() ? 1 : 0)) * max_num_qn + key + key_l_offset.at(l);
855  }
859  const static unsigned max_num_qn = ((1 + (SHGShell::max_qn+1)) * (2 + (SHGShell::max_qn+1)) * (3 + (SHGShell::max_qn+1)) /6);
860  const static unsigned max_key = 2 * OriginDerivative::max_key * max_num_qn;
861 
863  void print(std::ostream& os = std::cout) const;
864 
865  private:
867  static unsigned key_l_offset[SHGShell::max_key+2];
868  };
869 
870  SHGF operator+(const SHGF& A, const SHGF& B);
871  SHGF operator-(const SHGF& A, const SHGF& B);
872 #endif
873 
878  template <class T>
879  struct TrivialBFSet;
880  template <>
882  static const bool result = false;
883  };
884  template <>
885  struct TrivialBFSet<CGF> {
886  static const bool result = true;
887  };
888  template <CartesianAxis Axis>
889  struct TrivialBFSet< CGShell1d<Axis> > {
890  static const bool result = false;
891  };
892  template <CartesianAxis Axis>
893  struct TrivialBFSet< CGF1d<Axis> > {
894  static const bool result = true;
895  };
896 #if 0
897  template <>
899  static const bool result = false;
900  };
901  template <>
902  struct TrivialBFSet<SHGF> {
903  static const bool result = true;
904  };
905 #endif
906 
907 };
908 
909 #endif
910 
bool zero() const
norm() == 0
Definition: bfset.h:73
unsigned int operator[](unsigned int xyz) const
returns the number of quanta along xyz
Definition: bfset.h:130
use this as a base to add to Derived a "contracted()" attribute
Definition: contractable.h:26
Cartesian components of 3D CGF = 1D CGF.
Definition: bfset.h:425
TrivialBFSet<T> defines static member result, which is true if T is a basis function set consisting o...
Definition: bfset.h:879
Set of basis functions with incrementable/decrementable quantum numbers.
Definition: bfset.h:61
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:673
ConstructablePolymorphically is a base for all objects which can be constructed using a SafePtr to a ...
Definition: polyconstr.h:30
3D Cartesian Gaussian Shell
Definition: bfset.h:231
static CGF1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: bfset.h:575
void dec(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::dec().
Definition: bfset.h:531
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:23
Objects of Hashable<T> class provide hashing function key() which computes keys of type KeyType...
Definition: hashable.h:72
a "shell" of 1D CGFs with quantum number L is a set of 1D CGFs with quantum numbers 0 ...
Definition: bfset.h:614
static const unsigned max_key
The range of keys is [0,max_key).
Definition: bfset.h:190
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition: bfset.h:507
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:157
CGF1d & operator=(const CGF1d &source)
assignment
Definition: bfset.h:461
unsigned int norm() const
Returns the norm of the quantum numbers.
Definition: bfset.h:149
unsigned int qn(unsigned int dir=0) const
Returns the quantum number (what used to be "angular momentum")
Definition: bfset.h:675
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:545
void dec(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::dec().
Definition: bfset.h:693
unsigned int num_bf() const
Returns the number of basis functions in the set.
Definition: bfset.h:261
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:376
CGF iter_type
As far as SetIterator is concerned, CGShell is a set of CGFs.
Definition: bfset.h:245
SHGF iter_type
As far as SetIterator is concerned, SHGShell is a set of SHGFs.
Definition: bfset.h:759
bool pure_sh() const
contains only solid harmonics with the same quantum number as this shell? (this may permit simplified...
Definition: bfset.h:362
CGF1d iter_type
As far as SetIterator is concerned, CGF1d is a set of one CGF1d.
Definition: bfset.h:437
Solid-Harmonic Gaussian Shell.
Definition: bfset.h:748
unsigned int norm() const
Implements IncableBFSet::norm()
Definition: bfset.h:543
CGF1d()
Default constructor makes an qn=0 Gaussian.
Definition: bfset.h:441
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:836
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:353
bool operator==(const CGShell1d &a) const
Comparison operator.
Definition: bfset.h:681
std::string to_string(const T &x)
Converts x to its string representation.
Definition: entity.h:71
unsigned int qn(unsigned int m=0) const
Returns the angular momentum.
Definition: bfset.h:777
unsigned int num_bf() const
Returns the number of basis functions in the set (always 1)
Definition: bfset.h:505
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:285
void inc(unsigned int xyz, unsigned int c=1u)
Add c quanta along xyz.
Definition: bfset.h:134
bool valid() const
Return false if this object is invalid.
Definition: bfset.h:75
CGF1d< Axis > iter_type
CGShell1d is a set CGF1d&#39;s.
Definition: bfset.h:626
unsigned int num_bf() const
Returns the number of basis functions in the set.
Definition: bfset.h:775
bool operator==(const CGF1d &a) const
Comparison operator.
Definition: bfset.h:516
F unit(unsigned int X)
BF with unit quantum along X. F must behave like IncableBFSet.
Definition: bfset.h:89
const std::string label() const
Return a compact label.
Definition: bfset.h:490
void inc(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::inc().
Definition: bfset.h:524
unsigned int d(unsigned int xyz) const
returns the number of quanta along xyz
Definition: bfset.h:125
unsigned int norm() const
Implements IncableBFSet::norm()
Definition: bfset.h:697
bool exists(const IncableBFSet &A)
Return true if A is valid.
Definition: bfset.h:91
const std::string label() const
Return a compact label.
Definition: bfset.h:170
Array idential to C++0X arrays.
Definition: stdarray_bits.h:14
SHGF iter_type
As far as SetIterator is concerned, SHGF is a set of one SHGF.
Definition: bfset.h:816
void inc(unsigned int dir, unsigned int c=1u)
Implementation of IncableBFSet::inc().
Definition: bfset.h:689
unsigned int operator[](unsigned int xyz) const
returns the angular momentum
Definition: bfset.h:265
Set of basis functions.
Definition: bfset.h:41
unsigned key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:789
unsigned key() const
Implements Hashable<unsigned>::key()
Definition: bfset.h:850
CGShell1d()
Default constructor makes a qn=0 shell.
Definition: bfset.h:630
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: bfset.h:570
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:140
Solid-Harmonic Gaussian Function.
Definition: bfset.h:805
void invalidate()
make this object invalid
Definition: bfset.h:81
bool zero() const
norm() == 0
Definition: bfset.h:153
void print(std::ostream &os=std::cout) const
Print out the content.
Definition: bfset.h:724
void pure_sh(bool p)
Definition: bfset.h:276
const std::string label() const
Return a compact label.
Definition: bfset.h:656
CGShell1d & operator=(const CGShell1d &source)
assignment
Definition: bfset.h:642
static CGShell1d unit()
returns the unit shell (exponent=0, am=0, indicated by unit_=true)
Definition: bfset.h:729
3D Cartesian Gaussian Function
Definition: bfset.h:320
Represents cartesian derivatives of atom-centered basis functions.
Definition: bfset.h:96
bool valid() const
Return false if this object is invalid.
Definition: bfset.h:155
CGF iter_type
As far as SetIterator is concerned, CGF is a set of one CGF.
Definition: bfset.h:333
void pure_sh(bool p)
Definition: bfset.h:364
unsigned int qn(unsigned int xyz=0) const
Returns the angular momentum.
Definition: bfset.h:263
LIBINT2_UINT_LEAST64 key() const
Implements Hashable<LIBINT2_UINT_LEAST64>::key()
Definition: bfset.h:699
bool pure_sh() const
contains only solid harmonics with the same quantum number as this shell? (this may permit simplified...
Definition: bfset.h:274
void invalidate()
make this object invalid
Definition: bfset.h:198