votca 2026-dev
Loading...
Searching...
No Matches
aotransform.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2024 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 *Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20// Local VOTCA includes
22
23#if defined(__clang__)
24#pragma clang diagnostic push
25#pragma clang diagnostic ignored "-Wdeprecated-declarations"
26#elif defined(__GNUC__)
27#pragma GCC diagnostic push
28#pragma GCC diagnostic ignored "-Warray-bounds"
29#endif
30#include "libint2/solidharmonics.h"
31#if defined(__clang__)
32#pragma clang diagnostic pop
33#elif defined(__GNUC__)
34#pragma GCC diagnostic pop
35#endif
36
37namespace votca {
38namespace xtp {
39
40double AOTransform::getNorm(L l, const AOGaussianPrimitive& gaussian) {
41 const double contraction = gaussian.getContraction();
42 const double decay = gaussian.getDecay();
43 switch (l) {
44 case L::S: {
45 return contraction;
46 }
47 case L::P: {
48 return 2. * std::sqrt(decay) * contraction;
49 }
50 case L::D: {
51 return 4. * decay * contraction / std::sqrt(3);
52 }
53 case L::F: {
54 return 8 * std::pow(decay, 1.5) * contraction / std::sqrt(5 * 3);
55 }
56 case L::G: {
57 return decay * decay * contraction * 16.0 / std::sqrt(5. * 3. * 7.);
58 }
59 default:
60 throw std::runtime_error("No norms for shells higher than g (l=4)");
61 }
62
63 return 0;
64}
65
67template <typename Matrix>
68Matrix AOTransform::tform(L l_row, L l_col, const Matrix& cartesian) {
69 const auto& coefs_row =
70 libint2::solidharmonics::SolidHarmonicsCoefficients<double>::instance(
71 int(l_row));
72 const auto& coefs_col =
73 libint2::solidharmonics::SolidHarmonicsCoefficients<double>::instance(
74 int(l_col));
75 int npure_row = 2 * int(l_row) + 1;
76 int npure_col = 2 * int(l_col) + 1;
77 Matrix spherical = Matrix::Zero(npure_row, npure_col);
78 // loop over row shg
79 for (auto s1 = 0; s1 != npure_row; ++s1) {
80 const auto nc1 =
81 coefs_row.nnz(s1); // # of cartesians contributing to shg s1
82 const auto* c1_idxs =
83 coefs_row.row_idx(s1); // indices of cartesians contributing to shg s1
84 const auto* c1_vals = coefs_row.row_values(
85 s1); // coefficients of cartesians contributing to shg s1
86 // loop over col shg
87 for (auto s2 = 0; s2 != npure_col; ++s2) {
88 const auto nc2 =
89 coefs_col.nnz(s2); // # of cartesians contributing to shg s2
90 const auto* c2_idxs = coefs_col.row_idx(s2); // indices of cartesians
91 // contributing to shg s2
92 const auto* c2_vals = coefs_col.row_values(
93 s2); // coefficients of cartesians contributing to shg s2
94 for (size_t ic1 = 0; ic1 != nc1;
95 ++ic1) { // loop over contributing cartesians
96 auto c1 = c1_idxs[ic1];
97 auto s1_c1_coeff = c1_vals[ic1];
98 for (size_t ic2 = 0; ic2 != nc2;
99 ++ic2) { // loop over contributing cartesians
100 auto c2 = c2_idxs[ic2];
101 auto s2_c2_coeff = c2_vals[ic2];
102 spherical(s1, s2) += cartesian(c1, c2) * s1_c1_coeff * s2_c2_coeff;
103 } // cart2
104
105 } // cart1
106
107 } // shg2
108 }
109 return spherical;
110}
111template Eigen::MatrixXd AOTransform::tform(L l_row, L l_col,
112 const Eigen::MatrixXd& cartesian);
113template Eigen::MatrixXcd AOTransform::tform(L l_row, L l_col,
114 const Eigen::MatrixXcd& cartesian);
115
116Eigen::VectorXd AOTransform::XIntegrate(Index size, double U) {
117 Eigen::VectorXd FmU = Eigen::VectorXd::Zero(size);
118 XIntegrate(size, U, FmU.data());
119 return FmU;
120}
121
122void AOTransform::XIntegrate(Index size, double U, double* FmU) {
123
124 const Index mm = size - 1;
125 const double pi = boost::math::constants::pi<double>();
126 if (mm < 0) {
127 throw std::runtime_error("mm is: " + std::to_string(mm) +
128 " This should not have happened!");
129 }
130
131 if (U < 0.0) {
132 throw std::runtime_error("U is: " + std::to_string(U) +
133 " This should not have happened!");
134 }
135
136 if (U >= 10.0) {
137 // forward iteration
138 FmU[0] = 0.50 * std::sqrt(pi / U) * std::erf(std::sqrt(U));
139
140 const double expU = std::exp(-U);
141 for (Index m = 1; m < size; m++) {
142 FmU[m] =
143 (2.0 * double(m) - 1) * FmU[m - 1] / (2.0 * U) - expU / (2.0 * U);
144 }
145 }
146
147 else if (U < 1e-10) {
148 for (Index m = 0; m < size; m++) {
149 FmU[m] = 1.0 / (2.0 * double(m) + 1.0) - U / (2.0 * double(m) + 3.0);
150 }
151 }
152
153 else if (U >= 1e-10 && U < 10.0) {
154 // backward iteration
155 double fm = 0.0;
156 const double expU = std::exp(-U);
157 for (Index m = 60; m >= mm; m--) {
158 fm = (2.0 * U) / (2.0 * double(m) + 1.0) * (fm + expU / (2.0 * U));
159 }
160 FmU[mm] = fm;
161 for (Index m = mm - 1; m >= 0; m--) {
162 FmU[m] =
163 (2.0 * U) / (2.0 * double(m) + 1.0) * (FmU[m + 1] + expU / (2.0 * U));
164 }
165 }
166}
167
169 // Each cartesian shells has (l+1)(l+2)/2 elements
170 // Sum of all shells up to lmax_ leads to blocksize=1+11/6 l+l^2+1/6 l^3
171 Index blocksize = 6 + 11 * lmax + 6 * lmax * lmax + lmax * lmax * lmax;
172 blocksize /= 6;
173 return blocksize;
174}
175
176// blockSize till l=8
177std::array<int, 9> AOTransform::n_orbitals() {
178 return {1, 4, 10, 20, 35, 56, 84, 120, 165};
179}
180
181std::array<int, 165> AOTransform::nx() {
182 return {0, 1, 0, 0, 2, 1, 1, 0, 0, 0, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 4,
183 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 5, 4, 4, 3, 3, 3, 2,
184 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 6, 5, 5, 4, 4, 4, 3,
185 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
186 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,
187 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 7, 6, 6, 6,
188 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,
189 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
190}
191
192std::array<int, 165> AOTransform::ny() {
193 return {0, 0, 1, 0, 0, 1, 0, 2, 1, 0, 0, 1, 0, 2, 1, 0, 3, 2, 1, 0, 0,
194 1, 0, 2, 1, 0, 3, 2, 1, 0, 4, 3, 2, 1, 0, 0, 1, 0, 2, 1, 0, 3,
195 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 0, 1, 0, 2, 1, 0, 3,
196 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 6, 5, 4, 3, 2, 1, 0,
197 0, 1, 0, 2, 1, 0, 3, 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0,
198 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 0, 2, 1, 0,
199 3, 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 6, 5, 4, 3, 2, 1,
200 0, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4, 3, 2, 1, 0};
201}
202
203std::array<int, 165> AOTransform::nz() {
204 return {0, 0, 0, 1, 0, 0, 1, 0, 1, 2, 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0,
205 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 0, 1, 0, 1, 2, 0,
206 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 0, 1, 0, 1, 2, 0,
207 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6,
208 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5,
209 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 1, 0, 1, 2,
210 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
211 6, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8};
212}
213
214std::array<int, 165> AOTransform::i_less_x() {
215 return {0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 7,
216 8, 9, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17,
217 18, 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26,
218 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0,
219 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
220 49, 50, 51, 52, 53, 54, 55, 0, 0, 0, 0, 0, 0, 0,
221 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
222 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
223 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, 86, 87, 88, 89,
224 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
225 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
226 118, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0};
227}
228std::array<int, 165> AOTransform::i_less_y() {
229 return {0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 4, 0, 5,
230 6, 0, 7, 8, 9, 0, 0, 10, 0, 11, 12, 0, 13, 14,
231 15, 0, 16, 17, 18, 19, 0, 0, 20, 0, 21, 22, 0, 23,
232 24, 25, 0, 26, 27, 28, 29, 0, 30, 31, 32, 33, 34, 0,
233 0, 35, 0, 36, 37, 0, 38, 39, 40, 0, 41, 42, 43, 44,
234 0, 45, 46, 47, 48, 49, 0, 50, 51, 52, 53, 54, 55, 0,
235 0, 56, 0, 57, 58, 0, 59, 60, 61, 0, 62, 63, 64, 65,
236 0, 66, 67, 68, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0,
237 77, 78, 79, 80, 81, 82, 83, 0, 0, 84, 0, 85, 86, 0,
238 87, 88, 89, 0, 90, 91, 92, 93, 0, 94, 95, 96, 97, 98,
239 0, 99, 100, 101, 102, 103, 104, 0, 105, 106, 107, 108, 109, 110,
240 111, 0, 112, 113, 114, 115, 116, 117, 118, 119, 0};
241}
242
243std::array<int, 165> AOTransform::i_less_z() {
244 return {0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 4, 0,
245 5, 6, 0, 7, 8, 9, 0, 0, 10, 0, 11, 12, 0, 13,
246 14, 15, 0, 16, 17, 18, 19, 0, 0, 20, 0, 21, 22, 0,
247 23, 24, 25, 0, 26, 27, 28, 29, 0, 30, 31, 32, 33, 34,
248 0, 0, 35, 0, 36, 37, 0, 38, 39, 40, 0, 41, 42, 43,
249 44, 0, 45, 46, 47, 48, 49, 0, 50, 51, 52, 53, 54, 55,
250 0, 0, 56, 0, 57, 58, 0, 59, 60, 61, 0, 62, 63, 64,
251 65, 0, 66, 67, 68, 69, 70, 0, 71, 72, 73, 74, 75, 76,
252 0, 77, 78, 79, 80, 81, 82, 83, 0, 0, 84, 0, 85, 86,
253 0, 87, 88, 89, 0, 90, 91, 92, 93, 0, 94, 95, 96, 97,
254 98, 0, 99, 100, 101, 102, 103, 104, 0, 105, 106, 107, 108, 109,
255 110, 111, 0, 112, 113, 114, 115, 116, 117, 118, 119};
256}
257
258std::array<int, 120> AOTransform::i_more_x() {
259 return {1, 4, 5, 6, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23,
260 24, 25, 26, 27, 28, 29, 35, 36, 37, 38, 39, 40, 41, 42,
261 43, 44, 45, 46, 47, 48, 49, 56, 57, 58, 59, 60, 61, 62,
262 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
263 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
264 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
265 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
266 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
267 148, 149, 150, 151, 152, 153, 154, 155};
268}
269
270std::array<int, 120> AOTransform::i_more_y() {
271 return {2, 5, 7, 8, 11, 13, 14, 16, 17, 18, 21, 23, 24, 26,
272 27, 28, 30, 31, 32, 33, 36, 38, 39, 41, 42, 43, 45, 46,
273 47, 48, 50, 51, 52, 53, 54, 57, 59, 60, 62, 63, 64, 66,
274 67, 68, 69, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 82,
275 85, 87, 88, 90, 91, 92, 94, 95, 96, 97, 99, 100, 101, 102,
276 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
277 121, 123, 124, 126, 127, 128, 130, 131, 132, 133, 135, 136, 137, 138,
278 139, 141, 142, 143, 144, 145, 146, 148, 149, 150, 151, 152, 153, 154,
279 156, 157, 158, 159, 160, 161, 162, 163};
280}
281
282std::array<int, 120> AOTransform::i_more_z() {
283 return {3, 6, 8, 9, 12, 14, 15, 17, 18, 19, 22, 24, 25, 27,
284 28, 29, 31, 32, 33, 34, 37, 39, 40, 42, 43, 44, 46, 47,
285 48, 49, 51, 52, 53, 54, 55, 58, 60, 61, 63, 64, 65, 67,
286 68, 69, 70, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83,
287 86, 88, 89, 91, 92, 93, 95, 96, 97, 98, 100, 101, 102, 103,
288 104, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119,
289 122, 124, 125, 127, 128, 129, 131, 132, 133, 134, 136, 137, 138, 139,
290 140, 142, 143, 144, 145, 146, 147, 149, 150, 151, 152, 153, 154, 155,
291 157, 158, 159, 160, 161, 162, 163, 164};
292}
293
294} // namespace xtp
295} // namespace votca
double getContraction() const
Definition aoshell.h:74
static Eigen::VectorXd XIntegrate(Index size, double U)
static std::array< int, 120 > i_more_x()
static std::array< int, 165 > i_less_y()
static std::array< int, 120 > i_more_y()
static std::array< int, 165 > i_less_z()
static Index getBlockSize(Index lmax)
static Matrix tform(L l_row, L l_col, const Matrix &cartesian)
transforms a cartesian shell to a spherical cartesian shell
static std::array< int, 165 > i_less_x()
static std::array< int, 120 > i_more_z()
static double getNorm(L l, const AOGaussianPrimitive &gaussian)
static std::array< int, 165 > ny()
static std::array< int, 165 > nz()
static std::array< int, 9 > n_orbitals()
static std::array< int, 165 > nx()
Charge transport classes.
Definition ERIs.h:28
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26