votca 2026-dev
Loading...
Searching...
No Matches
sigma_cda.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_cda.h"
21#include "votca/xtp/gw.h"
23
24namespace votca {
25namespace xtp {
26
27// Prepares the zero and imaginary frequency kappa matrices with
28// kappa(omega) = epsilon^-1(omega) - 1 needed in numerical
29// integration and for the Gaussian tail
32 opt.homo = opt_.homo;
33 opt.order = opt_.order;
34 opt.qptotal = qptotal_;
35 opt.qpmin = opt_.qpmin;
36 opt.rpamax = opt_.rpamax;
37 opt.rpamin = opt_.rpamin;
38 opt.alpha = opt_.alpha;
39 opt.quadrature_scheme = opt_.quadrature_scheme;
40 // prepare the zero frequency inverse for Gaussian tail
41 // epsilon at zero frequency is positive definite
43 InverseSPD(rpa_.calculate_epsilon_r(std::complex<double>(0.0, 0.0)));
44 kDielMxInv_zero_.diagonal().array() -= 1.0;
45 gq_.configure(opt, rpa_, kDielMxInv_zero_);
46
47 tail_terms_.assign(std::size_t(qptotal_), Eigen::VectorXd());
48 const Index offset = opt_.qpmin - opt_.rpamin;
49#pragma omp parallel for schedule(dynamic)
50 for (Index level = 0; level < qptotal_; level++) {
51 tail_terms_[std::size_t(level)] =
54 }
55}
56
57// This function is used in the calculation of the residues and
58// calculates the real part of the dielectric function for a complex
59// frequency of the kind omega = delta + i*eta. Instead of explicit
60// inversion and multiplication with and Imx vector, a linear system
61// is solved.
63 const Eigen::MatrixXd::ConstRowXpr& Imx_row, double delta,
64 double eta) const {
65 std::complex<double> delta_eta(delta, eta);
66
67 Eigen::MatrixXd DielMxInv = rpa_.calculate_epsilon_r(delta_eta);
68 Eigen::VectorXd x =
69 DielMxInv.partialPivLu().solve(Imx_row.transpose()) - Imx_row.transpose();
70 return x.dot(Imx_row.transpose());
71}
72
73// Step-function prefactor for the residues
74double Sigma_CDA::CalcResiduePrefactor(double e_f, double e_m,
75 double frequency) const {
76 double factor = 0.0;
77 double tolerance = 1e-10;
78 if (e_f < e_m && e_m < frequency) {
79 factor = 1.0;
80 } else if (e_f > e_m && e_m > frequency) {
81 factor = -1.0;
82 } else if (std::abs(e_m - frequency) < tolerance && e_f > e_m) {
83 factor = -0.5;
84 } else if (std::abs(e_m - frequency) < tolerance && e_f < e_m) {
85 factor = 0.5;
86 }
87 return factor;
88}
89
90// Calculates the contribution of residues to the correlation
91// part of the self-energy of a fixed gw_level
92double Sigma_CDA::CalcResidueContribution(double frequency,
93 Index gw_level) const {
94
95 const Eigen::VectorXd& rpa_energies = rpa_.getRPAInputEnergies();
96 Index rpatotal = rpa_energies.size();
97 Index gw_level_offset = gw_level + opt_.qpmin - opt_.rpamin;
98
99 double sigma_c = 0.0;
100 double sigma_c_tail = 0.0;
101 Index homo = opt_.homo - opt_.rpamin;
102 Index lumo = homo + 1;
103 double fermi_rpa = (rpa_energies(lumo) + rpa_energies(homo)) / 2.0;
104 const Eigen::MatrixXd& Imx = Mmn_[gw_level_offset];
105
106 for (Index i = 0; i < rpatotal; ++i) {
107 double delta = rpa_energies(i) - frequency;
108 double abs_delta = std::abs(delta);
109 double factor = CalcResiduePrefactor(fermi_rpa, rpa_energies(i), frequency);
110
111 // Only considering the terms with a abs(prefactor) > 0.
112 // The prefactor can be 1,-1,0.5,-0.5 or 0. We avoid calculating the
113 // diagonal contribution if the prefactor is 0. We want to calculate it for
114 // all the other cases.
115 if (std::abs(factor) > 1e-10) {
116 sigma_c +=
117 factor * CalcDiagContribution(Imx.row(i), abs_delta, rpa_.getEta());
118 }
119 // adds the contribution from the Gaussian tail
120 if (abs_delta > 1e-10) {
121 sigma_c_tail += CalcDiagContributionValue_tail(
122 tail_terms_[std::size_t(gw_level)](i), delta, opt_.alpha);
123 }
124 }
125 return sigma_c + sigma_c_tail;
126}
127
128// Calculates the correlation part of the self-energy for a fixed
129// gw_level and frequence by evaluating the numerical integration
130// and residue contributions
132 double frequency) const {
134 double sigma_c_residue = CalcResidueContribution(frequency, gw_level);
135 double sigma_c_integral = gq_.SigmaGQDiag(frequency, gw_level, rpa_.getEta());
136 return sigma_c_residue + sigma_c_integral;
137}
138
139// Calculates the contribuion of the tail correction to the
140// residue term
141double Sigma_CDA::CalcDiagContributionValue_tail(double row_term, double delta,
142 double alpha) const {
143
144 double erfc_factor = 0.5 * std::copysign(1.0, delta) *
145 std::exp(std::pow(alpha * delta, 2)) *
146 std::erfc(std::abs(alpha * delta));
147
148 return row_term * erfc_factor;
149}
150
151} // namespace xtp
152} // namespace votca
static Eigen::VectorXd RowQuadraticForms(const Eigen::MatrixXd &M, const Eigen::MatrixXd &K)
q(i) = M.row(i) K M.row(i)^T for all rows of M.
double CalcDiagContribution(const Eigen::MatrixXd::ConstRowXpr &Imx_row, double delta, double eta) const
Definition sigma_cda.cc:62
double CalcCorrelationDiagElement(Index gw_level, double frequency) const final
Definition sigma_cda.cc:131
ImaginaryAxisIntegration gq_
Definition sigma_cda.h:86
double CalcResidueContribution(double frequency, Index gw_level) const
Definition sigma_cda.cc:92
std::vector< Eigen::VectorXd > tail_terms_
Definition sigma_cda.h:89
double CalcDiagContributionValue_tail(double row_term, double delta, double alpha) const
Definition sigma_cda.cc:141
double CalcResiduePrefactor(double e_f, double e_m, double frequency) const
Definition sigma_cda.cc:74
void PrepareScreening() final
Definition sigma_cda.cc:30
Eigen::MatrixXd kDielMxInv_zero_
Definition sigma_cda.h:87
TCMatrix_gwbse & Mmn_
Definition sigma_base.h:207
void CountDiagEval() const
Definition sigma_base.h:221
Charge transport classes.
Definition ERIs.h:28
Eigen::MatrixXd InverseSPD(const Eigen::MatrixXd &A)
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26