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