-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCGTOPair.hh
231 lines (218 loc) · 6.41 KB
/
CGTOPair.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#ifndef CGTOPAIR_HH
#define CGTOPAIR_HH
/*!
* \file CGTOPair.hh
* \brief Definition of the CGTOPair class
*/
#include <typeinfo>
#include <Eigen/Core>
#include "AbstractBFPair.hh"
#include "CGTO.hh"
#include "MultiArray.hh"
#include "constants.hh"
/*!
* \brief Class for pairs of contracted GTOs
*
* Class CGTOPair holds a pair of contracted Gaussian type orbitals, and
* defines a set of operations on this pair, like computing the overlap
* or kinetic energy integral.
*/
class CGTOPair: public AbstractBFPair
{
public:
//! Unique class ID, used in looking up integral calculation functions
static const size_t cid;
//! Constructor
CGTOPair(const CGTO& f, const CGTO& g):
AbstractBFPair(cid, f, g),
_shell_pair(CGTOShellList::singleton().pair(f.shell(), g.shell()))
{}
//! Return the first orbital in the pair
const CGTO& f() const
{
return static_cast< const CGTO& >(AbstractBFPair::f());
}
//! Return the second orbital in the pair
const CGTO& g() const
{
return static_cast< const CGTO& >(AbstractBFPair::g());
}
//! Return the pair of orbitals shells
const CGTOShellPair& shellPair() const { return _shell_pair; }
//! Compute the overlap between the two orbitals in this pair
double overlap() const;
//! Compute the kinetic energy integral between the two orbitals in this pair
double kineticEnergy() const;
/*!
* \brief Compute one-electron integrals
*
* Compute the overlap and kinetic energy integral between the two
* functions in this pair.
* \param S Place to store the overlap
* \param T Place to store the kinetic energy
*/
void oneElectron(double& S, double& T) const;
/*!
* \brief Compute nuclear attraction integrals
*
* Compute the nuclear attraction integrals, due to the nuclei with
* positions \a nuc_pos and charges \a nuc_charge, between the functions
* in this pair.
* \param nuc_pos The positions of the nuclei
* \param nuc_charge The nuclear charges
*/
double nuclearAttraction(const Eigen::MatrixXd& nuc_pos,
const Eigen::VectorXd& nuc_charge) const;
/*!
* \brief Return the total number of primitive pairs in this
* pair of contractions
*/
int size() const
{
return f().size() * g().size();
}
//! Return the angular momentum in the \a i direction for the first orbital
int lA(int i) const
{
return f().l(i);
}
//! Return the angular momentum in the \a i direction for the second orbital
int lB(int i) const
{
return g().l(i);
}
//! Return the sum of angular momenta in the \a i direction for the two orbitals
int lsum(int i) const
{
return lA(i) + lB(i);
}
/*!
* \brief Return the widths of the primitives in the first contraction,
* for all primitives in the second contraction.
*/
const Eigen::ArrayXXd& widthsA() const
{
//return f().widths().replicate(1, g().size());
return _shell_pair.widthsA();
}
/*!
* \brief Return the widths of the primitives in the second
* contraction, for all primitives in the first contraction.
*/
const Eigen::ArrayXXd& widthsB() const
{
//return g().widths().transpose().replicate(f().size(), 1);
return _shell_pair.widthsB();
}
//! The sums of primitive widths, equivalent to widthsA() + widthsB()
const Eigen::ArrayXXd& widthsSum() const
{
//return widthsA() + widthsB();
return _shell_pair.widthsSum();
}
//! The "reduced" primitive widths \f$\xi = \alpha\beta / (\alpha+\beta)\f$
const Eigen::ArrayXXd& widthsReduced() const
{
return _shell_pair.widthsReduced();
}
/*!
* \brief \f\frac{$\exp(-\xi r^2)}{\alpha+\beta}\f$ with \f$r\f$ the
* distance between the centers of the two orbitals.
*/
const Eigen::ArrayXXd& gaussReduced() const
{
return _shell_pair.gaussReduced();
}
//! Return half the inverse widths sums, \f$\frac{1}{2(\alpha+\beta)}\f$
const Eigen::ArrayXXd& hInvWidths() const
{
return _shell_pair.hInvWidths();
}
//! Return the first orbital center
const Eigen::Vector3d& centerA() const
{
return f().center();
}
//! Return the \a i coordinate of the first orbital center
double centerA(int i) const
{
return f().center(i);
}
//! Return the second orbital center
const Eigen::Vector3d& centerB() const
{
return g().center();
}
//! Return the \a i coordinate of the second orbital center
double centerB(int i) const
{
return g().center(i);
}
//! Return the vector from the first to the second orbital center
Eigen::Vector3d r() const
{
return g().center() - f().center();
}
//! Return the distance in the \a i direction between the two centers
double r(int i) const
{
return g().center(i) - f().center(i);
}
/*!
* \brief Return the weighted average \a i coordinate, for each
* combination of primitive widths.
*/
const Eigen::ArrayXXd& P(int i) const
{
return _shell_pair.P(i);
}
Eigen::ArrayXXd K() const
{
return Constants::sqrt_2_pi_5_4 * gaussReduced();
}
/*!
* \brief Create a new CGTOPair
*
* Create a new pairs of CGTOs. This pseudo-constructor provides a
* common interface that allows the Dispatcher to add pair creation
* functions for arbitrary pairs of basis function types.
* \param f The first orbital in the pair. Should be a CGTO.
* \param g The second orbital in the pair. Should be a CGTO.
*/
static AbstractBFPair *create(const AbstractBF& f, const AbstractBF& g)
{
try
{
const CGTO& ff = dynamic_cast< const CGTO& >(f);
const CGTO& gg = dynamic_cast< const CGTO& >(g);
return new CGTOPair(ff, gg);
}
catch (const std::bad_cast&)
{
throw Li::Exception("Invalid basis function type");
}
}
private:
/*!
* Multiply the contributions to an integral \a C of each primitive pair
* with the weights of the primitives, and sum the results to compute
* the integral over the contraction.
* \param C the primitve integrals
*/
template <typename Derived>
double mulWeights(const Eigen::ArrayBase<Derived>& C) const
{
return _shell_pair.mulWeights(C);
}
//! The shells for this pair of orbitals
CGTOShellPair _shell_pair;
//! Integrate the overlap matrix for this pair over dimension \a i.
void overlapPrim1D(int i, Eigen::ArrayXXd& Sp) const;
//! Integrate the overlap and kinetic energy matrices for this pair over dimension \a i.
void oneElecPrim1D(int i, Eigen::ArrayXXd& Sp, Eigen::ArrayXXd& Tp) const;
//! Integrate the coefficients for nuclear attraction integrals over dimension \a i.
void nucAttrPrim1D(int i, const Eigen::ArrayXXd& theta,
const Eigen::ArrayXXd& Pi, const Eigen::ArrayXXd& dPC,
MultiArray& res) const;
};
#endif // CGTOPAIR_HH