votca 2024.2-dev
Loading...
Searching...
No Matches
bse_operator.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// Local VOTCA includes
23#include "votca/xtp/vc2index.h"
24
25namespace votca {
26namespace xtp {
27
28template <Index cqp, Index cx, Index cd, Index cd2>
30 opt_ = opt;
31 Index bse_vmax = opt_.homo;
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_);
37}
38
39template <Index cqp, Index cx, Index cd, Index cd2>
41 const Eigen::MatrixXd& input) const {
42
43 static_assert(!(cd2 != 0 && cd != 0),
44 "Hamiltonian cannot contain Hd and Hd2 at the same time");
45
46 Index auxsize = Mmn_.auxsize();
47 vc2index vc = vc2index(0, 0, bse_ctotal_);
48
49 Index vmin = opt_.vmin - opt_.rpamin;
50 Index cmin = bse_cmin_ - opt_.rpamin;
51
52 OpenMP_CUDA transform;
53 if (cd != 0) {
54 transform.createTemporaries(epsilon_0_inv_, input, bse_ctotal_, bse_vtotal_,
55 auxsize);
56 } else {
57 transform.createTemporaries(epsilon_0_inv_, input, bse_vtotal_, bse_ctotal_,
58 auxsize);
59 }
60
61#pragma omp parallel
62 {
63 Index threadid = OPENMP::getThreadId();
64#pragma omp for schedule(dynamic)
65 for (Index c1 = 0; c1 < bse_ctotal_; c1++) {
66
67 // Temp matrix has to stay in this scope, because it has transform only
68 // holds a reference to it
69 Eigen::MatrixXd Temp;
70 if (cd != 0) {
71 Temp = -cd * (Mmn_[c1 + cmin].middleRows(cmin, bse_ctotal_));
72 transform.PrepareMatrix1(Temp, threadid);
73 } else if (cd2 != 0) {
74 Temp = -cd2 * (Mmn_[c1 + cmin].middleRows(vmin, bse_vtotal_));
75 transform.PrepareMatrix1(Temp, threadid);
76 }
77
78 for (Index v1 = 0; v1 < bse_vtotal_; v1++) {
79 transform.SetTempZero(threadid);
80 if (cd != 0) {
81 transform.PrepareMatrix2(
82 Mmn_[v1 + vmin].middleRows(vmin, bse_vtotal_), cd2 != 0,
83 threadid);
84 }
85 if (cd2 != 0) {
86 transform.PrepareMatrix2(
87 Mmn_[v1 + vmin].middleRows(cmin, bse_ctotal_), cd2 != 0,
88 threadid);
89 }
90 if (cqp != 0) {
91 Eigen::VectorXd vec = Hqp_row(v1, c1);
92 transform.Addvec(vec, threadid);
93 }
94 transform.MultiplyRow(vc.I(v1, c1), threadid);
95 }
96 }
97 }
98 if (cx > 0) {
99
100 transform.createAdditionalTemporaries(bse_ctotal_, auxsize);
101#pragma omp parallel
102 {
103 Index threadid = OPENMP::getThreadId();
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_);
108 transform.PushMatrix1(Mmn1, threadid);
109 for (Index v2 = v1; v2 < bse_vtotal_; v2++) {
110 Index vb = v2 + vmin;
111 transform.MultiplyBlocks(Mmn_[vb].middleRows(cmin, bse_ctotal_), v1,
112 v2, threadid);
113 }
114 }
115 }
116 }
117
118 return transform.getReductionVar();
119}
120
121template <Index cqp, Index cx, Index cd, Index cd2>
123 Index c1) const {
124 Eigen::MatrixXd Result = Eigen::MatrixXd::Zero(bse_ctotal_, bse_vtotal_);
125 Index cmin = bse_vtotal_;
126 // v->c
127 Result.col(v1) += cqp * Hqp_.col(c1 + cmin).segment(cmin, bse_ctotal_);
128 // c-> v
129 Result.row(c1) -= cqp * Hqp_.col(v1).head(bse_vtotal_);
130 return Eigen::Map<Eigen::VectorXd>(Result.data(), Result.size());
131}
132
133template <Index cqp, Index cx, Index cd, Index cd2>
135
136 static_assert(!(cd2 != 0 && cd != 0),
137 "Hamiltonian cannot contain Hd and Hd2 at the same time");
138
139 vc2index vc = vc2index(0, 0, bse_ctotal_);
140 Index vmin = opt_.vmin - opt_.rpamin;
141 Index cmin = bse_cmin_ - opt_.rpamin;
142
143 Eigen::VectorXd result = Eigen::VectorXd::Zero(bse_size_);
144
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++) {
148
149 double entry = 0.0;
150 if (cx != 0) {
151 entry += cx * Mmn_[v + vmin].row(cmin + c).squaredNorm();
152 }
153
154 if (cqp != 0) {
155 Index cmin_qp = bse_vtotal_;
156 entry += cqp * (Hqp_(c + cmin_qp, c + cmin_qp) - Hqp_(v, v));
157 }
158 if (cd != 0) {
159 entry -=
160 cd * (Mmn_[c + cmin].row(c + cmin) * epsilon_0_inv_.asDiagonal() *
161 Mmn_[v + vmin].row(v + vmin).transpose())
162 .value();
163 }
164 if (cd2 != 0) {
165 entry -=
166 cd2 * (Mmn_[c + cmin].row(v + vmin) * epsilon_0_inv_.asDiagonal() *
167 Mmn_[v + vmin].row(c + cmin).transpose())
168 .value();
169 }
170
171 result(vc.I(v, c)) = entry;
172 }
173 }
174 return result;
175}
176
177template class BSE_OPERATOR<1, 2, 1, 0>;
178template class BSE_OPERATOR<1, 0, 1, 0>;
179
180template class BSE_OPERATOR<1, 0, 0, 0>;
181template class BSE_OPERATOR<0, 1, 0, 0>;
182template class BSE_OPERATOR<0, 0, 1, 0>;
183template class BSE_OPERATOR<0, 0, 0, 1>;
184
185template class BSE_OPERATOR<0, 2, 0, 1>;
186
187} // namespace xtp
188
189} // namespace votca
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...
Definition vc2index.h:36
Index I(Index v, Index c) const
Definition vc2index.h:42
Index getThreadId()
Definition eigen.h:143
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26