votca 2026-dev
Loading...
Searching...
No Matches
aoshell.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2021 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
21#include "votca/xtp/aoshell.h"
22#include "votca/xtp/aobasis.h"
23#include "votca/xtp/aomatrix.h"
25
26namespace votca {
27namespace xtp {
28
30 : decay_(gaussian.decay()), contraction_(gaussian.contraction()) {
32}
33
35 table.addCol<Index>("atomidx", HOFFSET(data, atomid));
36 table.addCol<Index>("L", HOFFSET(data, l));
37 table.addCol<Index>("startidx", HOFFSET(data, startindex));
38 table.addCol<double>("decay", HOFFSET(data, decay));
39 table.addCol<double>("contr", HOFFSET(data, contraction));
40 table.addCol<double>("pos.x", HOFFSET(data, x));
41 table.addCol<double>("pos.y", HOFFSET(data, y));
42 table.addCol<double>("pos.z", HOFFSET(data, z));
43 table.addCol<double>("scale", HOFFSET(data, scale));
44}
45
47 d.atomid = s.getAtomIndex();
48 d.l = static_cast<Index>(s.getL());
49 d.startindex = s.getStartIndex();
50 d.decay = getDecay();
52 d.x = s.getPos().x();
53 d.y = s.getPos().y();
54 d.z = s.getPos().z();
55}
56
57AOShell::AOShell(const Shell& shell, const QMAtom& atom, Index startIndex)
58 : l_(shell.getL()),
59 startIndex_(startIndex),
60 pos_(atom.getPos()),
61 atomindex_(atom.getId()) {
62 ;
63}
64
65libint2::Shell AOShell::LibintShell() const {
66 libint2::svector<libint2::Shell::real_t> decays;
67 libint2::svector<libint2::Shell::Contraction> contractions;
68 const Eigen::Vector3d& pos = getPos();
69 libint2::Shell::Contraction contr;
70 contr.l = static_cast<int>(getL());
71 contr.pure = true;
72 for (const auto& primitive : gaussians_) {
73 decays.push_back(primitive.getDecay());
74 contr.coeff.push_back(primitive.getContraction());
75 }
76 contractions.push_back(contr);
77 std::array<libint2::Shell::real_t, 3> libintpos = {pos[0], pos[1], pos[2]};
78 return libint2::Shell(decays, contractions, libintpos);
79}
80
82 AOOverlap overlap;
83 Eigen::MatrixXd block = overlap.singleShellOverlap(*this);
84 double norm = std::sqrt(block(0, 0));
85 for (auto& gaussian : gaussians_) {
86 gaussian.contraction_ /= norm;
87 }
88 return;
89}
90
91AOShell::AOValues AOShell::EvalAOspace(const Eigen::Vector3d& grid_pos) const {
92
93 // need position of shell
94 const Eigen::Vector3d center = (grid_pos - pos_);
95 const double distsq = center.squaredNorm();
97 Eigen::VectorXd& AOvalues = AO.values;
98 Eigen::MatrixX3d& gradAOvalues = AO.derivatives;
99
100 // iterate over Gaussians in this shell
101 for (const AOGaussianPrimitive& gaussian : gaussians_) {
102
103 const double alpha = gaussian.getDecay();
104 const double contraction = gaussian.getContraction();
105
106 const double expofactor =
107 gaussian.getPowfactor() * std::exp(-alpha * distsq);
108 const Eigen::Vector3d second_term = -2.0 * alpha * center;
109
110 switch (l_) {
111 case L::S: {
112 double AOvalue = contraction * expofactor;
113 AOvalues(0) += AOvalue; // s-function
114 gradAOvalues.row(0) += second_term * AOvalue; // gradient of s-function
115 } break;
116 case L::P: {
117 const double factor = 2. * sqrt(alpha) * contraction * expofactor;
118
119 double AOvalue = factor * center.y(); // Y 1,-1
120 AOvalues(0) += AOvalue;
121 gradAOvalues.row(0) += second_term * AOvalue;
122 gradAOvalues(0, 1) += factor;
123
124 AOvalue = factor * center.z(); // Y 1,0
125 AOvalues(1) += AOvalue;
126 gradAOvalues.row(1) += second_term * AOvalue;
127 gradAOvalues(1, 2) += factor;
128
129 AOvalue = factor * center.x(); // Y 1,1
130 AOvalues(2) += AOvalue;
131 gradAOvalues(2, 0) += factor;
132 gradAOvalues.row(2) += second_term * AOvalue; // y gradient
133 } break;
134 case L::D: {
135 const double factor = 2. * alpha * contraction * expofactor;
136 const double factor_1 = factor / sqrt(3.);
137
138 double AOvalue = 2. * factor * (center.x() * center.y()); // Y 2,-2
139 AOvalues(0) += AOvalue;
140 Eigen::Array3d coeff = {2 * center.y(), 2 * center.x(), 0};
141 gradAOvalues.row(0) += factor * coeff.matrix() + second_term * AOvalue;
142
143 AOvalue = 2. * factor * (center.y() * center.z()); // Y 2,-1
144 AOvalues(1) += AOvalue;
145 coeff = {0, 2 * center.z(), 2 * center.y()};
146 gradAOvalues.row(1) += factor * coeff.matrix() + second_term * AOvalue;
147
148 AOvalue = factor_1 * (3. * center.z() * center.z() - distsq); // Y 2,0
149 AOvalues(2) += AOvalue;
150 coeff = {-2, -2, 4};
151 gradAOvalues.row(2) += (factor_1 * coeff * center.array()).matrix() +
152 second_term * AOvalue;
153
154 AOvalue = 2. * factor * (center.x() * center.z()); // Y 2,1
155 AOvalues(3) += AOvalue;
156 coeff = {2 * center.z(), 0, 2 * center.x()};
157 gradAOvalues.row(3) += factor * coeff.matrix() + second_term * AOvalue;
158
159 AOvalue = factor *
160 (center.x() * center.x() - center.y() * center.y()); // Y 2,2
161 AOvalues(4) += AOvalue;
162 coeff = {2 * center.x(), -2 * center.y(), 0};
163 gradAOvalues.row(4) += factor * coeff.matrix() + second_term * AOvalue;
164 } break;
165 case L::F: {
166 const double factor = 2. * pow(alpha, 1.5) * contraction * expofactor;
167 const double factor_1 = factor * 2. / sqrt(15.);
168 const double factor_2 = factor * sqrt(2.) / sqrt(5.);
169 const double factor_3 = factor * sqrt(2.) / sqrt(3.);
170 AxA c(center);
171
172 double AOvalue =
173 factor_3 * center.y() * (3. * c.xx() - c.yy()); // Y 3,-3
174 AOvalues(0) += AOvalue;
175 Eigen::Array3d coeff = {6. * c.xy(), 3. * (c.xx() - c.yy()), 0};
176 gradAOvalues.row(0) +=
177 factor_3 * coeff.matrix() + second_term * AOvalue;
178
179 AOvalue = 4. * factor * center.x() * center.y() * center.z(); // Y 3,-2
180 AOvalues(1) += AOvalue;
181 coeff = {c.yz(), c.xz(), c.xy()};
182 gradAOvalues.row(1) +=
183 4 * factor * coeff.matrix() + second_term * AOvalue;
184
185 AOvalue = factor_2 * center.y() * (5. * c.zz() - distsq); // Y 3,-1
186 AOvalues(2) += AOvalue;
187 coeff = {-2. * c.xy(), 4. * c.zz() - c.xx() - 3. * c.yy(), 8. * c.yz()};
188 gradAOvalues.row(2) +=
189 factor_2 * coeff.matrix() + second_term * AOvalue;
190
191 AOvalue = factor_1 * center.z() * (5. * c.zz() - 3. * distsq); // Y 3,0
192 AOvalues(3) += AOvalue;
193 coeff = {-6. * c.xz(), -6. * c.yz(), 3. * (3. * c.zz() - distsq)};
194 gradAOvalues.row(3) +=
195 factor_1 * coeff.matrix() + second_term * AOvalue;
196
197 AOvalue = factor_2 * center.x() * (5. * c.zz() - distsq); // Y 3,1
198 AOvalues(4) += AOvalue;
199 coeff = {4. * c.zz() - c.yy() - 3. * c.xx(), -2. * c.xy(), 8. * c.xz()};
200 gradAOvalues.row(4) +=
201 factor_2 * coeff.matrix() + second_term * AOvalue;
202
203 AOvalue = 2. * factor * center.z() * (c.xx() - c.yy()); // Y 3,2
204 AOvalues(5) += AOvalue;
205 coeff = {2. * c.xz(), -2. * c.yz(), c.xx() - c.yy()};
206 gradAOvalues.row(5) +=
207 2 * factor * coeff.matrix() + second_term * AOvalue;
208
209 AOvalue = factor_3 * center.x() * (c.xx() - 3. * c.yy()); // Y 3,3
210 AOvalues(6) += AOvalue;
211 coeff = {3. * (c.xx() - c.yy()), -6. * c.xy(), 0};
212 gradAOvalues.row(6) +=
213 factor_3 * coeff.matrix() + second_term * AOvalue;
214 } break;
215 case L::G: {
216 const double factor =
217 2. / sqrt(3.) * alpha * alpha * contraction * expofactor;
218 const double factor_1 = factor / sqrt(35.);
219 const double factor_2 = factor * 4. / sqrt(14.);
220 const double factor_3 = factor * 2. / sqrt(7.);
221 const double factor_4 = factor * 2. * sqrt(2.);
222 AxA c(center);
223
224 double AOvalue = 4. * factor * c.xy() * (c.xx() - c.yy()); // Y 4,-4
225 AOvalues(0) += AOvalue;
226 Eigen::Array3d coeff = {center.y() * (3. * c.xx() - c.yy()),
227 center.x() * (c.xx() - 3. * c.yy()), 0};
228 gradAOvalues.row(0) +=
229 4 * factor * coeff.matrix() + second_term * AOvalue;
230
231 AOvalue = factor_4 * c.yz() * (3. * c.xx() - c.yy()); // Y 4,-3
232 AOvalues(1) += AOvalue;
233 coeff = {6. * center.x() * c.yz(), 3. * center.z() * (c.xx() - c.yy()),
234 center.y() * (3. * c.xx() - c.yy())};
235 gradAOvalues.row(1) +=
236 factor_4 * coeff.matrix() + second_term * AOvalue;
237
238 AOvalue = 2. * factor_3 * c.xy() * (7. * c.zz() - distsq); // Y 4,-2
239 AOvalues(2) += AOvalue;
240 coeff = {center.y() * (6. * c.zz() - 3. * c.xx() - c.yy()),
241 center.x() * (6. * c.zz() - c.xx() - 3. * c.yy()),
242 12. * center.z() * c.xy()};
243 gradAOvalues.row(2) +=
244 2 * factor_3 * coeff.matrix() + second_term * AOvalue;
245
246 AOvalue = factor_2 * c.yz() * (7. * c.zz() - 3. * distsq); // Y 4,-1
247 AOvalues(3) += AOvalue;
248 coeff = {(-6. * center.x() * c.yz()),
249 center.z() * (4. * c.zz() - 3. * c.xx() - 9. * c.yy()),
250 3. * center.y() * (5. * c.zz() - distsq)};
251 gradAOvalues.row(3) +=
252 factor_2 * coeff.matrix() + second_term * AOvalue;
253
254 AOvalue = factor_1 * (35. * c.zz() * c.zz() - 30. * c.zz() * distsq +
255 3. * distsq * distsq); // Y 4,0
256 AOvalues(4) += AOvalue;
257 coeff = {12. * center.x() * (distsq - 5. * c.zz()),
258 12. * center.y() * (distsq - 5. * c.zz()),
259 16. * center.z() * (5. * c.zz() - 3. * distsq)};
260
261 gradAOvalues.row(4) +=
262 factor_1 * coeff.matrix() + second_term * AOvalue;
263
264 AOvalue = factor_2 * c.xz() * (7. * c.zz() - 3. * distsq); // Y 4,1
265 AOvalues(5) += AOvalue;
266 coeff = {center.z() * (4. * c.zz() - 9. * c.xx() - 3. * c.yy()),
267 (-6. * center.y() * c.xz()),
268 3. * center.x() * (5. * c.zz() - distsq)};
269 gradAOvalues.row(5) +=
270 factor_2 * coeff.matrix() + second_term * AOvalue;
271
272 AOvalue =
273 factor_3 * (c.xx() - c.yy()) * (7. * c.zz() - distsq); // Y 4,2
274 AOvalues(6) += AOvalue;
275 coeff = {4. * center.x() * (3. * c.zz() - c.xx()),
276 4. * center.y() * (c.yy() - 3. * c.zz()),
277 12. * center.z() * (c.xx() - c.yy())};
278 gradAOvalues.row(6) +=
279 factor_3 * coeff.matrix() + second_term * AOvalue;
280
281 AOvalue = factor_4 * c.xz() * (c.xx() - 3. * c.yy()); // Y 4,3
282 AOvalues(7) += AOvalue;
283 coeff = {3. * center.z() * (c.xx() - c.yy()),
284 (-6. * center.y() * c.xz()),
285 center.x() * (c.xx() - 3. * c.yy())};
286 gradAOvalues.row(7) +=
287 factor_4 * coeff.matrix() + second_term * AOvalue;
288
289 AOvalue = factor * (c.xx() * c.xx() - 6. * c.xx() * c.yy() +
290 c.yy() * c.yy()); // Y 4,4
291 AOvalues(8) += AOvalue;
292 coeff = {center.x() * (c.xx() - 3. * c.yy()),
293 center.y() * (c.yy() - 3. * c.xx()), 0};
294 gradAOvalues.row(8) +=
295 4 * factor * coeff.matrix() + second_term * AOvalue;
296 } break;
297 default:
298 throw std::runtime_error("Shell type:" + EnumToString(l_) +
299 " not known");
300 break;
301 }
302 } // contractions
303 return AO;
304}
305
307 const Eigen::Vector3d& grid_pos) const {
308
309 const Eigen::Vector3d center = (grid_pos - pos_);
310 const double distsq = center.squaredNorm();
312 Eigen::VectorXd& AOvalues = AO.values;
313 Eigen::MatrixX3d& gradAOvalues = AO.derivatives;
314 std::vector<Eigen::Matrix3d>& hessians = AO.hessians;
315
316 // Accumulates the Hessian contribution from ONE Gaussian primitive to
317 // function index k, given that primitive's own prefactor, alpha, and
318 // the shell-function's polynomial P (via its value P_val, gradient
319 // dP_vec, and Hessian d2P_mat at this point) -- NOT the running,
320 // multi-primitive-accumulated AOvalue/gradient, since a contracted
321 // basis function sums primitives with DIFFERENT alpha, and this
322 // formula's alpha-dependent terms must use each primitive's own
323 // alpha, not some already-summed value. See the STATUS comment on
324 // AOValuesHessian in aoshell.h for the formula and its derivation.
325 auto addHessianContribution = [&](Index k, double prefactor, double P_val,
326 const Eigen::Vector3d& dP_vec,
327 const Eigen::Matrix3d& d2P_mat,
328 double alpha) {
329 double AOvalue_local = prefactor * P_val;
330 Eigen::Vector3d second_term_local = -2.0 * alpha * center;
331 Eigen::Vector3d grad_local =
332 prefactor * dP_vec + second_term_local * AOvalue_local;
333 Eigen::Matrix3d H = Eigen::Matrix3d::Zero();
334 for (Index i = 0; i < 3; ++i) {
335 for (Index j = 0; j < 3; ++j) {
336 double delta_ij = (i == j) ? 1.0 : 0.0;
337 H(i, j) = prefactor * d2P_mat(i, j) -
338 2.0 * alpha * delta_ij * AOvalue_local -
339 2.0 * alpha * center(i) * grad_local(j) -
340 2.0 * alpha * center(j) * grad_local(i) -
341 4.0 * alpha * alpha * center(i) * center(j) * AOvalue_local;
342 }
343 }
344 hessians[k] += H;
345 };
346
347 for (const AOGaussianPrimitive& gaussian : gaussians_) {
348
349 const double alpha = gaussian.getDecay();
350 const double contraction = gaussian.getContraction();
351
352 const double expofactor =
353 gaussian.getPowfactor() * std::exp(-alpha * distsq);
354 const Eigen::Vector3d second_term = -2.0 * alpha * center;
355
356 switch (l_) {
357 case L::S: {
358 double AOvalue = contraction * expofactor;
359 AOvalues(0) += AOvalue;
360 gradAOvalues.row(0) += second_term * AOvalue;
361 // P = 1, dP = 0, d2P = 0
362 addHessianContribution(0, contraction * expofactor, 1.0,
363 Eigen::Vector3d::Zero(), Eigen::Matrix3d::Zero(),
364 alpha);
365 } break;
366 case L::P: {
367 const double factor = 2. * sqrt(alpha) * contraction * expofactor;
368 Eigen::Matrix3d zero3 = Eigen::Matrix3d::Zero();
369
370 double AOvalue = factor * center.y(); // Y 1,-1
371 AOvalues(0) += AOvalue;
372 gradAOvalues.row(0) += second_term * AOvalue;
373 gradAOvalues(0, 1) += factor;
374 addHessianContribution(0, factor, center.y(), Eigen::Vector3d(0, 1, 0),
375 zero3, alpha);
376
377 AOvalue = factor * center.z(); // Y 1,0
378 AOvalues(1) += AOvalue;
379 gradAOvalues.row(1) += second_term * AOvalue;
380 gradAOvalues(1, 2) += factor;
381 addHessianContribution(1, factor, center.z(), Eigen::Vector3d(0, 0, 1),
382 zero3, alpha);
383
384 AOvalue = factor * center.x(); // Y 1,1
385 AOvalues(2) += AOvalue;
386 gradAOvalues(2, 0) += factor;
387 gradAOvalues.row(2) += second_term * AOvalue;
388 addHessianContribution(2, factor, center.x(), Eigen::Vector3d(1, 0, 0),
389 zero3, alpha);
390 } break;
391 case L::D: {
392 const double factor = 2. * alpha * contraction * expofactor;
393 const double factor_1 = factor / sqrt(3.);
394 Eigen::Matrix3d d2P;
395
396 double AOvalue = 2. * factor * (center.x() * center.y()); // Y 2,-2
397 AOvalues(0) += AOvalue;
398 Eigen::Array3d coeff = {2 * center.y(), 2 * center.x(), 0};
399 gradAOvalues.row(0) += factor * coeff.matrix() + second_term * AOvalue;
400 d2P << 0, 2, 0, 2, 0, 0, 0, 0, 0;
401 addHessianContribution(0, factor, 2. * center.x() * center.y(),
402 coeff.matrix(), d2P, alpha);
403
404 AOvalue = 2. * factor * (center.y() * center.z()); // Y 2,-1
405 AOvalues(1) += AOvalue;
406 coeff = {0, 2 * center.z(), 2 * center.y()};
407 gradAOvalues.row(1) += factor * coeff.matrix() + second_term * AOvalue;
408 d2P << 0, 0, 0, 0, 0, 2, 0, 2, 0;
409 addHessianContribution(1, factor, 2. * center.y() * center.z(),
410 coeff.matrix(), d2P, alpha);
411
412 AOvalue = factor_1 * (3. * center.z() * center.z() - distsq); // Y 2,0
413 AOvalues(2) += AOvalue;
414 coeff = {-2, -2, 4};
415 gradAOvalues.row(2) += (factor_1 * coeff * center.array()).matrix() +
416 second_term * AOvalue;
417 d2P << -2, 0, 0, 0, -2, 0, 0, 0, 4;
418 addHessianContribution(2, factor_1,
419 3. * center.z() * center.z() - distsq,
420 (coeff * center.array()).matrix(), d2P, alpha);
421
422 AOvalue = 2. * factor * (center.x() * center.z()); // Y 2,1
423 AOvalues(3) += AOvalue;
424 coeff = {2 * center.z(), 0, 2 * center.x()};
425 gradAOvalues.row(3) += factor * coeff.matrix() + second_term * AOvalue;
426 d2P << 0, 0, 2, 0, 0, 0, 2, 0, 0;
427 addHessianContribution(3, factor, 2. * center.x() * center.z(),
428 coeff.matrix(), d2P, alpha);
429
430 AOvalue = factor *
431 (center.x() * center.x() - center.y() * center.y()); // Y 2,2
432 AOvalues(4) += AOvalue;
433 coeff = {2 * center.x(), -2 * center.y(), 0};
434 gradAOvalues.row(4) += factor * coeff.matrix() + second_term * AOvalue;
435 d2P << 2, 0, 0, 0, -2, 0, 0, 0, 0;
436 addHessianContribution(
437 4, factor, center.x() * center.x() - center.y() * center.y(),
438 coeff.matrix(), d2P, alpha);
439 } break;
440 case L::F: {
441 const double factor = 2. * pow(alpha, 1.5) * contraction * expofactor;
442 const double factor_1 = factor * 2. / sqrt(15.);
443 const double factor_2 = factor * sqrt(2.) / sqrt(5.);
444 const double factor_3 = factor * sqrt(2.) / sqrt(3.);
445 AxA c(center);
446 Eigen::Matrix3d d2P;
447 double x = center.x(), y = center.y(), z = center.z();
448
449 double AOvalue =
450 factor_3 * center.y() * (3. * c.xx() - c.yy()); // Y 3,-3
451 AOvalues(0) += AOvalue;
452 Eigen::Array3d coeff = {6. * c.xy(), 3. * (c.xx() - c.yy()), 0};
453 gradAOvalues.row(0) +=
454 factor_3 * coeff.matrix() + second_term * AOvalue;
455 d2P << 6 * y, 6 * x, 0, 6 * x, -6 * y, 0, 0, 0, 0;
456 addHessianContribution(0, factor_3, y * (3. * c.xx() - c.yy()),
457 coeff.matrix(), d2P, alpha);
458
459 AOvalue = 4. * factor * center.x() * center.y() * center.z(); // Y 3,-2
460 AOvalues(1) += AOvalue;
461 coeff = {c.yz(), c.xz(), c.xy()};
462 gradAOvalues.row(1) +=
463 4 * factor * coeff.matrix() + second_term * AOvalue;
464 d2P << 0, z, y, z, 0, x, y, x, 0;
465 addHessianContribution(1, 4. * factor, x * y * z, coeff.matrix(), d2P,
466 alpha);
467
468 AOvalue = factor_2 * center.y() * (5. * c.zz() - distsq); // Y 3,-1
469 AOvalues(2) += AOvalue;
470 coeff = {-2. * c.xy(), 4. * c.zz() - c.xx() - 3. * c.yy(), 8. * c.yz()};
471 gradAOvalues.row(2) +=
472 factor_2 * coeff.matrix() + second_term * AOvalue;
473 d2P << -2 * y, -2 * x, 0, -2 * x, -6 * y, 8 * z, 0, 8 * z, 8 * y;
474 addHessianContribution(2, factor_2, y * (5. * c.zz() - distsq),
475 coeff.matrix(), d2P, alpha);
476
477 AOvalue = factor_1 * center.z() * (5. * c.zz() - 3. * distsq); // Y 3,0
478 AOvalues(3) += AOvalue;
479 coeff = {-6. * c.xz(), -6. * c.yz(), 3. * (3. * c.zz() - distsq)};
480 gradAOvalues.row(3) +=
481 factor_1 * coeff.matrix() + second_term * AOvalue;
482 d2P << -6 * z, 0, -6 * x, 0, -6 * z, -6 * y, -6 * x, -6 * y, 12 * z;
483 addHessianContribution(3, factor_1, z * (5. * c.zz() - 3. * distsq),
484 coeff.matrix(), d2P, alpha);
485
486 AOvalue = factor_2 * center.x() * (5. * c.zz() - distsq); // Y 3,1
487 AOvalues(4) += AOvalue;
488 coeff = {4. * c.zz() - c.yy() - 3. * c.xx(), -2. * c.xy(), 8. * c.xz()};
489 gradAOvalues.row(4) +=
490 factor_2 * coeff.matrix() + second_term * AOvalue;
491 d2P << -6 * x, -2 * y, 8 * z, -2 * y, -2 * x, 0, 8 * z, 0, 8 * x;
492 addHessianContribution(4, factor_2, x * (5. * c.zz() - distsq),
493 coeff.matrix(), d2P, alpha);
494
495 AOvalue = 2. * factor * center.z() * (c.xx() - c.yy()); // Y 3,2
496 AOvalues(5) += AOvalue;
497 coeff = {2. * c.xz(), -2. * c.yz(), c.xx() - c.yy()};
498 gradAOvalues.row(5) +=
499 2 * factor * coeff.matrix() + second_term * AOvalue;
500 d2P << 2 * z, 0, 2 * x, 0, -2 * z, -2 * y, 2 * x, -2 * y, 0;
501 addHessianContribution(5, 2. * factor, z * (c.xx() - c.yy()),
502 coeff.matrix(), d2P, alpha);
503
504 AOvalue = factor_3 * center.x() * (c.xx() - 3. * c.yy()); // Y 3,3
505 AOvalues(6) += AOvalue;
506 coeff = {3. * (c.xx() - c.yy()), -6. * c.xy(), 0};
507 gradAOvalues.row(6) +=
508 factor_3 * coeff.matrix() + second_term * AOvalue;
509 d2P << 6 * x, -6 * y, 0, -6 * y, -6 * x, 0, 0, 0, 0;
510 addHessianContribution(6, factor_3, x * (c.xx() - 3. * c.yy()),
511 coeff.matrix(), d2P, alpha);
512 } break;
513 case L::G: {
514 const double factor =
515 2. / sqrt(3.) * alpha * alpha * contraction * expofactor;
516 const double factor_1 = factor / sqrt(35.);
517 const double factor_2 = factor * 4. / sqrt(14.);
518 const double factor_3 = factor * 2. / sqrt(7.);
519 const double factor_4 = factor * 2. * sqrt(2.);
520 AxA c(center);
521 Eigen::Matrix3d d2P;
522 double x = center.x(), y = center.y(), z = center.z();
523
524 double AOvalue = 4. * factor * c.xy() * (c.xx() - c.yy()); // Y 4,-4
525 AOvalues(0) += AOvalue;
526 Eigen::Array3d coeff = {center.y() * (3. * c.xx() - c.yy()),
527 center.x() * (c.xx() - 3. * c.yy()), 0};
528 gradAOvalues.row(0) +=
529 4 * factor * coeff.matrix() + second_term * AOvalue;
530 d2P << 6 * x * y, 3 * x * x - 3 * y * y, 0, 3 * x * x - 3 * y * y,
531 -6 * x * y, 0, 0, 0, 0;
532 addHessianContribution(0, 4. * factor, x * y * (c.xx() - c.yy()),
533 coeff.matrix(), d2P, alpha);
534
535 AOvalue = factor_4 * c.yz() * (3. * c.xx() - c.yy()); // Y 4,-3
536 AOvalues(1) += AOvalue;
537 coeff = {6. * center.x() * c.yz(), 3. * center.z() * (c.xx() - c.yy()),
538 center.y() * (3. * c.xx() - c.yy())};
539 gradAOvalues.row(1) +=
540 factor_4 * coeff.matrix() + second_term * AOvalue;
541 d2P << 6 * y * z, 6 * x * z, 6 * x * y, 6 * x * z, -6 * y * z,
542 3 * x * x - 3 * y * y, 6 * x * y, 3 * x * x - 3 * y * y, 0;
543 addHessianContribution(1, factor_4, y * z * (3. * c.xx() - c.yy()),
544 coeff.matrix(), d2P, alpha);
545
546 AOvalue = 2. * factor_3 * c.xy() * (7. * c.zz() - distsq); // Y 4,-2
547 AOvalues(2) += AOvalue;
548 coeff = {center.y() * (6. * c.zz() - 3. * c.xx() - c.yy()),
549 center.x() * (6. * c.zz() - c.xx() - 3. * c.yy()),
550 12. * center.z() * c.xy()};
551 gradAOvalues.row(2) +=
552 2 * factor_3 * coeff.matrix() + second_term * AOvalue;
553 d2P << -6 * x * y, -3 * x * x - 3 * y * y + 6 * z * z, 12 * y * z,
554 -3 * x * x - 3 * y * y + 6 * z * z, -6 * x * y, 12 * x * z,
555 12 * y * z, 12 * x * z, 12 * x * y;
556 addHessianContribution(2, 2. * factor_3, x * y * (7. * c.zz() - distsq),
557 coeff.matrix(), d2P, alpha);
558
559 AOvalue = factor_2 * c.yz() * (7. * c.zz() - 3. * distsq); // Y 4,-1
560 AOvalues(3) += AOvalue;
561 coeff = {(-6. * center.x() * c.yz()),
562 center.z() * (4. * c.zz() - 3. * c.xx() - 9. * c.yy()),
563 3. * center.y() * (5. * c.zz() - distsq)};
564 gradAOvalues.row(3) +=
565 factor_2 * coeff.matrix() + second_term * AOvalue;
566 d2P << -6 * y * z, -6 * x * z, -6 * x * y, -6 * x * z, -18 * y * z,
567 -3 * x * x - 9 * y * y + 12 * z * z, -6 * x * y,
568 -3 * x * x - 9 * y * y + 12 * z * z, 24 * y * z;
569 addHessianContribution(3, factor_2, y * z * (7. * c.zz() - 3. * distsq),
570 coeff.matrix(), d2P, alpha);
571
572 AOvalue = factor_1 * (35. * c.zz() * c.zz() - 30. * c.zz() * distsq +
573 3. * distsq * distsq); // Y 4,0
574 AOvalues(4) += AOvalue;
575 coeff = {12. * center.x() * (distsq - 5. * c.zz()),
576 12. * center.y() * (distsq - 5. * c.zz()),
577 16. * center.z() * (5. * c.zz() - 3. * distsq)};
578 gradAOvalues.row(4) +=
579 factor_1 * coeff.matrix() + second_term * AOvalue;
580 d2P << 36 * x * x + 12 * y * y - 48 * z * z, 24 * x * y, -96 * x * z,
581 24 * x * y, 12 * x * x + 36 * y * y - 48 * z * z, -96 * y * z,
582 -96 * x * z, -96 * y * z, -48 * x * x - 48 * y * y + 96 * z * z;
583 addHessianContribution(4, factor_1,
584 35. * c.zz() * c.zz() - 30. * c.zz() * distsq +
585 3. * distsq * distsq,
586 coeff.matrix(), d2P, alpha);
587
588 AOvalue = factor_2 * c.xz() * (7. * c.zz() - 3. * distsq); // Y 4,1
589 AOvalues(5) += AOvalue;
590 coeff = {center.z() * (4. * c.zz() - 9. * c.xx() - 3. * c.yy()),
591 (-6. * center.y() * c.xz()),
592 3. * center.x() * (5. * c.zz() - distsq)};
593 gradAOvalues.row(5) +=
594 factor_2 * coeff.matrix() + second_term * AOvalue;
595 d2P << -18 * x * z, -6 * y * z, -9 * x * x - 3 * y * y + 12 * z * z,
596 -6 * y * z, -6 * x * z, -6 * x * y,
597 -9 * x * x - 3 * y * y + 12 * z * z, -6 * x * y, 24 * x * z;
598 addHessianContribution(5, factor_2, x * z * (7. * c.zz() - 3. * distsq),
599 coeff.matrix(), d2P, alpha);
600
601 AOvalue =
602 factor_3 * (c.xx() - c.yy()) * (7. * c.zz() - distsq); // Y 4,2
603 AOvalues(6) += AOvalue;
604 coeff = {4. * center.x() * (3. * c.zz() - c.xx()),
605 4. * center.y() * (c.yy() - 3. * c.zz()),
606 12. * center.z() * (c.xx() - c.yy())};
607 gradAOvalues.row(6) +=
608 factor_3 * coeff.matrix() + second_term * AOvalue;
609 d2P << -12 * x * x + 12 * z * z, 0, 24 * x * z, 0,
610 12 * y * y - 12 * z * z, -24 * y * z, 24 * x * z, -24 * y * z,
611 12 * x * x - 12 * y * y;
612 addHessianContribution(6, factor_3,
613 (c.xx() - c.yy()) * (7. * c.zz() - distsq),
614 coeff.matrix(), d2P, alpha);
615
616 AOvalue = factor_4 * c.xz() * (c.xx() - 3. * c.yy()); // Y 4,3
617 AOvalues(7) += AOvalue;
618 coeff = {3. * center.z() * (c.xx() - c.yy()),
619 (-6. * center.y() * c.xz()),
620 center.x() * (c.xx() - 3. * c.yy())};
621 gradAOvalues.row(7) +=
622 factor_4 * coeff.matrix() + second_term * AOvalue;
623 d2P << 6 * x * z, -6 * y * z, 3 * x * x - 3 * y * y, -6 * y * z,
624 -6 * x * z, -6 * x * y, 3 * x * x - 3 * y * y, -6 * x * y, 0;
625 addHessianContribution(7, factor_4, x * z * (c.xx() - 3. * c.yy()),
626 coeff.matrix(), d2P, alpha);
627
628 AOvalue = factor * (c.xx() * c.xx() - 6. * c.xx() * c.yy() +
629 c.yy() * c.yy()); // Y 4,4
630 AOvalues(8) += AOvalue;
631 coeff = {center.x() * (c.xx() - 3. * c.yy()),
632 center.y() * (c.yy() - 3. * c.xx()), 0};
633 gradAOvalues.row(8) +=
634 4 * factor * coeff.matrix() + second_term * AOvalue;
635 d2P << 12 * x * x - 12 * y * y, -24 * x * y, 0, -24 * x * y,
636 -12 * x * x + 12 * y * y, 0, 0, 0, 0;
637 // NOTE: dP_vec scaled by 4 here specifically, NOT prefactor --
638 // this function's own gradient update uses coeff at a "quarter
639 // scale" (4*factor*coeff.matrix(), not factor*coeff.matrix()
640 // like every other function in this shell), confirmed by
641 // cross-checking every AOvalue/gradient multiplier pair in this
642 // file against each other (the only mismatch found across all
643 // of D/F/G). d2P itself is unaffected (computed directly from
644 // the exact polynomial, independent of coeff's scaling
645 // convention) -- only dP_vec needs the correction, so that
646 // addHessianContribution's internal grad_local reconstruction
647 // (prefactor*dP_vec + second_term*AOvalue_local) matches the
648 // real gradient (factor*(4*coeff) + second_term*AOvalue =
649 // 4*factor*coeff + second_term*AOvalue, exactly what
650 // gradAOvalues.row(8) above actually accumulates).
651 addHessianContribution(
652 8, factor, c.xx() * c.xx() - 6. * c.xx() * c.yy() + c.yy() * c.yy(),
653 4.0 * coeff.matrix(), d2P, alpha);
654 } break;
655 default:
656 throw std::runtime_error("Shell type:" + EnumToString(l_) +
657 " not known (Hessian evaluation)");
658 break;
659 }
660 } // contractions
661 return AO;
662}
663
664std::ostream& operator<<(std::ostream& out, const AOShell& shell) {
665 out << "AtomIndex:" << shell.getAtomIndex();
666 out << " Shelltype:" << EnumToString(shell.getL())
667 << " StartIndex:" << shell.getStartIndex()
668 << " MinDecay:" << shell.getMinDecay() << "\n";
669 for (const auto& gaussian : shell) {
670 out << " Gaussian Decay: " << gaussian.getDecay();
671 out << " Contraction: " << gaussian.getContraction();
672 out << "\n";
673 }
674 return out;
675}
676
677} // namespace xtp
678} // namespace votca
static double CalcPowFactor(double decay)
Definition aoshell.h:77
double getContraction() const
Definition aoshell.h:74
AOGaussianPrimitive(const GaussianPrimitive &gaussian)
Definition aoshell.cc:29
void WriteData(data &d, const AOShell &s) const
Definition aoshell.cc:46
static void SetupCptTable(CptTable &table)
Definition aoshell.cc:34
Eigen::MatrixXd singleShellOverlap(const AOShell &shell) const
void normalizeContraction()
Definition aoshell.cc:81
const Eigen::Vector3d & getPos() const
Definition aoshell.h:113
libint2::Shell LibintShell() const
Definition aoshell.cc:65
Index getAtomIndex() const
Definition aoshell.h:108
AOValues EvalAOspace(const Eigen::Vector3d &grid_pos) const
Definition aoshell.cc:91
Index getStartIndex() const
Definition aoshell.h:105
AOValuesHessian EvalAOspaceHessian(const Eigen::Vector3d &grid_pos) const
Definition aoshell.cc:306
double getMinDecay() const
Definition aoshell.h:122
Index getNumFunc() const
Definition aoshell.h:103
std::vector< AOGaussianPrimitive > gaussians_
Definition aoshell.h:199
AOShell(const Shell &shell, const QMAtom &atom, Index startIndex)
Definition aoshell.cc:57
Eigen::Vector3d pos_
Definition aoshell.h:195
const double & zz() const
Definition eigen.h:103
const double & yz() const
Definition eigen.h:102
const double & yy() const
Definition eigen.h:101
const double & xy() const
Definition eigen.h:99
const double & xz() const
Definition eigen.h:100
const double & xx() const
Definition eigen.h:98
void addCol(const std::string &name, const size_t &offset)
container for QM atoms
Definition qmatom.h:37
std::ostream & operator<<(std::ostream &out, const Correlate &c)
Definition correlate.h:53
Charge transport classes.
Definition ERIs.h:28
std::string EnumToString(L l)
Definition basisset.cc:60
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
std::vector< Eigen::Matrix3d > hessians
Definition aoshell.h:169
Eigen::MatrixX3d derivatives
Definition aoshell.h:131