votca 2026-dev
Loading...
Searching...
No Matches
sigma_exact_uks.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 "sigma_exact_uks.h"
21
22#include <algorithm>
23#include <iomanip>
24#include <sstream>
25#include <utility>
26#include <vector>
27
29#include "votca/xtp/rpa_uks.h"
31#include "votca/xtp/vc2index.h"
32
33namespace {} // namespace
34
35namespace votca {
36namespace xtp {
37
39
40 // Build Coulomb-active screening modes in the auxiliary basis from the full
41 // unrestricted H2p eigenvectors. This suppresses numerically dark / spin-like
42 // modes that can appear in the explicit alpha+beta transition basis but
43 // should not contribute to the screened Coulomb interaction W.
44 const Eigen::VectorXd* cached_omegas = nullptr;
45 const std::vector<Eigen::VectorXd>* cached_modes = nullptr;
46 rpa_.GetCachedScreeningModes(cached_omegas, cached_modes);
47
48 rpa_omegas_ = *cached_omegas;
49 screening_modes_ = *cached_modes;
50 // residues of level m: M_m times the modes, one GEMM per level
51 Eigen::MatrixXd modes(Mmn_.auxsize(), rpa_omegas_.size());
52 for (Index s = 0; s < rpa_omegas_.size(); s++) {
53 modes.col(s) = screening_modes_[std::size_t(s)];
54 }
55 residues_ = std::vector<Eigen::MatrixXd>(qptotal_);
56 const Index qpoffset = opt_.qpmin - opt_.rpamin;
57#pragma omp parallel for schedule(dynamic)
58 for (Index gw_level = 0; gw_level < qptotal_; gw_level++) {
59 residues_[gw_level] = Mmn_[gw_level + qpoffset] * modes;
60 }
61}
62
63namespace {
64ExactPoles UKSPoles(const Eigen::VectorXd& energies, Index n_occ,
65 const Eigen::VectorXd& omegas, double eta) {
66 return ExactPoles{energies, n_occ, omegas, eta};
67}
68} // namespace
69
71 double frequency) const {
72 const ExactPoles poles =
73 UKSPoles(getSpinRPAInputEnergies(), opt_.homo + 1 - opt_.rpamin,
74 rpa_omegas_, opt_.eta);
75 return exact_pole_sums::Value(poles, residues_[gw_level].data(), frequency);
76}
77
79 Index gw_level, const Eigen::VectorXd& frequencies) const {
80 const ExactPoles poles =
81 UKSPoles(getSpinRPAInputEnergies(), opt_.homo + 1 - opt_.rpamin,
82 rpa_omegas_, opt_.eta);
83 return exact_pole_sums::Values(poles, residues_[gw_level].data(),
84 frequencies);
85}
86
88 Index gw_level, double frequency) const {
89 const ExactPoles poles =
90 UKSPoles(getSpinRPAInputEnergies(), opt_.homo + 1 - opt_.rpamin,
91 rpa_omegas_, opt_.eta);
92 return exact_pole_sums::Derivative(poles, residues_[gw_level].data(),
93 frequency);
94}
95
97 Index gw_level2,
98 double frequency1,
99 double frequency2) const {
100 const ExactPoles poles =
101 UKSPoles(getSpinRPAInputEnergies(), opt_.homo + 1 - opt_.rpamin,
102 rpa_omegas_, opt_.eta);
103 const Eigen::MatrixXd r12 =
104 residues_[gw_level1].cwiseProduct(residues_[gw_level2]);
105 const Eigen::VectorXd sums = exact_pole_sums::ValuesDirectWeighted(
106 poles, r12.data(), Eigen::Vector2d(frequency1, frequency2));
107 return 0.5 * (sums(0) + sums(1));
108}
109
110} // namespace xtp
111} // namespace votca
std::vector< Eigen::MatrixXd > residues_
double CalcCorrelationDiagElement(Index gw_level, double frequency) const final
double CalcCorrelationOffDiagElement(Index gw_level1, Index gw_level2, double frequency1, double frequency2) const final
std::vector< Eigen::VectorXd > screening_modes_
double CalcCorrelationDiagElementDerivative(Index gw_level, double frequency) const final
Eigen::VectorXd CalcCorrelationDiagElements(Index gw_level, const Eigen::VectorXd &frequencies) const final
All frequencies of a level in one pass (see exact_pole_sums).
const Eigen::VectorXd & getSpinRPAInputEnergies() const
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::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
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.