46 #ifndef XPETRA_BLOCKEDCRSMATRIX_HPP 47 #define XPETRA_BLOCKEDCRSMATRIX_HPP 51 #include <Teuchos_SerialDenseMatrix.hpp> 52 #include <Teuchos_Hashtable.hpp> 72 #ifdef HAVE_XPETRA_THYRA 73 #include <Thyra_ProductVectorSpaceBase.hpp> 74 #include <Thyra_VectorSpaceBase.hpp> 75 #include <Thyra_LinearOpBase.hpp> 76 #include <Thyra_BlockedLinearOpBase.hpp> 77 #include <Thyra_PhysicallyBlockedLinearOpBase.hpp> 90 template <
class Scalar,
95 public Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
103 #undef XPETRA_BLOCKEDCRSMATRIX_SHORT 119 const Teuchos::RCP<const BlockedMap>& domainMaps,
130 for (
size_t r = 0; r <
Rows(); ++r)
131 for (
size_t c = 0; c <
Cols(); ++c)
148 Teuchos::RCP<const MapExtractor>& domainMaps,
158 for (
size_t r = 0; r <
Rows(); ++r)
159 for (
size_t c = 0; c <
Cols(); ++c)
166 #ifdef HAVE_XPETRA_THYRA 174 BlockedCrsMatrix(
const Teuchos::RCP<
const Thyra::BlockedLinearOpBase<Scalar> >& thyraOp,
const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
178 const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productRangeSpace = thyraOp->productRange();
179 const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productDomainSpace = thyraOp->productDomain();
181 int numRangeBlocks = productRangeSpace->numBlocks();
182 int numDomainBlocks = productDomainSpace->numBlocks();
185 std::vector<Teuchos::RCP<const Map> > subRangeMaps(numRangeBlocks);
186 for (
size_t r=0; r<Teuchos::as<size_t>(numRangeBlocks); ++r) {
187 for (
size_t c=0; c<Teuchos::as<size_t>(numDomainBlocks); ++c) {
188 if (thyraOp->blockExists(r,c)) {
190 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c);
191 Teuchos::RCP<const Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xop =
193 subRangeMaps[r] = xop->getRangeMap();
199 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > fullRangeMap = mergeMaps(subRangeMaps);
203 bool bRangeUseThyraStyleNumbering =
false;
204 size_t numAllElements = 0;
205 for(
size_t v = 0; v < subRangeMaps.size(); ++v) {
206 numAllElements += subRangeMaps[v]->getGlobalNumElements();
208 if ( fullRangeMap->getGlobalNumElements() != numAllElements) bRangeUseThyraStyleNumbering =
true;
212 std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > > subDomainMaps(numDomainBlocks);
213 for (
size_t c=0; c<Teuchos::as<size_t>(numDomainBlocks); ++c) {
214 for (
size_t r=0; r<Teuchos::as<size_t>(numRangeBlocks); ++r) {
215 if (thyraOp->blockExists(r,c)) {
217 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c);
218 Teuchos::RCP<const Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xop =
220 subDomainMaps[c] = xop->getDomainMap();
225 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > fullDomainMap = mergeMaps(subDomainMaps);
227 bool bDomainUseThyraStyleNumbering =
false;
229 for(
size_t v = 0; v < subDomainMaps.size(); ++v) {
230 numAllElements += subDomainMaps[v]->getGlobalNumElements();
232 if (fullDomainMap->getGlobalNumElements() != numAllElements) bDomainUseThyraStyleNumbering =
true;
241 for (
size_t r = 0; r <
Rows(); ++r) {
242 for (
size_t c = 0; c <
Cols(); ++c) {
243 if(thyraOp->blockExists(r,c)) {
245 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c);
246 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > op = Teuchos::rcp_const_cast<Thyra::LinearOpBase<Scalar> >(const_op);
247 Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xop =
249 Teuchos::RCP<Xpetra::CrsMatrixWrap<Scalar,LO,GO,Node> > xwrap =
275 std::vector<GlobalOrdinal> gids;
276 for(
size_t tt = 0; tt<subMaps.size(); ++tt) {
277 Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > subMap = subMaps[tt];
279 Teuchos::ArrayView< const GlobalOrdinal > subMapGids = subMap->getNodeElementList();
280 gids.insert(gids.end(), subMapGids.begin(), subMapGids.end());
282 size_t myNumElements = subMap->getNodeNumElements();
283 for(LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l) {
284 GlobalOrdinal gid = subMap->getGlobalElement(l);
294 const GO INVALID = Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid();
295 std::sort(gids.begin(), gids.end());
296 gids.erase(std::unique(gids.begin(), gids.end()), gids.end());
297 Teuchos::ArrayView<GO> gidsView(&gids[0], gids.size());
340 void insertGlobalValues(GlobalOrdinal globalRow,
const ArrayView<const GlobalOrdinal>& cols,
const ArrayView<const Scalar>& vals) {
343 getMatrix(0,0)->insertGlobalValues(globalRow, cols, vals);
360 void insertLocalValues(LocalOrdinal localRow,
const ArrayView<const LocalOrdinal>& cols,
const ArrayView<const Scalar>& vals) {
363 getMatrix(0,0)->insertLocalValues(localRow, cols, vals);
370 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::removeEmptyProcessesInPlace");
372 getMatrix(0,0)->removeEmptyProcessesInPlace(newMap);
388 const ArrayView<const GlobalOrdinal> &cols,
389 const ArrayView<const Scalar> &vals) {
392 getMatrix(0,0)->replaceGlobalValues(globalRow,cols,vals);
404 const ArrayView<const LocalOrdinal> &cols,
405 const ArrayView<const Scalar> &vals) {
408 getMatrix(0,0)->replaceLocalValues(localRow,cols,vals);
417 for (
size_t row = 0; row <
Rows(); row++) {
418 for (
size_t col = 0; col <
Cols(); col++) {
420 getMatrix(row,col)->setAllToScalar(alpha);
429 for (
size_t row = 0; row <
Rows(); row++) {
430 for (
size_t col = 0; col <
Cols(); col++) {
452 for (
size_t row = 0; row <
Rows(); row++) {
453 for (
size_t col = 0; col <
Cols(); col++) {
466 void fillComplete(
const RCP<const Map>& domainMap,
const RCP<const Map>& rangeMap,
const RCP<ParameterList>& params = null) {
469 getMatrix(0,0)->fillComplete(domainMap, rangeMap, params);
493 for (
size_t r = 0; r <
Rows(); ++r)
494 for (
size_t c = 0; c <
Cols(); ++c) {
496 Teuchos::RCP<Matrix> Ablock =
getMatrix(r,c);
498 if (Ablock != Teuchos::null && !Ablock->isFillComplete())
505 RCP<const Map> rangeMap =
rangemaps_->getFullMap();
506 fullrowmap_ =
MapFactory::Build(rangeMap()->lib(), rangeMap()->getGlobalNumElements(), rangeMap()->getNodeElementList(), rangeMap()->getIndexBase(), rangeMap()->getComm());
509 fullcolmap_ = Teuchos::null;
511 std::vector<GO> colmapentries;
512 for (
size_t c = 0; c <
Cols(); ++c) {
515 for (
size_t r = 0; r <
Rows(); ++r) {
516 Teuchos::RCP<CrsMatrix> Ablock =
getMatrix(r,c);
518 if (Ablock != Teuchos::null) {
519 Teuchos::ArrayView<const GO> colElements = Ablock->getColMap()->getNodeElementList();
520 Teuchos::RCP<const Map> colmap = Ablock->getColMap();
521 copy(colElements.getRawPtr(), colElements.getRawPtr() + colElements.size(), inserter(colset, colset.begin()));
526 colmapentries.reserve(colmapentries.size() + colset.size());
527 copy(colset.begin(), colset.end(), back_inserter(colmapentries));
528 sort(colmapentries.begin(), colmapentries.end());
529 typename std::vector<GO>::iterator gendLocation;
530 gendLocation = std::unique(colmapentries.begin(), colmapentries.end());
531 colmapentries.erase(gendLocation,colmapentries.end());
535 size_t numGlobalElements = 0;
536 Teuchos::reduceAll(*(rangeMap->getComm()), Teuchos::REDUCE_SUM, colmapentries.size(), Teuchos::outArg(numGlobalElements));
539 const Teuchos::ArrayView<const GO> aView = Teuchos::ArrayView<const GO>(colmapentries);
540 fullcolmap_ =
MapFactory::Build(rangeMap->lib(), numGlobalElements, aView, 0, rangeMap->getComm());
553 for (
size_t row = 0; row <
Rows(); row++)
554 for (
size_t col = 0; col <
Cols(); col++)
556 globalNumRows +=
getMatrix(row,col)->getGlobalNumRows();
560 return globalNumRows;
570 for (
size_t col = 0; col <
Cols(); col++)
571 for (
size_t row = 0; row <
Rows(); row++)
573 globalNumCols +=
getMatrix(row,col)->getGlobalNumCols();
577 return globalNumCols;
585 for (
size_t row = 0; row <
Rows(); ++row)
586 for (
size_t col = 0; col <
Cols(); col++)
588 nodeNumRows +=
getMatrix(row,col)->getNodeNumRows();
600 for (
size_t row = 0; row <
Rows(); ++row)
601 for (
size_t col = 0; col <
Cols(); ++col)
603 globalNumEntries +=
getMatrix(row,col)->getGlobalNumEntries();
605 return globalNumEntries;
613 for (
size_t row = 0; row <
Rows(); ++row)
614 for (
size_t col = 0; col <
Cols(); ++col)
616 nodeNumEntries +=
getMatrix(row,col)->getNodeNumEntries();
618 return nodeNumEntries;
624 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNumEntriesInLocalRow");
626 return getMatrix(0,0)->getNumEntriesInLocalRow(localRow);
629 GlobalOrdinal gid = this->
getRowMap()->getGlobalElement(localRow);
640 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getGlobalMaxNumRowEntries");
643 for (
size_t row = 0; row <
Rows(); row++) {
645 for (
size_t col = 0; col <
Cols(); col++) {
647 globalMaxEntriesBlockRows +=
getMatrix(row,col)->getGlobalMaxNumRowEntries();
650 if(globalMaxEntriesBlockRows > globalMaxEntries)
651 globalMaxEntries = globalMaxEntriesBlockRows;
653 return globalMaxEntries;
660 XPETRA_MONITOR(
"XpetraBlockedCrsMatrix::getNodeMaxNumRowEntries");
661 size_t localMaxEntries = 0;
663 for (
size_t row = 0; row <
Rows(); row++) {
664 size_t localMaxEntriesBlockRows = 0;
665 for (
size_t col = 0; col <
Cols(); col++) {
667 localMaxEntriesBlockRows +=
getMatrix(row,col)->getNodeMaxNumRowEntries();
670 if(localMaxEntriesBlockRows > localMaxEntries)
671 localMaxEntries = localMaxEntriesBlockRows;
673 return localMaxEntries;
682 for (
size_t i = 0; i <
blocks_.size(); ++i)
694 for (
size_t i = 0; i <
blocks_.size(); i++)
703 for (
size_t i = 0; i <
blocks_.size(); i++)
725 const ArrayView<LocalOrdinal>& Indices,
726 const ArrayView<Scalar>& Values,
727 size_t &NumEntries)
const {
730 getMatrix(0,0)->getLocalRowCopy(LocalRow, Indices, Values, NumEntries);
746 void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView<const GlobalOrdinal>& indices, ArrayView<const Scalar>& values)
const {
749 getMatrix(0,0)->getGlobalRowView(GlobalRow, indices, values);
765 void getLocalRowView(LocalOrdinal LocalRow, ArrayView<const LocalOrdinal>& indices, ArrayView<const Scalar>& values)
const {
768 getMatrix(0,0)->getLocalRowView(LocalRow, indices, values);
773 GlobalOrdinal gid = this->
getRowMap()->getGlobalElement(LocalRow);
790 Teuchos::RCP<Vector> rcpdiag = Teuchos::rcpFromRef(diag);
791 Teuchos::RCP<BlockedVector> bdiag = Teuchos::rcp_dynamic_cast<
BlockedVector>(rcpdiag);
796 if(
Rows() == 1 &&
Cols() == 1 && bdiag.is_null() ==
true) {
797 Teuchos::RCP<const Matrix> rm =
getMatrix(0,0);
798 rm->getLocalDiagCopy(diag);
802 TEUCHOS_TEST_FOR_EXCEPTION(bdiag.is_null() ==
true,
Xpetra::Exceptions::RuntimeError,
"BlockedCrsMatrix::getLocalDiagCopy: diag must be a Blocked(Multi)Vector.");
803 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());
805 "BlockedCrsMatrix::getLocalDiagCopy(): the number of blocks in diag differ from the number of blocks in this operator." );
809 for (
size_t row = 0; row <
Rows(); row++) {
810 Teuchos::RCP<const Matrix> rm =
getMatrix(row,row);
812 Teuchos::RCP<Vector> rv =
VectorFactory::Build(bdiag->getBlockedMap()->getMap(row,bdiag->getBlockedMap()->getThyraMode()));
813 rm->getLocalDiagCopy(*rv);
814 bdiag->setMultiVector(row,rv,bdiag->getBlockedMap()->getThyraMode());
823 Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
824 Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<
const BlockedVector>(rcpx);
831 if(
Rows() == 1 && bx.is_null() ==
true) {
832 for (
size_t col = 0; col <
Cols(); ++col) {
833 Teuchos::RCP<Matrix> rm =
getMatrix(0,col);
840 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());
842 "BlockedCrsMatrix::leftScale(): the number of blocks in diag differ from the number of blocks in this operator." );
844 for (
size_t row = 0; row <
Rows(); row++) {
845 Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(row);
846 Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
848 for (
size_t col = 0; col <
Cols(); ++col) {
849 Teuchos::RCP<Matrix> rm =
getMatrix(row,col);
851 rm->leftScale(*rscale);
861 Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
862 Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<
const BlockedVector>(rcpx);
869 if(
Cols() == 1 && bx.is_null() ==
true) {
870 for (
size_t row = 0; row <
Rows(); ++row) {
871 Teuchos::RCP<Matrix> rm =
getMatrix(row,0);
878 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());
880 "BlockedCrsMatrix::rightScale(): the number of blocks in diag differ from the number of blocks in this operator." );
882 for (
size_t col = 0; col <
Cols(); ++col) {
883 Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(col);
884 Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
886 for (
size_t row = 0; row <
Rows(); row++) {
887 Teuchos::RCP<Matrix> rm =
getMatrix(row,col);
889 rm->rightScale(*rscale);
899 typename ScalarTraits<Scalar>::magnitudeType ret = Teuchos::ScalarTraits<Scalar>::magnitude(Teuchos::ScalarTraits<Scalar>::zero());
900 for (
size_t col = 0; col <
Cols(); ++col) {
901 for (
size_t row = 0; row <
Rows(); ++row) {
903 typename ScalarTraits<Scalar>::magnitudeType n =
getMatrix(row,col)->getFrobeniusNorm();
908 return Teuchos::ScalarTraits< typename ScalarTraits<Scalar>::magnitudeType >::squareroot(ret);
951 Teuchos::ETransp mode = Teuchos::NO_TRANS,
952 Scalar alpha = ScalarTraits<Scalar>::one(),
953 Scalar beta = ScalarTraits<Scalar>::zero())
const 959 "apply() only supports the following modes: NO_TRANS and TRANS." );
962 RCP<const MultiVector> refX = rcpFromRef(X);
963 RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(refX);
968 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
976 SC one = ScalarTraits<SC>::one();
978 if (mode == Teuchos::NO_TRANS) {
980 for (
size_t row = 0; row <
Rows(); row++) {
982 for (
size_t col = 0; col <
Cols(); col++) {
985 RCP<Matrix> Ablock =
getMatrix(row, col);
987 if (Ablock.is_null())
992 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
995 RCP<const MultiVector> Xblock = Teuchos::null;
1004 Ablock->apply(*Xblock, *tmpYblock);
1006 Yblock->update(one, *tmpYblock, one);
1011 }
else if (mode == Teuchos::TRANS) {
1013 for (
size_t col = 0; col <
Cols(); col++) {
1016 for (
size_t row = 0; row<
Rows(); row++) {
1017 RCP<Matrix> Ablock =
getMatrix(row, col);
1019 if (Ablock.is_null())
1024 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
1026 RCP<const MultiVector> Xblock = Teuchos::null;
1032 Ablock->apply(*Xblock, *tmpYblock, Teuchos::TRANS);
1034 Yblock->update(one, *tmpYblock, one);
1039 Y.
update(alpha, *tmpY, beta);
1095 Teuchos::ETransp mode = Teuchos::NO_TRANS,
1096 Scalar alpha = ScalarTraits<Scalar>::one(),
1097 Scalar beta = ScalarTraits<Scalar>::zero()
1104 "apply() only supports the following modes: NO_TRANS and TRANS." );
1107 RCP<const MultiVector> refX = rcpFromRef(X);
1108 RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<
const BlockedMultiVector>(refX);
1112 bool bBlockedX = (refbX != Teuchos::null) ?
true :
false;
1118 SC one = ScalarTraits<SC>::one();
1120 if (mode == Teuchos::NO_TRANS) {
1122 for (
size_t col = 0; col <
Cols(); col++) {
1125 RCP<Matrix> Ablock =
getMatrix(row, col);
1127 if (Ablock.is_null())
1132 bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(Ablock) == Teuchos::null ?
false :
true;
1135 RCP<const MultiVector> Xblock = Teuchos::null;
1144 Ablock->apply(*Xblock, *tmpYblock);
1146 Yblock->update(one, *tmpYblock, one);
1152 Y.
update(alpha, *tmpY, beta);
1163 const Teuchos::RCP< const Map >
getMap()
const {
1175 getMatrix(0,0)->doImport(source, importer, CM);
1185 getMatrix(0,0)->doExport(dest, importer, CM);
1195 getMatrix(0,0)->doImport(source, exporter, CM);
1205 getMatrix(0,0)->doExport(dest, exporter, CM);
1217 std::string
description()
const {
return "Xpetra_BlockedCrsMatrix.description()"; }
1220 void describe(Teuchos::FancyOStream& out,
const Teuchos::EVerbosityLevel verbLevel = Teuchos::Describable::verbLevel_default)
const {
1221 out <<
"Xpetra::BlockedCrsMatrix: " <<
Rows() <<
" x " <<
Cols() << std::endl;
1224 out <<
"BlockMatrix is fillComplete" << std::endl;
1237 out <<
"BlockMatrix is NOT fillComplete" << std::endl;
1240 for (
size_t r = 0; r <
Rows(); ++r)
1241 for (
size_t c = 0; c <
Cols(); ++c) {
1243 out <<
"Block(" << r <<
"," << c <<
")" << std::endl;
1244 getMatrix(r,c)->describe(out,verbLevel);
1245 }
else out <<
"Block(" << r <<
"," << c <<
") = null" << std::endl;
1251 if (
Rows() == 1 &&
Cols () == 1)
return true;
1280 TEUCHOS_TEST_FOR_EXCEPTION(
Rows()!=1, std::out_of_range,
"Can only unwrap a 1x1 blocked matrix. The matrix has " <<
Rows() <<
" block rows, though.");
1281 TEUCHOS_TEST_FOR_EXCEPTION(
Cols()!=1, std::out_of_range,
"Can only unwrap a 1x1 blocked matrix. The matrix has " <<
Cols() <<
" block columns, though.");
1284 RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(mat);
1285 if (bmat == Teuchos::null)
return mat;
1292 size_t row =
Rows()+1, col =
Cols()+1;
1293 for (
size_t r = 0; r <
Rows(); ++r)
1294 for(
size_t c = 0; c <
Cols(); ++c)
1300 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.")
1302 RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(mm);
1303 if (bmat == Teuchos::null)
return mm;
1310 TEUCHOS_TEST_FOR_EXCEPTION(r >
Rows(), std::out_of_range,
"Error, r = " <<
Rows() <<
" is too big");
1311 TEUCHOS_TEST_FOR_EXCEPTION(c >
Cols(), std::out_of_range,
"Error, c = " <<
Cols() <<
" is too big");
1322 void setMatrix(
size_t r,
size_t c, Teuchos::RCP<Matrix> mat) {
1326 TEUCHOS_TEST_FOR_EXCEPTION(r >
Rows(), std::out_of_range,
"Error, r = " <<
Rows() <<
" is too big");
1327 TEUCHOS_TEST_FOR_EXCEPTION(c >
Cols(), std::out_of_range,
"Error, c = " <<
Cols() <<
" is too big");
1339 using Teuchos::rcp_dynamic_cast;
1340 Scalar one = ScalarTraits<SC>::one();
1343 "BlockedCrsMatrix::Merge: only implemented for Xpetra-style or Thyra-style numbering. No mixup allowed!" );
1346 "BlockedCrsMatrix::Merge: BlockMatrix must be fill-completed." );
1352 for (
size_t i = 0; i <
Rows(); i++) {
1353 for (
size_t j = 0; j <
Cols(); j++) {
1358 RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(mat);
1359 if (bMat != Teuchos::null) mat = bMat->
Merge();
1363 "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!" );
1366 if(mat->getNodeNumEntries() == 0)
continue;
1368 this->
Add(*mat, one, *sparse, one);
1374 for (
size_t i = 0; i <
Rows(); i++) {
1375 for (
size_t j = 0; j <
Cols(); j++) {
1379 RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(mat);
1380 if (bMat != Teuchos::null) mat = bMat->
Merge();
1384 "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!" );
1387 RCP<const CrsMatrixWrap> crsMat = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(mat);
1388 TEUCHOS_ASSERT(crsMat != Teuchos::null);
1391 RCP<const Map> trowMap = mat->getRowMap();
1392 RCP<const Map> tcolMap = mat->getColMap();
1393 RCP<const Map> tdomMap = mat->getDomainMap();
1408 if(mat->getNodeNumEntries() == 0)
continue;
1410 size_t maxNumEntries = mat->getNodeMaxNumRowEntries();
1413 Array<GO> inds (maxNumEntries);
1414 Array<GO> inds2(maxNumEntries);
1415 Array<SC> vals (maxNumEntries);
1418 for (
size_t k = 0; k < mat->getNodeNumRows(); k++) {
1419 GlobalOrdinal rowTGID = trowMap->getGlobalElement(k);
1420 crsMat->getCrsMatrix()->getGlobalRowCopy(rowTGID, inds(), vals(), numEntries);
1423 for (
size_t l = 0; l < numEntries; ++l) {
1424 LocalOrdinal lid = tcolMap->getLocalElement(inds[l]);
1425 inds2[l] = xcolMap->getGlobalElement(lid);
1428 GlobalOrdinal rowXGID = xrowMap->getGlobalElement(k);
1429 sparse->insertGlobalValues(
1430 rowXGID, inds2(0, numEntries),
1431 vals(0, numEntries));
1441 "BlockedCrsMatrix::Merge: Local number of entries of merged matrix does not coincide with local number of entries of blocked operator." );
1444 "BlockedCrsMatrix::Merge: Global number of entries of merged matrix does not coincide with global number of entries of blocked operator." );
1450 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR 1451 typedef typename CrsMatrix::local_matrix_type local_matrix_type;
1454 local_matrix_type getLocalMatrix ()
const {
1456 return getMatrix(0,0)->getLocalMatrix();
1462 #ifdef HAVE_XPETRA_THYRA 1463 Teuchos::RCP<Thyra::BlockedLinearOpBase<Scalar> > getThyraOperator() {
1464 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > thOp =
1465 Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(Teuchos::rcpFromRef(*
this));
1466 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thOp));
1468 Teuchos::RCP<Thyra::BlockedLinearOpBase<Scalar> > thbOp =
1469 Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<Scalar> >(thOp);
1470 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thbOp));
1494 "Matrix A is not completed");
1495 using Teuchos::Array;
1496 using Teuchos::ArrayView;
1500 Scalar one = ScalarTraits<SC>::one();
1501 Scalar zero = ScalarTraits<SC>::zero();
1503 if (scalarA == zero)
1506 Teuchos::RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
1507 Teuchos::RCP<const CrsMatrixWrap> rcpAwrap = Teuchos::rcp_dynamic_cast<
const CrsMatrixWrap>(rcpA);
1509 "BlockedCrsMatrix::Add: matrix A must be of type CrsMatrixWrap.");
1510 Teuchos::RCP<const CrsMatrix> crsA = rcpAwrap->getCrsMatrix();
1512 size_t maxNumEntries = crsA->getNodeMaxNumRowEntries();
1515 Array<GO> inds(maxNumEntries);
1516 Array<SC> vals(maxNumEntries);
1518 RCP<const Map> rowMap = crsA->getRowMap();
1519 RCP<const Map> colMap = crsA->getColMap();
1521 ArrayView<const GO> rowGIDs = crsA->getRowMap()->getNodeElementList();
1522 for (
size_t i = 0; i < crsA->getNodeNumRows(); i++) {
1523 GO row = rowGIDs[i];
1524 crsA->getGlobalRowCopy(row, inds(), vals(), numEntries);
1527 for (
size_t j = 0; j < numEntries; ++j)
1556 #ifdef HAVE_XPETRA_THYRA 1557 Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> > thyraOp_;
1566 #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.
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_
void doImport(const Matrix &source, const Import &importer, CombineMode CM)
Import.
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)
BlockedCrsMatrix(const Teuchos::RCP< const BlockedMap > &rangeMaps, const Teuchos::RCP< const BlockedMap > &domainMaps, size_t npr, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor.
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
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.
virtual bool isDiagonal() const
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 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.
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
std::vector< Teuchos::RCP< Matrix > > blocks_
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 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)
RCP< const Map > getFullDomainMap() const
Returns the Map associated with the full domain of this operator.
#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...
BlockedCrsMatrix(Teuchos::RCP< const MapExtractor > &rangeMaps, Teuchos::RCP< const MapExtractor > &domainMaps, size_t npr, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor.
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)
std::string description() const
Return a simple one-line description of this object.
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 IsView(const viewLabel_t viewLabel) const
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.
static RCP< Matrix > Build(const RCP< const Map > &rowMap, size_t maxNumEntriesPerRow, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor specifying the number of non-zeros for all rows.
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)
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, const Teuchos::RCP< Node > &=Teuchos::null)
Map constructor with Xpetra-defined contiguous uniform distribution.
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_
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.