10 #ifndef XPETRA_BLOCKEDCRSMATRIX_DEF_HPP
11 #define XPETRA_BLOCKEDCRSMATRIX_DEF_HPP
13 #include <Tpetra_KokkosCompat_DefaultNode.hpp>
15 #include <Teuchos_SerialDenseMatrix.hpp>
16 #include <Teuchos_Hashtable.hpp>
22 #include "Xpetra_MapFactory.hpp"
23 #include "Xpetra_MultiVector.hpp"
24 #include "Xpetra_BlockedMultiVector.hpp"
25 #include "Xpetra_MultiVectorFactory.hpp"
26 #include "Xpetra_BlockedVector.hpp"
31 #include "Xpetra_MapExtractor.hpp"
34 #include "Xpetra_Matrix.hpp"
35 #include "Xpetra_MatrixFactory.hpp"
36 #include "Xpetra_CrsMatrixWrap.hpp"
38 #ifdef HAVE_XPETRA_THYRA
39 #include <Thyra_ProductVectorSpaceBase.hpp>
40 #include <Thyra_VectorSpaceBase.hpp>
41 #include <Thyra_LinearOpBase.hpp>
42 #include <Thyra_BlockedLinearOpBase.hpp>
43 #include <Thyra_PhysicallyBlockedLinearOpBase.hpp>
44 #include "Xpetra_ThyraUtils.hpp"
47 #include "Xpetra_VectorFactory.hpp"
55 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
57 const Teuchos::RCP<const BlockedMap>& domainMaps,
58 size_t numEntriesPerRow)
59 : is_diagonal_(true) {
68 for (
size_t r = 0; r <
Rows(); ++r)
69 for (
size_t c = 0; c <
Cols(); ++c)
76 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
78 Teuchos::RCP<const MapExtractor>& domainMapExtractor,
79 size_t numEntriesPerRow)
81 , domainmaps_(domainMapExtractor)
82 , rangemaps_(rangeMapExtractor) {
89 for (
size_t r = 0; r <
Rows(); ++r)
90 for (
size_t c = 0; c <
Cols(); ++c)
97 #ifdef HAVE_XPETRA_THYRA
98 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
101 , thyraOp_(thyraOp) {
103 const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar>> productRangeSpace = thyraOp->productRange();
104 const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar>> productDomainSpace = thyraOp->productDomain();
106 int numRangeBlocks = productRangeSpace->numBlocks();
107 int numDomainBlocks = productDomainSpace->numBlocks();
110 std::vector<Teuchos::RCP<const Map>> subRangeMaps(numRangeBlocks);
111 for (
size_t r = 0; r < Teuchos::as<size_t>(numRangeBlocks); ++r) {
112 for (
size_t c = 0; c < Teuchos::as<size_t>(numDomainBlocks); ++c) {
113 if (thyraOp->blockExists(r, c)) {
115 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> const_op = thyraOp->getBlock(r, c);
116 Teuchos::RCP<const Xpetra::Matrix<Scalar, LO, GO, Node>> xop =
118 subRangeMaps[r] = xop->getRangeMap();
124 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> fullRangeMap = mergeMaps(subRangeMaps);
128 bool bRangeUseThyraStyleNumbering =
false;
129 size_t numAllElements = 0;
130 for (
size_t v = 0; v < subRangeMaps.size(); ++v) {
131 numAllElements += subRangeMaps[v]->getGlobalNumElements();
133 if (fullRangeMap->getGlobalNumElements() != numAllElements) bRangeUseThyraStyleNumbering =
true;
137 std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>> subDomainMaps(numDomainBlocks);
138 for (
size_t c = 0; c < Teuchos::as<size_t>(numDomainBlocks); ++c) {
139 for (
size_t r = 0; r < Teuchos::as<size_t>(numRangeBlocks); ++r) {
140 if (thyraOp->blockExists(r, c)) {
142 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> const_op = thyraOp->getBlock(r, c);
143 Teuchos::RCP<const Xpetra::Matrix<Scalar, LO, GO, Node>> xop =
145 subDomainMaps[c] = xop->getDomainMap();
150 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> fullDomainMap = mergeMaps(subDomainMaps);
152 bool bDomainUseThyraStyleNumbering =
false;
154 for (
size_t v = 0; v < subDomainMaps.size(); ++v) {
155 numAllElements += subDomainMaps[v]->getGlobalNumElements();
157 if (fullDomainMap->getGlobalNumElements() != numAllElements) bDomainUseThyraStyleNumbering =
true;
166 for (
size_t r = 0; r <
Rows(); ++r) {
167 for (
size_t c = 0; c <
Cols(); ++c) {
168 if (thyraOp->blockExists(r, c)) {
170 Teuchos::RCP<const Thyra::LinearOpBase<Scalar>> const_op = thyraOp->getBlock(r, c);
171 Teuchos::RCP<Thyra::LinearOpBase<Scalar>> op = Teuchos::rcp_const_cast<Thyra::LinearOpBase<Scalar>>(const_op);
172 Teuchos::RCP<Xpetra::Matrix<Scalar, LO, GO, Node>> xop =
174 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar, LO, GO, Node>> xwrap =
187 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
188 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::mergeMaps(std::vector<Teuchos::RCP<
const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>>>& subMaps) {
192 std::vector<GlobalOrdinal> gids;
193 for (
size_t tt = 0; tt < subMaps.size(); ++tt) {
194 Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> subMap = subMaps[tt];
196 Teuchos::ArrayView<const GlobalOrdinal> subMapGids = subMap->getLocalElementList();
197 gids.insert(gids.end(), subMapGids.begin(), subMapGids.end());
199 size_t myNumElements = subMap->getLocalNumElements();
200 for (LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l) {
201 GlobalOrdinal gid = subMap->getGlobalElement(l);
211 const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
212 std::sort(gids.begin(), gids.end());
213 gids.erase(std::unique(gids.begin(), gids.end()), gids.end());
214 Teuchos::ArrayView<GO> gidsView(&gids[0], gids.size());
221 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
224 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
227 if (Rows() == 1 && Cols() == 1) {
228 getMatrix(0, 0)->insertGlobalValues(globalRow, cols, vals);
234 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
237 if (Rows() == 1 && Cols() == 1) {
238 getMatrix(0, 0)->insertLocalValues(localRow, cols, vals);
244 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
246 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::removeEmptyProcessesInPlace");
247 if (Rows() == 1 && Cols() == 1) {
248 getMatrix(0, 0)->removeEmptyProcessesInPlace(newMap);
254 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
256 const ArrayView<const GlobalOrdinal>& cols,
257 const ArrayView<const Scalar>& vals) {
259 if (Rows() == 1 && Cols() == 1) {
260 getMatrix(0, 0)->replaceGlobalValues(globalRow, cols, vals);
266 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
268 const ArrayView<const LocalOrdinal>& cols,
269 const ArrayView<const Scalar>& vals) {
271 if (Rows() == 1 && Cols() == 1) {
272 getMatrix(0, 0)->replaceLocalValues(localRow, cols, vals);
279 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
282 for (
size_t row = 0; row < Rows(); row++) {
283 for (
size_t col = 0; col < Cols(); col++) {
284 if (!getMatrix(row, col).is_null()) {
285 getMatrix(row, col)->setAllToScalar(alpha);
292 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
295 for (
size_t row = 0; row < Rows(); row++) {
296 for (
size_t col = 0; col < Cols(); col++) {
297 if (!getMatrix(row, col).is_null()) {
298 getMatrix(row, col)->scale(alpha);
304 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
307 for (
size_t row = 0; row < Rows(); row++) {
308 for (
size_t col = 0; col < Cols(); col++) {
309 if (!getMatrix(row, col).is_null()) {
310 getMatrix(row, col)->resumeFill(params);
316 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
319 if (Rows() == 1 && Cols() == 1) {
320 getMatrix(0, 0)->fillComplete(domainMap, rangeMap, params);
323 fillComplete(params);
326 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
331 for (
size_t r = 0; r < Rows(); ++r)
332 for (
size_t c = 0; c < Cols(); ++c) {
333 if (getMatrix(r, c) != Teuchos::null) {
334 Teuchos::RCP<Matrix> Ablock = getMatrix(r, c);
335 if (r != c) is_diagonal_ =
false;
336 if (Ablock != Teuchos::null && !Ablock->isFillComplete())
337 Ablock->fillComplete(getDomainMap(c, bDomainThyraMode_), getRangeMap(r, bRangeThyraMode_), params);
343 RCP<const Map> rangeMap = rangemaps_->getFullMap();
344 fullrowmap_ =
MapFactory::Build(rangeMap()->lib(), rangeMap()->getGlobalNumElements(), rangeMap()->getLocalElementList(), rangeMap()->getIndexBase(), rangeMap()->getComm());
347 fullcolmap_ = Teuchos::null;
349 std::vector<GO> colmapentries;
350 for (
size_t c = 0; c < Cols(); ++c) {
353 for (
size_t r = 0; r < Rows(); ++r) {
354 Teuchos::RCP<CrsMatrix> Ablock = getMatrix(r,c);
356 if (Ablock != Teuchos::null) {
357 Teuchos::ArrayView<const GO> colElements = Ablock->getColMap()->getLocalElementList();
358 Teuchos::RCP<const Map> colmap = Ablock->getColMap();
359 copy(colElements.getRawPtr(), colElements.getRawPtr() + colElements.size(), inserter(colset, colset.begin()));
364 colmapentries.reserve(colmapentries.size() + colset.size());
365 copy(colset.begin(), colset.end(), back_inserter(colmapentries));
366 sort(colmapentries.begin(), colmapentries.end());
367 typename std::vector<GO>::iterator gendLocation;
368 gendLocation = std::unique(colmapentries.begin(), colmapentries.end());
369 colmapentries.erase(gendLocation,colmapentries.end());
373 size_t numGlobalElements = 0;
374 Teuchos::reduceAll(*(rangeMap->getComm()), Teuchos::REDUCE_SUM, colmapentries.size(), Teuchos::outArg(numGlobalElements));
377 const Teuchos::ArrayView<const GO> aView = Teuchos::ArrayView<const GO>(colmapentries);
378 fullcolmap_ =
MapFactory::Build(rangeMap->lib(), numGlobalElements, aView, 0, rangeMap->getComm());
382 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
387 for (
size_t row = 0; row < Rows(); row++)
388 for (
size_t col = 0; col < Cols(); col++)
389 if (!getMatrix(row, col).is_null()) {
390 globalNumRows += getMatrix(row, col)->getGlobalNumRows();
394 return globalNumRows;
397 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
402 for (
size_t col = 0; col < Cols(); col++)
403 for (
size_t row = 0; row < Rows(); row++)
404 if (!getMatrix(row, col).is_null()) {
405 globalNumCols += getMatrix(row, col)->getGlobalNumCols();
409 return globalNumCols;
412 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
417 for (
size_t row = 0; row < Rows(); ++row)
418 for (
size_t col = 0; col < Cols(); col++)
419 if (!getMatrix(row, col).is_null()) {
420 nodeNumRows += getMatrix(row, col)->getLocalNumRows();
427 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
432 for (
size_t row = 0; row < Rows(); ++row)
433 for (
size_t col = 0; col < Cols(); ++col)
434 if (!getMatrix(row, col).is_null())
435 globalNumEntries += getMatrix(row, col)->getGlobalNumEntries();
437 return globalNumEntries;
440 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
445 for (
size_t row = 0; row < Rows(); ++row)
446 for (
size_t col = 0; col < Cols(); ++col)
447 if (!getMatrix(row, col).is_null())
448 nodeNumEntries += getMatrix(row, col)->getLocalNumEntries();
450 return nodeNumEntries;
453 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
455 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNumEntriesInLocalRow");
456 GlobalOrdinal gid = this->getRowMap()->getGlobalElement(localRow);
457 size_t row = getBlockedRangeMap()->getMapIndexForGID(gid);
458 LocalOrdinal lid = getBlockedRangeMap()->getMap(row)->getLocalElement(gid);
459 size_t numEntriesInLocalRow = 0;
460 for (
size_t col = 0; col < Cols(); ++col)
461 if (!getMatrix(row, col).is_null())
462 numEntriesInLocalRow += getMatrix(row, col)->getNumEntriesInLocalRow(lid);
463 return numEntriesInLocalRow;
466 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
468 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNumEntriesInGlobalRow");
469 size_t row = getBlockedRangeMap()->getMapIndexForGID(globalRow);
470 size_t numEntriesInGlobalRow = 0;
471 for (
size_t col = 0; col < Cols(); ++col)
472 if (!getMatrix(row, col).is_null())
473 numEntriesInGlobalRow += getMatrix(row, col)->getNumEntriesInGlobalRow(globalRow);
474 return numEntriesInGlobalRow;
477 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
479 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getGlobalMaxNumRowEntries");
482 for (
size_t row = 0; row < Rows(); row++) {
484 for (
size_t col = 0; col < Cols(); col++) {
485 if (!getMatrix(row, col).is_null()) {
486 globalMaxEntriesBlockRows += getMatrix(row, col)->getGlobalMaxNumRowEntries();
489 if (globalMaxEntriesBlockRows > globalMaxEntries)
490 globalMaxEntries = globalMaxEntriesBlockRows;
492 return globalMaxEntries;
495 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
497 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getLocalMaxNumRowEntries");
498 size_t localMaxEntries = 0;
500 for (
size_t row = 0; row < Rows(); row++) {
501 size_t localMaxEntriesBlockRows = 0;
502 for (
size_t col = 0; col < Cols(); col++) {
503 if (!getMatrix(row, col).is_null()) {
504 localMaxEntriesBlockRows += getMatrix(row, col)->getLocalMaxNumRowEntries();
507 if (localMaxEntriesBlockRows > localMaxEntries)
508 localMaxEntries = localMaxEntriesBlockRows;
510 return localMaxEntries;
513 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
516 for (
size_t i = 0; i < blocks_.size(); ++i)
517 if (blocks_[i] != Teuchos::null && !blocks_[i]->isLocallyIndexed())
522 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
525 for (
size_t i = 0; i < blocks_.size(); i++)
526 if (blocks_[i] != Teuchos::null && !blocks_[i]->isGloballyIndexed())
531 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
534 for (
size_t i = 0; i < blocks_.size(); i++)
535 if (blocks_[i] != Teuchos::null && !blocks_[i]->isFillComplete())
540 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
542 const ArrayView<LocalOrdinal>& Indices,
543 const ArrayView<Scalar>& Values,
544 size_t& NumEntries)
const {
546 if (Rows() == 1 && Cols() == 1) {
547 getMatrix(0, 0)->getLocalRowCopy(LocalRow, Indices, Values, NumEntries);
553 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
556 if (Rows() == 1 && Cols() == 1) {
557 getMatrix(0, 0)->getGlobalRowView(GlobalRow, indices, values);
563 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
566 if (Rows() == 1 && Cols() == 1) {
567 getMatrix(0, 0)->getLocalRowView(LocalRow, indices, values);
569 }
else if (is_diagonal_) {
570 GlobalOrdinal gid = this->getRowMap()->getGlobalElement(LocalRow);
571 size_t row = getBlockedRangeMap()->getMapIndexForGID(gid);
572 getMatrix(row, row)->getLocalRowView(getMatrix(row, row)->getRowMap()->getLocalElement(gid), indices, values);
578 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
584 Teuchos::RCP<Vector> rcpdiag = Teuchos::rcpFromRef(diag);
585 Teuchos::RCP<BlockedVector> bdiag = Teuchos::rcp_dynamic_cast<
BlockedVector>(rcpdiag);
590 if (Rows() == 1 && Cols() == 1 && bdiag.is_null() ==
true) {
591 Teuchos::RCP<const Matrix> rm = getMatrix(0, 0);
592 rm->getLocalDiagCopy(diag);
596 TEUCHOS_TEST_FOR_EXCEPTION(bdiag.is_null() ==
true,
Xpetra::Exceptions::RuntimeError,
"BlockedCrsMatrix::getLocalDiagCopy: diag must be a Blocked(Multi)Vector.");
597 TEUCHOS_TEST_FOR_EXCEPTION(bdiag->getNumVectors() != 1,
Xpetra::Exceptions::RuntimeError,
"BlockedCrsMatrix::getLocalDiagCopy: diag must be a Blocked(Multi)Vector with exactly one vector. However, the number of stored vectors is " << bdiag->getNumVectors());
599 "BlockedCrsMatrix::getLocalDiagCopy(): the number of blocks in diag differ from the number of blocks in this operator.");
603 for (
size_t row = 0; row < Rows(); row++) {
604 Teuchos::RCP<const Matrix> rm = getMatrix(row, row);
606 Teuchos::RCP<Vector> rv =
VectorFactory::Build(bdiag->getBlockedMap()->getMap(row, bdiag->getBlockedMap()->getThyraMode()));
607 rm->getLocalDiagCopy(*rv);
608 bdiag->setMultiVector(row, rv, bdiag->getBlockedMap()->getThyraMode());
613 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
617 Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
618 Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<
const BlockedVector>(rcpx);
625 if (Rows() == 1 && bx.is_null() ==
true) {
626 for (
size_t col = 0; col < Cols(); ++col) {
627 Teuchos::RCP<Matrix> rm = getMatrix(0, col);
634 TEUCHOS_TEST_FOR_EXCEPTION(bx->getNumVectors() != 1,
Xpetra::Exceptions::RuntimeError,
"BlockedCrsMatrix::leftScale: x must be a Blocked(Multi)Vector with exactly one vector. However, the number of stored vectors is " << bx->getNumVectors());
636 "BlockedCrsMatrix::leftScale(): the number of blocks in diag differ from the number of blocks in this operator.");
638 for (
size_t row = 0; row < Rows(); row++) {
639 Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(row);
640 Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
642 for (
size_t col = 0; col < Cols(); ++col) {
643 Teuchos::RCP<Matrix> rm = getMatrix(row, col);
645 rm->leftScale(*rscale);
651 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
655 Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
656 Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<
const BlockedVector>(rcpx);
663 if (Cols() == 1 && bx.is_null() ==
true) {
664 for (
size_t row = 0; row < Rows(); ++row) {
665 Teuchos::RCP<Matrix> rm = getMatrix(row, 0);
672 TEUCHOS_TEST_FOR_EXCEPTION(bx->getNumVectors() != 1,
Xpetra::Exceptions::RuntimeError,
"BlockedCrsMatrix::rightScale: x must be a Blocked(Multi)Vector with exactly one vector. However, the number of stored vectors is " << bx->getNumVectors());
674 "BlockedCrsMatrix::rightScale(): the number of blocks in diag differ from the number of blocks in this operator.");
676 for (
size_t col = 0; col < Cols(); ++col) {
677 Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(col);
678 Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
680 for (
size_t row = 0; row < Rows(); row++) {
681 Teuchos::RCP<Matrix> rm = getMatrix(row, col);
683 rm->rightScale(*rscale);
689 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
692 typename ScalarTraits<Scalar>::magnitudeType ret = Teuchos::ScalarTraits<Scalar>::magnitude(Teuchos::ScalarTraits<Scalar>::zero());
693 for (
size_t col = 0; col < Cols(); ++col) {
694 for (
size_t row = 0; row < Rows(); ++row) {
695 if (getMatrix(row, col) != Teuchos::null) {
696 typename ScalarTraits<Scalar>::magnitudeType n = getMatrix(row, col)->getFrobeniusNorm();
701 return Teuchos::ScalarTraits<typename ScalarTraits<Scalar>::magnitudeType>::squareroot(ret);
704 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
707 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
710 const Teuchos::ArrayRCP<LocalOrdinal>& regionInterfaceLIDs)
const {}
712 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
714 Teuchos::ETransp mode,
721 "apply() only supports the following modes: NO_TRANS and TRANS.");
724 RCP<const MultiVector> refX = rcpFromRef(X);
725 RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(refX);
730 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
738 SC one = ScalarTraits<SC>::one();
740 if (mode == Teuchos::NO_TRANS) {
741 for (
size_t row = 0; row < Rows(); row++) {
742 RCP<MultiVector> Yblock = rangemaps_->getVector(row, Y.
getNumVectors(), bRangeThyraMode_,
true);
743 for (
size_t col = 0; col < Cols(); col++) {
745 RCP<Matrix> Ablock = getMatrix(row, col);
747 if (Ablock.is_null())
752 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
755 RCP<const MultiVector> Xblock = Teuchos::null;
761 Xblock = domainmaps_->ExtractVector(refbX, col, bDomainThyraMode_);
763 Xblock = domainmaps_->ExtractVector(refX, col, bBlockedSubMatrix ==
true ?
false : bDomainThyraMode_);
765 RCP<MultiVector> tmpYblock = rangemaps_->getVector(row, Y.
getNumVectors(), bRangeThyraMode_,
false);
766 Ablock->
apply(*Xblock, *tmpYblock);
768 Yblock->update(one, *tmpYblock, one);
770 rangemaps_->InsertVector(Yblock, row, tmpY, bRangeThyraMode_);
773 }
else if (mode == Teuchos::TRANS) {
775 for (
size_t col = 0; col < Cols(); col++) {
776 RCP<MultiVector> Yblock = domainmaps_->getVector(col, Y.
getNumVectors(), bDomainThyraMode_,
true);
778 for (
size_t row = 0; row < Rows(); row++) {
779 RCP<Matrix> Ablock = getMatrix(row, col);
781 if (Ablock.is_null())
786 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
788 RCP<const MultiVector> Xblock = Teuchos::null;
792 Xblock = rangemaps_->ExtractVector(refbX, row, bRangeThyraMode_);
794 Xblock = rangemaps_->ExtractVector(refX, row, bBlockedSubMatrix ==
true ?
false : bRangeThyraMode_);
795 RCP<MultiVector> tmpYblock = domainmaps_->getVector(col, Y.
getNumVectors(), bDomainThyraMode_,
false);
796 Ablock->
apply(*Xblock, *tmpYblock, Teuchos::TRANS);
798 Yblock->update(one, *tmpYblock, one);
800 domainmaps_->InsertVector(Yblock, col, tmpY, bDomainThyraMode_);
803 Y.
update(alpha, *tmpY, beta);
806 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
809 return domainmaps_->getFullMap();
812 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
815 return domainmaps_->getBlockedMap();
818 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
821 return domainmaps_->getMap();
824 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
827 return domainmaps_->getMap(i, bDomainThyraMode_);
830 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
832 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getDomainMap(size_t,bool)");
833 return domainmaps_->getMap(i, bThyraMode);
836 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
839 return rangemaps_->getFullMap();
842 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
845 return rangemaps_->getBlockedMap();
848 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
851 return rangemaps_->getMap();
854 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
857 return rangemaps_->getMap(i, bRangeThyraMode_);
860 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
862 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getRangeMap(size_t,bool)");
863 return rangemaps_->getMap(i, bThyraMode);
866 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
872 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
874 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getDomainMapExtractor()");
878 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
883 Teuchos::ETransp mode,
891 "apply() only supports the following modes: NO_TRANS and TRANS.");
894 RCP<const MultiVector> refX = rcpFromRef(X);
895 RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(refX);
899 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
905 SC one = ScalarTraits<SC>::one();
907 if (mode == Teuchos::NO_TRANS) {
908 RCP<MultiVector> Yblock = rangemaps_->getVector(row, Y.
getNumVectors(), bRangeThyraMode_,
true);
909 for (
size_t col = 0; col < Cols(); col++) {
911 RCP<Matrix> Ablock = getMatrix(row, col);
913 if (Ablock.is_null())
918 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
921 RCP<const MultiVector> Xblock = Teuchos::null;
927 Xblock = domainmaps_->ExtractVector(refbX, col, bDomainThyraMode_);
929 Xblock = domainmaps_->ExtractVector(refX, col, bBlockedSubMatrix ==
true ?
false : bDomainThyraMode_);
931 RCP<MultiVector> tmpYblock = rangemaps_->getVector(row, Y.
getNumVectors(), bRangeThyraMode_,
false);
932 Ablock->
apply(*Xblock, *tmpYblock);
934 Yblock->update(one, *tmpYblock, one);
936 rangemaps_->InsertVector(Yblock, row, tmpY, bRangeThyraMode_);
940 Y.
update(alpha, *tmpY, beta);
943 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
946 if (Rows() == 1 && Cols() == 1) {
947 return getMatrix(0, 0)->getMap();
952 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
955 if (Rows() == 1 && Cols() == 1) {
956 getMatrix(0, 0)->doImport(source, importer, CM);
962 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
965 if (Rows() == 1 && Cols() == 1) {
966 getMatrix(0, 0)->doExport(dest, importer, CM);
972 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
975 if (Rows() == 1 && Cols() == 1) {
976 getMatrix(0, 0)->doImport(source, exporter, CM);
983 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
986 if (Rows() == 1 && Cols() == 1) {
987 getMatrix(0, 0)->doExport(dest, exporter, CM);
993 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
996 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
998 out <<
"Xpetra::BlockedCrsMatrix: " << Rows() <<
" x " << Cols() << std::endl;
1000 if (isFillComplete()) {
1001 out <<
"BlockMatrix is fillComplete" << std::endl;
1014 out <<
"BlockMatrix is NOT fillComplete" << std::endl;
1017 for (
size_t r = 0; r < Rows(); ++r)
1018 for (
size_t c = 0; c < Cols(); ++c) {
1019 if (getMatrix(r, c) != Teuchos::null) {
1020 out <<
"Block(" << r <<
"," << c <<
")" << std::endl;
1021 getMatrix(r, c)->describe(out, verbLevel);
1023 out <<
"Block(" << r <<
"," << c <<
") = null" << std::endl;
1027 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1030 for (
size_t r = 0; r < Rows(); ++r)
1031 for (
size_t c = 0; c < Cols(); ++c) {
1032 if (getMatrix(r, c) != Teuchos::null) {
1033 std::ostringstream oss;
1034 oss << objectLabel <<
"(" << r <<
"," << c <<
")";
1035 getMatrix(r, c)->setObjectLabel(oss.str());
1040 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1042 if (Rows() == 1 && Cols() == 1)
1048 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1051 if (Rows() == 1 && Cols() == 1) {
1052 return getMatrix(0, 0)->getCrsGraph();
1057 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1060 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1063 return rangemaps_->NumMaps();
1066 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1069 return domainmaps_->NumMaps();
1072 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1075 TEUCHOS_TEST_FOR_EXCEPTION(Rows() != 1, std::out_of_range,
"Can only unwrap a 1x1 blocked matrix. The matrix has " << Rows() <<
" block rows, though.");
1076 TEUCHOS_TEST_FOR_EXCEPTION(Cols() != 1, std::out_of_range,
"Can only unwrap a 1x1 blocked matrix. The matrix has " << Cols() <<
" block columns, though.");
1078 RCP<Matrix> mat = getMatrix(0, 0);
1079 RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(mat);
1080 if (bmat == Teuchos::null)
return mat;
1084 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1087 size_t row = Rows() + 1, col = Cols() + 1;
1088 for (
size_t r = 0; r < Rows(); ++r)
1089 for (
size_t c = 0; c < Cols(); ++c)
1090 if (getMatrix(r, c) != Teuchos::null) {
1095 TEUCHOS_TEST_FOR_EXCEPTION(row == Rows() + 1 || col == Cols() + 1,
Xpetra::Exceptions::Incompatible,
"Xpetra::BlockedCrsMatrix::getInnermostCrsMatrix: Could not find a non-zero sub-block in blocked operator.")
1096 RCP<Matrix> mm = getMatrix(row, col);
1097 RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(mm);
1098 if (bmat == Teuchos::null)
return mm;
1102 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1105 TEUCHOS_TEST_FOR_EXCEPTION(r > Rows(), std::out_of_range,
"Error, r = " << Rows() <<
" is too big");
1106 TEUCHOS_TEST_FOR_EXCEPTION(c > Cols(), std::out_of_range,
"Error, c = " << Cols() <<
" is too big");
1112 return blocks_[r * Cols() + c];
1115 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1120 TEUCHOS_TEST_FOR_EXCEPTION(r > Rows(), std::out_of_range,
"Error, r = " << Rows() <<
" is too big");
1121 TEUCHOS_TEST_FOR_EXCEPTION(c > Cols(), std::out_of_range,
"Error, c = " << Cols() <<
" is too big");
1122 if (!mat.is_null() && r != c) is_diagonal_ =
false;
1124 blocks_[r * Cols() + c] = mat;
1127 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1131 using Teuchos::rcp_dynamic_cast;
1132 Scalar one = ScalarTraits<SC>::one();
1135 "BlockedCrsMatrix::Merge: only implemented for Xpetra-style or Thyra-style numbering. No mixup allowed!");
1138 "BlockedCrsMatrix::Merge: BlockMatrix must be fill-completed.");
1140 LocalOrdinal lclNumRows = getFullRangeMap()->getLocalNumElements();
1141 Teuchos::ArrayRCP<size_t> numEntPerRow(lclNumRows);
1142 for (LocalOrdinal lclRow = 0; lclRow < lclNumRows; ++lclRow)
1143 numEntPerRow[lclRow] = getNumEntriesInLocalRow(lclRow);
1147 if (bRangeThyraMode_ ==
false) {
1149 for (
size_t i = 0; i < Rows(); i++) {
1150 for (
size_t j = 0; j < Cols(); j++) {
1151 if (getMatrix(i, j) != Teuchos::null) {
1152 RCP<const Matrix> mat = getMatrix(i, j);
1155 RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(mat);
1156 if (bMat != Teuchos::null) mat = bMat->
Merge();
1160 "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!");
1163 if (mat->getLocalNumEntries() == 0)
continue;
1165 this->Add(*mat, one, *sparse, one);
1171 for (
size_t i = 0; i < Rows(); i++) {
1172 for (
size_t j = 0; j < Cols(); j++) {
1173 if (getMatrix(i, j) != Teuchos::null) {
1174 RCP<const Matrix> mat = getMatrix(i, j);
1176 RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(mat);
1177 if (bMat != Teuchos::null) mat = bMat->
Merge();
1181 "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!");
1184 RCP<const CrsMatrixWrap> crsMat = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(mat);
1185 TEUCHOS_ASSERT(crsMat != Teuchos::null);
1188 RCP<const Map> trowMap = mat->getRowMap();
1189 RCP<const Map> tcolMap = mat->getColMap();
1190 RCP<const Map> tdomMap = mat->getDomainMap();
1193 RCP<const Map> xrowMap = getRangeMapExtractor()->getMap(i,
false);
1194 RCP<const Map> xdomMap = getDomainMapExtractor()->getMap(j,
false);
1205 if (mat->getLocalNumEntries() == 0)
continue;
1207 size_t maxNumEntries = mat->getLocalMaxNumRowEntries();
1210 Array<GO> inds(maxNumEntries);
1211 Array<GO> inds2(maxNumEntries);
1212 Array<SC> vals(maxNumEntries);
1215 for (
size_t k = 0; k < mat->getLocalNumRows(); k++) {
1216 GlobalOrdinal rowTGID = trowMap->getGlobalElement(k);
1217 crsMat->getCrsMatrix()->getGlobalRowCopy(rowTGID, inds(), vals(), numEntries);
1220 for (
size_t l = 0; l < numEntries; ++l) {
1221 LocalOrdinal lid = tcolMap->getLocalElement(inds[l]);
1222 inds2[l] = xcolMap->getGlobalElement(lid);
1225 GlobalOrdinal rowXGID = xrowMap->getGlobalElement(k);
1226 sparse->insertGlobalValues(
1227 rowXGID, inds2(0, numEntries),
1228 vals(0, numEntries));
1235 sparse->fillComplete(getFullDomainMap(), getFullRangeMap());
1238 "BlockedCrsMatrix::Merge: Local number of entries of merged matrix does not coincide with local number of entries of blocked operator.");
1241 "BlockedCrsMatrix::Merge: Global number of entries of merged matrix does not coincide with global number of entries of blocked operator.");
1246 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1248 if (Rows() == 1 && Cols() == 1) {
1249 return getMatrix(0, 0)->getLocalMatrixDevice();
1254 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1256 if (Rows() == 1 && Cols() == 1) {
1257 return getMatrix(0, 0)->getLocalMatrixHost();
1262 #ifdef HAVE_XPETRA_THYRA
1263 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1265 Teuchos::RCP<Thyra::LinearOpBase<Scalar>> thOp =
1266 Xpetra::ThyraUtils<Scalar, LO, GO, Node>::toThyra(Teuchos::rcpFromRef(*
this));
1267 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thOp));
1269 Teuchos::RCP<Thyra::BlockedLinearOpBase<Scalar>> thbOp =
1270 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<Scalar>>(thOp);
1271 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thbOp));
1276 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1279 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1283 using STS = Teuchos::ScalarTraits<Scalar>;
1284 R.
update(STS::one(), B, STS::zero());
1285 this->apply(X, R, Teuchos::NO_TRANS, -STS::one(), STS::one());
1288 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1292 "Matrix A is not completed");
1293 using Teuchos::Array;
1294 using Teuchos::ArrayView;
1298 Scalar one = ScalarTraits<SC>::one();
1299 Scalar zero = ScalarTraits<SC>::zero();
1301 if (scalarA == zero)
1304 Teuchos::RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
1305 Teuchos::RCP<const CrsMatrixWrap> rcpAwrap = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(rcpA);
1307 "BlockedCrsMatrix::Add: matrix A must be of type CrsMatrixWrap.");
1308 Teuchos::RCP<const CrsMatrix> crsA = rcpAwrap->getCrsMatrix();
1310 size_t maxNumEntries = crsA->getLocalMaxNumRowEntries();
1313 Array<GO> inds(maxNumEntries);
1314 Array<SC> vals(maxNumEntries);
1316 RCP<const Map> rowMap = crsA->getRowMap();
1317 RCP<const Map> colMap = crsA->getColMap();
1319 ArrayView<const GO> rowGIDs = crsA->getRowMap()->getLocalElementList();
1320 for (
size_t i = 0; i < crsA->getLocalNumRows(); i++) {
1321 GO row = rowGIDs[i];
1322 crsA->getGlobalRowCopy(row, inds(), vals(), numEntries);
1325 for (
size_t j = 0; j < numEntries; ++j)
1332 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1337 this->defaultViewLabel_ =
"point";
1338 this->CreateView(this->GetDefaultViewLabel(), getRangeMap(), getDomainMap());
1341 this->currentViewLabel_ = this->GetDefaultViewLabel();
1346 #define XPETRA_BLOCKEDCRSMATRIX_SHORT
size_t getLocalNumRows() const
Returns the number of matrix rows owned on the calling node.
Teuchos::RCP< Matrix > Merge() const
merge BlockedCrsMatrix blocks in a CrsMatrix
local_matrix_type::HostMirror getLocalMatrixHost() const
Access the underlying local Kokkos::CrsMatrix object.
virtual void apply(const MultiVector &X, MultiVector &Y, Teuchos::ETransp mode, Scalar alpha, Scalar beta, bool sumInterfaceValues, const RCP< Xpetra::Import< LocalOrdinal, GlobalOrdinal, Node > > ®ionInterfaceImporter, const Teuchos::ArrayRCP< LocalOrdinal > ®ionInterfaceLIDs) const
sparse matrix-multivector multiplication for the region layout matrices (currently no blocked impleme...
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node >> &map, size_t NumVectors, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
RCP< const MapExtractor > getDomainMapExtractor() const
Returns map extractor for domain map.
bool isFillComplete() const
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
void replaceGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace matrix entries, using global IDs.
void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > ¶ms=null)
Signal that data entry is complete.
LocalOrdinal GetStorageBlockSize() const
Returns the block size of the storage mechanism.
RCP< const Map > getFullDomainMap() const
Returns the Map associated with the full domain of this operator.
Teuchos::RCP< const MapExtractor > rangemaps_
full range map together with all partial domain maps
void doImport(const Matrix &source, const Import &importer, CombineMode CM)
Import.
void getLocalRowView(LocalOrdinal LocalRow, ArrayView< const LocalOrdinal > &indices, ArrayView< const Scalar > &values) const
Extract a const, non-persisting view of local indices in a specified row of the matrix.
static Teuchos::RCP< Xpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node >> &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
Exception throws to report errors in the internal logical of the program.
virtual void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to scalar.
void doExport(const Matrix &dest, const Import &importer, CombineMode CM)
Export.
virtual size_t Cols() const
number of column blocks
size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
void Add(const Matrix &A, const Scalar scalarA, Matrix &B, const Scalar scalarB) const
Add a Xpetra::CrsMatrix to another: B = B*scalarB + A*scalarA.
void resumeFill(const RCP< ParameterList > ¶ms=null)
global_size_t getGlobalNumCols() const
Returns the number of global columns in the matrix.
virtual void update(const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Scalar &beta)=0
Update multi-vector values with scaled values of A, this = beta*this + alpha*A.
const RCP< const Map > getDomainMap() const
Returns the Map associated with the domain of this operator.
void rightScale(const Vector &x)
Right scale matrix using the given vector entries.
size_t getLocalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.
global_size_t getGlobalNumEntries() const
Returns the global number of entries in this matrix.
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
const Teuchos::RCP< const Map > getMap() const
Implements DistObject interface.
Exception indicating invalid cast attempted.
virtual bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using global IDs.
void getLocalDiagCopy(Vector &diag) const
Get a copy of the diagonal entries owned by this node, with local row indices.
virtual void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)=0
Insert matrix entries, using global IDs.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
bool is_diagonal_
If we're diagonal, a bunch of the extraction stuff should work.
RCP< const CrsGraph > getCrsGraph() const
Returns the CrsGraph associated with this matrix.
void leftScale(const Vector &x)
Left scale matrix using the given vector entries.
static Teuchos::RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int >> &comm, LocalGlobal lg=Xpetra::GloballyDistributed)
Map constructor with Xpetra-defined contiguous uniform distribution.
virtual ~BlockedCrsMatrix()
Destructor.
void setObjectLabel(const std::string &objectLabel)
void insertLocalValues(LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using local IDs.
virtual void getLocalRowCopy(LocalOrdinal LocalRow, const ArrayView< LocalOrdinal > &Indices, const ArrayView< Scalar > &Values, size_t &NumEntries) const
Extract a list of entries in a specified local row of the matrix. Put into storage allocated by calli...
virtual void bgs_apply(const MultiVector &X, MultiVector &Y, size_t row, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=ScalarTraits< Scalar >::one(), Scalar beta=ScalarTraits< Scalar >::zero()) const
Special multiplication routine (for BGS/Jacobi smoother)
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream object.
virtual ScalarTraits< Scalar >::magnitudeType getFrobeniusNorm() const
Get Frobenius norm of the matrix.
static Teuchos::RCP< Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > transformThyra2XpetraGIDs(const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &input, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &nonOvlInput, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &nonOvlReferenceInput)
replace set of global ids by new global ids
void scale(const Scalar &alpha)
Scale the current values of a matrix, this = alpha*this.
void residual(const MultiVector &X, const MultiVector &B, MultiVector &R) const
Compute a residual R = B - (*this) * X.
virtual size_t Rows() const
number of row blocks
void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView< const GlobalOrdinal > &indices, ArrayView< const Scalar > &values) const
Extract a const, non-persisting view of global indices in a specified row of the matrix.
const RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
Exception throws when you call an unimplemented method of Xpetra.
bool hasCrsGraph() const
Supports the getCrsGraph() call.
size_t global_size_t
Global size_t object.
std::vector< Teuchos::RCP< Matrix > > blocks_
row major matrix block storage
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.
virtual bool isDiagonal() const
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
BlockedCrsMatrix(const Teuchos::RCP< const BlockedMap > &rangeMaps, const Teuchos::RCP< const BlockedMap > &domainMaps, size_t numEntriesPerRow)
Constructor.
global_size_t getGlobalNumRows() const
Returns the number of global rows.
RCP< const BlockedMap > getBlockedDomainMap() const
Returns the BlockedMap associated with the domain of this operator.
static RCP< Matrix > Build(const RCP< const Map > &rowMap)
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries in the specified (locally owned) global row.
size_t getLocalNumEntries() const
Returns the local number of entries in this matrix.
void setMatrix(size_t r, size_t c, Teuchos::RCP< Matrix > mat)
set matrix block
std::string description() const
Return a simple one-line description of this object.
bool bDomainThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
bool isGloballyIndexed() const
If matrix indices are in the global range, this function returns true. Otherwise, this function retur...
Exception throws to report incompatible objects (like maps).
RCP< const Map > getFullRangeMap() const
Returns the Map associated with the full range of this operator.
Concrete implementation of Xpetra::Matrix.
CombineMode
Xpetra::Combine Mode enumerable type.
local_matrix_type getLocalMatrixDevice() const
Access the underlying local Kokkos::CrsMatrix object.
#define XPETRA_MONITOR(funcName)
virtual void scale(const Scalar &alpha)=0
Scale the current values of a matrix, this = alpha*this.
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
KokkosSparse::CrsMatrix< impl_scalar_type, LocalOrdinal, execution_space, void, typename local_graph_type::size_type > local_matrix_type
The specialization of Kokkos::CrsMatrix that represents the part of the sparse matrix on each MPI pro...
Teuchos::RCP< Matrix > getCrsMatrix() const
return unwrap 1x1 blocked operators
void removeEmptyProcessesInPlace(const Teuchos::RCP< const Map > &newMap)
Teuchos::RCP< Matrix > getInnermostCrsMatrix()
helper routine recursively returns the first inner-most non-null matrix block from a (nested) blocked...
RCP< const BlockedMap > getBlockedRangeMap() const
Returns the BlockedMap associated with the range of this operator.
bool isLocallyIndexed() const
If matrix indices of all matrix blocks are in the local range, this function returns true...
void replaceLocalValues(LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace matrix entries, using local IDs.
Xpetra-specific matrix class.
Teuchos::RCP< const MapExtractor > domainmaps_
full domain map together with all partial domain maps
bool bRangeThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)