39bool CdaDebugEnabled() {
40 const char* env = std::getenv(
"VOTCA_XTP_CDA_DEBUG");
41 return env !=
nullptr && std::string(env) ==
"1";
44bool CdaDebugLevelMatch(
Index level) {
45 const char* env = std::getenv(
"VOTCA_XTP_CDA_DEBUG_LEVELS");
50 std::set<int> allowed;
51 std::stringstream ss(env);
53 while (std::getline(ss, token,
',')) {
55 allowed.insert(std::stoi(token));
58 return allowed.count(
static_cast<int>(level)) > 0;
61bool CdaDebugMatch(
Index level) {
62 return CdaDebugEnabled() && CdaDebugLevelMatch(level);
72 options opt,
const RPA& rpa,
const Eigen::MatrixXd& kDielMxInv_zero) {
81 options opt,
const RPA_UKS& rpa,
const Eigen::MatrixXd& kDielMxInv_zero) {
90 const Eigen::MatrixXd& M,
const Eigen::MatrixXd& K) {
91 return (M * K).cwiseProduct(M).rowwise().sum();
97template <
class RPAType>
99 const RPAType& rpa,
const Eigen::MatrixXd& kDielMxInv_zero) {
100 std::vector<Eigen::MatrixXd> dielinv_matrices(std::size_t(
gq_->Order()));
101 for (
Index j = 0; j <
gq_->Order(); j++) {
102 double newpoint =
gq_->ScaledPoint(j);
103 Eigen::MatrixXd eps_inv_j =
InverseSPD(rpa.calculate_epsilon_i(newpoint));
104 eps_inv_j.diagonal().array() -= 1.0;
105 dielinv_matrices[std::size_t(j)] =
107 kDielMxInv_zero * std::exp(-std::pow(
opt_.alpha * newpoint, 2));
113 const RPA& rpa,
const Eigen::MatrixXd& kDielMxInv_zero);
115 const RPA_UKS& rpa,
const Eigen::MatrixXd& kDielMxInv_zero);
118 const std::vector<Eigen::MatrixXd>& dielinv_matrices) {
119 const Index order =
Index(dielinv_matrices.size());
122#pragma omp parallel for schedule(dynamic)
123 for (
Index level = 0; level <
opt_.qptotal; level++) {
124 const Eigen::MatrixXd& Imx =
Mmn_[level + offset];
125 Eigen::MatrixXd terms(Imx.rows(), order);
126 for (
Index j = 0; j < order; j++) {
129 node_terms_[std::size_t(level)] = std::move(terms);
136 const Eigen::ArrayXcd& DeltaE)
141 Eigen::ArrayXcd denominator;
142 const std::complex<double> cpoint(0.0, point);
144 denominator = (
DeltaE_ + cpoint).inverse() + (
DeltaE_ - cpoint).inverse();
146 denominator = (
DeltaE_ + cpoint).inverse();
149 (denominator.real() *
node_terms_.col(j).array()).sum();
163 const Eigen::MatrixXd& Imx =
Mmn_[gw_level_offset];
164 Eigen::ArrayXcd DeltaE = frequency -
energies_.array();
165 DeltaE.imag().head(occ) = eta;
166 DeltaE.imag().tail(unocc) = -eta;
168 if (CdaDebugMatch(gw_level)) {
169 double min_abs = std::numeric_limits<double>::max();
170 for (
Index i = 0; i < DeltaE.size(); ++i) {
171 min_abs = std::min(min_abs, std::abs(DeltaE(i)));
174 std::cout <<
"\n [CDA-DEBUG] ImagAxis level=" << gw_level
175 <<
" freq=" << frequency <<
" eta=" << eta
176 <<
" min|DeltaE|=" << min_abs <<
" ||Imx||=" << Imx.norm();
178 for (
Index i = 0; i < DeltaE.size(); ++i) {
179 std::cout <<
"\n [CDA-DEBUG] ImagAxis i=" << i
180 <<
" occ=" << (i < occ ? 1 : 0) <<
" DeltaE=" << DeltaE(i);
182 std::cout << std::flush;
186 return gq_->Integrate(f);
const Eigen::MatrixXd & node_terms_
double operator()(Index j, double point, bool symmetry) const
FunctionEvaluation(const Eigen::MatrixXd &node_terms, const Eigen::ArrayXcd &DeltaE)
const Eigen::ArrayXcd & DeltaE_
double SigmaGQDiag(double frequency, Index gw_level, double eta) const
const Eigen::VectorXd & energies_
ImaginaryAxisIntegration(const Eigen::VectorXd &energies, const TCMatrix_gwbse &Mmn)
void configure(options opt, const RPA &rpa, const Eigen::MatrixXd &kDielMxInv_zero)
void CalcDielInvVector(const RPAType &rpa, const Eigen::MatrixXd &kDielMxInv_zero)
const TCMatrix_gwbse & Mmn_
std::unique_ptr< GaussianQuadratureBase > gq_
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.
std::vector< Eigen::MatrixXd > node_terms_
void CalcNodeTerms(const std::vector< Eigen::MatrixXd > &dielinv_matrices)
Unrestricted RPA helper for spin-resolved GW screening.
Charge transport classes.
Eigen::MatrixXd InverseSPD(const Eigen::MatrixXd &A)
Provides a means for comparing floating point numbers.