24#include <boost/math/constants/constants.hpp>
43 const std::function<
void(
Index, Eigen::MatrixXd&)>& makeX)
const {
50 const Index block = std::max<Index>(
51 1, std::min<Index>(
qptotal_,
Index(kBlockBytes / (8.0 *
double(nrows) *
53 const Index chunk = std::max<Index>(
54 1, std::min<Index>(auxsize,
Index(kChunkBytes / (8.0 *
double(nrows) *
57 std::vector<Eigen::MatrixXd> X(
static_cast<std::size_t
>(block));
63#pragma omp parallel for schedule(dynamic)
64 for (
Index j = 0; j < nb; ++j) {
65 makeX(m0 + j, X[std::size_t(j)]);
67 for (
Index s0 = 0; s0 < auxsize; s0 += chunk) {
68 const Index ns = std::min(chunk, auxsize - s0);
70 Xc.resize(nrows * ns, nb);
71#pragma omp parallel for schedule(static)
73 Eigen::Map<Eigen::MatrixXd>(Mc.col(n).data(), nrows, ns) =
74 Mmn_[n + qpmin].block(0, s0, nrows, ns);
76 for (
Index j = 0; j < nb; ++j) {
77 Eigen::Map<Eigen::MatrixXd>(Xc.col(j).data(), nrows, ns) =
78 X[std::size_t(j)].middleCols(s0, ns);
80 A.middleRows(m0, nb).noalias() += Xc.transpose() * Mc;
87 throw std::runtime_error(
88 "The pole form of Sigma_c is only available for sigma_integrator ppm "
93 const Eigen::VectorXd&)
const {
94 throw std::runtime_error(
95 "Screening data are only available for sigma_integrator ppm and exact");
99 const Eigen::VectorXd& omegas,
101 const Index S = omegas.size();
103 Eigen::MatrixXd g(
S, 3 + nu.size());
104 for (
Index s = 0; s <
S; ++s) {
105 const double w = omegas(s);
109 for (
Index j = 0; j < nu.size(); ++j) {
110 g(s, 3 + j) = -w / (nu(j) * nu(j) + w * w);
113 const Eigen::MatrixXd sums = a * g;
125 const bool bare =
Mmn_.AuxFrameIsOrthogonal();
128 v =
Mmn_.ToCurrentAuxFrame(
129 Eigen::MatrixXd::Identity(
Mmn_.auxsize(),
Mmn_.auxsize()));
132 const Eigen::MatrixXd A =
135 X =
Mmn_[m + qpmin].topRows(occlevel);
137 X =
Mmn_[m + qpmin].topRows(occlevel) * v;
140 return -0.5 * (A + A.transpose());
147 Eigen::VectorXd d = Eigen::VectorXd::Zero(
Mmn_.auxsize());
148 for (
Index i = 0; i < occlevel; ++i) {
149 d +=
Mmn_[i].row(i).transpose();
157 if (R.rows() !=
Mmn_.auxsize() || R.cols() !=
Mmn_.auxsize()) {
158 throw std::runtime_error(
159 "Sigma_base::CalcHartreeMatrix: reaction field is " +
160 std::to_string(R.rows()) +
"x" + std::to_string(R.cols()) +
161 ", auxiliary basis has " + std::to_string(
Mmn_.auxsize()) +
164 d =
Mmn_.ToCurrentAuxFrame(
165 Eigen::MatrixXd::Identity(
Mmn_.auxsize(),
Mmn_.auxsize()) + R) *
167 }
else if (!
Mmn_.AuxFrameIsOrthogonal()) {
168 d =
Mmn_.ToCurrentAuxFrame(
169 Eigen::MatrixXd::Identity(
Mmn_.auxsize(),
Mmn_.auxsize())) *
173#pragma omp parallel for schedule(dynamic)
175 J.col(m) = 2.0 *
Mmn_[m + qpmin].middleRows(qpmin,
qptotal_) * d;
177 return 0.5 * (J + J.transpose());
181 const Eigen::MatrixXd& R)
const {
182 const Eigen::MatrixXd Rc =
Mmn_.ToCurrentAuxFrame(R);
186 const Eigen::MatrixXd A =
188 X = Mmn_[m + qpmin] * Rc;
189 X.topRows(occlevel) *= -1.0;
191 return 0.25 * (A + A.transpose());
195 const Eigen::VectorXd& frequencies)
const {
196 Eigen::VectorXd result = Eigen::VectorXd::Zero(
qptotal_);
197#pragma omp parallel for schedule(dynamic)
206 const Eigen::VectorXd& frequencies,
double s)
const {
208 throw std::runtime_error(
209 "SRG-regularized QSGW needs a self-energy with a pole form (exact or "
213 throw std::runtime_error(
"SRG flow parameter s must be positive");
215 if (frequencies.size() !=
qptotal_) {
216 throw std::runtime_error(
"CalcCorrelationSRG: one frequency per level");
218 std::vector<DiagPoleForm> forms;
219 forms.reserve(std::size_t(
qptotal_));
230 Eigen::ArrayXd c = Eigen::ArrayXd::Ones(
P);
231 for (
Index mode = 0; mode <
S; ++mode) {
232 for (
Index m = 0; m < B; ++m) {
233 z(m + B * mode) = poles.
energies(m) +
234 ((m < poles.
n_occ) ? -1.0 : 1.0) * poles.
omegas(mode);
241#pragma omp parallel for schedule(dynamic)
243 const Eigen::Map<const Eigen::ArrayXd> r1(forms[std::size_t(n1)].residues,
245 const Eigen::ArrayXd d1 = frequencies(n1) - z;
246 const Eigen::ArrayXd cr1 = c * r1;
247 for (
Index n2 = 0; n2 <= n1; ++n2) {
248 const Eigen::Map<const Eigen::ArrayXd> r2(forms[std::size_t(n2)].residues,
250 const Eigen::ArrayXd d2 = frequencies(n2) - z;
251 const Eigen::ArrayXd
D = d1.square() + d2.square();
253 const Eigen::ArrayXd damp = (s *
D < 1
e-12)
254 .select(Eigen::ArrayXd::Constant(
P, s),
255 -(-s *
D).unaryExpr([](
double x) {
256 return std::expm1(x);
259 first.
prefactor * (cr1 * r2 * (d1 + d2) * damp).sum();
260 result(n1, n2) = value;
261 result(n2, n1) = value;
268 const Eigen::VectorXd& frequencies)
const {
270#pragma omp parallel for schedule(dynamic)
271 for (
Index gw_level1 = 0; gw_level1 <
qptotal_; gw_level1++) {
272 for (
Index gw_level2 = gw_level1 + 1; gw_level2 <
qptotal_; gw_level2++) {
274 gw_level1, gw_level2, frequencies[gw_level1], frequencies[gw_level2]);
275 result(gw_level2, gw_level1) = sigma_c;
278 result = result.selfadjointView<Eigen::Lower>();
virtual bool HasPoleForm() const
Eigen::MatrixXd CalcHartreeMatrix(const Eigen::MatrixXd &R=Eigen::MatrixXd()) const
static void FrameSums(const Eigen::MatrixXd &a, const Eigen::VectorXd &omegas, const Eigen::VectorXd &nu, ScreeningData &data)
virtual Eigen::MatrixXd CalcCorrelationOffDiag(const Eigen::VectorXd &frequencies) const
Eigen::MatrixXd CalcCorrelationSRG(const Eigen::VectorXd &frequencies, double s) const
virtual ScreeningData ScreeningDump(const Eigen::VectorXd &nu) const
virtual double CalcCorrelationOffDiagElement(Index gw_level1, Index gw_level2, double frequency1, double frequency2) const =0
virtual DiagPoleForm PoleForm(Index gw_level) const
virtual double CalcCorrelationDiagElement(Index gw_level, double frequency) const =0
Eigen::MatrixXd PairContraction(Index nrows, const std::function< void(Index, Eigen::MatrixXd &)> &makeX) const
Eigen::VectorXd CalcCorrelationDiag(const Eigen::VectorXd &frequencies) const
Eigen::MatrixXd CalcReactionFieldMatrix(const Eigen::MatrixXd &R) const
Static self-energy of an environment reaction field: the COH+SEX pair for v_reac, in the QP window.
Eigen::MatrixXd CalcExchangeMatrix() const
Charge transport classes.
Provides a means for comparing floating point numbers.
Pole sums of the exact (RPA spectral) correlation self-energy.
const Eigen::VectorXd & energies
const Eigen::VectorXd & omegas
Eigen::MatrixXd frame_eps_inv_imag
Eigen::MatrixXd frame_moments