LIBINT  2.6.0
cartesian.h
1 //
2 // Created by Eduard Valeyev on 7/3/18.
3 //
4 
5 #ifndef _libint2_include_cartesian_h_
6 #define _libint2_include_cartesian_h_
7 
8 #include <array>
9 
10 #include <libint2/shell.h>
11 #include <libint2/cgshell_ordering.h>
12 
13 
14 namespace libint2 {
15 
16 namespace detail {
17 
18 template <typename Real, std::size_t N>
19 struct scale; /* {
20  void operator()(Real* intset, const std::array<std::pair<Real*,size_t>, N>& coeffs);
21 }; */
22 
23 template <typename Real>
24 struct scale<Real, 2> {
25  inline void operator()(Real* intset, const std::array<std::pair<Real*,size_t>, 2>& coeffs) {
26  auto* data = intset;
27  for(auto f0=0ul; f0 != coeffs[0].second; ++f0) {
28  for(auto f1=0ul; f1 != coeffs[1].second; ++f1) {
29  const auto scalar01 = coeffs[0].first[f0] * coeffs[1].first[f1];
30  *data *= scalar01;
31  ++data;
32  }
33  }
34  }
35 };
36 
37 template <typename Real>
38 struct scale<Real, 4> {
39  inline void operator()(Real* intset, const std::array<std::pair<Real*,size_t>, 4>& coeffs) {
40  auto* data = intset;
41  for(auto f0=0ul; f0 != coeffs[0].second; ++f0) {
42  for(auto f1=0ul; f1 != coeffs[1].second; ++f1) {
43  const auto scalar01 = coeffs[0].first[f0] * coeffs[1].first[f1];
44  for(auto f2=0ul; f2 != coeffs[2].second; ++f2) {
45  const auto scalar012 = scalar01 * coeffs[2].first[f2];
46  for(auto f3=0ul; f3 != coeffs[3].second; ++f3) {
47  const auto scalar0123 = scalar012 * coeffs[3].first[f3];
48  *data *= scalar0123;
49  ++data;
50  }
51  }
52  }
53  }
54  }
55 };
56 
57 // df_of_i_minux_1[i] = (i-1)!! , df_of_i_minux_1[0] = 1, df_of_i_minux_1[1] = 1, df_of_i_minux_1[2] = 1, df_of_i_minux_1[3] = 2, df_of_i_minux_1[4] = 3, etc.
58 template <typename Real>
59 inline std::vector<Real>
60 make_df_of_i_minux_1(int imax) {
61  std::vector<Real> df_of_i_minux_1(std::max(2, imax+1));
62  df_of_i_minux_1[0] = 1;
63  df_of_i_minux_1[1] = 1;
64  for(int i=2; i <= imax; ++i) {
65  df_of_i_minux_1[i] = (i-1) * df_of_i_minux_1[i-2]; // (i-1)!! = (i-1) * (i-3)!!
66  }
67  return df_of_i_minux_1;
68 }
69 
70 template <typename Real>
71 inline std::vector<std::vector<Real>>
72 make_cart_coeffs(int lmax) {
73  static std::vector<Real> dfm1 = make_df_of_i_minux_1<Real>(2*lmax); // dfm1[i] = (i-1)!! , dfm1[0] = 1
74 
75  std::vector<std::vector<Real>> result(lmax+1);
76  for(int l=0ul; l!=lmax; ++l) {
77  const auto cart_shell_size = (l+1) * (l+2)/2;
78  result[l].resize(cart_shell_size);
79  int ixyz = 0;
80  int ix, iy, iz;
81  FOR_CART(ix,iy,iz,l)
82  using std::sqrt;
83  result[l][ixyz] = sqrt(dfm1.at(2*l) / (dfm1.at(2*ix) * dfm1.at(2*iy) * dfm1.at(2*iz)) );
84  ++ixyz;
85  END_FOR_CART
86  }
87 
88  return result;
89 }
90 
91 } // namespace detail
92 
94 template <typename Real, std::size_t N>
95 inline void uniform_normalize_cartesian_shells(Real* intset, std::array<std::reference_wrapper<const Shell>, N> shells) {
96 
97  static std::vector<std::vector<Real>> cart_coeffs = detail::make_cart_coeffs<Real>(LIBINT_CARTGAUSS_MAX_AM);
98  const auto max_shellsize_pure = 2 * LIBINT_CARTGAUSS_MAX_AM + 1;
99  static std::vector<Real> pure_coeffs(max_shellsize_pure, Real(1));
100 
102  for(auto c=0u; c!=N; ++c) {
103  coeffs[c] = std::make_pair(shells[c].get().contr[0].pure ? &pure_coeffs[0] : &cart_coeffs[shells[c].get().contr[0].l][0], shells[c].get().size());
104  }
105 
106  detail::scale<Real, N>{}(intset, coeffs);
107 };
108 
109 } // namespace libint2
110 
111 #endif //_libint2_include_cartesian_h_
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
void uniform_normalize_cartesian_shells(Real *intset, std::array< std::reference_wrapper< const Shell >, N > shells)
rescales cartesian Gaussians to convert from standard to uniform-normalized convention
Definition: cartesian.h:95
Definition: cartesian.h:19
Array idential to C++0X arrays.
Definition: stdarray_bits.h:14