votca 2026-dev
Loading...
Searching...
No Matches
sigma_exact.cc
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#include <stdexcept>
21
22// Local VOTCA includes
23#include "sigma_exact.h"
25#include "votca/xtp/rpa.h"
27#include "votca/xtp/vc2index.h"
28
29namespace votca {
30namespace xtp {
31
33 RPA::rpa_eigensolution rpa_solution;
34 {
35 OptionalTiming t(timings_, "screening: RPA pair eigenproblem");
36 rpa_solution = rpa_.Diagonalize_H2p();
37 }
38 OptionalTiming t(timings_, "screening: residues");
39 rpa_omegas_ = rpa_solution.omega;
40 // residues of level m: M_m Z with the screening modes
41 // Z = sum_v M_v,virt^T (X+Y)_v, once for all levels
42 Eigen::MatrixXd modes = ScreeningModes(rpa_solution.XpY);
43 const Index B = Mmn_.nsize();
44 const Index S = rpa_omegas_.size();
45 residues_.resize(B * S, qptotal_);
46 const Index qpoffset = opt_.qpmin - opt_.rpamin;
47#pragma omp parallel for schedule(dynamic)
48 for (Index gw_level = 0; gw_level < qptotal_; gw_level++) {
49 Eigen::Map<Eigen::MatrixXd>(residues_.col(gw_level).data(), B, S)
50 .noalias() = Mmn_[gw_level + qpoffset] * modes;
51 }
53 modes_ = std::move(modes);
54 screening_energies_ = rpa_.getRPAInputEnergies();
55 }
56}
57
59 // factor 2: both (identical) spin channels
60 return DiagPoleForm{Poles(), Residues(gw_level), nullptr, 2.0};
61}
62
64 const Eigen::VectorXd& nu) const {
65 if (modes_.size() == 0) {
66 throw std::runtime_error(
67 "Sigma_Exact::ScreeningDump: screening modes were not kept "
68 "(setKeepScreeningData before PrepareScreening)");
69 }
70 ScreeningData data;
71 data.omegas = rpa_omegas_;
73 // W_c(i nu) = -4 sum_s Z_s Z_s^T Omega_s / (nu^2 + Omega_s^2) in the aux
74 // frame of the integrals (2 for the spin sum times 2 from the two poles
75 // +-Omega_s), so eps^-1(0) - 1 = -4 Z Omega^-1 Z^T; its eigenvectors are
76 // those of eps(0), i.e. the plasmon-pole frame, eigenvalues -w_i.
77 const Eigen::VectorXd inv_omega = rpa_omegas_.cwiseInverse();
78 // A = 4 Z Omega^-1 Z^T as a rank-k update (lower triangle, which is all
79 // SymmetricEigen reads; dsyevd with MKL or Accelerate)
80 const Index naux = modes_.rows();
81 Eigen::MatrixXd A = Eigen::MatrixXd::Zero(naux, naux);
82 A.selfadjointView<Eigen::Lower>().rankUpdate(
83 modes_ * (4.0 * inv_omega).cwiseSqrt().asDiagonal());
85 data.frame_weights = es.values;
86 const Eigen::MatrixXd a =
87 4.0 * (es.vectors.transpose() * modes_).array().square().matrix();
88 data.strength = (a.colwise().sum().transpose()).cwiseProduct(inv_omega);
89 FrameSums(a, rpa_omegas_, nu, data);
90 return data;
91}
92
94 return ExactPoles{rpa_.getRPAInputEnergies(), opt_.homo + 1 - opt_.rpamin,
95 rpa_omegas_, opt_.eta};
96}
97
99 double frequency) const {
101 // factor 2: both (identical) spin channels
102 return 2.0 * exact_pole_sums::Value(Poles(), Residues(gw_level), frequency);
103}
104
106 Index gw_level, const Eigen::VectorXd& frequencies) const {
107 for (Index i = 0; i < frequencies.size(); ++i) {
109 }
110 return 2.0 *
111 exact_pole_sums::Values(Poles(), Residues(gw_level), frequencies);
112}
113
115 Index gw_level, double frequency) const {
116 return 2.0 *
117 exact_pole_sums::Derivative(Poles(), Residues(gw_level), frequency);
118}
119
121 Index gw_level2,
122 double frequency1,
123 double frequency2) const {
124 // 2 (both spins) x 1/2 (symmetrised in the two frequencies)
125 const Eigen::Vector2d w(frequency1, frequency2);
126 const ExactPoles poles = Poles();
127 const Eigen::VectorXd r12 =
128 residues_.col(gw_level1).cwiseProduct(residues_.col(gw_level2));
129 const Eigen::VectorXd sums =
130 exact_pole_sums::ValuesDirectWeighted(poles, r12.data(), w);
131 return sums(0) + sums(1);
132}
133
135 const Eigen::VectorXd& frequencies) const {
136 return exact_pole_sums::OffDiagonal(Poles(), residues_, frequencies);
137}
138
139Eigen::MatrixXd Sigma_Exact::ScreeningModes(const Eigen::MatrixXd& XpY) const {
140 const Index lumo = opt_.homo + 1;
141 const Index n_occ = lumo - opt_.rpamin;
142 const Index n_unocc = opt_.rpamax - opt_.homo;
143 const Index rpasize = n_occ * n_unocc;
144 vc2index vc = vc2index(0, 0, n_unocc);
145 // rows (v, c) of the virtual rows of the hole slices
146 Eigen::MatrixXd M(rpasize, Mmn_.auxsize());
147#pragma omp parallel for schedule(dynamic)
148 for (Index v = 0; v < n_occ; v++) {
149 M.middleRows(vc.I(v, 0), n_unocc) = Mmn_[v].middleRows(n_occ, n_unocc);
150 }
151 return M.transpose() * XpY;
152}
153
154} // namespace xtp
155} // namespace votca
Eigen::VectorXd CalcCorrelationDiagElements(Index gw_level, const Eigen::VectorXd &frequencies) const final
ScreeningData ScreeningDump(const Eigen::VectorXd &nu) const final
Eigen::MatrixXd residues_
Definition sigma_exact.h:67
Eigen::MatrixXd CalcCorrelationOffDiag(const Eigen::VectorXd &frequencies) const final
All off-diagonal elements as blocked matrix products.
ExactPoles Poles() const
Eigen::MatrixXd ScreeningModes(const Eigen::MatrixXd &XpY) const
Eigen::VectorXd screening_energies_
Definition sigma_exact.h:71
const double * Residues(Index gw_level) const
Definition sigma_exact.h:74
double CalcCorrelationDiagElementDerivative(Index gw_level, double frequency) const final
void PrepareScreening() final
DiagPoleForm PoleForm(Index gw_level) const final
double CalcCorrelationDiagElement(Index gw_level, double frequency) const final
Eigen::VectorXd rpa_omegas_
Definition sigma_exact.h:64
Eigen::MatrixXd modes_
Definition sigma_exact.h:70
double CalcCorrelationOffDiagElement(Index gw_level1, Index gw_level2, double frequency1, double frequency2) const final
static void FrameSums(const Eigen::MatrixXd &a, const Eigen::VectorXd &omegas, const Eigen::VectorXd &nu, ScreeningData &data)
Definition sigma_base.cc:98
DFTTimings * timings_
Definition sigma_base.h:209
TCMatrix_gwbse & Mmn_
Definition sigma_base.h:207
void CountDiagEval() const
Definition sigma_base.h:221
This class transforms a pair of indices v,c into a compound index I, via I=ctotal*v+c the fast dimens...
Definition vc2index.h:36
Index I(Index v, Index c) const
Definition vc2index.h:42
double Value(const ExactPoles &poles, const double *residues, double w)
S_n(w) at one frequency.
double Derivative(const ExactPoles &poles, const double *residues, double w)
dS_n/dw at one frequency
Eigen::MatrixXd OffDiagonal(const ExactPoles &poles, const Eigen::MatrixXd &residues_all, const Eigen::VectorXd &w)
Eigen::VectorXd Values(const ExactPoles &poles, const double *residues, const Eigen::VectorXd &w)
Eigen::VectorXd ValuesDirectWeighted(const ExactPoles &poles, const double *weights, const Eigen::VectorXd &w)
sum_p a_p f(w - z_p) with given weights a_p (e.g. r_n1 r_n2)
Charge transport classes.
Definition ERIs.h:28
SymmetricEigenSystem SymmetricEigen(const Eigen::MatrixXd &A, bool vectors=true)
With vectors = false only the eigenvalues are computed.
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
Pole sums of the exact (RPA spectral) correlation self-energy.