votca 2026-dev
Loading...
Searching...
No Matches
threecenter.h
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20#pragma once
21#ifndef VOTCA_XTP_THREECENTER_H
22#define VOTCA_XTP_THREECENTER_H
23
24// Local VOTCA includes
25#include "aobasis.h"
26#include "eigen.h"
27#include "symmetric_matrix.h"
28
35
36namespace votca {
37namespace xtp {
38
39// due to different requirements for the data format for DFT and GW we have two
40// different classes TCMatrix_gwbse and TCMatrix_dft which inherit from TCMatrix
41class TCMatrix {
42
43 public:
44 TCMatrix() = default;
45 virtual ~TCMatrix() = default;
46 // the virtual destructor would otherwise suppress moving: moving the DFT
47 // tensor (tens of GB) must not fall back to a copy
48 TCMatrix(const TCMatrix&) = default;
49 TCMatrix(TCMatrix&&) = default;
50 TCMatrix& operator=(const TCMatrix&) = default;
53 enum class SpinChannel { Alpha, Beta };
54
55 protected:
57 Eigen::MatrixXd inv_sqrt_;
58};
59
74class TCMatrix_dft final : public TCMatrix {
75 public:
78 void Fill(const AOBasis& auxbasis, const AOBasis& dftbasis,
79 double pair_threshold = 0.0, Index build_columns = kBuildColumns);
80
82 Index size() const { return Index(data_.cols()); }
84 Index basissize() const { return basissize_; }
85
87 Eigen::MatrixXd FullMatrix(Index P) const;
88
92 void FillFullMatrix(Index P, Eigen::MatrixXd& full) const;
93
98 Eigen::VectorXd PackWeighted(const Eigen::MatrixXd& full) const;
99
102 Eigen::MatrixXd Unpack(const Eigen::VectorXd& packed) const;
103
105 const Eigen::MatrixXd& Data() const { return data_; }
106
108 Index StoredPairs() const { return Index(data_.rows()); }
109 Index AllPairs() const { return basissize_ * (basissize_ + 1) / 2; }
110
111 double MetricSeconds() const { return metric_seconds_; }
112
113 private:
122
125 std::vector<std::vector<Index>> SignificantPairs(
126 const AOBasis& dftbasis, const Eigen::MatrixXd& metric,
127 double pair_threshold) const;
128 void SetupLayout(const AOBasis& dftbasis,
129 const std::vector<std::vector<Index>>& kept);
130
131 Eigen::MatrixXd data_;
132 std::vector<Run> runs_;
133 // column mu starts at col_offset_[mu] in a data column
134 std::vector<Index> col_offset_;
136 double metric_seconds_ = 0.0;
137
140 static constexpr Index kBuildColumns = 512;
141};
142
143class TCMatrix_gwbse final : public TCMatrix {
144 public:
145 // Eigenvalue tolerance of the metric (Pseudo_InvSqrt_GWBSE) folded into
146 // the stored integrals. Shared with EnvironmentScreening::Metric, which
147 // must build the same T.
148 static constexpr double metric_tolerance = 5e-7;
149
150 // returns one level as a constant reference
151 const Eigen::MatrixXd& operator[](Index i) const { return matrix_[i]; }
152
153 // returns one level as a reference
154 Eigen::MatrixXd& operator[](Index i) { return matrix_[i]; }
155 // returns auxbasissize
156 Index auxsize() const { return auxbasissize_; }
157
158 Index get_mmin() const { return mmin_; }
159
160 Index get_mmax() const { return mmax_; }
161
162 Index get_nmin() const { return nmin_; }
163
164 Index get_nmax() const { return nmax_; }
165
166 Index msize() const { return mtotal_; }
167
168 Index nsize() const { return ntotal_; }
169
175 static Eigen::MatrixXd CoreExchange(const AOBasis& auxbasis,
176 const AOBasis& dftbasis,
177 const Eigen::MatrixXd& mos, Index ncore,
178 Index qpmin, Index qpmax);
179
180 void Initialize(Index basissize, Index mmin, Index mmax, Index nmin,
181 Index nmax);
182
183 void Fill(const AOBasis& auxbasis, const AOBasis& dftbasis,
184 const Eigen::MatrixXd& dft_orbitals);
185 // Rebuilds ThreeCenterIntegrals, only works if the original basisobjects
186 // still exist
188
189 void MultiplyRightWithAuxMatrix(const Eigen::MatrixXd& matrix);
190
204 void MultiplyRightWithAuxMatrixLeading(const Eigen::MatrixXd& U,
205 Index full_slices, Index lead);
207 bool PartiallyRotated() const { return partially_rotated_; }
208
209 // The metric that was folded into the stored integrals at Fill time:
210 // T = Pseudo_InvSqrt_GWBSE, with T T^T = V^-1 (pseudo-inverse) and
211 // T^T V T the projector onto the retained auxiliary functions. After
212 // Fill, operator[] holds M = (mn|Q) T, so the bare Coulomb operator
213 // exists only implicitly, as M M^T.
214 //
215 // Kept because anything that must act on the Coulomb interaction in
216 // the same space as M needs it. The environment reaction field is the
217 // case in point: a kernel B between auxiliary functions, taken as charge
218 // densities, enters as M (T^T B T) M^T -- see EnvironmentScreening.
219 //
220 // IN THE FILL-TIME AUXILIARY BASIS. MultiplyRightWithAuxMatrix, which the
221 // PPM and the BSE both call with an eigenvector matrix U, rotates the
222 // auxiliary index of M. This matrix is not rotated with it: a kernel
223 // built from it has to be brought into the current frame with
224 // ToCurrentAuxFrame before it meets operator[]. Refilled, and so reset,
225 // by every Fill and Rebuild.
226 const Eigen::MatrixXd& InvSqrt() const { return inv_sqrt_; }
227
228 // The auxiliary frame operator[] is currently in. Every
229 // MultiplyRightWithAuxMatrix since the last Fill or Rebuild is recorded
230 // here, so that operator[] holds M_fill * AuxFrame() with M_fill the
231 // integrals as Fill left them. Empty means the identity: nothing has
232 // rotated them yet.
233 //
234 // The bare Coulomb interaction does not care -- it is the identity in
235 // every orthonormal frame, which is why nothing tracked this before. A
236 // kernel K between the columns of M_fill does care: M_fill K M_fill^T is
237 // M K' M^T only with K' = ToCurrentAuxFrame(K).
238 const Eigen::MatrixXd& AuxFrame() const { return aux_frame_; }
239
240 // For code that snapshots slices through operator[] and later writes
241 // them back, which bypasses the bookkeeping above: restore the frame
242 // that was current when the snapshot was taken, alongside the slices.
243 void RestoreAuxFrame(const Eigen::MatrixXd& frame) {
244 aux_frame_ = frame;
245 aux_frame_known_ = true;
246 }
247
248 // K, a kernel between the columns of M_fill, as it must be applied to
249 // operator[] now: F^-1 K F^-T with F = AuxFrame(), which is F^T K F for
250 // the orthogonal eigenvector matrices the PPM and the BSE rotate with.
251 // Throws if the frame is not known -- after a non-square
252 // MultiplyRightWithAuxMatrix, which is not a change of frame.
253 Eigen::MatrixXd ToCurrentAuxFrame(const Eigen::MatrixXd& K) const;
254
255 // Whether AuxFrame() is orthogonal, so that the bare interaction M M^T is
256 // what it was at Fill time. False once the index has been dressed.
257 bool AuxFrameIsOrthogonal() const;
258
277 void DressAuxIndex(const Eigen::MatrixXd& S);
278 // Back to M_fill (times whatever rotations happened since), bare v.
279 void UndressAuxIndex();
280 bool Dressed() const { return dressing_.size() > 0; }
281
297 void RotateOrbitals(const Eigen::MatrixXd& U, Index first, Index last);
298
299 private:
300 // store vector of matrices
301 std::vector<Eigen::MatrixXd> matrix_;
302
303 // band summation indices
311
312 Eigen::MatrixXd aux_frame_; // empty: identity
313 bool aux_frame_known_ = true;
314 bool partially_rotated_ = false;
315 Eigen::MatrixXd dressing_; // S of DressAuxIndex; empty: bare
316
317 // M_fill -> M_fill A, whatever frame the integrals are in.
318 void MultiplyInFillFrame(const Eigen::MatrixXd& A);
319
320 const AOBasis* auxbasis_ = nullptr;
321 const AOBasis* dftbasis_ = nullptr;
322 const Eigen::MatrixXd* dft_orbitals_ = nullptr;
323
324 void Fill3cMO(const AOBasis& auxbasis, const AOBasis& dftbasis,
325 const Eigen::MatrixXd& dft_orbitals);
326};
327
340
341} // namespace xtp
342} // namespace votca
343
344#endif // VOTCA_XTP_THREECENTER_H
Container to hold Basisfunctions for all atoms.
Definition aobasis.h:42
RI three-centre tensor of the DFT code, B_P,mu nu = sum_Q V^-1/2_PQ (Q|mu nu).
Definition threecenter.h:74
std::vector< Index > col_offset_
std::vector< Run > runs_
std::vector< std::vector< Index > > SignificantPairs(const AOBasis &dftbasis, const Eigen::MatrixXd &metric, double pair_threshold) const
Index size() const
Number of aux functions.
Definition threecenter.h:82
const Eigen::MatrixXd & Data() const
The stored tensor, one column per aux function.
Eigen::VectorXd PackWeighted(const Eigen::MatrixXd &full) const
void Fill(const AOBasis &auxbasis, const AOBasis &dftbasis, double pair_threshold=0.0, Index build_columns=kBuildColumns)
double MetricSeconds() const
Eigen::MatrixXd FullMatrix(Index P) const
B_P as a full symmetric matrix, zero for the dropped pairs.
void SetupLayout(const AOBasis &dftbasis, const std::vector< std::vector< Index > > &kept)
void FillFullMatrix(Index P, Eigen::MatrixXd &full) const
Index StoredPairs() const
Stored pairs (nu <= mu) and all pairs N(N+1)/2.
Eigen::MatrixXd Unpack(const Eigen::VectorXd &packed) const
Eigen::MatrixXd data_
Index basissize() const
Number of basis functions.
Definition threecenter.h:84
static constexpr Index kBuildColumns
void Fill(const AOBasis &auxbasis, const AOBasis &dftbasis, const Eigen::MatrixXd &dft_orbitals)
const AOBasis * auxbasis_
static constexpr double metric_tolerance
void DressAuxIndex(const Eigen::MatrixXd &S)
Dress the auxiliary index with S: M_fill -> M_fill S.
void MultiplyRightWithAuxMatrixLeading(const Eigen::MatrixXd &U, Index full_slices, Index lead)
Rotate the auxiliary index of only the part of the tensor a consumer reads: all rows of slices [0,...
Eigen::MatrixXd aux_frame_
Eigen::MatrixXd dressing_
const Eigen::MatrixXd * dft_orbitals_
void RestoreAuxFrame(const Eigen::MatrixXd &frame)
bool AuxFrameIsOrthogonal() const
void Fill3cMO(const AOBasis &auxbasis, const AOBasis &dftbasis, const Eigen::MatrixXd &dft_orbitals)
void Initialize(Index basissize, Index mmin, Index mmax, Index nmin, Index nmax)
void MultiplyRightWithAuxMatrix(const Eigen::MatrixXd &matrix)
bool PartiallyRotated() const
Whether only a leading part was rotated since the last Fill.
std::vector< Eigen::MatrixXd > matrix_
static Eigen::MatrixXd CoreExchange(const AOBasis &auxbasis, const AOBasis &dftbasis, const Eigen::MatrixXd &mos, Index ncore, Index qpmin, Index qpmax)
void RotateOrbitals(const Eigen::MatrixXd &U, Index first, Index last)
Change the orbital basis of levels [first, last] for QSGW: phi_i = sum_k U_ki psi_k,...
const AOBasis * dftbasis_
const Eigen::MatrixXd & operator[](Index i) const
Eigen::MatrixXd & operator[](Index i)
void MultiplyInFillFrame(const Eigen::MatrixXd &A)
const Eigen::MatrixXd & InvSqrt() const
const Eigen::MatrixXd & AuxFrame() const
Eigen::MatrixXd ToCurrentAuxFrame(const Eigen::MatrixXd &K) const
TCMatrix & operator=(const TCMatrix &)=default
Eigen::MatrixXd inv_sqrt_
Definition threecenter.h:57
TCMatrix(TCMatrix &&)=default
virtual ~TCMatrix()=default
TCMatrix(const TCMatrix &)=default
Index Removedfunctions() const
Definition threecenter.h:52
TCMatrix & operator=(TCMatrix &&)=default
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
TCMatrix_gwbse & operator[](TCMatrix::SpinChannel spin)
const TCMatrix_gwbse & operator[](TCMatrix::SpinChannel spin) const