46 finalP = MatrixFactory2::BuildCopy(rcpFromRef(P0));
51 "For now, solving Hessenberg system works only for a single iteration");
53 SC one = Teuchos::ScalarTraits<SC>::one(), zero = Teuchos::ScalarTraits<SC>::zero();
55 RCP<const Matrix> A = rcpFromRef(Aref);
57 const auto rowMap = A->getRowMap();
58 auto invDiag = Xpetra::VectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(rowMap,
true);
62 A->getLocalDiagCopy(*invDiag);
63 invDiag->reciprocal(*invDiag);
65 invDiag->putScalar(one);
68 Teuchos::FancyOStream& mmfancy = this->GetOStream(
Statistics2);
71 RCP<Matrix> X = rcp_const_cast<Matrix>(rcpFromRef(P0)), tmpAP, newV;
72 std::vector<RCP<Matrix> > V(nIts_ + 1);
75 RCP<CrsMatrix> T_ = CrsMatrixFactory::Build(C.
GetPattern());
76 T_->fillComplete(P0.getDomainMap(), P0.getRangeMap());
77 RCP<Matrix> T = rcp(
new CrsMatrixWrap(T_));
83 tmpAP = MatrixMatrix::Multiply(*A,
false, *X,
false, mmfancy,
true ,
true );
86 V[0] = MatrixFactory2::BuildCopy(T);
87 V[0]->leftScale(*invDiag);
91 V[0]->scale(-one / rho);
94 std::vector<SC> h((nIts_ + 1) * (nIts_ + 1));
95 std::vector<SC> c(nIts_ + 1, 0.0);
96 std::vector<SC> s(nIts_ + 1, 0.0);
97 std::vector<SC> g(nIts_ + 1, 0.0);
100#define I(i, j) ((i) + (j) * (nIts_ + 1))
101 for (
size_t i = 0; i < nIts_; i++) {
103 tmpAP = MatrixMatrix::Multiply(*A,
false, *V[i],
false, mmfancy,
true ,
true );
106 V[i + 1] = MatrixFactory2::BuildCopy(T);
107 V[i + 1]->leftScale(*invDiag);
110 for (
size_t j = 0; j <= i; j++) {
114#ifndef TWO_ARG_MATRIX_ADD
115 newV = Teuchos::null;
116 MatrixMatrix::TwoMatrixAdd(*V[j],
false, -h[
I(j, i)], *V[i + 1],
false, one, newV, mmfancy);
117 newV->fillComplete(V[i + 1]->getDomainMap(), V[i + 1]->getRangeMap());
128 MatrixMatrix::TwoMatrixAdd(*V[j],
false, -h[
I(j, i)], *V[i + 1], one);
147 if (h[
I(i + 1, i)] != zero) {
149 V[i + 1]->scale(one / h[
I(i + 1, i)]);
153 givapp(&c[0], &s[0], &h[
I(0, i)], i);
155 SC nu = sqrt(h[
I(i, i)] * h[
I(i, i)] + h[
I(i + 1, i)] * h[
I(i + 1, i)]);
157 c[i] = h[
I(i, i)] / nu;
158 s[i] = -h[
I(i + 1, i)] / nu;
159 h[
I(i, i)] = c[i] * h[
I(i, i)] - s[i] * h[
I(i + 1, i)];
160 h[
I(i + 1, i)] = zero;
162 givapp(&c[i], &s[i], &g[i], 1);
168 std::vector<SC> y(nIts_);
170 y[0] = g[0] / h[
I(0, 0)];
175 for (
size_t i = 0; i < nIts_; i++) {
176#ifndef TWO_ARG_MATRIX_ADD
177 newV = Teuchos::null;
178 MatrixMatrix::TwoMatrixAdd(*V[i],
false, y[i], *finalP,
false, one, newV, mmfancy);
179 newV->fillComplete(finalP->getDomainMap(), finalP->getRangeMap());
182 MatrixMatrix::TwoMatrixAdd(*V[i],
false, y[i], *finalP, one);
static Scalar Frobenius(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &B)
Frobenius inner product of two matrices.