votca 2024.2-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
118 Eigen::VectorXd FmU = Eigen::VectorXd::Zero(size);
119 const Index mm = size - 1;
120 const double pi = boost::math::constants::pi<double>();
121 if (mm < 0) {
122 throw std::runtime_error("mm is: " + std::to_string(mm) +
123 " This should not have happened!");
124 }
125
126 if (U < 0.0) {
127 throw std::runtime_error("U is: " + std::to_string(U) +
128 " This should not have happened!");
129 }
130
131 if (U >= 10.0) {
132 // forward iteration
133 FmU[0] = 0.50 * std::sqrt(pi / U) * std::erf(std::sqrt(U));
134
135 const double expU = std::exp(-U);
136 for (Index m = 1; m < FmU.size(); m++) {
137 FmU[m] =
138 (2.0 * double(m) - 1) * FmU[m - 1] / (2.0 * U) - expU / (2.0 * U);
139 }
140 }
141
142 else if (U < 1e-10) {
143 for (Index m = 0; m < FmU.size(); m++) {
144 FmU[m] = 1.0 / (2.0 * double(m) + 1.0) - U / (2.0 * double(m) + 3.0);
145 }
146 }
147
148 else if (U >= 1e-10 && U < 10.0) {
149 // backward iteration
150 double fm = 0.0;
151 const double expU = std::exp(-U);
152 for (Index m = 60; m >= mm; m--) {
153 fm = (2.0 * U) / (2.0 * double(m) + 1.0) * (fm + expU / (2.0 * U));
154 }
155 FmU[mm] = fm;
156 for (Index m = mm - 1; m >= 0; m--) {
157 FmU[m] =
158 (2.0 * U) / (2.0 * double(m) + 1.0) * (FmU[m + 1] + expU / (2.0 * U));
159 }
160 }
161
162 return FmU;
163}
164
166 // Each cartesian shells has (l+1)(l+2)/2 elements
167 // Sum of all shells up to lmax_ leads to blocksize=1+11/6 l+l^2+1/6 l^3
168 Index blocksize = 6 + 11 * lmax + 6 * lmax * lmax + lmax * lmax * lmax;
169 blocksize /= 6;
170 return blocksize;
171}
172
173// blockSize till l=8
174std::array<int, 9> AOTransform::n_orbitals() {
175 return {1, 4, 10, 20, 35, 56, 84, 120, 165};
176}
177
178std::array<int, 165> AOTransform::nx() {
179 return {0, 1, 0, 0, 2, 1, 1, 0, 0, 0, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 4,
180 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 5, 4, 4, 3, 3, 3, 2,
181 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 6, 5, 5, 4, 4, 4, 3,
182 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
183 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,
184 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 7, 6, 6, 6,
185 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,
186 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
187}
188
189std::array<int, 165> AOTransform::ny() {
190 return {0, 0, 1, 0, 0, 1, 0, 2, 1, 0, 0, 1, 0, 2, 1, 0, 3, 2, 1, 0, 0,
191 1, 0, 2, 1, 0, 3, 2, 1, 0, 4, 3, 2, 1, 0, 0, 1, 0, 2, 1, 0, 3,
192 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 0, 1, 0, 2, 1, 0, 3,
193 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 6, 5, 4, 3, 2, 1, 0,
194 0, 1, 0, 2, 1, 0, 3, 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0,
195 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 0, 1, 0, 2, 1, 0,
196 3, 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0, 6, 5, 4, 3, 2, 1,
197 0, 7, 6, 5, 4, 3, 2, 1, 0, 8, 7, 6, 5, 4, 3, 2, 1, 0};
198}
199
200std::array<int, 165> AOTransform::nz() {
201 return {0, 0, 0, 1, 0, 0, 1, 0, 1, 2, 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0,
202 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 0, 1, 0, 1, 2, 0,
203 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 0, 1, 0, 1, 2, 0,
204 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6,
205 0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5,
206 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 1, 0, 1, 2,
207 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
208 6, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 8};
209}
210
211std::array<int, 165> AOTransform::i_less_x() {
212 return {0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 6, 7,
213 8, 9, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17,
214 18, 19, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26,
215 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0,
216 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
217 49, 50, 51, 52, 53, 54, 55, 0, 0, 0, 0, 0, 0, 0,
218 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
219 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
220 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, 86, 87, 88, 89,
221 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
222 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
223 118, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0};
224}
225std::array<int, 165> AOTransform::i_less_y() {
226 return {0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 4, 0, 5,
227 6, 0, 7, 8, 9, 0, 0, 10, 0, 11, 12, 0, 13, 14,
228 15, 0, 16, 17, 18, 19, 0, 0, 20, 0, 21, 22, 0, 23,
229 24, 25, 0, 26, 27, 28, 29, 0, 30, 31, 32, 33, 34, 0,
230 0, 35, 0, 36, 37, 0, 38, 39, 40, 0, 41, 42, 43, 44,
231 0, 45, 46, 47, 48, 49, 0, 50, 51, 52, 53, 54, 55, 0,
232 0, 56, 0, 57, 58, 0, 59, 60, 61, 0, 62, 63, 64, 65,
233 0, 66, 67, 68, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0,
234 77, 78, 79, 80, 81, 82, 83, 0, 0, 84, 0, 85, 86, 0,
235 87, 88, 89, 0, 90, 91, 92, 93, 0, 94, 95, 96, 97, 98,
236 0, 99, 100, 101, 102, 103, 104, 0, 105, 106, 107, 108, 109, 110,
237 111, 0, 112, 113, 114, 115, 116, 117, 118, 119, 0};
238}
239
240std::array<int, 165> AOTransform::i_less_z() {
241 return {0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 4, 0,
242 5, 6, 0, 7, 8, 9, 0, 0, 10, 0, 11, 12, 0, 13,
243 14, 15, 0, 16, 17, 18, 19, 0, 0, 20, 0, 21, 22, 0,
244 23, 24, 25, 0, 26, 27, 28, 29, 0, 30, 31, 32, 33, 34,
245 0, 0, 35, 0, 36, 37, 0, 38, 39, 40, 0, 41, 42, 43,
246 44, 0, 45, 46, 47, 48, 49, 0, 50, 51, 52, 53, 54, 55,
247 0, 0, 56, 0, 57, 58, 0, 59, 60, 61, 0, 62, 63, 64,
248 65, 0, 66, 67, 68, 69, 70, 0, 71, 72, 73, 74, 75, 76,
249 0, 77, 78, 79, 80, 81, 82, 83, 0, 0, 84, 0, 85, 86,
250 0, 87, 88, 89, 0, 90, 91, 92, 93, 0, 94, 95, 96, 97,
251 98, 0, 99, 100, 101, 102, 103, 104, 0, 105, 106, 107, 108, 109,
252 110, 111, 0, 112, 113, 114, 115, 116, 117, 118, 119};
253}
254
255std::array<int, 120> AOTransform::i_more_x() {
256 return {1, 4, 5, 6, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23,
257 24, 25, 26, 27, 28, 29, 35, 36, 37, 38, 39, 40, 41, 42,
258 43, 44, 45, 46, 47, 48, 49, 56, 57, 58, 59, 60, 61, 62,
259 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
260 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
261 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
262 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
263 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
264 148, 149, 150, 151, 152, 153, 154, 155};
265}
266
267std::array<int, 120> AOTransform::i_more_y() {
268 return {2, 5, 7, 8, 11, 13, 14, 16, 17, 18, 21, 23, 24, 26,
269 27, 28, 30, 31, 32, 33, 36, 38, 39, 41, 42, 43, 45, 46,
270 47, 48, 50, 51, 52, 53, 54, 57, 59, 60, 62, 63, 64, 66,
271 67, 68, 69, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 82,
272 85, 87, 88, 90, 91, 92, 94, 95, 96, 97, 99, 100, 101, 102,
273 103, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
274 121, 123, 124, 126, 127, 128, 130, 131, 132, 133, 135, 136, 137, 138,
275 139, 141, 142, 143, 144, 145, 146, 148, 149, 150, 151, 152, 153, 154,
276 156, 157, 158, 159, 160, 161, 162, 163};
277}
278
279std::array<int, 120> AOTransform::i_more_z() {
280 return {3, 6, 8, 9, 12, 14, 15, 17, 18, 19, 22, 24, 25, 27,
281 28, 29, 31, 32, 33, 34, 37, 39, 40, 42, 43, 44, 46, 47,
282 48, 49, 51, 52, 53, 54, 55, 58, 60, 61, 63, 64, 65, 67,
283 68, 69, 70, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83,
284 86, 88, 89, 91, 92, 93, 95, 96, 97, 98, 100, 101, 102, 103,
285 104, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 118, 119,
286 122, 124, 125, 127, 128, 129, 131, 132, 133, 134, 136, 137, 138, 139,
287 140, 142, 143, 144, 145, 146, 147, 149, 150, 151, 152, 153, 154, 155,
288 157, 158, 159, 160, 161, 162, 163, 164};
289}
290
291} // namespace xtp
292} // 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()
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26