28template <Index cqp, Index cx, Index cd, Index cd2>
32 bse_cmin_ = opt_.homo + 1;
33 bse_vtotal_ = bse_vmax - opt_.vmin + 1;
34 bse_ctotal_ = opt_.cmax - bse_cmin_ + 1;
35 bse_size_ = bse_vtotal_ * bse_ctotal_;
36 this->set_size(bse_size_);
39template <Index cqp, Index cx, Index cd, Index cd2>
41 const Eigen::MatrixXd& input)
const {
43 static_assert(!(cd2 != 0 && cd != 0),
44 "Hamiltonian cannot contain Hd and Hd2 at the same time");
46 Index auxsize = Mmn_.auxsize();
49 Index vmin = opt_.vmin - opt_.rpamin;
50 Index cmin = bse_cmin_ - opt_.rpamin;
64#pragma omp for schedule(dynamic)
65 for (
Index c1 = 0; c1 < bse_ctotal_; c1++) {
71 Temp = -cd * (Mmn_[c1 + cmin].middleRows(cmin, bse_ctotal_));
73 }
else if (cd2 != 0) {
74 Temp = -cd2 * (Mmn_[c1 + cmin].middleRows(vmin, bse_vtotal_));
78 for (
Index v1 = 0; v1 < bse_vtotal_; v1++) {
82 Mmn_[v1 + vmin].middleRows(vmin, bse_vtotal_), cd2 != 0,
87 Mmn_[v1 + vmin].middleRows(cmin, bse_ctotal_), cd2 != 0,
91 Eigen::VectorXd vec = Hqp_row(v1, c1);
92 transform.
Addvec(vec, threadid);
104#pragma omp for schedule(dynamic)
105 for (
Index v1 = 0; v1 < bse_vtotal_; v1++) {
106 Index va = v1 + vmin;
107 Eigen::MatrixXd Mmn1 = cx * Mmn_[va].middleRows(cmin, bse_ctotal_);
109 for (
Index v2 = v1; v2 < bse_vtotal_; v2++) {
110 Index vb = v2 + vmin;
111 transform.
MultiplyBlocks(Mmn_[vb].middleRows(cmin, bse_ctotal_), v1,
121template <Index cqp, Index cx, Index cd, Index cd2>
124 Eigen::MatrixXd Result = Eigen::MatrixXd::Zero(bse_ctotal_, bse_vtotal_);
125 Index cmin = bse_vtotal_;
127 Result.col(v1) += cqp * Hqp_.col(c1 + cmin).segment(cmin, bse_ctotal_);
129 Result.row(c1) -= cqp * Hqp_.col(v1).head(bse_vtotal_);
130 return Eigen::Map<Eigen::VectorXd>(Result.data(), Result.size());
133template <Index cqp, Index cx, Index cd, Index cd2>
136 static_assert(!(cd2 != 0 && cd != 0),
137 "Hamiltonian cannot contain Hd and Hd2 at the same time");
140 Index vmin = opt_.vmin - opt_.rpamin;
141 Index cmin = bse_cmin_ - opt_.rpamin;
143 Eigen::VectorXd result = Eigen::VectorXd::Zero(bse_size_);
145#pragma omp parallel for schedule(dynamic) reduction(+ : result)
146 for (
Index v = 0; v < bse_vtotal_; v++) {
147 for (
Index c = 0; c < bse_ctotal_; c++) {
151 entry += cx * Mmn_[v + vmin].row(cmin + c).squaredNorm();
155 Index cmin_qp = bse_vtotal_;
156 entry += cqp * (Hqp_(c + cmin_qp, c + cmin_qp) - Hqp_(v, v));
160 cd * (Mmn_[c + cmin].row(c + cmin) * epsilon_0_inv_.asDiagonal() *
161 Mmn_[v + vmin].row(v + vmin).transpose())
166 cd2 * (Mmn_[c + cmin].row(v + vmin) * epsilon_0_inv_.asDiagonal() *
167 Mmn_[v + vmin].row(c + cmin).transpose())
171 result(vc.
I(v, c)) = entry;
Eigen::VectorXd Hqp_row(Index v1, Index c1) const
void configure(BSEOperator_Options opt)
Eigen::MatrixXd matmul(const Eigen::MatrixXd &input) const
Eigen::VectorXd diagonal() const
void Addvec(const Eigen::VectorXd &row, Index OpenmpThread)
void PushMatrix1(const Eigen::MatrixXd &mat, Index OpenmpThread)
Eigen::MatrixXd getReductionVar()
void SetTempZero(Index OpenmpThread)
void createTemporaries(Index rows, Index cols)
void MultiplyBlocks(const Eigen::Block< const Eigen::MatrixXd > &mat, Index i1, Index i2, Index OpenmpThread)
void MultiplyRow(Index row, Index OpenmpThread)
void createAdditionalTemporaries(Index rows, Index cols)
void PrepareMatrix2(const Eigen::Block< const Eigen::MatrixXd > &mat, bool Hd2, Index OpenmpThread)
void PrepareMatrix1(Eigen::MatrixXd &mat, Index OpenmpThread)
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
base class for all analysis tools