10 #ifndef PACKAGES_XPETRA_SUP_UTILS_XPETRA_MATRIXMATRIX_DEF_HPP_
11 #define PACKAGES_XPETRA_SUP_UTILS_XPETRA_MATRIXMATRIX_DEF_HPP_
15 #include "Xpetra_BlockedCrsMatrix.hpp"
16 #include "Xpetra_CrsMatrixWrap.hpp"
17 #include "Xpetra_MapExtractor.hpp"
18 #include "Xpetra_Map.hpp"
19 #include "Xpetra_MatrixFactory.hpp"
20 #include "Xpetra_Matrix.hpp"
21 #include "Xpetra_StridedMapFactory.hpp"
22 #include "Xpetra_StridedMap.hpp"
24 #ifdef HAVE_XPETRA_EPETRA
28 #ifdef HAVE_XPETRA_EPETRAEXT
29 #include <EpetraExt_MatrixMatrix.h>
30 #include <EpetraExt_RowMatrixOut.h>
31 #include <Epetra_RowMatrixTransposer.h>
32 #endif // HAVE_XPETRA_EPETRAEXT
34 #ifdef HAVE_XPETRA_TPETRA
35 #include <TpetraExt_MatrixMatrix.hpp>
36 #include <Tpetra_RowMatrixTransposer.hpp>
37 #include <MatrixMarket_Tpetra.hpp>
38 #include <Xpetra_TpetraCrsMatrix.hpp>
39 #include <Xpetra_TpetraBlockCrsMatrix.hpp>
40 #include <Tpetra_BlockCrsMatrix_Helpers.hpp>
41 #include <Xpetra_TpetraMultiVector.hpp>
42 #include <Xpetra_TpetraVector.hpp>
43 #endif // HAVE_XPETRA_TPETRA
49 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
51 const Matrix& B,
bool transposeB,
53 bool call_FillComplete_on_result,
54 bool doOptimizeStorage,
55 const std::string& label,
56 const RCP<ParameterList>& params) {
57 TEUCHOS_TEST_FOR_EXCEPTION(transposeA ==
false && C.
getRowMap()->isSameAs(*A.
getRowMap()) ==
false,
65 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
68 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
69 throw(
Xpetra::Exceptions::RuntimeError(
"Xpetra::MatrixMatrix::Multiply only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
75 #ifdef HAVE_XPETRA_TPETRA
77 if (helpers::isTpetraCrs(A) && helpers::isTpetraCrs(B) && helpers::isTpetraCrs(C)) {
79 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpA = helpers::Op2TpetraCrs(A);
80 const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpB = helpers::Op2TpetraCrs(B);
81 Tpetra::CrsMatrix<SC, LO, GO, NO>& tpC = helpers::Op2NonConstTpetraCrs(C);
85 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
86 }
else if (helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(B)) {
91 std::cout <<
"WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
95 using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
96 RCP<const CRS> Acrs = Tpetra::convertToCrsMatrix(tpA);
97 RCP<const CRS> Bcrs = Tpetra::convertToCrsMatrix(tpB);
100 RCP<ParameterList> new_params;
101 if (!params.is_null()) {
102 new_params = rcp(
new Teuchos::ParameterList(*params));
103 new_params->set(
"compute global constants",
true);
107 RCP<CRS> tempAc = Teuchos::rcp(
new CRS(Acrs->getRowMap(), 0));
108 Tpetra::MatrixMatrix::Multiply(*Acrs, transposeA, *Bcrs, transposeB, *tempAc, haveMultiplyDoFillComplete, label, new_params);
111 RCP<Tpetra::BlockCrsMatrix<SC, LO, GO, NO>> Ac_t = Tpetra::convertToBlockCrsMatrix(*tempAc, A.
GetStorageBlockSize());
113 RCP<Xpetra::CrsMatrix<SC, LO, GO, NO>> Ac_p = Ac_x;
120 TEUCHOS_TEST_FOR_EXCEPTION(1,
Exceptions::RuntimeError,
"Mix-and-match Crs/BlockCrs Multiply not currently supported");
127 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
128 RCP<Teuchos::ParameterList> fillParams = rcp(
new Teuchos::ParameterList());
129 fillParams->set(
"Optimize Storage", doOptimizeStorage);
136 RCP<Matrix> rcpA = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(A));
137 RCP<Matrix> rcpB = Teuchos::rcp_const_cast<
Matrix>(Teuchos::rcpFromRef(B));
138 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
141 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
142 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(
const Matrix& A,
bool transposeA,
const Matrix& B,
bool transposeB, RCP<Matrix> C_in,
143 Teuchos::FancyOStream& fos,
145 bool doOptimizeStorage,
146 const std::string& label,
147 const RCP<ParameterList>& params) {
152 RCP<Matrix> C = C_in;
154 if (C == Teuchos::null) {
155 double nnzPerRow = Teuchos::as<double>(0);
164 nnzPerRow *= nnzPerRow;
167 if (totalNnz < minNnz)
171 fos <<
"Matrix product nnz per row estimate = " << Teuchos::as<LO>(nnzPerRow) << std::endl;
181 fos <<
"Reuse C pattern" << std::endl;
184 Multiply(A, transposeA, B, transposeB, *C, doFillComplete, doOptimizeStorage, label, params);
189 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
190 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>>
MatrixMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Multiply(
const Matrix& A,
bool transposeA,
const Matrix& B,
bool transposeB, Teuchos::FancyOStream& fos,
191 bool callFillCompleteOnResult,
bool doOptimizeStorage,
const std::string& label,
192 const RCP<ParameterList>& params) {
193 return Multiply(A, transposeA, B, transposeB, Teuchos::null, fos, callFillCompleteOnResult, doOptimizeStorage, label, params);
196 #ifdef HAVE_XPETRA_EPETRAEXT
197 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
199 const Epetra_CrsMatrix& epB,
200 Teuchos::FancyOStream& fos) {
201 throw(
Xpetra::Exceptions::RuntimeError(
"MLTwoMatrixMultiply only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
202 TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
204 #endif // ifdef HAVE_XPETRA_EPETRAEXT
206 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
209 Teuchos::FancyOStream& fos,
211 bool doOptimizeStorage) {
213 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
222 RCP<BlockedCrsMatrix> C = rcp(
new BlockedCrsMatrix(rgmapextractor, domapextractor, 33 ));
224 for (
size_t i = 0; i < A.
Rows(); ++i) {
225 for (
size_t j = 0; j < B.
Cols(); ++j) {
228 for (
size_t l = 0; l < B.
Rows(); ++l) {
232 if (crmat1.is_null() || crmat2.is_null())
240 if (unwrap1.is_null() != unwrap2.is_null()) {
241 if (unwrap1 != Teuchos::null && unwrap1->Rows() == 1 && unwrap1->Cols() == 1)
243 if (unwrap2 != Teuchos::null && unwrap2->Rows() == 1 && unwrap2->Cols() == 1)
244 crmat2 = unwrap2->getCrsMatrix();
248 RCP<CrsMatrixWrap> crop1 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat1);
249 RCP<CrsMatrixWrap> crop2 = Teuchos::rcp_dynamic_cast<
CrsMatrixWrap>(crmat2);
251 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
254 if (!crop1.is_null())
255 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
256 if (!crop2.is_null())
257 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
260 "crmat1 does not have global constants");
262 "crmat2 does not have global constants");
264 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
268 RCP<Matrix> temp = Teuchos::null;
270 if (crop1 != Teuchos::null && crop2 != Teuchos::null)
271 temp = Multiply(*crop1,
false, *crop2,
false, fos);
273 RCP<BlockedCrsMatrix> bop1 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat1);
274 RCP<BlockedCrsMatrix> bop2 = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(crmat2);
275 TEUCHOS_TEST_FOR_EXCEPTION(bop1.is_null() ==
true,
Xpetra::Exceptions::BadCast,
"A is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
276 TEUCHOS_TEST_FOR_EXCEPTION(bop2.is_null() ==
true,
Xpetra::Exceptions::BadCast,
"B is not a BlockedCrsMatrix. (TwoMatrixMultiplyBlock)");
277 TEUCHOS_TEST_FOR_EXCEPTION(bop1->Cols() != bop2->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << bop1->Cols() <<
" columns and B has " << bop2->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
278 TEUCHOS_TEST_FOR_EXCEPTION(bop1->getDomainMap()->isSameAs(*(bop2->getRangeMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixMultiplyBlock)");
281 temp = TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
283 RCP<BlockedCrsMatrix> btemp = Teuchos::rcp_dynamic_cast<
BlockedCrsMatrix>(temp);
284 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Rows() != bop1->Rows(),
Xpetra::Exceptions::RuntimeError,
"Number of block rows of local blocked operator is " << btemp->Rows() <<
" but should be " << bop1->Rows() <<
". (TwoMatrixMultiplyBlock)");
285 TEUCHOS_TEST_FOR_EXCEPTION(btemp->Cols() != bop2->Cols(),
Xpetra::Exceptions::RuntimeError,
"Number of block cols of local blocked operator is " << btemp->Cols() <<
" but should be " << bop2->Cols() <<
". (TwoMatrixMultiplyBlock)");
286 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getFullMap()->isSameAs(*(bop1->getRangeMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of local blocked operator should be same as first operator. (TwoMatrixMultiplyBlock)");
287 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getFullMap()->isSameAs(*(bop2->getDomainMapExtractor()->getFullMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of local blocked operator should be same as second operator. (TwoMatrixMultiplyBlock)");
288 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getRangeMapExtractor()->getThyraMode() != bop1->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local range map extractor incompatible with range map extractor of A (TwoMatrixMultiplyBlock)");
289 TEUCHOS_TEST_FOR_EXCEPTION(btemp->getDomainMapExtractor()->getThyraMode() != bop2->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Thyra mode of local domain map extractor incompatible with domain map extractor of B (TwoMatrixMultiplyBlock)");
294 RCP<Matrix> addRes = null;
303 if (!Cij.is_null()) {
304 if (Cij->isFillComplete())
307 C->setMatrix(i, j, Cij);
309 C->setMatrix(i, j, Teuchos::null);
320 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
326 throw Exceptions::RuntimeError(
"TwoMatrixAdd for Epetra matrices needs <double,int,int> for Scalar, LocalOrdinal and GlobalOrdinal.");
328 #ifdef HAVE_XPETRA_TPETRA
332 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, beta);
339 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
341 const Matrix& B,
bool transposeB,
const SC& beta,
342 RCP<Matrix>& C, Teuchos::FancyOStream& fos,
bool AHasFixedNnzPerRow) {
343 RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
344 RCP<const Matrix> rcpB = Teuchos::rcpFromRef(B);
345 RCP<const BlockedCrsMatrix> rcpBopA = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpA);
346 RCP<const BlockedCrsMatrix> rcpBopB = Teuchos::rcp_dynamic_cast<
const BlockedCrsMatrix>(rcpB);
354 if (rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
360 #ifdef HAVE_XPETRA_TPETRA
361 using tcrs_matrix_type = Tpetra::CrsMatrix<SC, LO, GO, NO>;
363 const tcrs_matrix_type& tpA = helpers::Op2TpetraCrs(A);
364 const tcrs_matrix_type& tpB = helpers::Op2TpetraCrs(B);
365 C = helpers::tpetraAdd(tpA, transposeA, alpha, tpB, transposeB, beta);
371 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
372 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
376 else if (rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
377 RCP<const MapExtractor> rgmapextractor = rcpBopB->getRangeMapExtractor();
378 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
384 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
385 RCP<Matrix> Cij = Teuchos::null;
386 if (rcpA != Teuchos::null &&
387 rcpBopB->getMatrix(i, j) != Teuchos::null) {
389 TwoMatrixAdd(*rcpA, transposeA, alpha,
390 *(rcpBopB->getMatrix(i, j)), transposeB, beta,
391 Cij, fos, AHasFixedNnzPerRow);
392 }
else if (rcpA == Teuchos::null &&
393 rcpBopB->getMatrix(i, j) != Teuchos::null) {
394 Cij = rcpBopB->getMatrix(i, j);
395 }
else if (rcpA != Teuchos::null &&
396 rcpBopB->getMatrix(i, j) == Teuchos::null) {
397 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpA);
402 if (!Cij.is_null()) {
403 if (Cij->isFillComplete())
406 bC->setMatrix(i, j, Cij);
408 bC->setMatrix(i, j, Teuchos::null);
413 else if (rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
414 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
415 RCP<const MapExtractor> domapextractor = rcpBopA->getDomainMapExtractor();
420 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
421 RCP<Matrix> Cij = Teuchos::null;
422 if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
423 rcpB != Teuchos::null) {
425 TwoMatrixAdd(*(rcpBopA->getMatrix(i, j)), transposeA, alpha,
426 *rcpB, transposeB, beta,
427 Cij, fos, AHasFixedNnzPerRow);
428 }
else if (rcpBopA->getMatrix(i, j) == Teuchos::null &&
429 rcpB != Teuchos::null) {
430 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpB);
431 }
else if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
432 rcpB == Teuchos::null) {
433 Cij = rcpBopA->getMatrix(i, j);
438 if (!Cij.is_null()) {
439 if (Cij->isFillComplete())
442 bC->setMatrix(i, j, Cij);
444 bC->setMatrix(i, j, Teuchos::null);
453 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows() != rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Rows() <<
" rows and B has " << rcpBopA->Rows() <<
" rows. Matrices are not compatible! (TwoMatrixAdd)");
454 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->Rows() != rcpBopB->Rows(),
Xpetra::Exceptions::RuntimeError,
"A has " << rcpBopA->Cols() <<
" cols and B has " << rcpBopA->Cols() <<
" cols. Matrices are not compatible! (TwoMatrixAdd)");
455 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMap()->isSameAs(*(rcpBopB->getRangeMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Range map of A is not the same as range map of B. Matrices are not compatible! (TwoMatrixAdd)");
456 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMap()->isSameAs(*(rcpBopB->getDomainMap())) ==
false,
Xpetra::Exceptions::RuntimeError,
"Domain map of A is not the same as domain map of B. Matrices are not compatible! (TwoMatrixAdd)");
457 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getRangeMapExtractor()->getThyraMode() != rcpBopB->getRangeMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in RangeMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
458 TEUCHOS_TEST_FOR_EXCEPTION(rcpBopA->getDomainMapExtractor()->getThyraMode() != rcpBopB->getDomainMapExtractor()->getThyraMode(),
Xpetra::Exceptions::RuntimeError,
"Different Thyra/Xpetra style gids in DomainMapExtractor of A and B. Matrices are not compatible! (TwoMatrixAdd)");
460 RCP<const MapExtractor> rgmapextractor = rcpBopA->getRangeMapExtractor();
461 RCP<const MapExtractor> domapextractor = rcpBopB->getDomainMapExtractor();
465 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
466 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
468 RCP<Matrix> Cij = Teuchos::null;
469 if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
470 rcpBopB->getMatrix(i, j) != Teuchos::null) {
472 TwoMatrixAdd(*(rcpBopA->getMatrix(i, j)), transposeA, alpha,
473 *(rcpBopB->getMatrix(i, j)), transposeB, beta,
474 Cij, fos, AHasFixedNnzPerRow);
475 }
else if (rcpBopA->getMatrix(i, j) == Teuchos::null &&
476 rcpBopB->getMatrix(i, j) != Teuchos::null) {
477 Cij = rcpBopB->getMatrix(i, j);
478 }
else if (rcpBopA->getMatrix(i, j) != Teuchos::null &&
479 rcpBopB->getMatrix(i, j) == Teuchos::null) {
480 Cij = rcpBopA->getMatrix(i, j);
485 if (!Cij.is_null()) {
486 if (Cij->isFillComplete())
489 bC->setMatrix(i, j, Cij);
491 bC->setMatrix(i, j, Teuchos::null);
static RCP< BlockedCrsMatrix > TwoMatrixMultiplyBlock(const BlockedCrsMatrix &A, bool transposeA, const BlockedCrsMatrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true)
Helper function to do matrix-matrix multiply "in-place".
virtual global_size_t getGlobalNumRows() const =0
Returns the number of global rows in this matrix.
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. ...
Xpetra utility class containing transformation routines between Xpetra::Matrix and Epetra/Tpetra obje...
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
virtual void resumeFill(const RCP< ParameterList > ¶ms=null)=0
virtual LocalOrdinal GetStorageBlockSize() const =0
Returns the block size of the storage mechanism, which is usually 1, except for Tpetra::BlockCrsMatri...
Exception throws to report errors in the internal logical of the program.
virtual size_t Cols() const
number of column blocks
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< Matrix > Op)
const RCP< const Map > getDomainMap() const
Returns the Map associated with the domain of this operator.
Exception indicating invalid cast attempted.
virtual void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > ¶ms=null)=0
Signal that data entry is complete, specifying domain and range maps.
bool IsView(const viewLabel_t viewLabel) const
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
void CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
static RCP< Epetra_CrsMatrix > MLTwoMatrixMultiply(const Epetra_CrsMatrix &epA, const Epetra_CrsMatrix &epB, Teuchos::FancyOStream &fos)
virtual size_t Rows() const
number of row blocks
const RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
virtual const Teuchos::RCP< const map_type > getRangeMap() const =0
The Map associated with the range of this operator, which must be compatible with Y...
static RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraCrs(RCP< Matrix > Op)
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
void replaceCrsMatrix(RCP< CrsMatrix > &M)
Expert only.
static RCP< Matrix > Build(const RCP< const Map > &rowMap)
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
Exception throws to report incompatible objects (like maps).
virtual global_size_t getGlobalNumEntries() const =0
Returns the global number of entries in this matrix.
Concrete implementation of Xpetra::Matrix.
virtual const Teuchos::RCP< const map_type > getDomainMap() const =0
The Map associated with the domain of this operator, which must be compatible with X...
static RCP< const Tpetra::BlockCrsMatrix< SC, LO, GO, NO > > Op2TpetraBlockCrs(RCP< Matrix > Op)
static void Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Matrix &C, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Teuchos::RCP< Matrix > getCrsMatrix() const
return unwrap 1x1 blocked operators
Xpetra-specific matrix class.