votca 2026-dev
Loading...
Searching...
No Matches
ImaginaryAxisIntegration.cc
Go to the documentation of this file.
1
2/*
3 * Copyright 2009-2023 The VOTCA Development Team
4 * (http://www.votca.org)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License")
7 *
8 * You may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
22
23#include <algorithm>
24#include <cstdlib>
25#include <limits>
26#include <set>
27#include <sstream>
28
32
33namespace votca {
34namespace xtp {
35
36namespace {
37
38bool CdaDebugEnabled() {
39 const char* env = std::getenv("VOTCA_XTP_CDA_DEBUG");
40 return env != nullptr && std::string(env) == "1";
41}
42
43bool CdaDebugLevelMatch(Index level) {
44 const char* env = std::getenv("VOTCA_XTP_CDA_DEBUG_LEVELS");
45 if (env == nullptr) {
46 return true;
47 }
48
49 std::set<int> allowed;
50 std::stringstream ss(env);
51 std::string token;
52 while (std::getline(ss, token, ',')) {
53 if (!token.empty()) {
54 allowed.insert(std::stoi(token));
55 }
56 }
57 return allowed.count(static_cast<int>(level)) > 0;
58}
59
60bool CdaDebugMatch(Index level) {
61 return CdaDebugEnabled() && CdaDebugLevelMatch(level);
62}
63
64} // namespace
65
67 const Eigen::VectorXd& energies, const TCMatrix_gwbse& Mmn)
68 : energies_(energies), Mmn_(Mmn) {}
69
71 options opt, const RPA& rpa, const Eigen::MatrixXd& kDielMxInv_zero) {
72 opt_ = opt;
73 gq_ = QuadratureFactory().Create(opt_.quadrature_scheme);
74 gq_->configure(opt_.order);
75
76 CalcDielInvVector(rpa, kDielMxInv_zero);
77}
78
80 options opt, const RPA_UKS& rpa, const Eigen::MatrixXd& kDielMxInv_zero) {
81 opt_ = opt;
82 gq_ = QuadratureFactory().Create(opt_.quadrature_scheme);
83 gq_->configure(opt_.order);
84
85 CalcDielInvVector(rpa, kDielMxInv_zero);
86}
87
88// This function calculates and stores inverses of the microscopic dielectric
89// matrix in a matrix vector
91 const RPA& rpa, const Eigen::MatrixXd& kDielMxInv_zero) {
92 dielinv_matrices_r_.resize(gq_->Order());
93
94 for (Index j = 0; j < gq_->Order(); j++) {
95 double newpoint = gq_->ScaledPoint(j);
96 Eigen::MatrixXd eps_inv_j = rpa.calculate_epsilon_i(newpoint).inverse();
97 eps_inv_j.diagonal().array() -= 1.0;
99 -eps_inv_j +
100 kDielMxInv_zero * std::exp(-std::pow(opt_.alpha * newpoint, 2));
101 }
102}
103
105 const RPA_UKS& rpa, const Eigen::MatrixXd& kDielMxInv_zero) {
106 dielinv_matrices_r_.resize(gq_->Order());
107
108 for (Index j = 0; j < gq_->Order(); j++) {
109 double newpoint = gq_->ScaledPoint(j);
110 Eigen::MatrixXd eps_inv_j = rpa.calculate_epsilon_i(newpoint).inverse();
111 eps_inv_j.diagonal().array() -= 1.0;
113 -eps_inv_j +
114 kDielMxInv_zero * std::exp(-std::pow(opt_.alpha * newpoint, 2));
115 }
116}
117
119 public:
120 FunctionEvaluation(const Eigen::MatrixXd& Imx, const Eigen::ArrayXcd& DeltaE,
121 const std::vector<Eigen::MatrixXd>& dielinv_matrices_r)
122 : Imx_(Imx), DeltaE_(DeltaE), dielinv_matrices_r_(dielinv_matrices_r) {};
123
124 double operator()(Index j, double point, bool symmetry) const {
125 Eigen::VectorXcd denominator;
126 const std::complex<double> cpoint(0.0, point);
127 if (symmetry) {
128 denominator =
129 (DeltaE_ + cpoint).cwiseInverse() + (DeltaE_ - cpoint).cwiseInverse();
130 } else {
131 denominator = (DeltaE_ + cpoint).cwiseInverse();
132 }
133 return 0.5 / tools::conv::Pi *
134 ((Imx_ * (dielinv_matrices_r_[j].conjugate()))
135 .cwiseProduct(denominator.asDiagonal() * Imx_))
136 .sum()
137 .real();
138 }
139
140 private:
141 const Eigen::MatrixXd& Imx_;
142 const Eigen::ArrayXcd& DeltaE_;
143 const std::vector<Eigen::MatrixXd>& dielinv_matrices_r_;
144};
145
146double ImaginaryAxisIntegration::SigmaGQDiag(double frequency, Index gw_level,
147 double eta) const {
148 Index lumo = opt_.homo + 1;
149 const Index occ = lumo - opt_.rpamin;
150 const Index unocc = opt_.rpamax - opt_.homo;
151 Index gw_level_offset = gw_level + opt_.qpmin - opt_.rpamin;
152 const Eigen::MatrixXd& Imx = Mmn_[gw_level_offset];
153 Eigen::ArrayXcd DeltaE = frequency - energies_.array();
154 DeltaE.imag().head(occ) = eta;
155 DeltaE.imag().tail(unocc) = -eta;
156
157 if (CdaDebugMatch(gw_level)) {
158 double min_abs = std::numeric_limits<double>::max();
159 for (Index i = 0; i < DeltaE.size(); ++i) {
160 min_abs = std::min(min_abs, std::abs(DeltaE(i)));
161 }
162
163 std::cout << "\n [CDA-DEBUG] ImagAxis level=" << gw_level
164 << " freq=" << frequency << " eta=" << eta
165 << " min|DeltaE|=" << min_abs << " ||Imx||=" << Imx.norm();
166
167 for (Index i = 0; i < DeltaE.size(); ++i) {
168 std::cout << "\n [CDA-DEBUG] ImagAxis i=" << i
169 << " occ=" << (i < occ ? 1 : 0) << " DeltaE=" << DeltaE(i);
170 }
171 std::cout << std::flush;
172 }
173
175 return gq_->Integrate(f);
176}
177
178} // namespace xtp
179} // namespace votca
virtual std::unique_ptr< T > Create(const key_t &key, args_t &&...arguments)
const std::vector< Eigen::MatrixXd > & dielinv_matrices_r_
double operator()(Index j, double point, bool symmetry) const
FunctionEvaluation(const Eigen::MatrixXd &Imx, const Eigen::ArrayXcd &DeltaE, const std::vector< Eigen::MatrixXd > &dielinv_matrices_r)
double SigmaGQDiag(double frequency, Index gw_level, double eta) const
void CalcDielInvVector(const RPA &rpa, const Eigen::MatrixXd &kDielMxInv_zero)
std::vector< Eigen::MatrixXd > dielinv_matrices_r_
ImaginaryAxisIntegration(const Eigen::VectorXd &energies, const TCMatrix_gwbse &Mmn)
void configure(options opt, const RPA &rpa, const Eigen::MatrixXd &kDielMxInv_zero)
std::unique_ptr< GaussianQuadratureBase > gq_
Unrestricted RPA helper for spin-resolved GW screening.
Definition rpa_uks.h:68
Eigen::MatrixXd calculate_epsilon_i(double frequency) const
Dielectric matrix on the imaginary frequency axis.
Definition rpa_uks.h:111
Eigen::MatrixXd calculate_epsilon_i(double frequency) const
Definition rpa.h:47
const double Pi
Definition constants.h:36
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