votca 2026-dev
Loading...
Searching...
No Matches
ppm.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// Standard includes
21#include <iostream>
22
23#include "votca/xtp/ppm.h"
24#include "votca/xtp/rpa_uks.h"
25
26namespace votca {
27namespace xtp {
28
29namespace {
30template <typename RPAType>
31Index ConstructPPMParametersImpl(const RPAType& rpa, Eigen::MatrixXd& ppm_phi,
32 Eigen::VectorXd& ppm_weight,
33 Eigen::VectorXd& ppm_freq, double screening_r,
34 double screening_i) {
36 SymmetricEigen(rpa.calculate_epsilon_r(screening_r));
37 ppm_phi = std::move(es.vectors);
38
39 ppm_weight = 1 - es.values.array().inverse();
40
41 // epsilon at an imaginary frequency is positive definite
42 const Eigen::MatrixXd eps_i = rpa.calculate_epsilon_i(screening_i);
43 const Eigen::MatrixXd half = eps_i * ppm_phi;
44 const Eigen::MatrixXd epsilon_1_inv = InverseSPD(ppm_phi.transpose() * half);
45
46 ppm_freq.resize(es.values.size());
47 Index invalid = 0;
48#pragma omp parallel for reduction(+ : invalid)
49 for (Index i = 0; i < es.values.size(); i++) {
50 if (ppm_weight(i) < 1.e-5) {
51 ppm_weight(i) = 0.0;
52 ppm_freq(i) = 0.5;
53 continue;
54 } else {
55 double nom = epsilon_1_inv(i, i) - 1.0;
56 double frac =
57 -1.0 * nom / (nom + ppm_weight(i)) * screening_i * screening_i;
58 // frac < 0: this mode has no real plasmon-pole frequency at the
59 // imaginary fitting point; |frac| is used, as before, and counted
60 if (frac < 0.0) {
61 ++invalid;
62 }
63 ppm_freq(i) = std::sqrt(std::abs(frac));
64 }
65 }
66 return invalid;
67}
68} // namespace
69
71 invalid_modes_ = ConstructPPMParametersImpl(
73}
74
76 invalid_modes_ = ConstructPPMParametersImpl(
78}
79
80} // namespace xtp
81} // namespace votca
Eigen::VectorXd ppm_freq_
Definition ppm.h:53
Eigen::VectorXd ppm_weight_
Definition ppm.h:54
void PPM_construct_parameters(const RPA &rpa)
Definition ppm.cc:70
Eigen::MatrixXd ppm_phi_
Definition ppm.h:52
double screening_i
Definition ppm.h:50
Index invalid_modes_
Definition ppm.h:55
double screening_r
Definition ppm.h:49
Unrestricted RPA helper for spin-resolved GW screening.
Definition rpa_uks.h:70
Charge transport classes.
Definition ERIs.h:28
SymmetricEigenSystem SymmetricEigen(const Eigen::MatrixXd &A, bool vectors=true)
With vectors = false only the eigenvalues are computed.
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