votca 2026-dev
Loading...
Searching...
No Matches
sigma_ppm_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
21#include <votca/tools/globals.h>
22
23#include "sigma_ppm_uks.h"
24#include "votca/xtp/ppm.h"
26
27namespace votca {
28namespace xtp {
29
31 if (ppm_ == nullptr) {
32 throw std::runtime_error(
33 "Sigma_PPM_UKS: shared PPM parameters were not set before "
34 "PrepareScreening().");
35 }
36 Mmn_.MultiplyRightWithAuxMatrix(ppm_->getPpm_phi());
37}
38
40 double frequency) const {
41 const Index lumo = opt_.homo + 1;
42 const double eta2 = opt_.eta * opt_.eta;
43 const Index levelsum = Mmn_.nsize();
44 const Index qpmin_offset = opt_.qpmin - opt_.rpamin;
45 const Eigen::VectorXd& energies = getSpinRPAInputEnergies();
46
47 double sigma = 0.0;
48 for (Index i_aux = 0; i_aux < Mmn_.auxsize(); i_aux++) {
49 if (ppm_->getPpm_weight()(i_aux) < 1.e-9) {
50 continue;
51 }
52
53 const double ppm_freq = ppm_->getPpm_freq()(i_aux);
54 const double fac = 0.5 * ppm_->getPpm_weight()(i_aux) * ppm_freq;
55
56 const Eigen::ArrayXd Mmn2 =
57 Mmn_[gw_level + qpmin_offset].col(i_aux).cwiseAbs2();
58
59 Eigen::ArrayXd temp = frequency - energies.array();
60 temp.segment(0, lumo) += ppm_freq;
61 temp.segment(lumo, levelsum - lumo) -= ppm_freq;
62
63 Eigen::ArrayXd denom = temp.abs2() + eta2;
64 sigma += fac * (Mmn2 * temp / denom).sum();
65 }
66 return sigma;
67}
68
70 Index gw_level, double frequency) const {
71 const Index lumo = opt_.homo + 1;
72 const double eta2 = opt_.eta * opt_.eta;
73 const Index levelsum = Mmn_.nsize();
74 const Index qpmin_offset = opt_.qpmin - opt_.rpamin;
75 const Eigen::VectorXd& energies = getSpinRPAInputEnergies();
76
77 double dsigma_domega = 0.0;
78 for (Index i_aux = 0; i_aux < Mmn_.auxsize(); i_aux++) {
79 if (ppm_->getPpm_weight()(i_aux) < 1.e-9) {
80 continue;
81 }
82
83 const double ppm_freq = ppm_->getPpm_freq()(i_aux);
84 const double fac = 0.5 * ppm_->getPpm_weight()(i_aux) * ppm_freq;
85
86 const Eigen::ArrayXd Mmn2 =
87 Mmn_[gw_level + qpmin_offset].col(i_aux).cwiseAbs2();
88
89 Eigen::ArrayXd temp = frequency - energies.array();
90 temp.segment(0, lumo) += ppm_freq;
91 temp.segment(lumo, levelsum - lumo) -= ppm_freq;
92
93 Eigen::ArrayXd denom = temp.abs2() + eta2;
94 dsigma_domega += fac * ((eta2 - temp.abs2()) * Mmn2 / denom.abs2()).sum();
95 }
96 return dsigma_domega;
97}
98
100 Index gw_level2,
101 double frequency1,
102 double frequency2) const {
103 const Index lumo = opt_.homo + 1;
104 const double eta2 = opt_.eta * opt_.eta;
105 const Index levelsum = Mmn_.nsize();
106 const Index auxsize = Mmn_.auxsize();
107 const Eigen::VectorXd ppm_weight = ppm_->getPpm_weight();
108 const Eigen::VectorXd ppm_freqs = ppm_->getPpm_freq();
109 const Index qpmin_offset = opt_.qpmin - opt_.rpamin;
110 const Eigen::VectorXd& energies = getSpinRPAInputEnergies();
111
112 double sigma_c = 0.0;
113 for (Index i_aux = 0; i_aux < auxsize; i_aux++) {
114 if (ppm_weight(i_aux) < 1.e-9) {
115 continue;
116 }
117
118 const double ppm_freq = ppm_freqs(i_aux);
119 const double fac = 0.25 * ppm_weight(i_aux) * ppm_freq;
120
121 const Eigen::MatrixXd& Mmn1 = Mmn_[gw_level1 + qpmin_offset];
122 const Eigen::MatrixXd& Mmn2 = Mmn_[gw_level2 + qpmin_offset];
123
124 const Eigen::ArrayXd Mmn1xMmn2 =
125 Mmn1.col(i_aux).cwiseProduct(Mmn2.col(i_aux));
126
127 Eigen::ArrayXd temp1 = energies.array();
128 temp1.segment(0, lumo) -= ppm_freq;
129 temp1.segment(lumo, levelsum - lumo) += ppm_freq;
130
131 Eigen::ArrayXd temp2 = (frequency2 - temp1);
132 temp1 = (frequency1 - temp1);
133
134 sigma_c +=
135 fac * ((temp1 / (temp1.abs2() + eta2) + temp2 / (temp2.abs2() + eta2)) *
136 Mmn1xMmn2)
137 .sum();
138 }
139 return sigma_c;
140}
141
142} // namespace xtp
143} // namespace votca
double CalcCorrelationDiagElementDerivative(Index gw_level, double frequency) const final
double CalcCorrelationOffDiagElement(Index gw_level1, Index gw_level2, double frequency1, double frequency2) const final
double CalcCorrelationDiagElement(Index gw_level, double frequency) const final
const Eigen::VectorXd & getSpinRPAInputEnergies() const
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