GQCP
Loading...
Searching...
No Matches
MixedSpinResolved2DMComponent.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
25
26
27namespace GQCP {
28
29
35template <typename _Scalar>
37 public VectorSpaceArithmetic<MixedSpinResolved2DMComponent<_Scalar>, _Scalar> {
38public:
39 // The scalar type used for a density matrix element: real or complex.
40 using Scalar = _Scalar;
41
42 // The type of 'this'.
44
45
46private:
47 // The matrix representation of this two-electron density matrix.
49
50
51public:
52 /*
53 * MARK: Constructors
54 */
55
62 d {d} {}
63
64
70
71
72 /*
73 * MARK: Access
74 */
75
79 const SquareRankFourTensor<Scalar>& tensor() const { return this->d; }
80
84 SquareRankFourTensor<Scalar>& tensor() { return this->d; }
85
86
87 /*
88 * MARK: General information
89 */
90
94 size_t numberOfOrbitals() const { return this->tensor().dimension(); }
95
96
97 /*
98 * MARK: Conforming to `VectorSpaceArithmetic`
99 */
100
104 Self& operator+=(const Self& rhs) override {
105 this->tensor().Eigen() += rhs.tensor().Eigen();
106 return *this;
107 }
108
109
113 Self& operator*=(const Scalar& a) override {
114 this->tensor() = this->tensor().Eigen() * a; // A compiler error occurs when writing "this->tensor().Eigen() *= a".
115 return *this;
116 }
117
118
119 /*
120 * MARK: Contractions
121 */
122
126 Scalar trace() const {
127
128 // FIXME: This is duplicate code from `Simple2DM`. It would be double work to introduce a temporary intermediate class before resolving issue #559 (https://github.com/GQCG/GQCP/issues/559), which is why we chose to just copy-paste the implementation.
129
130 // TODO: when Eigen3 releases tensor.trace(), use it to implement the trace
131
132 const auto K = this->numberOfOrbitals();
133
134 Scalar trace {};
135 for (size_t p = 0; p < K; p++) {
136 for (size_t q = 0; q < K; q++) {
137 trace += this->tensor()(p, p, q, q);
138 }
139 }
140
141 return trace;
142 }
143
144
145 /*
146 * MARK: Basis transformations
147 */
148
160
161 // The transformation formulas for two-electron operators and 2-DMs are similar, but not quite the same. Instead of using T, the transformation formula for the 2-DM uses T_inverse_transpose. See also (https://gqcg-res.github.io/knowdes/spinor-transformations.html).
162
163 // Since we're only getting T as a matrix, we should convert it to an appropriate tensor to perform contractions.
164 // Although not a necessity for the einsum implementation, it makes it a lot easier to follow the formulas.
165 const GQCP::SquareMatrix<Scalar> T_related = T.matrix().transpose().inverse();
166 const GQCP::Tensor<Scalar, 2> T_related_tensor = Eigen::TensorMap<Eigen::Tensor<const Scalar, 2>>(T_related.data(), T_related.rows(), T_related.cols());
167
168 // We calculate the conjugate as a tensor as well.
169 const GQCP::Tensor<Scalar, 2> T_related_conjugate = T_related_tensor.conjugate();
170
171
172 // Depending on the given spin-component, we should either transform the first two, or the second two axes.
173 switch (sigma) {
174 case Spin::alpha: {
175 const auto temp = T_related_tensor.template einsum<1>("UQ,TUVW->TQVW", this->tensor());
176 const auto transformed = T_related_conjugate.template einsum<1>("TP,TQVW->PQVW", temp);
177 return Self {transformed};
178 break;
179 }
180
181 case Spin::beta: {
182 const auto temp = this->tensor().template einsum<1>("PQVW, WS->PQVS", T_related_tensor);
183 const auto transformed = temp.template einsum<1>("PQVS, VR->PQRS", T_related_conjugate);
184 return Self {transformed};
185 break;
186 }
187 }
188 }
189
190
199 void transform(const UTransformationComponent<Scalar>& T, const Spin sigma) {
200
201 auto result = this->transformed(T, sigma);
202 *this = result;
203 }
204
205
216 Self rotated(const JacobiRotation& jacobi_rotation, const Spin sigma) const {
217
218 const auto J = UTransformationComponent<Scalar>::FromJacobi(jacobi_rotation, this->numberOfOrbitals());
219 return this->transformed(J, sigma);
220 }
221
222
231 void rotate(const JacobiRotation& jacobi_rotation, const Spin sigma) {
232
233 auto result = this->rotated(jacobi_rotation, sigma);
234 *this = result;
235 }
236};
237
238
239} // namespace GQCP
Definition: JacobiRotation.hpp:33
Definition: MixedSpinResolved2DMComponent.hpp:37
Self & operator+=(const Self &rhs) override
Definition: MixedSpinResolved2DMComponent.hpp:104
size_t numberOfOrbitals() const
Definition: MixedSpinResolved2DMComponent.hpp:94
const SquareRankFourTensor< Scalar > & tensor() const
Definition: MixedSpinResolved2DMComponent.hpp:79
void rotate(const JacobiRotation &jacobi_rotation, const Spin sigma)
Definition: MixedSpinResolved2DMComponent.hpp:231
Self rotated(const JacobiRotation &jacobi_rotation, const Spin sigma) const
Definition: MixedSpinResolved2DMComponent.hpp:216
Self & operator*=(const Scalar &a) override
Definition: MixedSpinResolved2DMComponent.hpp:113
Scalar trace() const
Definition: MixedSpinResolved2DMComponent.hpp:126
SquareRankFourTensor< Scalar > & tensor()
Definition: MixedSpinResolved2DMComponent.hpp:84
_Scalar Scalar
Definition: MixedSpinResolved2DMComponent.hpp:40
void transform(const UTransformationComponent< Scalar > &T, const Spin sigma)
Definition: MixedSpinResolved2DMComponent.hpp:199
MixedSpinResolved2DMComponent(const SquareRankFourTensor< Scalar > &d)
Definition: MixedSpinResolved2DMComponent.hpp:61
MixedSpinResolved2DMComponent()
Definition: MixedSpinResolved2DMComponent.hpp:68
Self transformed(const UTransformationComponent< Scalar > &T, const Spin sigma) const
Definition: MixedSpinResolved2DMComponent.hpp:159
static DerivedTransformation FromJacobi(const JacobiRotation &jacobi_rotation, const size_t dim)
Definition: SimpleTransformation.hpp:108
const SquareMatrix< Scalar > & matrix() const
Definition: SimpleTransformation.hpp:168
Definition: SquareMatrix.hpp:39
Definition: SquareRankFourTensor.hpp:36
size_t dimension() const
Definition: SquareRankFourTensor.hpp:209
Definition: Tensor.hpp:46
const Base & Eigen() const
Definition: Tensor.hpp:116
Definition: UTransformationComponent.hpp:41
Definition: VectorSpaceArithmetic.hpp:35
Definition: BaseOneElectronIntegralBuffer.hpp:25
Spin
Definition: Spin.hpp:27
@ beta
Definition: Spin.hpp:29
@ alpha
Definition: Spin.hpp:28