GQCP
Loading...
Searching...
No Matches
USQOneElectronOperator.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
20
32
33
34namespace GQCP {
35
36
43template <typename _Scalar, typename _Vectorizer>
45 public SpinResolvedBase<USQOneElectronOperatorComponent<_Scalar, _Vectorizer>, USQOneElectronOperator<_Scalar, _Vectorizer>>,
46 public SpinResolvedBasisTransformable<USQOneElectronOperator<_Scalar, _Vectorizer>>,
47 public SpinResolvedJacobiRotatable<USQOneElectronOperator<_Scalar, _Vectorizer>>,
48 public VectorSpaceArithmetic<USQOneElectronOperator<_Scalar, _Vectorizer>, _Scalar> {
49public:
50 // The scalar type used for a single parameter: real or complex.
51 using Scalar = _Scalar;
52
53 // The type of the vectorizer that relates a one-dimensional storage of matrices to the tensor structure of one-electron operators. This allows for a distinction between scalar operators (such as the kinetic energy operator), vector operators (such as the spin operator) and matrix/tensor operators (such as quadrupole and multipole operators).
54 using Vectorizer = _Vectorizer;
55
56 // The type of 'this'.
58
59 // The spinor tag corresponding to a `USQOneElectronOperator`.
61
62 // The type of transformation that is naturally related to a `USQOneElectronOperator`.
64
65 // The type component this spin resolved object is made of.
67
68public:
69 /*
70 * MARK: Constructors
71 */
72
73 // Inherit `SpinResolvedBase`'s constructors.
75
76
86 template <size_t N>
87 USQOneElectronOperator(const std::array<SquareMatrix<Scalar>, N>& fs_a, const std::array<SquareMatrix<Scalar>, N>& fs_b, const Vectorizer& vectorizer) :
88
89 // Encapsulate the array of matrix representations in the alpha- and beta- operator components, and put them together to form the `USQOneElectronOperator`.
93
94 // Check if the given matrix representations have the same dimensions.
95 const auto dimension_of_first_a = fs_a[0].dimension();
96 const auto dimension_of_first_b = fs_b[0].dimension();
97
98 for (size_t i = 1; i < N; i++) {
99 const auto dimension_of_ith_a = fs_a[i].dimension();
100 const auto dimension_of_ith_b = fs_b[i].dimension();
101
102 if ((dimension_of_first_a != dimension_of_ith_a) || (dimension_of_first_b != dimension_of_ith_b)) {
103 throw std::invalid_argument("USQOneElectronOperator(const std::array<SquareMatrix<Scalar>, Components>&, const std::array<SquareMatrix<Scalar>, components>&): The given matrix representations do not have the same dimensions for either the alpha or beta component.");
104 }
105 }
106 }
107
108
117 template <typename Z = Vectorizer>
119 typename std::enable_if<std::is_same<Z, ScalarVectorizer>::value>::type* = 0) :
120 USQOneElectronOperator(std::array<SquareMatrix<Scalar>, 1> {f_a}, std::array<SquareMatrix<Scalar>, 1> {f_b}, ScalarVectorizer()) {}
121
122
128
129
130 /*
131 * MARK: Named constructors
132 */
133
140
141 const auto zero_component = USQOneElectronOperatorComponent<Scalar, Vectorizer>::Zero(dim);
143 }
144
145
152
153 return USQOneElectronOperator<Scalar, Vectorizer> {f_restricted.alpha(), f_restricted.beta()};
154 }
155
156
157 /*
158 * MARK: Parameter access
159 */
160
168 template <typename... Indices>
170
171 return USQOneElectronOperator<Scalar, ScalarVectorizer> {this->alpha().parameters(indices...), this->beta().parameters(indices...)};
172 }
173
174
175 /*
176 * MARK: Calculations
177 */
178
187
188 // Calculate the sum of the alpha- and beta-contributions.
189 // Unfortunately, we can't give `StorageArray` out-of-the-box vector-space arithmetic (since the default scalar type for scalar multiplication is unknown), so we'll have to do the summation ourselves.
190 auto result_elements = this->alpha().calculateExpectationValue(D.alpha()).elements(); // Initialize the calculation with the alpha elements.
191 const auto beta_expectation_value_elements = this->beta().calculateExpectationValue(D.beta()).elements();
192
193 // Use the STL to implement element-wise addition.
194 std::transform(result_elements.begin(), result_elements.end(),
195 beta_expectation_value_elements.begin(), result_elements.begin(),
196 std::plus<Scalar> {});
197
198 return StorageArray<Scalar, Vectorizer> {result_elements, this->alpha().vectorizer()};
199 }
200
201
202 /*
203 * MARK: General information
204 */
205
206 /*
207 * @return The number of orbital related to the alpha part of the unrestricted one-electron operator.
208 *
209 * @note It is advised to only use this API when it is known that all spin-components of the one-electron operator are equal.
210 */
211 size_t numberOfOrbitals() const { return this->alpha().numberOfOrbitals(); }
212
213
219 size_t numberOfOrbitals(const Spin sigma) const { return this->component(sigma).numberOfOrbitals(); }
220
221
222 /*
223 * MARK: Conforming to VectorSpaceArithmetic
224 */
225
229 Self& operator+=(const Self& rhs) {
230
231 // Add the alpha-components and the beta-components.
232 this->alpha() += rhs.alpha();
233 this->beta() += rhs.beta();
234
235 return *this;
236 }
237
238
242 Self& operator*=(const Scalar& a) {
243
244 // Multiply the alpha- and beta-components with the scalar.
245 this->alpha() *= a;
246 this->beta() *= a;
247
248 return *this;
249 }
250
251
256 // Since `rotate` and `rotated` are both defined in `SpinResolvedBasisTransformable` and `SpinResolvedJacobiRotatable`, we have to explicitly enable these methods here.
257
258 // Allow the `rotate` method from `SpinResolvedBasisTransformable`, since there's also a `rotate` from `SpinResolvedJacobiRotatable`.
260
261 // Allow the `rotated` method from `SpinResolvedBasisTransformable`, since there's also a `rotated` from `SpinResolvedJacobiRotatable`.
263
264 // Allow the `rotate` method from `SpinResolvedJacobiRotatable`, since there's also a `rotate` from `SpinResolvedBasisTransformable`.
266
267 // Allow the `rotated` method from `SpinResolvedJacobiRotatable`, since there's also a `rotated` from `SpinResolvedBasisTransformable`.
269
270
271 /*
272 * MARK: One-index transformations
273 */
274
283
284 // Transform both components of this unrestricted one-electron operator.
285 return Self {this->alpha().oneIndexTransformed(T.alpha()), this->beta().oneIndexTransformed(T.beta())};
286 }
287
288
289 /*
290 * MARK: Mulliken domain
291 */
292
300 Self partitioned(const UTransformation<Scalar>& mulliken_projection_matrix) const { return 0.5 * this->oneIndexTransformed(mulliken_projection_matrix); }
301};
302
303
304/*
305 * MARK: Convenience aliases
306 */
307
308// A scalar-like USQOneElectronOperator, i.e. with scalar-like access.
309template <typename Scalar>
311
312// A vector-like USQOneElectronOperator, i.e. with vector-like access.
313template <typename Scalar>
315
316// A matrix-like USQOneElectronOperator, i.e. with matrix-like access.
317template <typename Scalar>
319
320// A tensor-like USQOneElectronOperator, i.e. with tensor-like access.
321template <typename Scalar, size_t N>
323
324
325/*
326 * MARK: Operator traits
327 */
328
335template <typename Scalar, typename Vectorizer>
336struct OperatorTraits<USQOneElectronOperator<Scalar, Vectorizer>> {
337
338 // A type that corresponds to the scalar version of the associated unrestricted one-electron operator type.
340
341 // The type of transformation that is naturally associated to an unrestricted one-electron operator.
343
344 // The type of the one-particle density matrix that is naturally associated an unrestricted one-electron operator.
346
347 // The type of the two-particle density matrix that is naturally associated an unrestricted one-electron operator.
349};
350
351
352/*
353 * MARK: BasisTransformableTraits
354 */
355
359template <typename Scalar, typename Vectorizer>
361
362 // The type of transformation that is naturally related to a `USQOneElectronOperator`.
364};
365
366
367/*
368 * MARK: JacobiRotatableTraits
369 */
370
374template <typename Scalar, typename Vectorizer>
376
377 // The type of Jacobi rotation for which the Jacobi rotation should be defined.
379};
380
381
382} // namespace GQCP
void rotate(const Transformation &U)
Definition: BasisTransformable.hpp:107
Definition: RSQOneElectronOperator.hpp:42
USQOneElectronOperatorComponent< Scalar, Vectorizer > beta() const
Definition: RSQOneElectronOperator.hpp:81
USQOneElectronOperatorComponent< Scalar, Vectorizer > alpha() const
Definition: RSQOneElectronOperator.hpp:70
const MatrixRepresentation & parameters(const Indices &... indices) const
Definition: SQOperatorStorageBase.hpp:236
size_t numberOfOrbitals() const
Definition: SQOperatorStorageBase.hpp:277
const Vectorizer & vectorizer() const
Definition: SQOperatorStorageBase.hpp:282
static FinalOperator Zero(const size_t dim, const Vectorizer &vectorizer)
Definition: SQOperatorStorageBase.hpp:145
DerivedOperator oneIndexTransformed(const Transformation &T) const
Definition: SimpleSQOneElectronOperator.hpp:301
StorageArray< Scalar, Vectorizer > calculateExpectationValue(const Derived1DM &D) const
Definition: SimpleSQOneElectronOperator.hpp:96
Definition: SpinResolved1DM.hpp:44
Definition: SpinResolved2DM.hpp:44
Definition: SpinResolvedBase.hpp:39
USQOneElectronOperatorComponent< _Scalar, _Vectorizer > Of
Definition: SpinResolvedBase.hpp:42
Definition: SpinResolvedBasisTransformable.hpp:34
Definition: SpinResolvedJacobiRotatable.hpp:35
USQOneElectronOperator< _Scalar, _Vectorizer > rotated(const JacobiRotationType &jacobi_rotation) const override
Definition: SpinResolvedJacobiRotatable.hpp:54
Definition: SquareMatrix.hpp:39
Definition: StorageArray.hpp:38
Definition: UJacobiRotation.hpp:32
Definition: USQOneElectronOperatorComponent.hpp:40
Definition: USQOneElectronOperator.hpp:48
Self & operator+=(const Self &rhs)
Definition: USQOneElectronOperator.hpp:229
Self oneIndexTransformed(const UTransformation< Scalar > &T) const
Definition: USQOneElectronOperator.hpp:282
_Scalar Scalar
Definition: USQOneElectronOperator.hpp:51
USQOneElectronOperator< Scalar, ScalarVectorizer > operator()(const Indices &... indices) const
Definition: USQOneElectronOperator.hpp:169
static USQOneElectronOperator< Scalar, Vectorizer > Zero(const size_t dim)
Definition: USQOneElectronOperator.hpp:139
StorageArray< Scalar, Vectorizer > calculateExpectationValue(const SpinResolved1DM< Scalar > &D) const
Definition: USQOneElectronOperator.hpp:186
Self partitioned(const UTransformation< Scalar > &mulliken_projection_matrix) const
Definition: USQOneElectronOperator.hpp:300
USQOneElectronOperator< Scalar, Vectorizer > Self
Definition: USQOneElectronOperator.hpp:57
Self & operator*=(const Scalar &a)
Definition: USQOneElectronOperator.hpp:242
USQOneElectronOperator()
Definition: USQOneElectronOperator.hpp:126
USQOneElectronOperator(const SquareMatrix< Scalar > &f_a, const SquareMatrix< Scalar > &f_b, typename std::enable_if< std::is_same< Z, ScalarVectorizer >::value >::type *=0)
Definition: USQOneElectronOperator.hpp:118
static USQOneElectronOperator< Scalar, Vectorizer > FromRestricted(const RSQOneElectronOperator< Scalar, Vectorizer > &f_restricted)
Definition: USQOneElectronOperator.hpp:151
size_t numberOfOrbitals(const Spin sigma) const
Definition: USQOneElectronOperator.hpp:219
_Vectorizer Vectorizer
Definition: USQOneElectronOperator.hpp:54
size_t numberOfOrbitals() const
Definition: USQOneElectronOperator.hpp:211
typename SpinResolvedBase< USQOneElectronOperatorComponent< Scalar, Vectorizer >, Self >::Of ComponentType
Definition: USQOneElectronOperator.hpp:66
USQOneElectronOperator(const std::array< SquareMatrix< Scalar >, N > &fs_a, const std::array< SquareMatrix< Scalar >, N > &fs_b, const Vectorizer &vectorizer)
Definition: USQOneElectronOperator.hpp:87
Definition: spinor_tags.hpp:37
Definition: VectorSpaceArithmetic.hpp:35
Definition: BaseOneElectronIntegralBuffer.hpp:25
UnrestrictedSpinorTag UnrestrictedSpinOrbitalTag
Definition: spinor_tags.hpp:42
DenseVectorizer< 0 > ScalarVectorizer
Definition: DenseVectorizer.hpp:203
Spin
Definition: Spin.hpp:27
Definition: BasisTransformable.hpp:37
Definition: JacobiRotatable.hpp:37
Definition: OperatorTraits.hpp:28