46 #ifndef MUELU_UTILITIES_KOKKOS_DEF_HPP 47 #define MUELU_UTILITIES_KOKKOS_DEF_HPP 49 #include <Teuchos_DefaultComm.hpp> 50 #include <Teuchos_ParameterList.hpp> 54 #ifdef HAVE_MUELU_EPETRA 56 # include "Epetra_MpiComm.h" 60 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_EPETRAEXT) 67 #include <Xpetra_EpetraUtils.hpp> 68 #include <Xpetra_EpetraMultiVector.hpp> 72 #ifdef HAVE_MUELU_TPETRA 73 #include <MatrixMarket_Tpetra.hpp> 74 #include <Tpetra_RowMatrixTransposer.hpp> 75 #include <TpetraExt_MatrixMatrix.hpp> 76 #include <Xpetra_TpetraMultiVector.hpp> 77 #include <Xpetra_TpetraCrsMatrix.hpp> 78 #include <Xpetra_TpetraBlockCrsMatrix.hpp> 81 #ifdef HAVE_MUELU_EPETRA 82 #include <Xpetra_EpetraMap.hpp> 85 #include <Xpetra_BlockedCrsMatrix.hpp> 86 #include <Xpetra_DefaultPlatform.hpp> 87 #include <Xpetra_Import.hpp> 88 #include <Xpetra_ImportFactory.hpp> 89 #include <Xpetra_Map.hpp> 90 #include <Xpetra_MapFactory.hpp> 91 #include <Xpetra_Matrix.hpp> 92 #include <Xpetra_MatrixMatrix.hpp> 93 #include <Xpetra_MatrixFactory.hpp> 94 #include <Xpetra_MultiVector.hpp> 95 #include <Xpetra_MultiVectorFactory.hpp> 96 #include <Xpetra_Operator.hpp> 97 #include <Xpetra_Vector.hpp> 98 #include <Xpetra_VectorFactory.hpp> 104 #ifdef HAVE_MUELU_EPETRA 105 using Xpetra::EpetraCrsMatrix;
106 using Xpetra::EpetraMultiVector;
109 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
110 Teuchos::ArrayRCP<Scalar> Utils_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetMatrixDiagonal(
const Matrix& A) {
113 size_t numRows = A.getRowMap()->getNodeNumElements();
114 Teuchos::ArrayRCP<SC> diag(numRows);
116 Teuchos::ArrayView<const LO> cols;
117 Teuchos::ArrayView<const SC> vals;
118 for (
size_t i = 0; i < numRows; ++i) {
119 A.getLocalRowView(i, cols, vals);
122 for (; j < cols.size(); ++j) {
123 if (Teuchos::as<size_t>(cols[j]) == i) {
128 if (j == cols.size()) {
130 diag[i] = Teuchos::ScalarTraits<SC>::zero();
137 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
138 Teuchos::RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > Utils_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetMatrixDiagonalInverse(
const Matrix& A, Magnitude tol) {
140 RCP<const Map> rowMap = A.getRowMap();
141 RCP<Vector> diag = VectorFactory::Build(rowMap);
142 ArrayRCP<SC> diagVals = diag->getDataNonConst(0);
144 size_t numRows = rowMap->getNodeNumElements();
146 Teuchos::ArrayView<const LO> cols;
147 Teuchos::ArrayView<const SC> vals;
148 for (
size_t i = 0; i < numRows; ++i) {
149 A.getLocalRowView(i, cols, vals);
152 for (; j < cols.size(); ++j) {
153 if (Teuchos::as<size_t>(cols[j]) == i) {
154 if(Teuchos::ScalarTraits<SC>::magnitude(vals[j]) > tol)
155 diagVals[i] = Teuchos::ScalarTraits<SC>::one() / vals[j];
157 diagVals[i]=Teuchos::ScalarTraits<SC>::zero();
161 if (j == cols.size()) {
163 diagVals[i]=Teuchos::ScalarTraits<SC>::zero();
171 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
172 Teuchos::ArrayRCP<Scalar> Utils_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetLumpedMatrixDiagonal(
const Matrix &A) {
174 size_t numRows = A.getRowMap()->getNodeNumElements();
175 Teuchos::ArrayRCP<SC> diag(numRows);
177 Teuchos::ArrayView<const LO> cols;
178 Teuchos::ArrayView<const SC> vals;
179 for (
size_t i = 0; i < numRows; ++i) {
180 A.getLocalRowView(i, cols, vals);
182 diag[i] = Teuchos::ScalarTraits<Scalar>::zero();
183 for (LO j = 0; j < cols.size(); ++j) {
184 diag[i] += Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]);
191 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
192 RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > Utils_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetMatrixOverlappedDiagonal(
const Matrix& A) {
194 RCP<const Map> rowMap = A.getRowMap(), colMap = A.getColMap();
195 RCP<Vector> localDiag = VectorFactory::Build(rowMap);
198 const CrsMatrixWrap* crsOp =
dynamic_cast<const CrsMatrixWrap*
>(&A);
200 throw Exceptions::RuntimeError(
"cast to CrsMatrixWrap failed");
202 Teuchos::ArrayRCP<size_t> offsets;
203 crsOp->getLocalDiagOffsets(offsets);
204 crsOp->getLocalDiagCopy(*localDiag,offsets());
207 ArrayRCP<SC> localDiagVals = localDiag->getDataNonConst(0);
208 Teuchos::ArrayRCP<SC> diagVals = GetMatrixDiagonal(A);
209 for (LO i = 0; i < localDiagVals.size(); i++)
210 localDiagVals[i] = diagVals[i];
211 localDiagVals = diagVals = null;
214 RCP<Vector> diagonal = VectorFactory::Build(colMap);
215 RCP< const Import> importer;
216 importer = A.getCrsGraph()->getImporter();
217 if (importer == Teuchos::null) {
218 importer = ImportFactory::Build(rowMap, colMap);
220 diagonal->doImport(*localDiag, *(importer), Xpetra::INSERT);
225 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
226 void Utils_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::ScaleMatrix(Matrix& Op,
const Teuchos::ArrayRCP<SC>& scalingVector,
bool doInverse) {
228 #ifdef HAVE_MUELU_TPETRA 230 Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& tpOp = Op2NonConstTpetraCrs(Op);
232 Tpetra::Vector<SC,LO,GO,NO> x(tpOp.getRowMap(), scalingVector());
234 Tpetra::Vector<SC,LO,GO,NO> xi(tpOp.getRowMap());
242 throw Exceptions::RuntimeError(
"Matrix scaling has not been implemented Epetra");
245 throw Exceptions::RuntimeError(
"Matrix scaling has not been implemented Epetra");
246 #endif // HAVE_MUELU_TPETRA 249 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
250 void Utils_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MyOldScaleMatrix(Matrix& Op,
const Teuchos::ArrayRCP<const SC>& scalingVector,
bool doInverse,
252 bool doOptimizeStorage)
254 SC one = Teuchos::ScalarTraits<SC>::one();
255 Teuchos::ArrayRCP<SC> sv(scalingVector.size());
257 for (
int i = 0; i < scalingVector.size(); ++i)
258 sv[i] = one / scalingVector[i];
260 for (
int i = 0; i < scalingVector.size(); ++i)
261 sv[i] = scalingVector[i];
264 switch (Op.getRowMap()->lib()) {
265 case Xpetra::UseTpetra:
266 MyOldScaleMatrix_Tpetra(Op, sv, doFillComplete, doOptimizeStorage);
269 case Xpetra::UseEpetra:
272 throw std::runtime_error(
"FIXME");
276 throw Exceptions::RuntimeError(
"Only Epetra and Tpetra matrices can be scaled.");
281 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
282 void Utils_kokkos<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MyOldScaleMatrix_Tpetra(Matrix& Op,
const Teuchos::ArrayRCP<SC>& scalingVector,
284 bool doOptimizeStorage)
286 #ifdef HAVE_MUELU_TPETRA 288 Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& tpOp = Op2NonConstTpetraCrs(Op);
290 const RCP<const Tpetra::Map<LO,GO,NO> > rowMap = tpOp.getRowMap();
291 const RCP<const Tpetra::Map<LO,GO,NO> > domainMap = tpOp.getDomainMap();
292 const RCP<const Tpetra::Map<LO,GO,NO> > rangeMap = tpOp.getRangeMap();
294 size_t maxRowSize = tpOp.getNodeMaxNumRowEntries();
295 if (maxRowSize == Teuchos::as<size_t>(-1))
298 std::vector<SC> scaledVals(maxRowSize);
299 if (tpOp.isFillComplete())
302 if (Op.isLocallyIndexed() ==
true) {
303 Teuchos::ArrayView<const LO> cols;
304 Teuchos::ArrayView<const SC> vals;
306 for (
size_t i = 0; i < rowMap->getNodeNumElements(); ++i) {
307 tpOp.getLocalRowView(i, cols, vals);
308 size_t nnz = tpOp.getNumEntriesInLocalRow(i);
309 if (nnz > maxRowSize) {
311 scaledVals.resize(maxRowSize);
313 for (
size_t j = 0; j < nnz; ++j)
314 scaledVals[j] = vals[j]*scalingVector[i];
317 Teuchos::ArrayView<const SC> valview(&scaledVals[0], nnz);
318 tpOp.replaceLocalValues(i, cols, valview);
323 Teuchos::ArrayView<const GO> cols;
324 Teuchos::ArrayView<const SC> vals;
326 for (
size_t i = 0; i < rowMap->getNodeNumElements(); ++i) {
327 GO gid = rowMap->getGlobalElement(i);
328 tpOp.getGlobalRowView(gid, cols, vals);
329 size_t nnz = tpOp.getNumEntriesInGlobalRow(gid);
330 if (nnz > maxRowSize) {
332 scaledVals.resize(maxRowSize);
335 for (
size_t j = 0; j < nnz; ++j)
336 scaledVals[j] = vals[j]*scalingVector[i];
339 Teuchos::ArrayView<const SC> valview(&scaledVals[0], nnz);
340 tpOp.replaceGlobalValues(gid, cols, valview);
345 if (doFillComplete) {
346 if (domainMap == Teuchos::null || rangeMap == Teuchos::null)
347 throw Exceptions::RuntimeError(
"In Utils_kokkos::Scaling: cannot fillComplete because the domain and/or range map hasn't been defined");
349 RCP<Teuchos::ParameterList> params = rcp(
new Teuchos::ParameterList());
350 params->set(
"Optimize Storage", doOptimizeStorage);
351 params->set(
"No Nonlocal Changes",
true);
352 Op.fillComplete(Op.getDomainMap(), Op.getRangeMap(), params);
355 throw Exceptions::RuntimeError(
"Only Tpetra::CrsMatrix types can be scaled (Err.1)");
358 throw Exceptions::RuntimeError(
"Matrix scaling is not possible because Tpetra has not been enabled.");
362 template <
class SC,
class LO,
class GO,
class NO>
363 ArrayRCP<const bool> Utils_kokkos<SC, LO, GO, NO>::DetectDirichletRows(
const Matrix& A,
const typename Teuchos::ScalarTraits<SC>::magnitudeType& tol) {
364 LO numRows = A.getNodeNumRows();
366 typedef Teuchos::ScalarTraits<SC> STS;
368 ArrayRCP<bool> boundaryNodes(numRows,
true);
369 for (LO row = 0; row < numRows; row++) {
370 ArrayView<const LO> indices;
371 ArrayView<const SC> vals;
372 A.getLocalRowView(row, indices, vals);
374 size_t nnz = A.getNumEntriesInLocalRow(row);
376 for (
size_t col = 0; col < nnz; col++)
377 if ( (indices[col] != row) && STS::magnitude(vals[col]) > tol) {
378 boundaryNodes[row] =
false;
383 return boundaryNodes;
386 template <
class SC,
class LO,
class GO,
class NO>
387 void Utils_kokkos<SC, LO, GO, NO>::findDirichletRows(Teuchos::RCP<Matrix> A,
388 std::vector<LO>& dirichletRows) {
389 dirichletRows.resize(0);
390 for(
size_t i=0; i<A->getNodeNumRows(); i++) {
391 Teuchos::ArrayView<const LO> indices;
392 Teuchos::ArrayView<const SC> values;
393 A->getLocalRowView(i,indices,values);
395 for (
int j=0; j<indices.size(); j++) {
396 if (
abs(values[j]) > 1.0e-16) {
400 if (nnz == 1 || nnz == 2) {
401 dirichletRows.push_back(i);
406 template<
class SC,
class LO,
class GO,
class NO>
407 void Utils_kokkos<SC, LO, GO, NO>::findDirichletCols(Teuchos::RCP<Matrix> A,
408 std::vector<LO>& dirichletRows,
409 std::vector<LO>& dirichletCols) {
410 Teuchos::RCP<const Map> domMap = A->getDomainMap();
411 Teuchos::RCP<const Map> colMap = A->getColMap();
412 Teuchos::RCP< Xpetra::Export<LO,GO,NO> > exporter
413 = Xpetra::ExportFactory<LO,GO,NO>::Build(colMap,domMap);
414 Teuchos::RCP<MultiVector> myColsToZero = MultiVectorFactory::Build(colMap,1);
415 Teuchos::RCP<MultiVector> globalColsToZero = MultiVectorFactory::Build(domMap,1);
416 myColsToZero->putScalar((SC)0.0);
417 globalColsToZero->putScalar((SC)0.0);
418 for(
size_t i=0; i<dirichletRows.size(); i++) {
419 Teuchos::ArrayView<const LO> indices;
420 Teuchos::ArrayView<const SC> values;
421 A->getLocalRowView(dirichletRows[i],indices,values);
422 for(
int j=0; j<indices.size(); j++)
423 myColsToZero->replaceLocalValue(indices[j],0,(SC)1.0);
425 globalColsToZero->doExport(*myColsToZero,*exporter,Xpetra::ADD);
426 myColsToZero->doImport(*globalColsToZero,*exporter,Xpetra::INSERT);
427 Teuchos::ArrayRCP<const SC> myCols = myColsToZero->getData(0);
428 dirichletCols.resize(colMap->getNodeNumElements());
429 for(
size_t i=0; i<colMap->getNodeNumElements(); i++) {
430 if(
abs(myCols[i])>0.0)
437 template<
class SC,
class LO,
class GO,
class NO>
438 void Utils_kokkos<SC, LO, GO, NO>::Apply_BCsToMatrixRows(Teuchos::RCP<Matrix>& A,
439 std::vector<LO>& dirichletRows) {
440 for(
size_t i=0; i<dirichletRows.size(); i++) {
441 Teuchos::ArrayView<const LO> indices;
442 Teuchos::ArrayView<const SC> values;
443 A->getLocalRowView(dirichletRows[i],indices,values);
445 vec.resize(indices.size());
446 Teuchos::ArrayView<SC> zerovalues(vec);
447 for(
int j=0; j<indices.size(); j++)
448 zerovalues[j]=(SC)1.0e-32;
449 A->replaceLocalValues(dirichletRows[i],indices,zerovalues);
453 template<
class SC,
class LO,
class GO,
class NO>
454 void Utils_kokkos<SC, LO, GO, NO>::Apply_BCsToMatrixCols(Teuchos::RCP<Matrix>& A,
455 std::vector<LO>& dirichletCols) {
456 for(
size_t i=0; i<A->getNodeNumRows(); i++) {
457 Teuchos::ArrayView<const LO> indices;
458 Teuchos::ArrayView<const SC> values;
459 A->getLocalRowView(i,indices,values);
461 vec.resize(indices.size());
462 Teuchos::ArrayView<SC> zerovalues(vec);
463 for(
int j=0; j<indices.size(); j++) {
464 if(dirichletCols[indices[j]]==1)
465 zerovalues[j]=(SC)1.0e-32;
467 zerovalues[j]=values[j];
469 A->replaceLocalValues(i,indices,zerovalues);
473 template<
class SC,
class LO,
class GO,
class NO>
474 void Utils_kokkos<SC, LO, GO, NO>::Remove_Zeroed_Rows(Teuchos::RCP<Matrix>& A,
double tol) {
475 Teuchos::RCP<const Map> rowMap = A->getRowMap();
476 RCP<Matrix> DiagMatrix = MatrixFactory::Build(rowMap,1);
477 RCP<Matrix> NewMatrix = MatrixFactory::Build(rowMap,1);
478 for(
size_t i=0; i<A->getNodeNumRows(); i++) {
479 Teuchos::ArrayView<const LO> indices;
480 Teuchos::ArrayView<const SC> values;
481 A->getLocalRowView(i,indices,values);
483 for (
int j=0; j<indices.size(); j++) {
484 if (
abs(values[j]) > tol) {
490 GO row = rowMap->getGlobalElement(i);
492 DiagMatrix->insertGlobalValues(row,
493 Teuchos::ArrayView<GO>(&row,1),
494 Teuchos::ArrayView<SC>(&one,1));
497 DiagMatrix->insertGlobalValues(row,
498 Teuchos::ArrayView<GO>(&row,1),
499 Teuchos::ArrayView<SC>(&zero,1));
502 DiagMatrix->fillComplete();
505 RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
506 Xpetra::MatrixMatrix<SC,LO,GO,NO>::TwoMatrixAdd(*DiagMatrix,
false,(SC)1.0,*A,
false,(SC)1.0,NewMatrix,*out);
507 NewMatrix->fillComplete();
513 #define MUELU_UTILITIES_KOKKOS_SHORT 514 #endif // MUELU_UTILITIES_KOKKOS_DEF_HPP
Namespace for MueLu classes and methods.
KOKKOS_INLINE_FUNCTION RealType abs(const complex< RealType > &x)