48 #ifndef PACKAGES_XPETRA_SUP_UTILS_XPETRA_MATRIXMATRIX_HPP_
49 #define PACKAGES_XPETRA_SUP_UTILS_XPETRA_MATRIXMATRIX_HPP_
62 #ifdef HAVE_XPETRA_EPETRA
66 #ifdef HAVE_XPETRA_EPETRAEXT
67 #include <EpetraExt_MatrixMatrix.h>
68 #include <EpetraExt_RowMatrixOut.h>
69 #include <Epetra_RowMatrixTransposer.h>
70 #endif // HAVE_XPETRA_EPETRAEXT
72 #ifdef HAVE_XPETRA_TPETRA
73 #include <TpetraExt_MatrixMatrix.hpp>
74 #include <MatrixMarket_Tpetra.hpp>
75 #include <Xpetra_TpetraCrsMatrix.hpp>
76 #include <Xpetra_TpetraMultiVector.hpp>
77 #include <Xpetra_TpetraVector.hpp>
78 #endif // HAVE_XPETRA_TPETRA
88 template <
class Scalar,
89 class LocalOrdinal = int,
90 class GlobalOrdinal = LocalOrdinal,
97 #ifdef HAVE_XPETRA_EPETRA
102 "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
107 "Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
109 return tmp_ECrsMtx->getEpetra_CrsMatrix();
117 "Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed");
121 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null,
Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
123 return tmp_ECrsMtx->getEpetra_CrsMatrixNonConst();
133 "Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed");
135 return *tmp_ECrsMtx->getEpetra_CrsMatrix();
151 return *Teuchos::rcp_const_cast<
Epetra_CrsMatrix>(tmp_ECrsMtx->getEpetra_CrsMatrix());
157 #endif // HAVE_XPETRA_EPETRA
159 #ifdef HAVE_XPETRA_TPETRA
167 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
169 return tmp_ECrsMtx->getTpetra_CrsMatrix();
178 TEUCHOS_TEST_FOR_EXCEPTION(tmp_ECrsMtx == Teuchos::null,
Xpetra::Exceptions::BadCast,
"Cast from Xpetra::CrsMatrix to Xpetra::TpetraCrsMatrix failed");
180 return tmp_ECrsMtx->getTpetra_CrsMatrixNonConst();
191 return *tmp_TCrsMtx->getTpetra_CrsMatrix();
206 return *Teuchos::rcp_const_cast<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(tmp_TCrsMtx->getTpetra_CrsMatrix());
212 #endif // HAVE_XPETRA_TPETRA
216 template <
class Scalar,
218 class GlobalOrdinal ,
221 #undef XPETRA_MATRIXMATRIX_SHORT
251 const Matrix& B,
bool transposeB,
253 bool call_FillComplete_on_result =
true,
254 bool doOptimizeStorage =
true,
255 const std::string & label = std::string(),
266 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
269 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
270 throw(
Xpetra::Exceptions::RuntimeError(
"Xpetra::MatrixMatrix::Multiply only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
276 #ifdef HAVE_XPETRA_TPETRA
283 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
289 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
291 fillParams->
set(
"Optimize Storage", doOptimizeStorage);
300 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
327 bool doFillComplete =
true,
328 bool doOptimizeStorage =
true,
329 const std::string & label = std::string(),
338 if (C == Teuchos::null) {
339 double nnzPerRow = Teuchos::as<double>(0);
348 nnzPerRow *= nnzPerRow;
351 if (totalNnz < minNnz)
355 fos <<
"Matrix product nnz per row estimate = " << Teuchos::as<LO>(nnzPerRow) << std::endl;
363 fos <<
"Reuse C pattern" << std::endl;
366 Multiply(A, transposeA, B, transposeB, *C, doFillComplete, doOptimizeStorage, label, params);
382 bool callFillCompleteOnResult =
true,
bool doOptimizeStorage =
true,
const std::string& label = std::string(),
384 return Multiply(A, transposeA, B, transposeB, Teuchos::null, fos, callFillCompleteOnResult, doOptimizeStorage, label, params);
387 #ifdef HAVE_XPETRA_EPETRAEXT
392 throw(
Xpetra::Exceptions::RuntimeError(
"MLTwoMatrixMultiply only available for GO=int or GO=long long with EpetraNode (Serial or OpenMP depending on configuration)"));
395 #endif //ifdef HAVE_XPETRA_EPETRAEXT
410 bool doFillComplete =
true,
411 bool doOptimizeStorage =
true) {
413 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
424 for (
size_t i = 0; i < A.
Rows(); ++i) {
425 for (
size_t j = 0; j < B.
Cols(); ++j) {
428 for (
size_t l = 0; l < B.
Rows(); ++l) {
438 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
442 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
443 if (!crop2.is_null())
444 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
447 "crmat1 does not have global constants");
449 "crmat2 does not have global constants");
451 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
457 if(crop1 != Teuchos::null && crop2 != Teuchos::null)
458 temp =
Multiply (*crop1,
false, *crop2,
false, fos);
468 temp =
TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
491 if (Cij->isFillComplete())
494 C->setMatrix(i, j, Cij);
496 C->setMatrix(i, j, Teuchos::null);
524 throw Exceptions::RuntimeError(
"TwoMatrixAdd for Epetra matrices needs <double,int,int> for Scalar, LocalOrdinal and GlobalOrdinal.");
526 #ifdef HAVE_XPETRA_TPETRA
530 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, beta);
551 const Matrix& B,
bool transposeB,
const SC& beta,
563 if(rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
569 if (C == Teuchos::null) {
572 size_t numLocalRows = 0;
578 if (maxNzInA == 1 || maxNzInB == 1 || AHasFixedNnzPerRow) {
583 if ((maxNzInA == 1 && maxNzInB > 1) || AHasFixedNnzPerRow) {
584 for (
size_t i = 0; i < numLocalRows; ++i)
588 for (
size_t i = 0; i < numLocalRows; ++i)
592 fos <<
"MatrixMatrix::TwoMatrixAdd : special case detected (one matrix has a fixed nnz per row)"
593 <<
", using static profiling" << std::endl;
599 LO nnzToAllocate = Teuchos::as<LO>( (nnzPerRowInA + nnzPerRowInB) * 1.5) + Teuchos::as<LO>(1);
606 fos <<
"nnzPerRowInA = " << nnzPerRowInA <<
", nnzPerRowInB = " << nnzPerRowInB << std::endl;
607 fos <<
"MatrixMatrix::TwoMatrixAdd : space allocated per row = " << nnzToAllocate
608 <<
", max possible nnz per row in sum = " << maxPossible
614 fos <<
"MatrixMatrix::TwoMatrixAdd : ** WARNING ** estimate could be badly wrong because second summand is transposed" << std::endl;
620 #ifdef HAVE_XPETRA_TPETRA
625 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, transposeB, beta, tpC);
631 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
632 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
636 else if(rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
644 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
646 if(rcpA != Teuchos::null &&
647 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
650 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
651 Cij, fos, AHasFixedNnzPerRow);
652 }
else if (rcpA == Teuchos::null &&
653 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
654 Cij = rcpBopB->getMatrix(i,j);
655 }
else if (rcpA != Teuchos::null &&
656 rcpBopB->getMatrix(i,j)==Teuchos::null) {
657 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpA);
663 if (Cij->isFillComplete())
666 bC->setMatrix(i, j, Cij);
668 bC->setMatrix(i, j, Teuchos::null);
673 else if(rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
680 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
682 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
683 rcpB!=Teuchos::null) {
685 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
686 *rcpB, transposeB, beta,
687 Cij, fos, AHasFixedNnzPerRow);
688 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
689 rcpB!=Teuchos::null) {
690 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpB);
691 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
692 rcpB==Teuchos::null) {
693 Cij = rcpBopA->getMatrix(i,j);
699 if (Cij->isFillComplete())
702 bC->setMatrix(i, j, Cij);
704 bC->setMatrix(i, j, Teuchos::null);
726 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
727 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
730 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
731 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
733 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
734 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
735 Cij, fos, AHasFixedNnzPerRow);
736 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
737 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
738 Cij = rcpBopB->getMatrix(i,j);
739 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
740 rcpBopB->getMatrix(i,j)==Teuchos::null) {
741 Cij = rcpBopA->getMatrix(i,j);
747 if (Cij->isFillComplete())
750 bC->setMatrix(i, j, Cij);
752 bC->setMatrix(i, j, Teuchos::null);
764 #ifdef HAVE_XPETRA_EPETRA
801 const Matrix& B,
bool transposeB,
803 bool call_FillComplete_on_result =
true,
804 bool doOptimizeStorage =
true,
805 const std::string & label = std::string(),
815 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
818 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
823 int i = EpetraExt::MatrixMatrix::Multiply(epA, transposeA, epB, transposeB, epC, haveMultiplyDoFillComplete);
824 if (haveMultiplyDoFillComplete) {
835 std::ostringstream buf;
837 std::string msg =
"EpetraExt::MatrixMatrix::Multiply return value of " + buf.str();
845 #ifdef HAVE_XPETRA_TPETRA
846 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \
847 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT))))
856 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
863 if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
865 fillParams->
set(
"Optimize Storage",doOptimizeStorage);
874 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
900 const Matrix& B,
bool transposeB,
903 bool doFillComplete =
true,
904 bool doOptimizeStorage =
true,
905 const std::string & label = std::string(),
913 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT) && defined(HAVE_XPETRA_ML_MMM)
919 RCP<Matrix> C = Convert_Epetra_CrsMatrix_ToXpetra_CrsMatrixWrap<SC,LO,GO,NO> (epC);
920 if (doFillComplete) {
922 fillParams->
set(
"Optimize Storage", doOptimizeStorage);
929 C->CreateView(
"stridedMaps", rcpFromRef(A), transposeA, rcpFromRef(B), transposeB);
933 #endif // EPETRA + EPETRAEXT + ML
938 if (C == Teuchos::null) {
939 double nnzPerRow = Teuchos::as<double>(0);
948 nnzPerRow *= nnzPerRow;
951 if (totalNnz < minNnz)
955 fos <<
"Matrix product nnz per row estimate = " << Teuchos::as<LO>(nnzPerRow) << std::endl;
964 fos <<
"Reuse C pattern" << std::endl;
967 Multiply(A, transposeA, B, transposeB, *C, doFillComplete, doOptimizeStorage, label, params);
983 const Matrix& B,
bool transposeB,
985 bool callFillCompleteOnResult =
true,
986 bool doOptimizeStorage =
true,
987 const std::string & label = std::string(),
989 return Multiply(A, transposeA, B, transposeB, Teuchos::null, fos, callFillCompleteOnResult, doOptimizeStorage, label, params);
992 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
997 #if defined(HAVE_XPETRA_ML_MMM) // Note: this is currently not supported
999 ML_Comm_Create(&comm);
1000 fos <<
"****** USING ML's MATRIX MATRIX MULTIPLY ******" << std::endl;
1005 ML_Comm_Set_UsrComm(comm,Mcomm->
GetMpiComm());
1008 EpetraExt::CrsMatrix_SolverMap Atransform;
1009 EpetraExt::CrsMatrix_SolverMap Btransform;
1010 const Epetra_CrsMatrix& A = Atransform(const_cast<Epetra_CrsMatrix&>(epA));
1011 const Epetra_CrsMatrix& B = Btransform(const_cast<Epetra_CrsMatrix&>(epB));
1017 ML_Operator* ml_As = ML_Operator_Create(comm);
1018 ML_Operator* ml_Bs = ML_Operator_Create(comm);
1019 ML_Operator_WrapEpetraCrsMatrix(const_cast<Epetra_CrsMatrix*>(&A),ml_As);
1020 ML_Operator_WrapEpetraCrsMatrix(const_cast<Epetra_CrsMatrix*>(&B),ml_Bs);
1021 ML_Operator* ml_AtimesB = ML_Operator_Create(comm);
1024 ML_2matmult(ml_As,ml_Bs,ml_AtimesB,ML_CSR_MATRIX);
1026 ML_Operator_Destroy(&ml_As);
1027 ML_Operator_Destroy(&ml_Bs);
1032 int N_local = ml_AtimesB->invec_leng;
1033 ML_CommInfoOP* getrow_comm = ml_AtimesB->getrow->pre_comm;
1035 ML_Comm* comm_AB = ml_AtimesB->comm;
1041 for (
int i = 0; i < getrow_comm->N_neighbors; i++) {
1042 N_rcvd += (getrow_comm->neighbors)[i].N_rcv;
1043 N_send += (getrow_comm->neighbors)[i].N_send;
1044 if ( ((getrow_comm->neighbors)[i].N_rcv != 0) &&
1045 ((getrow_comm->neighbors)[i].rcv_list != NULL) ) flag = 1;
1049 std::vector<double> dtemp(N_local + N_rcvd + 1);
1050 std::vector<int> cmap (N_local + N_rcvd + 1);
1051 for (
int i = 0; i < N_local; ++i) {
1053 dtemp[i] = (double) cmap[i];
1055 ML_cheap_exchange_bdry(&dtemp[0],getrow_comm,N_local,N_send,comm_AB);
1057 int count = N_local;
1058 const int neighbors = getrow_comm->N_neighbors;
1059 for (
int i = 0; i < neighbors; i++) {
1060 const int nrcv = getrow_comm->neighbors[i].N_rcv;
1061 for (
int j = 0; j < nrcv; j++)
1062 cmap[getrow_comm->neighbors[i].rcv_list[j]] = (
int) dtemp[count++];
1065 for (
int i = 0; i < N_local+N_rcvd; ++i)
1066 cmap[i] = (
int)dtemp[i];
1084 int educatedguess = 0;
1085 for (
int i = 0; i < myrowlength; ++i) {
1087 ML_get_matrix_row(ml_AtimesB, 1, &i, &allocated, &bindx, &val, &rowlength, 0);
1088 if (rowlength>educatedguess)
1089 educatedguess = rowlength;
1095 std::vector<int> gcid(educatedguess);
1096 for (
int i = 0; i < myrowlength; ++i) {
1097 const int grid = rowmap.
GID(i);
1099 ML_get_matrix_row(ml_AtimesB, 1, &i, &allocated, &bindx, &val, &rowlength, 0);
1100 if (!rowlength)
continue;
1101 if ((
int)gcid.size() < rowlength) gcid.resize(rowlength);
1102 for (
int j = 0; j < rowlength; ++j) {
1103 gcid[j] = gcmap.GID(bindx[j]);
1108 if (err != 0 && err != 1) {
1109 std::ostringstream errStr;
1110 errStr <<
"Epetra_CrsMatrix::InsertGlobalValues returned err=" << err;
1115 if (bindx) ML_free(bindx);
1116 if (val) ML_free(val);
1117 ML_Operator_Destroy(&ml_AtimesB);
1118 ML_Comm_Destroy(&comm);
1121 #else // no MUELU_ML
1126 "No ML multiplication available. This feature is currently not supported by Xpetra.");
1130 #endif //ifdef HAVE_XPETRA_EPETRAEXT
1145 bool doFillComplete =
true,
1146 bool doOptimizeStorage =
true) {
1148 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
1159 for (
size_t i = 0; i < A.
Rows(); ++i) {
1160 for (
size_t j = 0; j < B.
Cols(); ++j) {
1163 for (
size_t l = 0; l < B.
Rows(); ++l) {
1173 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
1177 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
1178 if (!crop2.is_null())
1179 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
1182 "crmat1 does not have global constants");
1184 "crmat2 does not have global constants");
1186 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
1193 if(crop1 != Teuchos::null && crop2 != Teuchos::null)
1194 temp =
Multiply (*crop1,
false, *crop2,
false, fos);
1204 temp =
TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
1227 if (Cij->isFillComplete())
1230 C->setMatrix(i, j, Cij);
1232 C->setMatrix(i, j, Teuchos::null);
1257 "TwoMatrixAdd: matrix row maps are not the same.");
1260 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
1265 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, beta);
1269 std::ostringstream buf;
1274 #ifdef HAVE_XPETRA_TPETRA
1275 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \
1276 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT))))
1282 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, beta);
1304 const Matrix& B,
bool transposeB,
const SC& beta,
1311 if(rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
1317 if (C == Teuchos::null) {
1318 size_t maxNzInA = 0;
1319 size_t maxNzInB = 0;
1320 size_t numLocalRows = 0;
1328 if (maxNzInA == 1 || maxNzInB == 1 || AHasFixedNnzPerRow) {
1333 if ((maxNzInA == 1 && maxNzInB > 1) || AHasFixedNnzPerRow) {
1334 for (
size_t i = 0; i < numLocalRows; ++i)
1338 for (
size_t i = 0; i < numLocalRows; ++i)
1342 fos <<
"MatrixMatrix::TwoMatrixAdd : special case detected (one matrix has a fixed nnz per row)"
1343 <<
", using static profiling" << std::endl;
1350 LO nnzToAllocate = Teuchos::as<LO>( (nnzPerRowInA + nnzPerRowInB) * 1.5) + Teuchos::as<LO>(1);
1357 fos <<
"nnzPerRowInA = " << nnzPerRowInA <<
", nnzPerRowInB = " << nnzPerRowInB << std::endl;
1358 fos <<
"MatrixMatrix::TwoMatrixAdd : space allocated per row = " << nnzToAllocate
1359 <<
", max possible nnz per row in sum = " << maxPossible
1365 fos <<
"MatrixMatrix::TwoMatrixAdd : ** WARNING ** estimate could be badly wrong because second summand is transposed" << std::endl;
1369 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
1376 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, transposeB, beta, ref2epC);
1384 #ifdef HAVE_XPETRA_TPETRA
1385 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \
1386 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT))))
1393 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, transposeB, beta, tpC);
1401 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
1402 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
1406 else if(rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
1414 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
1416 if(rcpA != Teuchos::null &&
1417 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1420 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
1421 Cij, fos, AHasFixedNnzPerRow);
1422 }
else if (rcpA == Teuchos::null &&
1423 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1424 Cij = rcpBopB->getMatrix(i,j);
1425 }
else if (rcpA != Teuchos::null &&
1426 rcpBopB->getMatrix(i,j)==Teuchos::null) {
1427 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpA);
1429 Cij = Teuchos::null;
1433 if (Cij->isFillComplete())
1435 Cij->fillComplete();
1436 bC->setMatrix(i, j, Cij);
1438 bC->setMatrix(i, j, Teuchos::null);
1443 else if(rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
1451 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
1453 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
1454 rcpB!=Teuchos::null) {
1456 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
1457 *rcpB, transposeB, beta,
1458 Cij, fos, AHasFixedNnzPerRow);
1459 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
1460 rcpB!=Teuchos::null) {
1461 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpB);
1462 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
1463 rcpB==Teuchos::null) {
1464 Cij = rcpBopA->getMatrix(i,j);
1466 Cij = Teuchos::null;
1470 if (Cij->isFillComplete())
1472 Cij->fillComplete();
1473 bC->setMatrix(i, j, Cij);
1475 bC->setMatrix(i, j, Teuchos::null);
1498 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
1499 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
1502 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
1503 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1506 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
1507 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
1508 Cij, fos, AHasFixedNnzPerRow);
1509 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
1510 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
1511 Cij = rcpBopB->getMatrix(i,j);
1512 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
1513 rcpBopB->getMatrix(i,j)==Teuchos::null) {
1514 Cij = rcpBopA->getMatrix(i,j);
1516 Cij = Teuchos::null;
1520 if (Cij->isFillComplete())
1523 Cij->fillComplete();
1524 bC->setMatrix(i, j, Cij);
1526 bC->setMatrix(i, j, Teuchos::null);
1571 const Matrix& B,
bool transposeB,
1573 bool call_FillComplete_on_result =
true,
1574 bool doOptimizeStorage =
true,
1575 const std::string & label = std::string(),
1586 bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
1589 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
1594 int i = EpetraExt::MatrixMatrix::Multiply(epA, transposeA, epB, transposeB, epC, haveMultiplyDoFillComplete);
1595 if (haveMultiplyDoFillComplete) {
1606 std::ostringstream buf;
1608 std::string msg =
"EpetraExt::MatrixMatrix::Multiply return value of " + buf.str();
1616 #ifdef HAVE_XPETRA_TPETRA
1617 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \
1618 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))))
1627 Tpetra::MatrixMatrix::Multiply(tpA, transposeA, tpB, transposeB, tpC, haveMultiplyDoFillComplete, label, params);
1634 if(call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
1636 fillParams->
set(
"Optimize Storage",doOptimizeStorage);
1645 C.
CreateView(
"stridedMaps", rcpA, transposeA, rcpB, transposeB);
1671 const Matrix& B,
bool transposeB,
1674 bool doFillComplete =
true,
1675 bool doOptimizeStorage =
true,
1676 const std::string & label = std::string(),
1685 if (C == Teuchos::null) {
1686 double nnzPerRow = Teuchos::as<double>(0);
1695 nnzPerRow *= nnzPerRow;
1698 if (totalNnz < minNnz)
1702 fos <<
"Matrix product nnz per row estimate = " << Teuchos::as<LO>(nnzPerRow) << std::endl;
1710 fos <<
"Reuse C pattern" << std::endl;
1713 Multiply(A, transposeA, B, transposeB, *C, doFillComplete, doOptimizeStorage, label, params);
1729 const Matrix& B,
bool transposeB,
1731 bool callFillCompleteOnResult =
true,
1732 bool doOptimizeStorage =
true,
1733 const std::string & label = std::string(),
1735 return Multiply(A, transposeA, B, transposeB, Teuchos::null, fos, callFillCompleteOnResult, doOptimizeStorage, label, params);
1738 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
1744 "No ML multiplication available. This feature is currently not supported by Xpetra.");
1747 #endif //ifdef HAVE_XPETRA_EPETRAEXT
1762 bool doFillComplete =
true,
1763 bool doOptimizeStorage =
true) {
1765 "TwoMatrixMultiply for BlockedCrsMatrix not implemented for transposeA==true or transposeB==true");
1776 for (
size_t i = 0; i < A.
Rows(); ++i) {
1777 for (
size_t j = 0; j < B.
Cols(); ++j) {
1780 for (
size_t l = 0; l < B.
Rows(); ++l) {
1790 "A and B must be either both (compatible) BlockedCrsMatrix objects or both CrsMatrixWrap objects.");
1794 Teuchos::rcp_const_cast<CrsGraph>(crmat1->getCrsGraph())->computeGlobalConstants();
1795 if (!crop2.is_null())
1796 Teuchos::rcp_const_cast<CrsGraph>(crmat2->getCrsGraph())->computeGlobalConstants();
1799 "crmat1 does not have global constants");
1801 "crmat2 does not have global constants");
1803 if (crmat1->getGlobalNumEntries() == 0 || crmat2->getGlobalNumEntries() == 0)
1809 if(crop1 != Teuchos::null && crop2 != Teuchos::null)
1810 temp =
Multiply (*crop1,
false, *crop2,
false, fos);
1820 temp =
TwoMatrixMultiplyBlock(*bop1, transposeA, *bop2, transposeB, fos, doFillComplete, doOptimizeStorage);
1843 if (Cij->isFillComplete())
1846 C->setMatrix(i, j, Cij);
1848 C->setMatrix(i, j, Teuchos::null);
1873 "TwoMatrixAdd: matrix row maps are not the same.");
1876 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
1881 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, beta);
1885 std::ostringstream buf;
1890 #ifdef HAVE_XPETRA_TPETRA
1891 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \
1892 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))))
1898 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, beta);
1920 const Matrix& B,
bool transposeB,
const SC& beta,
1927 if(rcpBopA == Teuchos::null && rcpBopB == Teuchos::null) {
1929 "TwoMatrixAdd: matrix row maps are not the same.");
1931 if (C == Teuchos::null) {
1932 size_t maxNzInA = 0;
1933 size_t maxNzInB = 0;
1934 size_t numLocalRows = 0;
1941 if (maxNzInA == 1 || maxNzInB == 1 || AHasFixedNnzPerRow) {
1946 if ((maxNzInA == 1 && maxNzInB > 1) || AHasFixedNnzPerRow) {
1947 for (
size_t i = 0; i < numLocalRows; ++i)
1951 for (
size_t i = 0; i < numLocalRows; ++i)
1955 fos <<
"MatrixMatrix::TwoMatrixAdd : special case detected (one matrix has a fixed nnz per row)"
1956 <<
", using static profiling" << std::endl;
1963 LO nnzToAllocate = Teuchos::as<LO>( (nnzPerRowInA + nnzPerRowInB) * 1.5) + Teuchos::as<LO>(1);
1970 fos <<
"nnzPerRowInA = " << nnzPerRowInA <<
", nnzPerRowInB = " << nnzPerRowInB << std::endl;
1971 fos <<
"MatrixMatrix::TwoMatrixAdd : space allocated per row = " << nnzToAllocate
1972 <<
", max possible nnz per row in sum = " << maxPossible
1978 fos <<
"MatrixMatrix::TwoMatrixAdd : ** WARNING ** estimate could be badly wrong because second summand is transposed" << std::endl;
1982 #if defined(HAVE_XPETRA_EPETRA) && defined(HAVE_XPETRA_EPETRAEXT)
1989 int rv = EpetraExt::MatrixMatrix::Add(epA, transposeA, alpha, epB, transposeB, beta, ref2epC);
1997 #ifdef HAVE_XPETRA_TPETRA
1998 # if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \
1999 (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))))
2006 Tpetra::MatrixMatrix::Add(tpA, transposeA, alpha, tpB, transposeB, beta, tpC);
2014 if (A.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(A));
2015 if (B.
IsView(
"stridedMaps")) C->CreateView(
"stridedMaps", rcpFromRef(B));
2019 else if(rcpBopA == Teuchos::null && rcpBopB != Teuchos::null) {
2027 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
2029 if(rcpA != Teuchos::null &&
2030 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2033 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
2034 Cij, fos, AHasFixedNnzPerRow);
2035 }
else if (rcpA == Teuchos::null &&
2036 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2037 Cij = rcpBopB->getMatrix(i,j);
2038 }
else if (rcpA != Teuchos::null &&
2039 rcpBopB->getMatrix(i,j)==Teuchos::null) {
2040 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpA);
2042 Cij = Teuchos::null;
2046 if (Cij->isFillComplete())
2048 Cij->fillComplete();
2049 bC->setMatrix(i, j, Cij);
2051 bC->setMatrix(i, j, Teuchos::null);
2056 else if(rcpBopA != Teuchos::null && rcpBopB == Teuchos::null) {
2064 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
2066 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
2067 rcpB!=Teuchos::null) {
2069 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
2070 *rcpB, transposeB, beta,
2071 Cij, fos, AHasFixedNnzPerRow);
2072 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
2073 rcpB!=Teuchos::null) {
2074 Cij = Teuchos::rcp_const_cast<
Matrix>(rcpB);
2075 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
2076 rcpB==Teuchos::null) {
2077 Cij = rcpBopA->getMatrix(i,j);
2079 Cij = Teuchos::null;
2083 if (Cij->isFillComplete())
2085 Cij->fillComplete();
2086 bC->setMatrix(i, j, Cij);
2088 bC->setMatrix(i, j, Teuchos::null);
2111 for (
size_t i = 0; i < rcpBopA->Rows(); ++i) {
2112 for (
size_t j = 0; j < rcpBopB->Cols(); ++j) {
2115 if(rcpBopA->getMatrix(i,j)!=Teuchos::null &&
2116 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2119 TwoMatrixAdd(*(rcpBopA->getMatrix(i,j)), transposeA, alpha,
2120 *(rcpBopB->getMatrix(i,j)), transposeB, beta,
2121 Cij, fos, AHasFixedNnzPerRow);
2122 }
else if (rcpBopA->getMatrix(i,j) == Teuchos::null &&
2123 rcpBopB->getMatrix(i,j)!=Teuchos::null) {
2124 Cij = rcpBopB->getMatrix(i,j);
2125 }
else if (rcpBopA->getMatrix(i,j) != Teuchos::null &&
2126 rcpBopB->getMatrix(i,j)==Teuchos::null) {
2127 Cij = rcpBopA->getMatrix(i,j);
2129 Cij = Teuchos::null;
2133 if (Cij->isFillComplete())
2136 Cij->fillComplete();
2137 bC->setMatrix(i, j, Cij);
2139 bC->setMatrix(i, j, Teuchos::null);
2148 #endif // HAVE_XPETRA_EPETRA
2152 #define XPETRA_MATRIXMATRIX_SHORT
virtual size_t getNodeMaxNumRowEntries() const =0
Returns the maximum number of entries across all rows/columns on this node.
virtual size_t getNodeNumRows() const =0
Returns the number of matrix rows owned on the calling node.
const Epetra_Map & RangeMap() const
static void TwoMatrixAdd(const Matrix &A, bool transposeA, const SC &alpha, const Matrix &B, bool transposeB, const SC &beta, RCP< Matrix > &C, Teuchos::FancyOStream &fos, bool AHasFixedNnzPerRow=false)
Helper function to calculate C = alpha*A + beta*B.
virtual size_t getNodeNumEntries() const =0
Returns the local number of entries in this matrix.
static void TwoMatrixAdd(const Matrix &A, bool transposeA, const SC &alpha, const Matrix &B, bool transposeB, const SC &beta, RCP< Matrix > &C, Teuchos::FancyOStream &fos, bool AHasFixedNnzPerRow=false)
Helper function to calculate C = alpha*A + beta*B.
MPI_Comm GetMpiComm() const
RCP< CrsMatrix > getCrsMatrix() const
virtual global_size_t getGlobalNumRows() const =0
Returns the number of global rows in this matrix.
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, RCP< Matrix > C_in, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
bool isFillComplete() const
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
static Epetra_CrsMatrix & Op2NonConstEpetraCrs(const Matrix &Op)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Xpetra utility class containing transformation routines between Xpetra::Matrix and Epetra/Tpetra obje...
Exception throws to report errors in the internal logical of the program.
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".
const Epetra_Map & ColMap() const
static const Epetra_CrsMatrix & Op2EpetraCrs(const Matrix &Op)
static RCP< Time > getNewTimer(const std::string &name)
Exception indicating invalid cast attempted.
const Epetra_Map & RowMap() const
int NumMyElements() const
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.
static void TwoMatrixAdd(const Matrix &A, bool transposeA, const SC &alpha, const Matrix &B, bool transposeB, const SC &beta, RCP< Matrix > &C, Teuchos::FancyOStream &fos, bool AHasFixedNnzPerRow=false)
Helper function to calculate C = alpha*A + beta*B.
static RCP< Epetra_CrsMatrix > MLTwoMatrixMultiply(const Epetra_CrsMatrix &, const Epetra_CrsMatrix &, Teuchos::FancyOStream &)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool callFillCompleteOnResult=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
bool IsView(const viewLabel_t viewLabel) const
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
virtual size_t Cols() const
number of column blocks
void CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
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)
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, RCP< Matrix > C_in, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
static Tpetra::CrsMatrix< SC, LO, GO, NO > & Op2NonConstTpetraCrs(const Matrix &Op)
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, RCP< Matrix > C_in, Teuchos::FancyOStream &fos, bool doFillComplete=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
virtual size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const =0
Returns the current number of entries on this node in the specified local row.
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)
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".
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
static RCP< const Epetra_CrsMatrix > Op2EpetraCrs(RCP< Matrix > Op)
RCP< const MapExtractor > getDomainMapExtractor() const
Returns map extractor for domain map.
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
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)
static RCP< Epetra_CrsMatrix > Op2NonConstEpetraCrs(RCP< Matrix > Op)
const Epetra_Map & DomainMap() const
Exception throws to report incompatible objects (like maps).
RCP< const Map > getDomainMap() const
Returns the Map associated with the domain of this operator.
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
virtual global_size_t getGlobalNumEntries() const =0
Returns the global number of entries in this matrix.
Concrete implementation of Xpetra::Matrix.
virtual Teuchos::RCP< const Map > getRangeMap() const =0
The Map associated with the range of this operator, which must be compatible with Y...
virtual size_t Rows() const
number of row blocks
static RCP< Epetra_CrsMatrix > MLTwoMatrixMultiply(const Epetra_CrsMatrix &epA, const Epetra_CrsMatrix &epB, Teuchos::FancyOStream &fos)
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.
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 const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
static RCP< Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2NonConstTpetraCrs(RCP< Matrix > Op)
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool callFillCompleteOnResult=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
const Epetra_Comm & Comm() const
static RCP< Epetra_CrsMatrix > MLTwoMatrixMultiply(const Epetra_CrsMatrix &epA, const Epetra_CrsMatrix &epB, Teuchos::FancyOStream &fos)
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
static const Tpetra::CrsMatrix< SC, LO, GO, NO > & Op2TpetraCrs(const Matrix &Op)
virtual Teuchos::RCP< const Map > getDomainMap() const =0
The Map associated with the domain of this operator, which must be compatible with X...
Xpetra-specific matrix class.
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< Matrix > Op)
std::string toString(const T &t)
static RCP< Matrix > Multiply(const Matrix &A, bool transposeA, const Matrix &B, bool transposeB, Teuchos::FancyOStream &fos, bool callFillCompleteOnResult=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > ¶ms=null)
Helper function to do matrix-matrix multiply.
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.