GQCP
Loading...
Searching...
No Matches
PrimitiveOverlapIntegralEngine.hpp
Go to the documentation of this file.
1// This file is part of GQCG-GQCP.
2//
3// Copyright (C) 2017-2020 the GQCG developers
4//
5// GQCG-GQCP is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GQCG-GQCP is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GQCG-GQCP. If not, see <http://www.gnu.org/licenses/>.
17
18#pragma once
19
27#include "Utilities/complex.hpp"
29
30#include <boost/math/constants/constants.hpp>
31
32
33namespace GQCP {
34
35
41template <typename _Shell>
44public:
45 // The type of shell that this integral engine is related to.
46 using Shell = _Shell;
47
48 // The type of primitive that underlies the type of shell.
49 using Primitive = typename Shell::Primitive;
50
51 // The scalar representation of an overlap integral.
53
54
55public:
56 /*
57 * MARK: CartesianGTO integrals
58 */
59
68 template <typename Z = Shell>
70
71 // The 3D integral is separable in three 1D integrals.
72 IntegralScalar primitive_integral {1.0};
74 const auto i = left.cartesianExponents().value(direction);
75 const auto j = right.cartesianExponents().value(direction);
76
77 primitive_integral *= this->calculate1D(left.gaussianExponent(), left.center()(direction), i, right.gaussianExponent(), right.center()(direction), j);
78 }
79
80 return primitive_integral;
81 }
82
83
96 template <typename Z = Shell>
97 enable_if_t<std::is_same<Z, GTOShell>::value, IntegralScalar> calculate1D(const double a, const double K, const int i, const double b, const double L, const int j) {
98
99 // Negative Cartesian exponents should be ignored: the correct value for the corresponding integral is 0.
100 if ((i < 0) || (j < 0)) {
101 return 0.0;
102 }
103
104 // Use the McMurchie-Davidson recursion to calculate the overlap integral.
105 const auto p = a + b;
106 const McMurchieDavidsonCoefficient E {K, a, L, b};
107
108 return std::pow(boost::math::constants::pi<double>() / p, 0.5) * E(i, j, 0);
109 }
110
111
112 /*
113 * MARK: LondonCartesianGTO integrals
114 */
115
124 template <typename Z = Shell>
126
127 const Vector<double, 3> k1 = right.kVector() - left.kVector(); // The k-vector of the London overlap distribution.
128
129 // The 3D integral is separable in three 1D integrals.
130 IntegralScalar primitive_integral {1.0};
132 const auto a = left.cartesianGTO().gaussianExponent();
133 const auto K = left.cartesianGTO().center()(direction);
134 const auto i = left.cartesianGTO().cartesianExponents().value(direction);
135
136 const auto b = right.cartesianGTO().gaussianExponent();
137 const auto L = right.cartesianGTO().center()(direction);
138 const auto j = right.cartesianGTO().cartesianExponents().value(direction);
139
140 const auto k1_component = k1(direction);
141 primitive_integral *= this->calculate1D(k1_component, a, K, i, b, L, j);
142 }
143
144 return primitive_integral;
145 }
146
147
161 template <typename Z = Shell>
162 enable_if_t<std::is_same<Z, LondonGTOShell>::value, IntegralScalar> calculate1D(const complex k1, const double a, const double K, const int i, const double b, const double L, const int j) {
163
164 // Negative Cartesian exponents should be ignored: the correct value for the corresponding integral is 0.
165 if ((i < 0) || (j < 0)) {
166 return 0.0;
167 }
168
169 using namespace GQCP::literals;
170
171
172 // Use the McMurchie-Davidson recursion to calculate the overlap integral.
173 const auto p = a + b;
174 const McMurchieDavidsonCoefficient E {K, a, L, b};
175 const auto P = E.centerOfMass();
176
177 IntegralScalar integral {0.0};
178 for (int t = 0; t <= i + j; t++) {
179 integral += E(i, j, t) *
180 std::pow(-1.0_ii * k1, t) *
181 std::pow(boost::math::constants::pi<double>() / p, 0.5) *
182 std::exp(-1.0_ii * k1 * P) *
183 std::exp(-std::pow(k1, 2) / (4 * p));
184 }
185
186 return integral;
187 }
188};
189
190
191} // namespace GQCP
Definition: BaseScalarPrimitiveIntegralEngine.hpp:30
Definition: CartesianGTO.hpp:38
const Vector< double, 3 > & center() const
Definition: CartesianGTO.hpp:129
double gaussianExponent() const
Definition: CartesianGTO.hpp:139
const CartesianExponents & cartesianExponents() const
Definition: CartesianGTO.hpp:112
Definition: LondonCartesianGTO.hpp:38
Vector< double, 3 > kVector() const
Definition: LondonCartesianGTO.cpp:45
const CartesianGTO & cartesianGTO() const
Definition: LondonCartesianGTO.hpp:89
Definition: Matrix.hpp:47
Definition: McMurchieDavidsonCoefficient.hpp:30
double centerOfMass() const
Definition: McMurchieDavidsonCoefficient.cpp:87
Definition: PrimitiveOverlapIntegralEngine.hpp:43
product_t< OverlapOperator::Scalar, typename Primitive::OutputType > IntegralScalar
Definition: PrimitiveOverlapIntegralEngine.hpp:52
_Shell Shell
Definition: PrimitiveOverlapIntegralEngine.hpp:46
typename Shell::Primitive Primitive
Definition: PrimitiveOverlapIntegralEngine.hpp:49
enable_if_t< std::is_same< Z, GTOShell >::value, IntegralScalar > calculate1D(const double a, const double K, const int i, const double b, const double L, const int j)
Definition: PrimitiveOverlapIntegralEngine.hpp:97
enable_if_t< std::is_same< Z, LondonGTOShell >::value, IntegralScalar > calculate(const LondonCartesianGTO &left, const LondonCartesianGTO &right)
Definition: PrimitiveOverlapIntegralEngine.hpp:125
enable_if_t< std::is_same< Z, LondonGTOShell >::value, IntegralScalar > calculate1D(const complex k1, const double a, const double K, const int i, const double b, const double L, const int j)
Definition: PrimitiveOverlapIntegralEngine.hpp:162
enable_if_t< std::is_same< Z, GTOShell >::value, IntegralScalar > calculate(const CartesianGTO &left, const CartesianGTO &right)
Definition: PrimitiveOverlapIntegralEngine.hpp:69
Definition: complex.hpp:57
Definition: BaseOneElectronIntegralBuffer.hpp:25
typename std::enable_if< B, T >::type enable_if_t
Definition: type_traits.hpp:37
decltype(std::declval< T >() *std::declval< U >()) product_t
Definition: aliases.hpp:35
std::complex< double > complex
Definition: complex.hpp:31
@ z
Definition: CartesianDirection.hpp:30
@ x
Definition: CartesianDirection.hpp:28
@ y
Definition: CartesianDirection.hpp:29
size_t value(const CartesianDirection direction) const
Definition: CartesianExponents.hpp:116