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