votca 2024-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
306std::ostream& operator<<(std::ostream& out, const AOShell& shell) {
307 out << "AtomIndex:" << shell.getAtomIndex();
308 out << " Shelltype:" << EnumToString(shell.getL())
309 << " StartIndex:" << shell.getStartIndex()
310 << " MinDecay:" << shell.getMinDecay() << "\n";
311 for (const auto& gaussian : shell) {
312 out << " Gaussian Decay: " << gaussian.getDecay();
313 out << " Contraction: " << gaussian.getContraction();
314 out << "\n";
315 }
316 return out;
317}
318
319} // namespace xtp
320} // 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
double getMinDecay() const
Definition aoshell.h:122
Index getNumFunc() const
Definition aoshell.h:103
std::vector< AOGaussianPrimitive > gaussians_
Definition aoshell.h:161
AOShell(const Shell &shell, const QMAtom &atom, Index startIndex)
Definition aoshell.cc:57
Eigen::Vector3d pos_
Definition aoshell.h:157
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
std::string EnumToString(L l)
Definition basisset.cc:60
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
Eigen::MatrixX3d derivatives
Definition aoshell.h:131