46 #ifndef XPETRA_BLOCKEDCRSMATRIX_HPP 47 #define XPETRA_BLOCKEDCRSMATRIX_HPP 51 #include <Teuchos_SerialDenseMatrix.hpp> 52 #include <Teuchos_Hashtable.hpp> 57 #include "Xpetra_MapFactory.hpp" 58 #include "Xpetra_MultiVector.hpp" 59 #include "Xpetra_BlockedMultiVector.hpp" 60 #include "Xpetra_MultiVectorFactory.hpp" 61 #include "Xpetra_BlockedVector.hpp" 66 #include "Xpetra_MapExtractor.hpp" 71 #include "Xpetra_CrsMatrixWrap.hpp" 73 #ifdef HAVE_XPETRA_THYRA 74 #include <Thyra_ProductVectorSpaceBase.hpp> 75 #include <Thyra_VectorSpaceBase.hpp> 76 #include <Thyra_LinearOpBase.hpp> 77 #include <Thyra_BlockedLinearOpBase.hpp> 78 #include <Thyra_PhysicallyBlockedLinearOpBase.hpp> 82 #include "Xpetra_VectorFactory.hpp" 93 template <
class Scalar,
98 public Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
106 #undef XPETRA_BLOCKEDCRSMATRIX_SHORT 121 const Teuchos::RCP<const BlockedMap>& domainMaps,
122 size_t numEntriesPerRow)
133 for (
size_t r = 0; r <
Rows(); ++r)
134 for (
size_t c = 0; c <
Cols(); ++c)
150 Teuchos::RCP<const MapExtractor>& domainMapExtractor,
151 size_t numEntriesPerRow)
160 for (
size_t r = 0; r <
Rows(); ++r)
161 for (
size_t c = 0; c <
Cols(); ++c)
168 #ifdef HAVE_XPETRA_THYRA 175 BlockedCrsMatrix(
const Teuchos::RCP<
const Thyra::BlockedLinearOpBase<Scalar> >& thyraOp,
const Teuchos::RCP<
const Teuchos::Comm<int> >& )
179 const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productRangeSpace = thyraOp->productRange();
180 const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productDomainSpace = thyraOp->productDomain();
182 int numRangeBlocks = productRangeSpace->numBlocks();
183 int numDomainBlocks = productDomainSpace->numBlocks();
186 std::vector<Teuchos::RCP<const Map> > subRangeMaps(numRangeBlocks);
187 for (
size_t r=0; r<Teuchos::as<size_t>(numRangeBlocks); ++r) {
188 for (
size_t c=0; c<Teuchos::as<size_t>(numDomainBlocks); ++c) {
189 if (thyraOp->blockExists(r,c)) {
191 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c);
192 Teuchos::RCP<const Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xop =
194 subRangeMaps[r] = xop->getRangeMap();
200 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > fullRangeMap = mergeMaps(subRangeMaps);
204 bool bRangeUseThyraStyleNumbering =
false;
205 size_t numAllElements = 0;
206 for(
size_t v = 0; v < subRangeMaps.size(); ++v) {
207 numAllElements += subRangeMaps[v]->getGlobalNumElements();
209 if ( fullRangeMap->getGlobalNumElements() != numAllElements) bRangeUseThyraStyleNumbering =
true;
213 std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > > subDomainMaps(numDomainBlocks);
214 for (
size_t c=0; c<Teuchos::as<size_t>(numDomainBlocks); ++c) {
215 for (
size_t r=0; r<Teuchos::as<size_t>(numRangeBlocks); ++r) {
216 if (thyraOp->blockExists(r,c)) {
218 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c);
219 Teuchos::RCP<const Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xop =
221 subDomainMaps[c] = xop->getDomainMap();
226 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > fullDomainMap = mergeMaps(subDomainMaps);
228 bool bDomainUseThyraStyleNumbering =
false;
230 for(
size_t v = 0; v < subDomainMaps.size(); ++v) {
231 numAllElements += subDomainMaps[v]->getGlobalNumElements();
233 if (fullDomainMap->getGlobalNumElements() != numAllElements) bDomainUseThyraStyleNumbering =
true;
242 for (
size_t r = 0; r <
Rows(); ++r) {
243 for (
size_t c = 0; c <
Cols(); ++c) {
244 if(thyraOp->blockExists(r,c)) {
246 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c);
247 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > op = Teuchos::rcp_const_cast<Thyra::LinearOpBase<Scalar> >(const_op);
248 Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xop =
250 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar,LO,GO,Node> > xwrap =
276 std::vector<GlobalOrdinal> gids;
277 for(
size_t tt = 0; tt<subMaps.size(); ++tt) {
278 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > subMap = subMaps[tt];
280 Teuchos::ArrayView< const GlobalOrdinal > subMapGids = subMap->getNodeElementList();
281 gids.insert(gids.end(), subMapGids.begin(), subMapGids.end());
283 size_t myNumElements = subMap->getNodeNumElements();
284 for(LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l) {
285 GlobalOrdinal gid = subMap->getGlobalElement(l);
295 const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
296 std::sort(gids.begin(), gids.end());
297 gids.erase(std::unique(gids.begin(), gids.end()), gids.end());
298 Teuchos::ArrayView<GO> gidsView(&gids[0], gids.size());
341 void insertGlobalValues(GlobalOrdinal globalRow,
const ArrayView<const GlobalOrdinal>& cols,
const ArrayView<const Scalar>& vals) {
344 getMatrix(0,0)->insertGlobalValues(globalRow, cols, vals);
361 void insertLocalValues(LocalOrdinal localRow,
const ArrayView<const LocalOrdinal>& cols,
const ArrayView<const Scalar>& vals) {
364 getMatrix(0,0)->insertLocalValues(localRow, cols, vals);
371 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::removeEmptyProcessesInPlace");
373 getMatrix(0,0)->removeEmptyProcessesInPlace(newMap);
389 const ArrayView<const GlobalOrdinal> &cols,
390 const ArrayView<const Scalar> &vals) {
393 getMatrix(0,0)->replaceGlobalValues(globalRow,cols,vals);
405 const ArrayView<const LocalOrdinal> &cols,
406 const ArrayView<const Scalar> &vals) {
409 getMatrix(0,0)->replaceLocalValues(localRow,cols,vals);
418 for (
size_t row = 0; row <
Rows(); row++) {
419 for (
size_t col = 0; col <
Cols(); col++) {
421 getMatrix(row,col)->setAllToScalar(alpha);
430 for (
size_t row = 0; row <
Rows(); row++) {
431 for (
size_t col = 0; col <
Cols(); col++) {
453 for (
size_t row = 0; row <
Rows(); row++) {
454 for (
size_t col = 0; col <
Cols(); col++) {
467 void fillComplete(
const RCP<const Map>& domainMap,
const RCP<const Map>& rangeMap,
const RCP<ParameterList>& params = null) {
470 getMatrix(0,0)->fillComplete(domainMap, rangeMap, params);
494 for (
size_t r = 0; r <
Rows(); ++r)
495 for (
size_t c = 0; c <
Cols(); ++c) {
497 Teuchos::RCP<Matrix> Ablock =
getMatrix(r,c);
499 if (Ablock != Teuchos::null && !Ablock->isFillComplete())
506 RCP<const Map> rangeMap =
rangemaps_->getFullMap();
507 fullrowmap_ =
MapFactory::Build(rangeMap()->lib(), rangeMap()->getGlobalNumElements(), rangeMap()->getNodeElementList(), rangeMap()->getIndexBase(), rangeMap()->getComm());
510 fullcolmap_ = Teuchos::null;
512 std::vector<GO> colmapentries;
513 for (
size_t c = 0; c <
Cols(); ++c) {
516 for (
size_t r = 0; r <
Rows(); ++r) {
517 Teuchos::RCP<CrsMatrix> Ablock =
getMatrix(r,c);
519 if (Ablock != Teuchos::null) {
520 Teuchos::ArrayView<const GO> colElements = Ablock->getColMap()->getNodeElementList();
521 Teuchos::RCP<const Map> colmap = Ablock->getColMap();
522 copy(colElements.getRawPtr(), colElements.getRawPtr() + colElements.size(), inserter(colset, colset.begin()));
527 colmapentries.reserve(colmapentries.size() + colset.size());
528 copy(colset.begin(), colset.end(), back_inserter(colmapentries));
529 sort(colmapentries.begin(), colmapentries.end());
530 typename std::vector<GO>::iterator gendLocation;
531 gendLocation = std::unique(colmapentries.begin(), colmapentries.end());
532 colmapentries.erase(gendLocation,colmapentries.end());
536 size_t numGlobalElements = 0;
537 Teuchos::reduceAll(*(rangeMap->getComm()), Teuchos::REDUCE_SUM, colmapentries.size(), Teuchos::outArg(numGlobalElements));
540 const Teuchos::ArrayView<const GO> aView = Teuchos::ArrayView<const GO>(colmapentries);
541 fullcolmap_ =
MapFactory::Build(rangeMap->lib(), numGlobalElements, aView, 0, rangeMap->getComm());
554 for (
size_t row = 0; row <
Rows(); row++)
555 for (
size_t col = 0; col <
Cols(); col++)
557 globalNumRows +=
getMatrix(row,col)->getGlobalNumRows();
561 return globalNumRows;
571 for (
size_t col = 0; col <
Cols(); col++)
572 for (
size_t row = 0; row <
Rows(); row++)
574 globalNumCols +=
getMatrix(row,col)->getGlobalNumCols();
578 return globalNumCols;
586 for (
size_t row = 0; row <
Rows(); ++row)
587 for (
size_t col = 0; col <
Cols(); col++)
589 nodeNumRows +=
getMatrix(row,col)->getNodeNumRows();
601 for (
size_t row = 0; row <
Rows(); ++row)
602 for (
size_t col = 0; col <
Cols(); ++col)
604 globalNumEntries +=
getMatrix(row,col)->getGlobalNumEntries();
606 return globalNumEntries;
614 for (
size_t row = 0; row <
Rows(); ++row)
615 for (
size_t col = 0; col <
Cols(); ++col)
617 nodeNumEntries +=
getMatrix(row,col)->getNodeNumEntries();
619 return nodeNumEntries;
625 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNumEntriesInLocalRow");
626 GlobalOrdinal gid = this->
getRowMap()->getGlobalElement(localRow);
629 size_t numEntriesInLocalRow = 0;
630 for (
size_t col = 0; col <
Cols(); ++col)
632 numEntriesInLocalRow +=
getMatrix(row,col)->getNumEntriesInLocalRow(lid);
633 return numEntriesInLocalRow;
639 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNumEntriesInGlobalRow");
641 size_t numEntriesInGlobalRow = 0;
642 for (
size_t col = 0; col <
Cols(); ++col)
644 numEntriesInGlobalRow +=
getMatrix(row,col)->getNumEntriesInGlobalRow(globalRow);
645 return numEntriesInGlobalRow;
652 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getGlobalMaxNumRowEntries");
655 for (
size_t row = 0; row <
Rows(); row++) {
657 for (
size_t col = 0; col <
Cols(); col++) {
659 globalMaxEntriesBlockRows +=
getMatrix(row,col)->getGlobalMaxNumRowEntries();
662 if(globalMaxEntriesBlockRows > globalMaxEntries)
663 globalMaxEntries = globalMaxEntriesBlockRows;
665 return globalMaxEntries;
672 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNodeMaxNumRowEntries");
673 size_t localMaxEntries = 0;
675 for (
size_t row = 0; row <
Rows(); row++) {
676 size_t localMaxEntriesBlockRows = 0;
677 for (
size_t col = 0; col <
Cols(); col++) {
679 localMaxEntriesBlockRows +=
getMatrix(row,col)->getNodeMaxNumRowEntries();
682 if(localMaxEntriesBlockRows > localMaxEntries)
683 localMaxEntries = localMaxEntriesBlockRows;
685 return localMaxEntries;
694 for (
size_t i = 0; i <
blocks_.size(); ++i)
706 for (
size_t i = 0; i <
blocks_.size(); i++)
715 for (
size_t i = 0; i <
blocks_.size(); i++)
737 const ArrayView<LocalOrdinal>& Indices,
738 const ArrayView<Scalar>& Values,
739 size_t &NumEntries)
const {
742 getMatrix(0,0)->getLocalRowCopy(LocalRow, Indices, Values, NumEntries);
758 void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView<const GlobalOrdinal>& indices, ArrayView<const Scalar>& values)
const {
761 getMatrix(0,0)->getGlobalRowView(GlobalRow, indices, values);
777 void getLocalRowView(LocalOrdinal LocalRow, ArrayView<const LocalOrdinal>& indices, ArrayView<const Scalar>& values)
const {
780 getMatrix(0,0)->getLocalRowView(LocalRow, indices, values);
784 GlobalOrdinal gid = this->
getRowMap()->getGlobalElement(LocalRow);
801 Teuchos::RCP<Vector> rcpdiag = Teuchos::rcpFromRef(diag);
802 Teuchos::RCP<BlockedVector> bdiag = Teuchos::rcp_dynamic_cast<
BlockedVector>(rcpdiag);
807 if(
Rows() == 1 &&
Cols() == 1 && bdiag.is_null() ==
true) {
808 Teuchos::RCP<const Matrix> rm =
getMatrix(0,0);
809 rm->getLocalDiagCopy(diag);
813 TEUCHOS_TEST_FOR_EXCEPTION(bdiag.is_null() ==
true,
Xpetra::Exceptions::RuntimeError,
"BlockedCrsMatrix::getLocalDiagCopy: diag must be a Blocked(Multi)Vector.");
814 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());
816 "BlockedCrsMatrix::getLocalDiagCopy(): the number of blocks in diag differ from the number of blocks in this operator." );
820 for (
size_t row = 0; row <
Rows(); row++) {
821 Teuchos::RCP<const Matrix> rm =
getMatrix(row,row);
823 Teuchos::RCP<Vector> rv =
VectorFactory::Build(bdiag->getBlockedMap()->getMap(row,bdiag->getBlockedMap()->getThyraMode()));
824 rm->getLocalDiagCopy(*rv);
825 bdiag->setMultiVector(row,rv,bdiag->getBlockedMap()->getThyraMode());
834 Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
835 Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<
const BlockedVector>(rcpx);
842 if(
Rows() == 1 && bx.is_null() ==
true) {
843 for (
size_t col = 0; col <
Cols(); ++col) {
844 Teuchos::RCP<Matrix> rm =
getMatrix(0,col);
851 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());
853 "BlockedCrsMatrix::leftScale(): the number of blocks in diag differ from the number of blocks in this operator." );
855 for (
size_t row = 0; row <
Rows(); row++) {
856 Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(row);
857 Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
859 for (
size_t col = 0; col <
Cols(); ++col) {
860 Teuchos::RCP<Matrix> rm =
getMatrix(row,col);
862 rm->leftScale(*rscale);
872 Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
873 Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<
const BlockedVector>(rcpx);
880 if(
Cols() == 1 && bx.is_null() ==
true) {
881 for (
size_t row = 0; row <
Rows(); ++row) {
882 Teuchos::RCP<Matrix> rm =
getMatrix(row,0);
889 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());
891 "BlockedCrsMatrix::rightScale(): the number of blocks in diag differ from the number of blocks in this operator." );
893 for (
size_t col = 0; col <
Cols(); ++col) {
894 Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(col);
895 Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
897 for (
size_t row = 0; row <
Rows(); row++) {
898 Teuchos::RCP<Matrix> rm =
getMatrix(row,col);
900 rm->rightScale(*rscale);
910 typename ScalarTraits<Scalar>::magnitudeType ret = Teuchos::ScalarTraits<Scalar>::magnitude(Teuchos::ScalarTraits<Scalar>::zero());
911 for (
size_t col = 0; col <
Cols(); ++col) {
912 for (
size_t row = 0; row <
Rows(); ++row) {
914 typename ScalarTraits<Scalar>::magnitudeType n =
getMatrix(row,col)->getFrobeniusNorm();
919 return Teuchos::ScalarTraits< typename ScalarTraits<Scalar>::magnitudeType >::squareroot(ret);
960 const Teuchos::ArrayRCP<LocalOrdinal>& regionInterfaceLIDs)
const 968 Teuchos::ETransp mode = Teuchos::NO_TRANS,
969 Scalar alpha = ScalarTraits<Scalar>::one(),
970 Scalar beta = ScalarTraits<Scalar>::zero())
const 976 "apply() only supports the following modes: NO_TRANS and TRANS." );
979 RCP<const MultiVector> refX = rcpFromRef(X);
980 RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(refX);
985 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
993 SC one = ScalarTraits<SC>::one();
995 if (mode == Teuchos::NO_TRANS) {
997 for (
size_t row = 0; row <
Rows(); row++) {
999 for (
size_t col = 0; col <
Cols(); col++) {
1002 RCP<Matrix> Ablock =
getMatrix(row, col);
1004 if (Ablock.is_null())
1009 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
1012 RCP<const MultiVector> Xblock = Teuchos::null;
1021 Ablock->apply(*Xblock, *tmpYblock);
1023 Yblock->update(one, *tmpYblock, one);
1028 }
else if (mode == Teuchos::TRANS) {
1030 for (
size_t col = 0; col <
Cols(); col++) {
1033 for (
size_t row = 0; row<
Rows(); row++) {
1034 RCP<Matrix> Ablock =
getMatrix(row, col);
1036 if (Ablock.is_null())
1041 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
1043 RCP<const MultiVector> Xblock = Teuchos::null;
1049 Ablock->apply(*Xblock, *tmpYblock, Teuchos::TRANS);
1051 Yblock->update(one, *tmpYblock, one);
1056 Y.
update(alpha, *tmpY, beta);
1112 Teuchos::ETransp mode = Teuchos::NO_TRANS,
1113 Scalar alpha = ScalarTraits<Scalar>::one(),
1114 Scalar beta = ScalarTraits<Scalar>::zero()
1121 "apply() only supports the following modes: NO_TRANS and TRANS." );
1124 RCP<const MultiVector> refX = rcpFromRef(X);
1125 RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(refX);
1129 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
1135 SC one = ScalarTraits<SC>::one();
1137 if (mode == Teuchos::NO_TRANS) {
1139 for (
size_t col = 0; col <
Cols(); col++) {
1142 RCP<Matrix> Ablock =
getMatrix(row, col);
1144 if (Ablock.is_null())
1149 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
1152 RCP<const MultiVector> Xblock = Teuchos::null;
1161 Ablock->apply(*Xblock, *tmpYblock);
1163 Yblock->update(one, *tmpYblock, one);
1169 Y.
update(alpha, *tmpY, beta);
1180 const Teuchos::RCP< const Map >
getMap()
const {
1192 getMatrix(0,0)->doImport(source, importer, CM);
1202 getMatrix(0,0)->doExport(dest, importer, CM);
1212 getMatrix(0,0)->doImport(source, exporter, CM);
1222 getMatrix(0,0)->doExport(dest, exporter, CM);
1234 std::string
description()
const {
return "Xpetra_BlockedCrsMatrix.description()"; }
1237 void describe(Teuchos::FancyOStream& out,
const Teuchos::EVerbosityLevel verbLevel = Teuchos::Describable::verbLevel_default)
const {
1238 out <<
"Xpetra::BlockedCrsMatrix: " <<
Rows() <<
" x " <<
Cols() << std::endl;
1241 out <<
"BlockMatrix is fillComplete" << std::endl;
1254 out <<
"BlockMatrix is NOT fillComplete" << std::endl;
1257 for (
size_t r = 0; r <
Rows(); ++r)
1258 for (
size_t c = 0; c <
Cols(); ++c) {
1260 out <<
"Block(" << r <<
"," << c <<
")" << std::endl;
1261 getMatrix(r,c)->describe(out,verbLevel);
1262 }
else out <<
"Block(" << r <<
"," << c <<
") = null" << std::endl;
1270 for (
size_t r = 0; r <
Rows(); ++r)
1271 for (
size_t c = 0; c <
Cols(); ++c) {
1273 std::ostringstream oss; oss<< objectLabel <<
"(" << r <<
"," << c <<
")";
1274 getMatrix(r,c)->setObjectLabel(oss.str());
1283 if (
Rows() == 1 &&
Cols () == 1)
return true;
1312 TEUCHOS_TEST_FOR_EXCEPTION(
Rows()!=1, std::out_of_range,
"Can only unwrap a 1x1 blocked matrix. The matrix has " <<
Rows() <<
" block rows, though.");
1313 TEUCHOS_TEST_FOR_EXCEPTION(
Cols()!=1, std::out_of_range,
"Can only unwrap a 1x1 blocked matrix. The matrix has " <<
Cols() <<
" block columns, though.");
1316 RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(mat);
1317 if (bmat == Teuchos::null)
return mat;
1324 size_t row =
Rows()+1, col =
Cols()+1;
1325 for (
size_t r = 0; r <
Rows(); ++r)
1326 for(
size_t c = 0; c <
Cols(); ++c)
1332 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.")
1334 RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(mm);
1335 if (bmat == Teuchos::null)
return mm;
1342 TEUCHOS_TEST_FOR_EXCEPTION(r >
Rows(), std::out_of_range,
"Error, r = " <<
Rows() <<
" is too big");
1343 TEUCHOS_TEST_FOR_EXCEPTION(c >
Cols(), std::out_of_range,
"Error, c = " <<
Cols() <<
" is too big");
1354 void setMatrix(
size_t r,
size_t c, Teuchos::RCP<Matrix> mat) {
1358 TEUCHOS_TEST_FOR_EXCEPTION(r >
Rows(), std::out_of_range,
"Error, r = " <<
Rows() <<
" is too big");
1359 TEUCHOS_TEST_FOR_EXCEPTION(c >
Cols(), std::out_of_range,
"Error, c = " <<
Cols() <<
" is too big");
1371 using Teuchos::rcp_dynamic_cast;
1372 Scalar one = ScalarTraits<SC>::one();
1375 "BlockedCrsMatrix::Merge: only implemented for Xpetra-style or Thyra-style numbering. No mixup allowed!" );
1378 "BlockedCrsMatrix::Merge: BlockMatrix must be fill-completed." );
1381 Teuchos::ArrayRCP<size_t> numEntPerRow (lclNumRows);
1382 for (LocalOrdinal lclRow = 0; lclRow < lclNumRows; ++lclRow)
1389 for (
size_t i = 0; i <
Rows(); i++) {
1390 for (
size_t j = 0; j <
Cols(); j++) {
1395 RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(mat);
1396 if (bMat != Teuchos::null) mat = bMat->
Merge();
1400 "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!" );
1403 if(mat->getNodeNumEntries() == 0)
continue;
1405 this->
Add(*mat, one, *sparse, one);
1411 for (
size_t i = 0; i <
Rows(); i++) {
1412 for (
size_t j = 0; j <
Cols(); j++) {
1416 RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(mat);
1417 if (bMat != Teuchos::null) mat = bMat->
Merge();
1421 "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!" );
1424 RCP<const CrsMatrixWrap> crsMat = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(mat);
1425 TEUCHOS_ASSERT(crsMat != Teuchos::null);
1428 RCP<const Map> trowMap = mat->getRowMap();
1429 RCP<const Map> tcolMap = mat->getColMap();
1430 RCP<const Map> tdomMap = mat->getDomainMap();
1445 if(mat->getNodeNumEntries() == 0)
continue;
1447 size_t maxNumEntries = mat->getNodeMaxNumRowEntries();
1450 Array<GO> inds (maxNumEntries);
1451 Array<GO> inds2(maxNumEntries);
1452 Array<SC> vals (maxNumEntries);
1455 for (
size_t k = 0; k < mat->getNodeNumRows(); k++) {
1456 GlobalOrdinal rowTGID = trowMap->getGlobalElement(k);
1457 crsMat->getCrsMatrix()->getGlobalRowCopy(rowTGID, inds(), vals(), numEntries);
1460 for (
size_t l = 0; l < numEntries; ++l) {
1461 LocalOrdinal lid = tcolMap->getLocalElement(inds[l]);
1462 inds2[l] = xcolMap->getGlobalElement(lid);
1465 GlobalOrdinal rowXGID = xrowMap->getGlobalElement(k);
1466 sparse->insertGlobalValues(
1467 rowXGID, inds2(0, numEntries),
1468 vals(0, numEntries));
1478 "BlockedCrsMatrix::Merge: Local number of entries of merged matrix does not coincide with local number of entries of blocked operator." );
1481 "BlockedCrsMatrix::Merge: Global number of entries of merged matrix does not coincide with global number of entries of blocked operator." );
1487 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR 1488 typedef typename CrsMatrix::local_matrix_type local_matrix_type;
1489 #ifdef TPETRA_ENABLE_DEPRECATED_CODE 1490 local_matrix_type getLocalMatrix ()
const {
1491 return getLocalMatrixDevice();
1494 local_matrix_type getLocalMatrixDevice ()
const {
1497 return getMatrix(0,0)->getLocalMatrixDevice();
1502 typename local_matrix_type::HostMirror getLocalMatrixHost ()
const {
1504 return getMatrix(0,0)->getLocalMatrixHost();
1512 #ifdef HAVE_XPETRA_THYRA 1513 Teuchos::RCP<Thyra::BlockedLinearOpBase<Scalar> > getThyraOperator() {
1514 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > thOp =
1515 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(Teuchos::rcpFromRef(*
this));
1516 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thOp));
1518 Teuchos::RCP<Thyra::BlockedLinearOpBase<Scalar> > thbOp =
1519 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<Scalar> >(thOp);
1520 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thbOp));
1529 using STS = Teuchos::ScalarTraits<Scalar>;
1530 R.
update(STS::one(),B,STS::zero());
1531 this->
apply (X, R, Teuchos::NO_TRANS, -STS::one(), STS::one());
1553 "Matrix A is not completed");
1554 using Teuchos::Array;
1555 using Teuchos::ArrayView;
1559 Scalar one = ScalarTraits<SC>::one();
1560 Scalar zero = ScalarTraits<SC>::zero();
1562 if (scalarA == zero)
1565 Teuchos::RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
1566 Teuchos::RCP<const CrsMatrixWrap> rcpAwrap = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(rcpA);
1568 "BlockedCrsMatrix::Add: matrix A must be of type CrsMatrixWrap.");
1569 Teuchos::RCP<const CrsMatrix> crsA = rcpAwrap->getCrsMatrix();
1571 size_t maxNumEntries = crsA->getNodeMaxNumRowEntries();
1574 Array<GO> inds(maxNumEntries);
1575 Array<SC> vals(maxNumEntries);
1577 RCP<const Map> rowMap = crsA->getRowMap();
1578 RCP<const Map> colMap = crsA->getColMap();
1580 ArrayView<const GO> rowGIDs = crsA->getRowMap()->getNodeElementList();
1581 for (
size_t i = 0; i < crsA->getNodeNumRows(); i++) {
1582 GO row = rowGIDs[i];
1583 crsA->getGlobalRowCopy(row, inds(), vals(), numEntries);
1586 for (
size_t j = 0; j < numEntries; ++j)
1614 #ifdef HAVE_XPETRA_THYRA 1615 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > thyraOp_;
1624 #define XPETRA_BLOCKEDCRSMATRIX_SHORT
Teuchos::RCP< Matrix > Merge() const
merge BlockedCrsMatrix blocks in a CrsMatrix
size_t getNodeMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.
RCP< const CrsGraph > getCrsGraph() const
Returns the CrsGraph associated with this matrix.
const Teuchos::RCP< const Map > getMap() const
Implements DistObject interface.
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.
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.
bool isLocallyIndexed() const
If matrix indices of all matrix blocks are in the local range, this function returns true...
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
bool isFillComplete() const
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
RCP< const Map > getRangeMap(size_t i, bool bThyraMode) const
Returns the Map associated with the i'th block range of this operator.
RCP< const BlockedMap > getBlockedDomainMap() const
Returns the BlockedMap associated with the domain of this operator.
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.
virtual void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to scalar.
RCP< const Map > getDomainMap(size_t i) const
Returns the Map associated with the i'th block 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.
static RCP< Matrix > Build(const RCP< const Map > &rowMap)
Exception throws to report errors in the internal logical of the program.
virtual ScalarTraits< Scalar >::magnitudeType getFrobeniusNorm() const
Get Frobenius norm of the matrix.
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 ~BlockedCrsMatrix()
Destructor.
Teuchos::RCP< Matrix > getCrsMatrix() const
return unwrap 1x1 blocked operators
void doExport(const Matrix &dest, const Import &importer, CombineMode CM)
Export.
virtual bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
LocalOrdinal local_ordinal_type
size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
global_size_t getGlobalNumCols() const
Returns the number of global columns in the matrix.
void resumeFill(const RCP< ParameterList > ¶ms=null)
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.
void rightScale(const Vector &x)
Right scale matrix using the given vector entries.
RCP< const BlockedMap > getBlockedRangeMap() const
Returns the BlockedMap associated with the range of this operator.
RCP< const Map > getFullRangeMap() const
Returns the Map associated with the full range of this operator.
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.
Exception indicating invalid cast attempted.
void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using global IDs.
viewLabel_t defaultViewLabel_
virtual void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)=0
Insert matrix entries, using global IDs.
size_t getNodeNumRows() const
Returns the number of matrix rows owned on the calling node.
GlobalOrdinal global_ordinal_type
bool is_diagonal_
If we're diagonal, a bunch of the extraction stuff should work.
void doExport(const Matrix &dest, const Export &exporter, CombineMode CM)
Export (using an Importer).
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 bool isDiagonal() const
void setObjectLabel(const std::string &objectLabel)
Teuchos::RCP< Matrix > getInnermostCrsMatrix()
helper routine recursively returns the first inner-most non-null matrix block from a (nested) blocked...
void insertLocalValues(LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using local IDs.
bool isGloballyIndexed() const
If matrix indices are in the global range, this function returns true. Otherwise, this function retur...
RCP< const Map > getDomainMap(size_t i, bool bThyraMode) const
Returns the Map associated with the i'th block domain of this operator.
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
const viewLabel_t & GetDefaultViewLabel() const
void getLocalDiagCopy(Vector &diag) const
Get a copy of the diagonal entries owned by this node, with local row indices.
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.
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 CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
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...
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
viewLabel_t currentViewLabel_
void doImport(const Matrix &source, const Export &exporter, CombineMode CM)
Import (using an Exporter).
bool hasCrsGraph() const
Supports the getCrsGraph() call.
Exception throws when you call an unimplemented method of Xpetra.
RCP< const Map > getRangeMap(size_t i) const
Returns the Map associated with the i'th block range of this operator.
size_t global_size_t
Global size_t object.
global_size_t getGlobalNumEntries() const
Returns the global number of entries in this matrix.
std::vector< Teuchos::RCP< Matrix > > blocks_
row major matrix block storage
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)
BlockedCrsMatrix(const Teuchos::RCP< const BlockedMap > &rangeMaps, const Teuchos::RCP< const BlockedMap > &domainMaps, size_t numEntriesPerRow)
Constructor.
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...
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.
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)
void residual(const MultiVector &X, const MultiVector &B, MultiVector &R) const
Compute a residual R = B - (*this) * X.
RCP< const Map > getFullDomainMap() const
Returns the Map associated with the full domain of this operator.
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries in the specified (locally owned) global row.
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void setMatrix(size_t r, size_t c, Teuchos::RCP< Matrix > mat)
set matrix block
bool bDomainThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
Exception throws to report incompatible objects (like maps).
size_t getNodeNumEntries() const
Returns the local number of entries in this matrix.
RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
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.
Concrete implementation of Xpetra::Matrix.
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
BlockedCrsMatrix(Teuchos::RCP< const MapExtractor > &rangeMapExtractor, Teuchos::RCP< const MapExtractor > &domainMapExtractor, size_t numEntriesPerRow)
Constructor.
std::string description() const
Return a simple one-line description of this object.
CombineMode
Xpetra::Combine Mode enumerable type.
global_size_t getGlobalNumRows() const
Returns the number of global rows.
#define XPETRA_MONITOR(funcName)
RCP< const MapExtractor > getDomainMapExtractor() const
Returns map extractor for domain map.
virtual void scale(const Scalar &alpha)=0
Scale the current values of a matrix, this = alpha*this.
void fillComplete(const RCP< ParameterList > ¶ms=null)
Signal that data entry is complete.
virtual size_t Rows() const
number of row blocks
virtual size_t Cols() const
number of column blocks
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
RCP< const Map > getDomainMap() const
Returns the Map associated with the domain of this operator.
void removeEmptyProcessesInPlace(const Teuchos::RCP< const Map > &newMap)
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
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...
virtual void apply(const MultiVector &X, MultiVector &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=ScalarTraits< Scalar >::one(), Scalar beta=ScalarTraits< Scalar >::zero()) const
Computes the sparse matrix-multivector multiplication.