GQCP
Loading...
Searching...
No Matches
TwoElectronIntegralEngine.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
23
24
25namespace GQCP {
26
27
33template <typename _PrimitiveIntegralEngine>
35 public BaseTwoElectronIntegralEngine<typename _PrimitiveIntegralEngine::Shell, _PrimitiveIntegralEngine::Components, typename _PrimitiveIntegralEngine::IntegralScalar> {
36public:
37 // The type of integral engine that is used for calculating integrals over primitives.
38 using PrimitiveIntegralEngine = _PrimitiveIntegralEngine;
39
40 // The type of shell that this engine can calculate integrals over.
41 using Shell = typename _PrimitiveIntegralEngine::Shell;
42
43 // The scalar representation of one of the integrals.
44 using IntegralScalar = typename _PrimitiveIntegralEngine::IntegralScalar;
45
46 // The number of components the operator has.
47 static constexpr auto N = _PrimitiveIntegralEngine::Components;
48
49
50private:
51 // The integral engine that is used for calculating integrals over primitives.
52 PrimitiveIntegralEngine primitive_engine;
53
54
55public:
56 /*
57 * MARK: Constructors
58 */
59
64 primitive_engine {primitive_engine} {}
65
66
67 /*
68 * MARK: Integral calculations
69 */
70
83 std::shared_ptr<BaseTwoElectronIntegralBuffer<IntegralScalar, N>> calculate(const Shell& shell1, const Shell& shell2, const Shell& shell3, const Shell& shell4) override {
84
85 // In this function, we loop over all basis functions that the shells contain.
86 const auto basis_functions1 = shell1.basisFunctions();
87 const auto basis_functions2 = shell2.basisFunctions();
88 const auto basis_functions3 = shell3.basisFunctions();
89 const auto basis_functions4 = shell4.basisFunctions();
90
91 std::array<std::vector<IntegralScalar>, N> integrals; // A "buffer" that stores the calculated integrals.
92
93 for (size_t i = 0; i < N; i++) { // Loop over all components of the operator.
94 this->primitive_engine.prepareStateForComponent(i);
95
96 for (const auto& bf1 : basis_functions1) {
97 const auto& coefficients1 = bf1.coefficients();
98 const auto& primitives1 = bf1.functions();
99
100 for (const auto& bf2 : basis_functions2) {
101 const auto& coefficients2 = bf2.coefficients();
102 const auto& primitives2 = bf2.functions();
103
104 for (const auto& bf3 : basis_functions3) {
105 const auto& coefficients3 = bf3.coefficients();
106 const auto& primitives3 = bf3.functions();
107
108 for (const auto& bf4 : basis_functions4) {
109 const auto& coefficients4 = bf4.coefficients();
110 const auto& primitives4 = bf4.functions();
111
112 IntegralScalar integral {};
113 for (size_t c1 = 0; c1 < bf1.length(); c1++) {
114 const auto& d1 = coefficients1[c1];
115 const auto& primitive1 = primitives1[c1];
116
117 for (size_t c2 = 0; c2 < bf2.length(); c2++) {
118 const auto& d2 = coefficients2[c2];
119 const auto& primitive2 = primitives2[c2];
120
121 for (size_t c3 = 0; c3 < bf3.length(); c3++) {
122 const auto& d3 = coefficients3[c3];
123 const auto& primitive3 = primitives3[c3];
124
125 for (size_t c4 = 0; c4 < bf4.length(); c4++) {
126 const auto& d4 = coefficients4[c4];
127 const auto& primitive4 = primitives4[c4];
128
129 const auto primitive_integral = this->primitive_engine.calculate(primitive1, primitive2, primitive3, primitive4);
130 integral += d1 * d2 * d3 * d4 * primitive_integral;
131 }
132 }
133 }
134 }
135 integrals[i].push_back(integral);
136 }
137 }
138 }
139 }
140 }
141
142 return std::make_shared<TwoElectronIntegralBuffer<IntegralScalar, N>>(shell1.numberOfBasisFunctions(), shell2.numberOfBasisFunctions(), shell3.numberOfBasisFunctions(), shell4.numberOfBasisFunctions(), integrals);
143 }
144};
145
146
147} // namespace GQCP
Definition: BaseTwoElectronIntegralEngine.hpp:37
Definition: TwoElectronIntegralEngine.hpp:35
std::shared_ptr< BaseTwoElectronIntegralBuffer< IntegralScalar, N > > calculate(const Shell &shell1, const Shell &shell2, const Shell &shell3, const Shell &shell4) override
Definition: TwoElectronIntegralEngine.hpp:83
TwoElectronIntegralEngine(const PrimitiveIntegralEngine &primitive_engine)
Definition: TwoElectronIntegralEngine.hpp:63
typename _PrimitiveIntegralEngine::IntegralScalar IntegralScalar
Definition: TwoElectronIntegralEngine.hpp:44
static constexpr auto N
Definition: TwoElectronIntegralEngine.hpp:47
_PrimitiveIntegralEngine PrimitiveIntegralEngine
Definition: TwoElectronIntegralEngine.hpp:38
typename _PrimitiveIntegralEngine::Shell Shell
Definition: TwoElectronIntegralEngine.hpp:41
Definition: BaseOneElectronIntegralBuffer.hpp:25