LIBINT 2.9.0
cartesian.h
1/*
2 * Copyright (C) 2004-2024 Edward F. Valeev
3 *
4 * This file is part of Libint library.
5 *
6 * Libint library is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser 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 library 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 Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with Libint library. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef _libint2_include_cartesian_h_
22#define _libint2_include_cartesian_h_
23
24#include <libint2/cgshell_ordering.h>
25#include <libint2/shell.h>
26
27#include <array>
28
29namespace libint2 {
30
31namespace detail {
32
33template <typename Real, std::size_t N>
34struct scale; /* {
35 void operator()(Real* intset, const std::array<std::pair<Real*,size_t>, N>&
36coeffs);
37}; */
38
39template <typename Real>
40struct scale<Real, 2> {
41 inline void operator()(
42 Real* intset, const std::array<std::pair<Real*, size_t>, 2>& coeffs) {
43 auto* data = intset;
44 for (auto f0 = 0ul; f0 != coeffs[0].second; ++f0) {
45 for (auto f1 = 0ul; f1 != coeffs[1].second; ++f1) {
46 const auto scalar01 = coeffs[0].first[f0] * coeffs[1].first[f1];
47 *data *= scalar01;
48 ++data;
49 }
50 }
51 }
52};
53
54template <typename Real>
55struct scale<Real, 4> {
56 inline void operator()(
57 Real* intset, const std::array<std::pair<Real*, size_t>, 4>& coeffs) {
58 auto* data = intset;
59 for (auto f0 = 0ul; f0 != coeffs[0].second; ++f0) {
60 for (auto f1 = 0ul; f1 != coeffs[1].second; ++f1) {
61 const auto scalar01 = coeffs[0].first[f0] * coeffs[1].first[f1];
62 for (auto f2 = 0ul; f2 != coeffs[2].second; ++f2) {
63 const auto scalar012 = scalar01 * coeffs[2].first[f2];
64 for (auto f3 = 0ul; f3 != coeffs[3].second; ++f3) {
65 const auto scalar0123 = scalar012 * coeffs[3].first[f3];
66 *data *= scalar0123;
67 ++data;
68 }
69 }
70 }
71 }
72 }
73};
74
75// df_of_i_minux_1[i] = (i-1)!! , df_of_i_minux_1[0] = 1, df_of_i_minux_1[1] =
76// 1, df_of_i_minux_1[2] = 1, df_of_i_minux_1[3] = 2, df_of_i_minux_1[4] = 3,
77// etc.
78template <typename Real>
79inline std::vector<Real> make_df_of_i_minux_1(int imax) {
80 std::vector<Real> df_of_i_minux_1(std::max(2, imax + 1));
81 df_of_i_minux_1[0] = 1;
82 df_of_i_minux_1[1] = 1;
83 for (int i = 2; i <= imax; ++i) {
84 df_of_i_minux_1[i] =
85 (i - 1) * df_of_i_minux_1[i - 2]; // (i-1)!! = (i-1) * (i-3)!!
86 }
87 return df_of_i_minux_1;
88}
89
90template <typename Real>
91inline std::vector<std::vector<Real>> make_cart_coeffs(int lmax) {
92 static std::vector<Real> dfm1 =
93 make_df_of_i_minux_1<Real>(2 * lmax); // dfm1[i] = (i-1)!! , dfm1[0] = 1
94
95 std::vector<std::vector<Real>> result(lmax + 1);
96 for (int l = 0ul; l != lmax; ++l) {
97 const auto cart_shell_size = (l + 1) * (l + 2) / 2;
98 result[l].resize(cart_shell_size);
99 int ixyz = 0;
100 int ix, iy, iz;
101 FOR_CART(ix, iy, iz, l)
102 using std::sqrt;
103 result[l][ixyz] = sqrt(
104 dfm1.at(2 * l) / (dfm1.at(2 * ix) * dfm1.at(2 * iy) * dfm1.at(2 * iz)));
105 ++ixyz;
106 END_FOR_CART
107 }
108
109 return result;
110}
111
112} // namespace detail
113
116template <typename Real, std::size_t N>
118 Real* intset, std::array<std::reference_wrapper<const Shell>, N> shells) {
119 static std::vector<std::vector<Real>> cart_coeffs =
120 detail::make_cart_coeffs<Real>(LIBINT_CARTGAUSS_MAX_AM);
121 const auto max_shellsize_pure = 2 * LIBINT_CARTGAUSS_MAX_AM + 1;
122 static std::vector<Real> pure_coeffs(max_shellsize_pure, Real(1));
123
124 std::array<std::pair<Real*, size_t>, N> coeffs;
125 for (auto c = 0u; c != N; ++c) {
126 coeffs[c] =
127 std::make_pair(shells[c].get().contr[0].pure
128 ? &pure_coeffs[0]
129 : &cart_coeffs[shells[c].get().contr[0].l][0],
130 shells[c].get().size());
131 }
132
133 detail::scale<Real, N>{}(intset, coeffs);
134};
135
136} // namespace libint2
137
138#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:117
Definition cartesian.h:34