37 const size_t NSDim = Bc->getNumVectors();
41 size_t numRows = Ppattern_->getLocalNumRows();
42 XXtInv_.resize(numRows);
44 RCP<const Import> importer = Ppattern_->getImporter();
46 X_ = MultiVectorFactory::Build(Ppattern_->getColMap(), NSDim);
47 if (!importer.is_null())
48 X_->doImport(*Bc, *importer, Xpetra::INSERT);
52 std::vector<const SC*> Xval(NSDim);
53 for (
size_t j = 0; j < NSDim; j++)
54 Xval[j] = X_->getData(j).get();
56 SC zero = Teuchos::ScalarTraits<SC>::zero();
57 SC one = Teuchos::ScalarTraits<SC>::one();
59 Teuchos::BLAS<LO, SC> blas;
60 Teuchos::LAPACK<LO, SC> lapack;
62 ArrayRCP<LO> IPIV(NSDim);
63 ArrayRCP<SC> WORK(lwork);
65 for (
size_t i = 0; i < numRows; i++) {
66 Teuchos::ArrayView<const LO> indices;
67 Ppattern_->getLocalRowView(i, indices);
69 size_t nnz = indices.size();
71 XXtInv_[i] = Teuchos::SerialDenseMatrix<LO, SC>(NSDim, NSDim,
false );
72 Teuchos::SerialDenseMatrix<LO, SC>& XXtInv = XXtInv_[i];
76 for (
size_t j = 0; j < nnz; j++)
77 d += Xval[0][indices[j]] * Xval[0][indices[j]];
78 XXtInv(0, 0) = one / d;
81 Teuchos::SerialDenseMatrix<LO, SC> locX(NSDim, nnz,
false );
82 for (
size_t j = 0; j < nnz; j++)
83 for (
size_t k = 0; k < NSDim; k++)
84 locX(k, j) = Xval[k][indices[j]];
87 blas.GEMM(Teuchos::NO_TRANS, Teuchos::CONJ_TRANS, NSDim, NSDim, nnz,
88 one, locX.values(), locX.stride(),
89 locX.values(), locX.stride(),
90 zero, XXtInv.values(), XXtInv.stride());
94 lapack.GETRF(NSDim, NSDim, XXtInv.values(), XXtInv.stride(), IPIV.get(), &info);
96 lapack.GETRI(NSDim, XXtInv.values(), XXtInv.stride(), IPIV.get(), WORK.get(), lwork, &info);
104 const auto one = Teuchos::ScalarTraits<Scalar>::one();
106 auto residual = MultiVectorFactory::Build(B_->getMap(), B_->getNumVectors());
107 P->apply(*Bc_, *residual, Teuchos::NO_TRANS);
108 residual->update(one, *B_, -one);
109 Teuchos::Array<MagnitudeType> norms(B_->getNumVectors());
110 residual->norm2(norms);
111 MagnitudeType residualNorm = Teuchos::ScalarTraits<MagnitudeType>::zero();
112 for (
size_t k = 0; k < B_->getNumVectors(); ++k) {
113 residualNorm += norms[k] * norms[k];
115 return Teuchos::ScalarTraits<MagnitudeType>::squareroot(residualNorm);
123 "Row maps are incompatible");
124 const size_t NSDim = X_->getNumVectors();
125 const size_t numRows = P.getLocalNumRows();
127 const Map& colMap = *P.getColMap();
128 const Map& PColMap = *Projected.getColMap();
130 Projected.resumeFill();
132 Teuchos::ArrayView<const LO> indices, pindices;
133 Teuchos::ArrayView<const SC> values, pvalues;
134 Teuchos::Array<SC> valuesAll(colMap.getLocalNumElements()), newValues;
136 LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
137 LO oneLO = Teuchos::OrdinalTraits<LO>::one();
138 SC zero = Teuchos::ScalarTraits<SC>::zero();
139 SC one = Teuchos::ScalarTraits<SC>::one();
141 std::vector<const SC*> Xval(NSDim);
142 for (
size_t j = 0; j < NSDim; j++)
143 Xval[j] = X_->getData(j).get();
145 for (
size_t i = 0; i < numRows; i++) {
146 P.getLocalRowView(i, indices, values);
147 Projected.getLocalRowView(i, pindices, pvalues);
149 size_t nnz = indices.size();
150 size_t pnnz = pindices.size();
152 newValues.resize(pnnz);
162 for (
size_t j = 0; j < nnz; j++)
163 valuesAll[indices[j]] = values[j];
164 for (
size_t j = 0; j < pnnz; j++) {
165 LO ind = colMap.getLocalElement(PColMap.getGlobalElement(pindices[j]));
168 newValues[j] = valuesAll[ind];
172 for (
size_t j = 0; j < nnz; j++)
173 valuesAll[indices[j]] = zero;
176 Teuchos::SerialDenseMatrix<LO, SC>& XXtInv = XXtInv_[i];
178 Teuchos::SerialDenseMatrix<LO, SC> locX(NSDim, pnnz,
false);
179 for (
size_t j = 0; j < pnnz; j++)
180 for (
size_t k = 0; k < NSDim; k++)
181 locX(k, j) = Xval[k][pindices[j]];
183 Teuchos::SerialDenseVector<LO, SC> val(pnnz,
false), val1(NSDim,
false), val2(NSDim,
false);
184 for (
size_t j = 0; j < pnnz; j++)
185 val[j] = newValues[j];
187 Teuchos::BLAS<LO, SC> blas;
189 blas.GEMV(Teuchos::NO_TRANS, NSDim, pnnz,
190 one, locX.values(), locX.stride(),
192 zero, val1.values(), oneLO);
194 blas.GEMV(Teuchos::NO_TRANS, NSDim, NSDim,
195 one, XXtInv.values(), XXtInv.stride(),
196 val1.values(), oneLO,
197 zero, val2.values(), oneLO);
199 blas.GEMV(Teuchos::CONJ_TRANS, NSDim, pnnz,
200 one, locX.values(), locX.stride(),
201 val2.values(), oneLO,
202 zero, val.values(), oneLO);
204 for (
size_t j = 0; j < pnnz; j++)
205 newValues[j] -= val[j];
207 Projected.replaceLocalValues(i, pindices, newValues);
210 Projected.fillComplete(Projected.getDomainMap(), Projected.getRangeMap());