31template <Index cqp, Index cx, Index cd, Index cd2>
42template <Index cqp, Index cx, Index cd, Index cd2>
44 const Eigen::MatrixXd& input)
const {
46 static_assert(!(cd2 != 0 && cd != 0),
47 "Hamiltonian cannot contain Hd and Hd2 at the same time");
52 Eigen::MatrixXd result;
58 result =
direct_cache_->Multiply(input, -
double((cd != 0) ? cd : cd2));
59 }
else if (cd != 0 || cd2 != 0) {
62 result = Eigen::MatrixXd::Zero(
bse_size_, input.cols());
67 static_cast<double>(cqp));
72 static_cast<double>(cx));
77template <Index cqp, Index cx, Index cd, Index cd2>
79 const Eigen::MatrixXd& input)
const {
87 Eigen::MatrixXd result(
bse_size_, input.cols());
88#pragma omp parallel for schedule(dynamic)
90 const Eigen::MatrixXd
S =
92 ? Eigen::MatrixXd(-
double(cd) *
95 : Eigen::MatrixXd(-
double(cd2) *
107 const Eigen::Map<const Eigen::VectorXd> row(K.data(), K.size());
108 result.row(vc.
I(v1, c1)).noalias() = row.transpose() * input;
124template <Index cqp, Index cx, Index cd, Index cd2>
126 const Eigen::MatrixXd& input)
const {
127 using RowMajorMatrix =
128 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
134 const double prefactor = -double((cd != 0) ? cd : cd2);
138 const Index nblocks = (cd != 0) ? nc : nv;
139 const Index blockrows = (cd != 0) ? nv : nc;
141 const Index nslice = (cd != 0) ? nv : nc;
142 const Index first_slice = (cd != 0) ? vmin : cmin;
144#pragma omp parallel for
145 for (
Index m = 0; m < nslice; m++) {
147 Mmn_[m + first_slice].middleRows(vmin, nv);
151 Eigen::MatrixXd result(
bse_size_, input.cols());
152 Eigen::MatrixXd
S(
stacked_.rows() / blockrows, aux);
153 RowMajorMatrix T(
stacked_.rows(),
S.rows());
154 Eigen::MatrixXd out(blockrows, input.cols());
155 for (
Index b = 0; b < nblocks; b++) {
157 const Index slice = (cd != 0) ? b + cmin : b + vmin;
158 S.noalias() = prefactor *
Mmn_[slice].middleRows(cmin, nc) *
161 const Eigen::Map<const RowMajorMatrix> R(T.data(), blockrows,
bse_size_);
162 out.noalias() = R * input;
164 for (
Index v1 = 0; v1 < nv; v1++) {
165 result.row(v1 * nc + b) = out.row(v1);
168 result.middleRows(b * nc, nc) = out;
180template <Index cqp, Index cx, Index cd, Index cd2>
185 throw std::runtime_error(
186 "BSE_OPERATOR: the shared direct-term cache holds a different "
195#pragma omp parallel for schedule(dynamic)
196 for (
Index c1 = 0; c1 < nc; c1++) {
197 const Eigen::MatrixXd
S =
198 (cd != 0) ? Eigen::MatrixXd(
Mmn_[c1 + cmin].middleRows(cmin, nc) *
200 : Eigen::MatrixXd(
Mmn_[c1 + cmin].middleRows(vmin, nv) *
202 Eigen::MatrixXd K(nc, nv);
203 for (
Index v1 = 0; v1 < nv; v1++) {
206 auto Kv = K.leftCols(v1 + 1);
208 Kv.noalias() =
S *
Mmn_[v1 + vmin].middleRows(vmin, v1 + 1).transpose();
210 Kv.noalias() =
Mmn_[v1 + vmin].middleRows(cmin, nc) *
211 S.topRows(v1 + 1).transpose();
219template <Index cqp, Index cx, Index cd, Index cd2>
222 static_assert(!(cd2 != 0 && cd != 0),
223 "Hamiltonian cannot contain Hd and Hd2 at the same time");
229 Eigen::VectorXd result = Eigen::VectorXd::Zero(
bse_size_);
231#pragma omp parallel for schedule(dynamic) reduction(+ : result)
237 entry += cx *
Mmn_[v + vmin].row(cmin + c).squaredNorm();
242 entry += cqp * (
Hqp_(c + cmin_qp, c + cmin_qp) -
Hqp_(v, v));
247 Mmn_[v + vmin].row(v + vmin).transpose())
253 Mmn_[v + vmin].row(c + cmin).transpose())
257 result(vc.
I(v, c)) = entry;
std::shared_ptr< SymmetricTiles > direct_cache_
Eigen::MatrixXd ApplyDirectRows(const Eigen::MatrixXd &input) const
const Eigen::VectorXd & epsilon_0_inv_
const Eigen::MatrixXd & Hqp_
void BuildDirectMatrix() const
static constexpr Index DirectKind()
Tag of the direct term an operator caches: 1 for Hd, 2 for Hd2.
void configure(BSEOperator_Options opt)
const TCMatrix_gwbse & Mmn_
Eigen::MatrixXd matmul(const Eigen::MatrixXd &input) const
Eigen::MatrixXd ApplyDirectBlocks(const Eigen::MatrixXd &input) const
Eigen::VectorXd diagonal() const
bool direct_term_cached() const
void set_size(Index size)
This class transforms a pair of indices v,c into a compound index I, via I=ctotal*v+c the fast dimens...
Index I(Index v, Index c) const
Charge transport classes.
Eigen::MatrixXd ApplyBSEExchange(const TCMatrix_gwbse &Mout, const BSEWindow &out, const TCMatrix_gwbse &Min, const BSEWindow &in, const Eigen::MatrixXd &x, double prefactor)
Eigen::MatrixXd ApplyBSEQuasiparticle(const Eigen::MatrixXd &Hqp, Index vtotal, Index ctotal, const Eigen::MatrixXd &x, double prefactor)
Provides a means for comparing floating point numbers.