LIBINT 2.7.2
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
14namespace libint2 {
15
16namespace detail {
17
18template <typename Real, std::size_t N>
19struct scale; /* {
20 void operator()(Real* intset, const std::array<std::pair<Real*,size_t>, N>& coeffs);
21}; */
22
23template <typename Real>
24struct 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
37template <typename Real>
38struct 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.
58template <typename Real>
59inline std::vector<Real>
60make_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
70template <typename Real>
71inline std::vector<std::vector<Real>>
72make_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
94template <typename Real, std::size_t N>
95inline 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_
Array idential to C++0X arrays.
Definition: stdarray_bits.h:14
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