46 #ifndef MUELU_CONSTRAINT_DEF_HPP 47 #define MUELU_CONSTRAINT_DEF_HPP 49 #include <Teuchos_BLAS.hpp> 50 #include <Teuchos_LAPACK.hpp> 51 #include <Teuchos_SerialDenseVector.hpp> 52 #include <Teuchos_SerialDenseMatrix.hpp> 53 #include <Teuchos_SerialDenseHelpers.hpp> 55 #include <Xpetra_Import_fwd.hpp> 56 #include <Xpetra_ImportFactory.hpp> 57 #include <Xpetra_Map.hpp> 58 #include <Xpetra_Matrix.hpp> 59 #include <Xpetra_MultiVectorFactory.hpp> 60 #include <Xpetra_MultiVector.hpp> 61 #include <Xpetra_CrsGraph.hpp> 64 #include "MueLu_Utilities.hpp" 68 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
70 const size_t NSDim = Bc.getNumVectors();
74 size_t numRows = Ppattern_->getNodeNumRows();
75 XXtInv_.resize(numRows);
77 RCP<const Import> importer = Ppattern_->getImporter();
79 X_ = MultiVectorFactory::Build(Ppattern_->getColMap(), NSDim);
80 if (!importer.is_null())
81 X_->doImport(Bc, *importer, Xpetra::INSERT);
85 std::vector<const SC*> Xval(NSDim);
86 for (
size_t j = 0; j < NSDim; j++)
87 Xval[j] = X_->getData(j).get();
89 SC zero = Teuchos::ScalarTraits<SC>::zero();
90 SC one = Teuchos::ScalarTraits<SC>::one();
92 Teuchos::BLAS <LO,SC> blas;
93 Teuchos::LAPACK<LO,SC> lapack;
95 ArrayRCP<LO> IPIV(NSDim);
96 ArrayRCP<SC> WORK(lwork);
98 for (
size_t i = 0; i < numRows; i++) {
99 Teuchos::ArrayView<const LO> indices;
100 Ppattern_->getLocalRowView(i, indices);
102 size_t nnz = indices.size();
104 XXtInv_[i] = Teuchos::SerialDenseMatrix<LO,SC>(NSDim, NSDim,
false);
105 Teuchos::SerialDenseMatrix<LO,SC>& XXtInv = XXtInv_[i];
109 for (
size_t j = 0; j < nnz; j++)
110 d += Xval[0][indices[j]] * Xval[0][indices[j]];
114 Teuchos::SerialDenseMatrix<LO,SC> locX(NSDim, nnz,
false);
115 for (
size_t j = 0; j < nnz; j++)
116 for (
size_t k = 0; k < NSDim; k++)
117 locX(k,j) = Xval[k][indices[j]];
120 blas.GEMM(Teuchos::NO_TRANS, Teuchos::CONJ_TRANS, NSDim, NSDim, nnz,
121 one, locX.values(), locX.stride(),
122 locX.values(), locX.stride(),
123 zero, XXtInv.values(), XXtInv.stride());
127 lapack.GETRF(NSDim, NSDim, XXtInv.values(), XXtInv.stride(), IPIV.get(), &info);
129 lapack.GETRI(NSDim, XXtInv.values(), XXtInv.stride(), IPIV.get(), WORK.get(), lwork, &info);
135 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
139 "Row maps are incompatible");
140 const size_t NSDim = X_->getNumVectors();
141 const size_t numRows = P.getNodeNumRows();
143 const Map& colMap = *P.getColMap();
144 const Map& PColMap = *Projected.getColMap();
146 Projected.resumeFill();
148 Teuchos::ArrayView<const LO> indices, pindices;
149 Teuchos::ArrayView<const SC> values, pvalues;
150 Teuchos::Array<SC> valuesAll(colMap.getNodeNumElements()), newValues;
152 LO invalid = Teuchos::OrdinalTraits<LO>::invalid();
153 LO oneLO = Teuchos::OrdinalTraits<LO>::one();
154 SC zero = Teuchos::ScalarTraits<SC> ::zero();
155 SC one = Teuchos::ScalarTraits<SC> ::one();
157 std::vector<const SC*> Xval(NSDim);
158 for (
size_t j = 0; j < NSDim; j++)
159 Xval[j] = X_->getData(j).get();
161 for (
size_t i = 0; i < numRows; i++) {
162 P .getLocalRowView(i, indices, values);
163 Projected.getLocalRowView(i, pindices, pvalues);
165 size_t nnz = indices.size();
166 size_t pnnz = pindices.size();
168 newValues.resize(pnnz);
178 for (
size_t j = 0; j < nnz; j++)
179 valuesAll[indices[j]] = values[j];
180 for (
size_t j = 0; j < pnnz; j++) {
181 LO ind = colMap.getLocalElement(PColMap.getGlobalElement(pindices[j]));
184 newValues[j] = valuesAll[ind];
188 for (
size_t j = 0; j < nnz; j++)
189 valuesAll[indices[j]] = zero;
192 Teuchos::SerialDenseMatrix<LO,SC>& XXtInv = XXtInv_[i];
194 Teuchos::SerialDenseMatrix<LO,SC> locX(NSDim, pnnz,
false);
195 for (
size_t j = 0; j < pnnz; j++)
196 for (
size_t k = 0; k < NSDim; k++)
197 locX(k,j) = Xval[k][pindices[j]];
199 Teuchos::SerialDenseVector<LO,SC> val(pnnz,
false), val1(NSDim,
false), val2(NSDim,
false);
200 for (
size_t j = 0; j < pnnz; j++)
201 val[j] = newValues[j];
203 Teuchos::BLAS<LO,SC> blas;
205 blas.GEMV(Teuchos::NO_TRANS, NSDim, pnnz,
206 one, locX.values(), locX.stride(),
208 zero, val1.values(), oneLO);
210 blas.GEMV(Teuchos::NO_TRANS, NSDim, NSDim,
211 one, XXtInv.values(), XXtInv.stride(),
212 val1.values(), oneLO,
213 zero, val2.values(), oneLO);
215 blas.GEMV(Teuchos::CONJ_TRANS, NSDim, pnnz,
216 one, locX.values(), locX.stride(),
217 val2.values(), oneLO,
218 zero, val.values(), oneLO);
220 for (
size_t j = 0; j < pnnz; j++)
221 newValues[j] -= val[j];
223 Projected.replaceLocalValues(i, pindices, newValues);
226 Projected.fillComplete(Projected.getDomainMap(), Projected.getRangeMap());
231 #endif //ifndef MUELU_CONSTRAINT_DEF_HPP void Setup(const MultiVector &B, const MultiVector &Bc, RCP< const CrsGraph > Ppattern)
Namespace for MueLu classes and methods.
Exception throws to report incompatible objects (like maps).
void Apply(const Matrix &P, Matrix &Projected) const
Apply constraint.