10#ifndef XPETRA_BLOCKEDCRSMATRIX_DEF_HPP
11#define XPETRA_BLOCKEDCRSMATRIX_DEF_HPP
13#include <Tpetra_KokkosCompat_DefaultNode.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"
55template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
58 size_t numEntriesPerRow)
60 domainmaps_ = MapExtractorFactory::Build(domainMaps);
61 rangemaps_ = MapExtractorFactory::Build(rangeMaps);
68 for (
size_t r = 0; r <
Rows(); ++r)
69 for (
size_t c = 0; c <
Cols(); ++c)
76template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
78 Teuchos::RCP<
const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& domainMapExtractor,
79 size_t numEntriesPerRow)
89 for (
size_t r = 0; r <
Rows(); ++r)
90 for (
size_t c = 0; c <
Cols(); ++c)
97#ifdef HAVE_XPETRA_THYRA
98template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
101 , thyraOp_(thyraOp) {
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)) {
117 Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(const_op);
118 subRangeMaps[r] = xop->getRangeMap();
119 if (r != c) is_diagonal_ =
false;
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;
134 rangemaps_ =
Teuchos::rcp(
new Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node>(fullRangeMap, subRangeMaps, bRangeUseThyraStyleNumbering));
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 =
144 Xpetra::ThyraUtils<Scalar, LO, GO, Node>::toXpetra(const_op);
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;
158 domainmaps_ =
Teuchos::rcp(
new Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node>(fullDomainMap, subDomainMaps, bDomainUseThyraStyleNumbering));
166 for (
size_t r = 0; r <
Rows(); ++r) {
167 for (
size_t c = 0; c <
Cols(); ++c) {
168 if (thyraOp->blockExists(r, c)) {
173 Xpetra::ThyraUtils<Scalar, LO, GO, Node>::toXpetra(op);
175 Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<Scalar, LO, GO, Node>>(xop,
true);
179 blocks_.push_back(MatrixFactory::Build(getRangeMap(r, bRangeThyraMode_), 0));
187template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
192 std::vector<GlobalOrdinal> gids;
193 for (
size_t tt = 0; tt < subMaps.size(); ++tt) {
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);
212 std::sort(gids.begin(), gids.end());
213 gids.erase(std::unique(gids.begin(), gids.end()), gids.end());
221template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
222BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::~BlockedCrsMatrix() =
default;
224template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
228 getMatrix(0, 0)->insertGlobalValues(globalRow, cols, vals);
234template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
238 getMatrix(0, 0)->insertLocalValues(localRow, cols, vals);
244template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
248 getMatrix(0, 0)->removeEmptyProcessesInPlace(newMap);
254template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
260 getMatrix(0, 0)->replaceGlobalValues(globalRow, cols, vals);
266template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
272 getMatrix(0, 0)->replaceLocalValues(localRow, cols, vals);
279template <
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++) {
285 getMatrix(row, col)->setAllToScalar(alpha);
292template <
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++) {
304template <
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++) {
316template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
320 getMatrix(0, 0)->fillComplete(domainMap, rangeMap, params);
326template <
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) {
336 if (Ablock != Teuchos::null && !Ablock->isFillComplete())
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) {
356 if (Ablock != Teuchos::null) {
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());
382template <
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++)
390 globalNumRows +=
getMatrix(row, col)->getGlobalNumRows();
394 return globalNumRows;
397template <
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++)
405 globalNumCols +=
getMatrix(row, col)->getGlobalNumCols();
409 return globalNumCols;
412template <
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++)
427template <
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)
435 globalNumEntries +=
getMatrix(row, col)->getGlobalNumEntries();
437 return globalNumEntries;
440template <
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)
448 nodeNumEntries +=
getMatrix(row, col)->getLocalNumEntries();
450 return nodeNumEntries;
453template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
455 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNumEntriesInLocalRow");
456 GlobalOrdinal gid = this->
getRowMap()->getGlobalElement(localRow);
459 size_t numEntriesInLocalRow = 0;
460 for (
size_t col = 0; col <
Cols(); ++col)
462 numEntriesInLocalRow +=
getMatrix(row, col)->getNumEntriesInLocalRow(lid);
463 return numEntriesInLocalRow;
466template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
470 size_t numEntriesInGlobalRow = 0;
471 for (
size_t col = 0; col <
Cols(); ++col)
473 numEntriesInGlobalRow +=
getMatrix(row, col)->getNumEntriesInGlobalRow(globalRow);
474 return numEntriesInGlobalRow;
477template <
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++) {
486 globalMaxEntriesBlockRows +=
getMatrix(row, col)->getGlobalMaxNumRowEntries();
489 if (globalMaxEntriesBlockRows > globalMaxEntries)
490 globalMaxEntries = globalMaxEntriesBlockRows;
492 return globalMaxEntries;
495template <
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++) {
504 localMaxEntriesBlockRows +=
getMatrix(row, col)->getLocalMaxNumRowEntries();
507 if (localMaxEntriesBlockRows > localMaxEntries)
508 localMaxEntries = localMaxEntriesBlockRows;
510 return localMaxEntries;
513template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
516 for (
size_t i = 0; i <
blocks_.size(); ++i)
522template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
531template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
534 for (
size_t i = 0; i <
blocks_.size(); i++)
540template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
544 size_t& NumEntries)
const {
547 getMatrix(0, 0)->getLocalRowCopy(LocalRow, Indices, Values, NumEntries);
553template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
557 getMatrix(0, 0)->getGlobalRowView(GlobalRow, indices, values);
563template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
567 getMatrix(0, 0)->getLocalRowView(LocalRow, indices, values);
569 }
else if (is_diagonal_) {
570 GlobalOrdinal gid = this->getRowMap()->getGlobalElement(LocalRow);
578template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
592 rm->getLocalDiagCopy(diag);
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++) {
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());
613template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
626 for (
size_t col = 0; col <
Cols(); ++col) {
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++) {
642 for (
size_t col = 0; col <
Cols(); ++col) {
645 rm->leftScale(*rscale);
651template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
664 for (
size_t row = 0; row <
Rows(); ++row) {
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) {
680 for (
size_t row = 0; row <
Rows(); row++) {
683 rm->rightScale(*rscale);
689template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
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) {
704template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
707template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
712template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
721 "apply() only supports the following modes: NO_TRANS and TRANS.");
730 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
741 for (
size_t row = 0; row <
Rows(); row++) {
743 for (
size_t col = 0; col <
Cols(); col++) {
752 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Ablock) == Teuchos::null ? false :
true;
766 Ablock->apply(*Xblock, *tmpYblock);
768 Yblock->update(one, *tmpYblock, one);
775 for (
size_t col = 0; col <
Cols(); col++) {
778 for (
size_t row = 0; row <
Rows(); row++) {
786 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Ablock) == Teuchos::null ? false :
true;
798 Yblock->update(one, *tmpYblock, one);
803 Y.
update(alpha, *tmpY, beta);
806template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
812template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
818template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
824template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
830template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
832 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getDomainMap(size_t,bool)");
836template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
842template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
848template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
854template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
860template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
862 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getRangeMap(size_t,bool)");
866template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
872template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
874 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getDomainMapExtractor()");
878template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
891 "apply() only supports the following modes: NO_TRANS and TRANS.");
899 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
909 for (
size_t col = 0; col <
Cols(); col++) {
918 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Ablock) == Teuchos::null ? false :
true;
932 Ablock->apply(*Xblock, *tmpYblock);
934 Yblock->update(one, *tmpYblock, one);
940 Y.
update(alpha, *tmpY, beta);
943template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
952template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
956 getMatrix(0, 0)->doImport(source, importer, CM);
962template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
966 getMatrix(0, 0)->doExport(dest, importer, CM);
972template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
976 getMatrix(0, 0)->doImport(source, exporter, CM);
983template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
987 getMatrix(0, 0)->doExport(dest, exporter, CM);
993template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
996template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
998 out <<
"Xpetra::BlockedCrsMatrix: " <<
Rows() <<
" x " <<
Cols() << std::endl;
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) {
1020 out <<
"Block(" << r <<
"," << c <<
")" << std::endl;
1021 getMatrix(r, c)->describe(out, verbLevel);
1023 out <<
"Block(" << r <<
"," << c <<
") = null" << std::endl;
1027template <
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) {
1033 std::ostringstream oss;
1034 oss << objectLabel <<
"(" << r <<
"," << c <<
")";
1035 getMatrix(r, c)->setObjectLabel(oss.str());
1040template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1048template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1057template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1060template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1066template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1072template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1080 if (bmat == Teuchos::null)
return mat;
1081 return bmat->getCrsMatrix();
1084template <
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)
1098 if (bmat == Teuchos::null)
return mm;
1099 return bmat->getInnermostCrsMatrix();
1102template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1115template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1127template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1131 using Teuchos::rcp_dynamic_cast;
1135 "BlockedCrsMatrix::Merge: only implemented for Xpetra-style or Thyra-style numbering. No mixup allowed!");
1138 "BlockedCrsMatrix::Merge: BlockMatrix must be fill-completed.");
1142 for (LocalOrdinal lclRow = 0; lclRow < lclNumRows; ++lclRow)
1149 for (
size_t i = 0; i <
Rows(); i++) {
1150 for (
size_t j = 0; j <
Cols(); j++) {
1156 if (bMat != Teuchos::null) mat = bMat->Merge();
1158 bMat = Teuchos::rcp_dynamic_cast<const BlockedCrsMatrix>(mat);
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++) {
1177 if (bMat != Teuchos::null) mat = bMat->Merge();
1179 bMat = Teuchos::rcp_dynamic_cast<const BlockedCrsMatrix>(mat);
1181 "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!");
1205 if (mat->getLocalNumEntries() == 0)
continue;
1207 size_t maxNumEntries = mat->getLocalMaxNumRowEntries();
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));
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.");
1246template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1249 return getMatrix(0, 0)->getLocalMatrixDevice();
1254template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1257 return getMatrix(0, 0)->getLocalMatrixHost();
1262#ifdef HAVE_XPETRA_THYRA
1263template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1266 Xpetra::ThyraUtils<Scalar, LO, GO, Node>::toThyra(Teuchos::rcpFromRef(*
this));
1270 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<Scalar>>(thOp);
1276template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1279template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1284 R.
update(STS::one(), B, STS::zero());
1288template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1292 "Matrix A is not completed");
1301 if (scalarA == zero)
1307 "BlockedCrsMatrix::Add: matrix A must be of type CrsMatrixWrap.");
1310 size_t maxNumEntries = crsA->getLocalMaxNumRowEntries();
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)
1332template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1346#define XPETRA_BLOCKEDCRSMATRIX_SHORT
#define XPETRA_MONITOR(funcName)
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< const MapExtractor > domainmaps_
full domain map together with all partial domain maps
virtual size_t Cols() const
number of column blocks
bool isLocallyIndexed() const
Teuchos::RCP< const MapExtractor > rangemaps_
full range map together with all partial domain maps
const RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
BlockedCrsMatrix(const Teuchos::RCP< const BlockedMap > &rangeMaps, const Teuchos::RCP< const BlockedMap > &domainMaps, size_t numEntriesPerRow)
Constructor.
void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > ¶ms=null)
Signal that data entry is complete.
bool bDomainThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
size_t getLocalNumEntries() const
Returns the local number of entries in this matrix.
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
std::vector< Teuchos::RCP< Matrix > > blocks_
row major matrix block storage
bool isFillComplete() const
const RCP< const Map > getDomainMap() const
bool is_diagonal_
If we're diagonal, a bunch of the extraction stuff should work.
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.
bool bRangeThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
virtual size_t Rows() const
number of row blocks
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.
RCP< const BlockedMap > getBlockedRangeMap() const
Returns the BlockedMap associated with the range of this operator.
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...
RCP< const Map > getFullDomainMap() const
Returns the Map associated with the full domain of this operator.
RCP< const Map > getFullRangeMap() const
Returns the Map associated with the full range of this operator.
bool isGloballyIndexed() const
RCP< const MapExtractor > getDomainMapExtractor() const
Returns map extractor for domain map.
global_size_t getGlobalNumEntries() const
Returns the global number of entries in this matrix.
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...
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
Exception indicating invalid cast attempted.
Exception throws to report incompatible objects (like maps).
Exception throws when you call an unimplemented method of Xpetra.
Exception throws to report errors in the internal logical of the program.
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.
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 CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
viewLabel_t currentViewLabel_
virtual const RCP< const Map > & getRowMap() const
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode.
const viewLabel_t & GetDefaultViewLabel() const
viewLabel_t defaultViewLabel_
virtual void scale(const Scalar &alpha)=0
Scale the current values of a matrix, this = alpha*this.
virtual void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)=0
Insert matrix entries, using global IDs.
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.
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
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.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
bool is_null(const std::shared_ptr< T > &p)
basic_FancyOStream< char > FancyOStream
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
size_t global_size_t
Global size_t object.
CombineMode
Xpetra::Combine Mode enumerable type.
static magnitudeType magnitude(T a)