MADNESS 0.10.1
gaussian.h
Go to the documentation of this file.
1/* This file is a part of Slymer, which is distributed under the Creative
2 Commons Attribution-NonCommercial 4.0 International Public License.
3
4 (c) 2017 Stony Brook University. */
5
6/**
7 * \file Basis/gaussian.h
8 * \brief Gaussian basis function API and routines.
9 *
10 * Handles Gaussian basis functions as special cases (class inheritance). Both
11 * primitive and contracted Gaussians from electronic structure codes are
12 * implemented, but not using those labels.
13 */
14
15#ifndef __Basis_gaussian_h__
16#define __Basis_gaussian_h__
17
18#include <forward_list>
19#include <utility>
23#include <madness/mra/mra.h>
24#include <madness/constants.h>
25
26namespace slymer {
27
28/// Implemented types of Gaussian orbitals (from quantum chemistry codes).
29enum class GaussianType {
30 // both Cartesian and spherical
31 s, px, py, pz,
32
33 // Cartesian (and possibly spherical)
34 dxx, dxy, dxz, dyy, dyz, dzz,
36
37 // spherical only ('m' denotes "minus")
40
41 // g
42 // cartesian
45 // spherical
46 // ('d' denotes "dot" for multiplication)
47 // (numbers in names indicate powers of preceding variable)
50
51 // h
52 // cartesian
56 // spherical
57 // at this point, just giving names corresponding to value
58 // quantum number m
59 hm5, hm4, hm3, hm2, hm1, hzero, hp1, hp2, hp3, hp4, hp5
60
61};
62
63// forward declaration
64class GaussianFunction;
65
66/**
67 * \brief A primitive Gaussian function.
68 *
69 * This basis function has the form \f[
70 * f(x,y,z) = p(x,y,z) \exp[(x-x_0)^T \Sigma (x-x_0)],
71 * \f]
72 * where \f$p\f$ is a polynomial and \f$x_0\f$ is the ``center'' of the
73 * Gaussian and \f$\Sigma\f$ is the variance/covariance matrix.
74 *
75 * This class is designed to work with Gaussian basis functions in quantum
76 * chemistry codes, but is made to be a bit more general for other
77 * applications.
78 *
79 * The wikipedia page on multivariable normal distributions may be helpful
80 * (https://en.wikipedia.org/wiki/Multivariate_normal_distribution).
81 */
83
84protected:
85 /// Polynomial prefactor (\f$p\f$ in the class description).
87
88 /// Coefficients in the exponent's quadratic function.
90
91 /**
92 * \brief Return type for the function's canonical form.
93 *
94 * The first element is the polynomial prefactor, converted to use the principal coordinates.
95 * The second element is the array of decay values (eigenvalues of the covariance matrix).
96 * The third element is the \f$\nu\f$ vector (essentially the center of the Gaussian).
97 * The fourth element are the canonical axes in the original coordinates (for debugging purposes).
98 */
99 using CF = std::tuple<PolynomialCoeffs, std::array<double, 3>, std::array<double, 3>, std::array<std::array<double, 3>, 3>>;
100
101public:
102 /// Default constructor: Make the function 1 (\f$p=1\f$, \f$f(\vec{x})=0\f$).
104 : prefactor(0), exppoly(2)
105 {
106 prefactor[{{0,0,0}}] = 1.;
107 }
108
109 /**
110 * \brief Create a primitive Gaussian function centered on the specific point,
111 * with the specified decay constant and type.
112 *
113 * \throw std::invalid_argument if the decay constant is non-positive.
114 *
115 * \param[in] type The orbital type of the Gaussian.
116 * \param[in] center The center of the Gaussian.
117 * \param[in] ec The decay constant in the exponential.
118 */
120 const std::array<double, 3> &center, const double ec);
121
122 /**
123 * \brief Create a primitive Gaussian function with the specified exponential
124 * polynomial (quadratic) and polynomial prefactor.
125 *
126 * \throw std::invalid_argument if the exponential polynomial is not
127 * quadratic (or constant or linear as subsets).
128 *
129 * \param[in] exppoly_ The exponential polynomial.
130 * \param[in] prefactor_ The degree of the prefactor.
131 */
132 PrimitiveGaussian(const PolynomialCoeffs &exppoly_,
133 const PolynomialCoeffs &prefactor_);
134
135 /**
136 * \brief Evaluate the Gaussian primitive at the specified point.
137 *
138 * \param[in] x The point.
139 * \return The Gaussian primitive evaluated at the point x.
140 */
141 double operator() (const std::array<double, 3> &x) const;
142
143 /**
144 * \brief Multiply two primitive Gaussians. The result is another.
145 *
146 * \param[in] rhs The right-hand object.
147 * \result The product.
148 */
150};
151
152
153/**
154 * \brief A Gaussian basis function used by chemistry electronic structure
155 * codes.
156 *
157 * This basis function has the form \f[
158 * \sum_j c_j x^{l_j} y^{m_j} z^{n_j} \exp[f_j(\vec{x})],
159 * \f]
160 * where \f$f_j(\vec{x})\f$ is a quadratic function. Note that this functional
161 * form is a bit more general than that used by standard electronic structure
162 * codes; we do not require the prinicpal axes of the Gaussian function to be
163 * coincident with the x-, y-, and z-axes. This class can also hold/handle any
164 * linear combination of primitive Gaussian functions (the exponents and
165 * centers do not have to be the same).
166 */
168
169protected:
170 /// Helper class for storing terms in the sum of Gaussian primitives.
171 using TermT = std::pair<double, PrimitiveGaussian>;
172
173 /// The list of terms in the sum of Gaussian primitives.
174 std::forward_list<TermT> terms;
175
176 /**
177 * \brief Removes terms with very small linear expansion coefficients.
178 *
179 * \param[in] eps The threshold for "small". Defaults to 1.e-6.
180 */
181 void removeSmallTerms(const double eps = 1.e-6) {
182 terms.remove_if(
183 [eps](const TermT &t) {
184 return std::abs(t.first) < eps;
185 }
186 );
187 }
188
189public:
190
191 /// The center of the gaussian
192 std::array<double, 3> center;
193
194 /// The exponent coefficients
195 std::vector<double> expcoeff;
196
197 /// Default constructor: Make the function 0.
198 GaussianFunction() : terms(0), center({{0,0,0}}), expcoeff(std::vector<double>{0.0}) {}
199
200 /**
201 * \brief Create a Gaussian orbital (uncontracted or contracted) from
202 * quantum chemistry codes.
203 *
204 * Both Cartesian and spherical orbitals are supported. The expcoeff and
205 * coeff parameters must be arrays. If the orbital is uncontracted, the
206 * arrays will be length 1.
207 *
208 * All uncontracted primitive Gaussian orbitals used underneath the
209 * GaussianFunction are normalized.
210 *
211 * \throw invalid_argument If a non-positive exponential coefficient is
212 * passed or if the lengths of expcoeff and coeff are not equal.
213 *
214 * \param[in] type The orbital type (from enum OrbitalType).
215 * \param[in] center The center of the Gaussian orbital.
216 * \param[in] expcoeff Array of coefficients in the exponents of the
217 * primitive Gaussians.
218 * \param[in] coeff Array of linear expansion coefficients of the primitive
219 * Gaussians.
220 */
221 GaussianFunction(const GaussianType type, const std::array<double, 3> &center,
222 const std::vector<double> &expcoeff, const std::vector<double> &coeff);
223
224 /**
225 * \brief Create an uncontracted Gaussian orbital (shortcut to the more
226 * general constructor for Gaussian orbitals).
227 *
228 * \param[in] type The orbital type (from enum OrbitalType).
229 * \param[in] center The center of the Gaussian orbital.
230 * \param[in] expcoeff The coefficient in the exponent of the primitive
231 * Gaussian.
232 */
233 GaussianFunction(const GaussianType type, const std::array<double, 3> &center,
234 const double expcoeff)
235 : GaussianFunction(type, center, {expcoeff}, {1.}) {}
236
237 /**
238 * \brief Evaluate the Gaussian function at the specified point.
239 *
240 * \param[in] x The point.
241 * \return The Gaussian function evaluated at the point x.
242 */
243 virtual double operator() (const std::array<double, 3> &x) const override;
244
245 /**
246 * \brief Evaluate the Gaussian function at the specified point.
247 *
248 * \param[in] x The point.
249 * \return The Gaussian function evaluated at the point x.
250 */
251 double operator() (const madness::coord_3d& r) const {
252 return operator()(std::array<double, 3>{{r[0], r[1], r[2]}});
253 };
254
255 /**
256 * \brief Additive inverse of the GaussianFunction (deep copy).
257 *
258 * \return The negated function.
259 */
261
262 /**
263 * \brief Add two GaussianFunction objects, resulting in a new one.
264 *
265 * \param[in] rhs The right-hand GaussianFunction.
266 * \return The sum of this GaussianFunction and rhs.
267 */
269
270 /**
271 * \brief Add a GaussianFunction to this GaussianFunction.
272 *
273 * \param[in] rhs The right-hand GaussianFunction.
274 * \return The sum of this GaussianFunction and rhs, stored in *this.
275 */
277
278 /**
279 * \brief Subtract a GaussianFunction from this one, returning the difference.
280 *
281 * \param[in] rhs The GaussianFunction to be subtracted.
282 * \return The difference of the two GaussianFunction objects.
283 */
285 return *this + (-rhs);
286 }
287
288 /**
289 * \brief Subtract a GaussianFunction from this one.
290 *
291 * \param[in] rhs The GaussianFunction to be subtracted.
292 * \return This GaussianFunction (the difference).
293 */
295 return operator+=(-rhs);
296 }
297
298 /**
299 * \brief Multiply the GaussianFunction by a scalar.
300 *
301 * \param[in] rhs The scalar multiplicative factor.
302 * \return This GaussianFunction, which has been scaled.
303 */
304 GaussianFunction &operator*=(const double rhs);
305
306 /**
307 * \brief Multiply the GaussianFunction by another.
308 *
309 * \param[in] rhs The right-hand GaussianFunction object.
310 * \return This GaussianFunction, which is now the product.
311 */
313 GaussianFunction ret = (*this) * rhs;
314 terms.swap(ret.terms);
315 return *this;
316 }
317
318 /**
319 * \brief Multiply the GaussianFunction by a scalar.
320 *
321 * \param[in] rhs The scalar multiplicative factor.
322 * \return The scaled GaussianFunction.
323 */
324 GaussianFunction operator*(const double rhs) const {
325 GaussianFunction ret(*this);
326 ret *= rhs;
327 return ret;
328 }
329
330 /**
331 * \brief Multiply two GaussianFunctions.
332 *
333 * \param[in] rhs The right-hand GaussianFunction object.
334 * \return The product.
335 */
337
338 /**
339 * \brief Divide the GaussianFunction by a scalar.
340 *
341 * Does not check that the scalar is nonzero.
342 *
343 * \param[in] rhs The scalar factor.
344 * \return This GaussianFunction, which has been scaled.
345 */
346 GaussianFunction &operator/=(const double rhs) {
347 operator*=(1./rhs);
348 return *this;
349 }
350
351 /**
352 * \brief Divide the GaussianFunction by a scalar.
353 *
354 * \param[in] rhs The scalar factor.
355 * \return The scaled GaussianFunction.
356 */
357 GaussianFunction operator/(const double rhs) const {
358 return (*this) * (1./rhs);
359 }
360};
361
362
363// helper functions
364
365/**
366 * \brief Multiply a GaussianFunction by a scalar.
367 *
368 * \param[in] lhs The scalar multiplicative factor.
369 * \param[in] rhs The GaussianFunction.
370 * \return The scaled GaussianFunction.
371 */
372inline GaussianFunction operator*(const double lhs, const GaussianFunction &rhs) {
373 return rhs * lhs;
374}
375
377private:
379 std::vector<madness::coord_3d> centers;
380public:
381 Gaussian_Functor(GaussianFunction func, std::vector<madness::coord_3d> centers) : func(func), centers(centers) {}
382
383 double operator()(const madness::coord_3d& r) const {
384 return func(r);
385 }
386
387 std::vector<madness::coord_3d> special_points() const {
388 return centers;
389 }
390
392 // From Robert:
393 // Pick initial level such that average gap between quadrature points
394 // will find a significant value
395 const int N = 6; // looking for where exp(-a*x^2) < 10**-N
396 const int K = 6; // typically the lowest order of the polyn
397 const double log10 = std::log(10.0);
398 const double log2 = std::log(2.0);
400 const double expnt = *(std::max_element(func.expcoeff.begin(), func.expcoeff.end()));
401 const double a = expnt*L*L;
402 //const double fac = pow(2.0/(expnt*madness::constants::pi), 3.0/2.0);
403 const double fac = 100.0;
404 double n = std::log(a/(4*K*K*(N*log10+std::log(fac))))/(2*log2);
405 return (n < 2 ? 2.0 : std::ceil(n)+1); // Added in the +1 for paranoia's sake
406 }
407};
408
409} // namespace slymer
410#endif
static double get_cell_min_width()
Returns the minimum width of any user cell dimension.
Definition funcdefaults.h:478
Abstract base class interface required for functors used as input to Functions.
Definition function_interface.h:68
Abstract base class for generic basis functions.
Definition basis.h:25
A Gaussian basis function used by chemistry electronic structure codes.
Definition gaussian.h:167
GaussianFunction operator-(const GaussianFunction &rhs) const
Subtract a GaussianFunction from this one, returning the difference.
Definition gaussian.h:284
GaussianFunction operator*(const double rhs) const
Multiply the GaussianFunction by a scalar.
Definition gaussian.h:324
virtual double operator()(const std::array< double, 3 > &x) const override
Evaluate the Gaussian function at the specified point.
Definition madness/chem/gaussian.cc:1406
std::forward_list< TermT > terms
The list of terms in the sum of Gaussian primitives.
Definition gaussian.h:174
GaussianFunction operator+(const GaussianFunction &rhs) const
Add two GaussianFunction objects, resulting in a new one.
Definition madness/chem/gaussian.cc:1422
GaussianFunction & operator+=(const GaussianFunction &rhs)
Add a GaussianFunction to this GaussianFunction.
Definition madness/chem/gaussian.cc:1430
GaussianFunction & operator*=(const double rhs)
Multiply the GaussianFunction by a scalar.
Definition madness/chem/gaussian.cc:1440
GaussianFunction & operator-=(const GaussianFunction &rhs)
Subtract a GaussianFunction from this one.
Definition gaussian.h:294
GaussianFunction(const GaussianType type, const std::array< double, 3 > &center, const double expcoeff)
Create an uncontracted Gaussian orbital (shortcut to the more general constructor for Gaussian orbita...
Definition gaussian.h:233
GaussianFunction & operator*=(const GaussianFunction &rhs)
Multiply the GaussianFunction by another.
Definition gaussian.h:312
void removeSmallTerms(const double eps=1.e-6)
Removes terms with very small linear expansion coefficients.
Definition gaussian.h:181
std::array< double, 3 > center
The center of the gaussian.
Definition gaussian.h:192
std::pair< double, PrimitiveGaussian > TermT
Helper class for storing terms in the sum of Gaussian primitives.
Definition gaussian.h:171
GaussianFunction operator-() const
Additive inverse of the GaussianFunction (deep copy).
Definition madness/chem/gaussian.cc:1413
GaussianFunction()
Default constructor: Make the function 0.
Definition gaussian.h:198
std::vector< double > expcoeff
The exponent coefficients.
Definition gaussian.h:195
GaussianFunction operator/(const double rhs) const
Divide the GaussianFunction by a scalar.
Definition gaussian.h:357
GaussianFunction & operator/=(const double rhs)
Divide the GaussianFunction by a scalar.
Definition gaussian.h:346
Definition gaussian.h:376
std::vector< madness::coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition gaussian.h:387
double operator()(const madness::coord_3d &r) const
Definition gaussian.h:383
GaussianFunction func
Definition gaussian.h:378
Gaussian_Functor(GaussianFunction func, std::vector< madness::coord_3d > centers)
Definition gaussian.h:381
madness::Level special_level()
Override this change level refinement for special points (default is 6)
Definition gaussian.h:391
std::vector< madness::coord_3d > centers
Definition gaussian.h:379
Array for storing coefficients of a polynomial of three variables with specified degree.
Definition polynomial.h:35
A primitive Gaussian function.
Definition gaussian.h:82
PrimitiveGaussian()
Default constructor: Make the function 1 ( , ).
Definition gaussian.h:103
PolynomialCoeffs exppoly
Coefficients in the exponent's quadratic function.
Definition gaussian.h:89
std::tuple< PolynomialCoeffs, std::array< double, 3 >, std::array< double, 3 >, std::array< std::array< double, 3 >, 3 > > CF
Return type for the function's canonical form.
Definition gaussian.h:99
PrimitiveGaussian operator*(const PrimitiveGaussian &rhs) const
Multiply two primitive Gaussians. The result is another.
Definition madness/chem/gaussian.cc:1368
double operator()(const std::array< double, 3 > &x) const
Evaluate the Gaussian primitive at the specified point.
Definition madness/chem/gaussian.cc:1364
PolynomialCoeffs prefactor
Polynomial prefactor ( in the class description).
Definition gaussian.h:86
Defines common mathematical and physical constants.
vecfuncT K(vecfuncT &ket, vecfuncT &bra, vecfuncT &vf)
Main include file for MADNESS and defines Function interface.
int Level
Definition key.h:55
Definition basis.h:22
GaussianType
Implemented types of Gaussian orbitals (from quantum chemistry codes).
Definition gaussian.h:29
GaussianFunction operator*(const double lhs, const GaussianFunction &rhs)
Multiply a GaussianFunction by a scalar.
Definition gaussian.h:372
static long abs(long a)
Definition tensor.h:218
static const double a
Definition nonlinschro.cc:118
static const double L
Definition rk.cc:46
#define N
Definition testconv.cc:37