36 finalP = MatrixFactory2::BuildCopy(rcpFromRef(P0));
40 RCP<const Matrix> A = rcpFromRef(Aref);
41 const auto rowMap = A->getRowMap();
42 auto invDiag = Xpetra::VectorFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(rowMap,
true);
43 A->getLocalDiagCopy(*invDiag);
44 invDiag->reciprocal(*invDiag);
46 bool useTpetra = (A->getRowMap()->lib() == Xpetra::UseTpetra);
48 Teuchos::FancyOStream& mmfancy = this->GetOStream(
Statistics2);
50 SC one = Teuchos::ScalarTraits<SC>::one();
52 RCP<Matrix> X, P, R, Z, AP;
53 RCP<Matrix> newX, tmpAP;
54#ifndef TWO_ARG_MATRIX_ADD
55 RCP<Matrix> newR, newP;
58 SC oldRZ, newRZ, alpha, beta, app;
61 RCP<CrsMatrix> T_ = CrsMatrixFactory::Build(C.
GetPattern());
62 T_->fillComplete(P0.getDomainMap(), P0.getRangeMap());
63 RCP<Matrix> T = rcp(
new CrsMatrixWrap(T_));
66 X = rcp_const_cast<Matrix>(rcpFromRef(P0));
68 tmpAP = MatrixMatrix::Multiply(*A,
false, *X,
false, mmfancy,
true ,
true );
72 R = Xpetra::MatrixFactory2<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(T);
77 Z = Xpetra::MatrixFactory2<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(R);
78 Z->leftScale(*invDiag);
81 P = Xpetra::MatrixFactory2<Scalar, LocalOrdinal, GlobalOrdinal, Node>::BuildCopy(Z);
85 for (
size_t i = 0; i < nIts_; i++) {
87 if (i == 0 || useTpetra) {
92 tmpAP = MatrixMatrix::Multiply(*A,
false, *P,
false, mmfancy,
true ,
true );
95 tmpAP = MatrixMatrix::Multiply(*A,
false, *P,
false, tmpAP, mmfancy,
true ,
true );
101 if (Teuchos::ScalarTraits<SC>::magnitude(app) < Teuchos::ScalarTraits<SC>::sfmin()) {
106 X = MatrixFactory2::BuildCopy(rcpFromRef(P0));
112 this->GetOStream(
Runtime1, 1) <<
"alpha = " << alpha << std::endl;
115#ifndef TWO_ARG_MATRIX_ADD
116 newX = Teuchos::null;
117 MatrixMatrix::TwoMatrixAdd(*P,
false, alpha, *X,
false, one, newX, mmfancy);
118 newX->fillComplete(P0.getDomainMap(), P0.getRangeMap());
121 MatrixMatrix::TwoMatrixAdd(*P,
false, alpha, *X, one);
128#ifndef TWO_ARG_MATRIX_ADD
129 newR = Teuchos::null;
130 MatrixMatrix::TwoMatrixAdd(*AP,
false, -alpha, *R,
false, one, newR, mmfancy);
131 newR->fillComplete(P0.getDomainMap(), P0.getRangeMap());
134 MatrixMatrix::TwoMatrixAdd(*AP,
false, -alpha, *R, one);
138 Z = MatrixFactory2::BuildCopy(R);
139 Z->leftScale(*invDiag);
143 beta = newRZ / oldRZ;
146#ifndef TWO_ARG_MATRIX_ADD
147 newP = Teuchos::null;
148 MatrixMatrix::TwoMatrixAdd(*P,
false, beta, *Z,
false, one, newP, mmfancy);
149 newP->fillComplete(P0.getDomainMap(), P0.getRangeMap());
152 MatrixMatrix::TwoMatrixAdd(*Z,
false, one, *P, beta);
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.