Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Xpetra_TripleMatrixMultiply_decl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Xpetra: A linear algebra interface package
4 //
5 // Copyright 2012 NTESS and the Xpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_DECL_HPP_
11 #define PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_DECL_HPP_
12 
13 #include "Xpetra_ConfigDefs.hpp"
14 
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"
23 #include "Xpetra_IO.hpp"
24 
25 #ifdef HAVE_XPETRA_TPETRA
26 #include <TpetraExt_TripleMatrixMultiply.hpp>
27 #include <Xpetra_TpetraCrsMatrix.hpp>
28 #include <Tpetra_BlockCrsMatrix.hpp>
29 #include <Tpetra_BlockCrsMatrix_Helpers.hpp>
30 // #include <Xpetra_TpetraMultiVector.hpp>
31 // #include <Xpetra_TpetraVector.hpp>
32 #endif // HAVE_XPETRA_TPETRA
33 
34 namespace Xpetra {
35 
36 template <class Scalar,
37  class LocalOrdinal /*= int*/,
38  class GlobalOrdinal /*= LocalOrdinal*/,
39  class Node /*= Tpetra::KokkosClassic::DefaultNode::DefaultNodeType*/>
41 #undef XPETRA_TRIPLEMATRIXMULTIPLY_SHORT
42 #include "Xpetra_UseShortNames.hpp"
43 
44  public:
69  static void MultiplyRAP(const Matrix& R, bool transposeR,
70  const Matrix& A, bool transposeA,
71  const Matrix& P, bool transposeP,
72  Matrix& Ac,
73  bool call_FillComplete_on_result = true,
74  bool doOptimizeStorage = true,
75  const std::string& label = std::string(),
76  const RCP<ParameterList>& params = null);
77 
78 }; // class TripleMatrixMultiply
79 
80 #ifdef HAVE_XPETRA_EPETRA
81 // specialization TripleMatrixMultiply for SC=double, LO=GO=int
82 template <>
83 class TripleMatrixMultiply<double, int, int, EpetraNode> {
84  typedef double Scalar;
85  typedef int LocalOrdinal;
86  typedef int GlobalOrdinal;
87  typedef EpetraNode Node;
88 #include "Xpetra_UseShortNames.hpp"
89 
90  public:
91  static void MultiplyRAP(const Matrix& R, bool transposeR,
92  const Matrix& A, bool transposeA,
93  const Matrix& P, bool transposeP,
94  Matrix& Ac,
95  bool call_FillComplete_on_result = true,
96  bool doOptimizeStorage = true,
97  const std::string& label = std::string(),
98  const RCP<ParameterList>& params = null) {
99  TEUCHOS_TEST_FOR_EXCEPTION(transposeR == false && Ac.getRowMap()->isSameAs(*R.getRowMap()) == false,
100  Exceptions::RuntimeError, "XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as row map of R");
101  TEUCHOS_TEST_FOR_EXCEPTION(transposeR == true && Ac.getRowMap()->isSameAs(*R.getDomainMap()) == false,
102  Exceptions::RuntimeError, "XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as domain map of R");
103 
104  TEUCHOS_TEST_FOR_EXCEPTION(!R.isFillComplete(), Exceptions::RuntimeError, "R is not fill-completed");
105  TEUCHOS_TEST_FOR_EXCEPTION(!A.isFillComplete(), Exceptions::RuntimeError, "A is not fill-completed");
106  TEUCHOS_TEST_FOR_EXCEPTION(!P.isFillComplete(), Exceptions::RuntimeError, "P is not fill-completed");
107 
108  bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
109 
110  if (Ac.getRowMap()->lib() == Xpetra::UseEpetra) {
111  throw(Xpetra::Exceptions::RuntimeError("Xpetra::TripleMatrixMultiply::MultiplyRAP is only implemented for Tpetra"));
112  } else if (Ac.getRowMap()->lib() == Xpetra::UseTpetra) {
113 #ifdef HAVE_XPETRA_TPETRA
114 #if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_INT))) || \
115  (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_INT))))
116  throw(Xpetra::Exceptions::RuntimeError("Xpetra must be compiled with Tpetra <double,int,int> ETI enabled."));
117 #else
118  using helpers = Xpetra::Helpers<SC, LO, GO, NO>;
119  if (helpers::isTpetraCrs(R) && helpers::isTpetraCrs(A) && helpers::isTpetraCrs(P) && helpers::isTpetraCrs(Ac)) {
120  // All matrices are Crs
121  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpR = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(R);
122  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(A);
123  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpP = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(P);
124  Tpetra::CrsMatrix<SC, LO, GO, NO>& tpAc = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstTpetraCrs(Ac);
125 
126  // 18Feb2013 JJH I'm reenabling the code that allows the matrix matrix multiply to do the fillComplete.
127  // Previously, Tpetra's matrix matrix multiply did not support fillComplete.
128  Tpetra::TripleMatrixMultiply::MultiplyRAP(tpR, transposeR, tpA, transposeA, tpP, transposeP, tpAc, haveMultiplyDoFillComplete, label, params);
129  } else if (helpers::isTpetraBlockCrs(R) && helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(P)) {
130  // All matrices are BlockCrs (except maybe Ac)
131  // FIXME: For the moment we're just going to clobber the innards of AC, so no reuse. Once we have a reuse kernel,
132  // we'll need to think about refactoring BlockCrs so we can do something smarter here.
133  if (!A.getRowMap()->getComm()->getRank())
134  std::cout << "WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
135 
136  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpR = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(R);
137  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(A);
138  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpP = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(P);
139  // Tpetra::BlockCrsMatrix<SC,LO,GO,NO> & tpAc = Xpetra::Helpers<SC,LO,GO,NO>::Op2NonConstTpetraBlockCrs(Ac);
140 
141  using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
142  RCP<const CRS> Rcrs = Tpetra::convertToCrsMatrix(tpR);
143  RCP<const CRS> Acrs = Tpetra::convertToCrsMatrix(tpA);
144  RCP<const CRS> Pcrs = Tpetra::convertToCrsMatrix(tpP);
145  // RCP<CRS> Accrs = Tpetra::convertToCrsMatrix(tpAc);
146 
147  // FIXME: The lines below only works because we're assuming Ac is Point
148  RCP<CRS> Accrs = Teuchos::rcp(new CRS(Rcrs->getRowMap(), 0));
149  const bool do_fill_complete = true;
150  Tpetra::TripleMatrixMultiply::MultiplyRAP(*Rcrs, transposeR, *Acrs, transposeA, *Pcrs, transposeP, *Accrs, do_fill_complete, label, params);
151 
152  // Temporary output matrix
153  RCP<Tpetra::BlockCrsMatrix<SC, LO, GO, NO> > Ac_t = Tpetra::convertToBlockCrsMatrix(*Accrs, A.GetStorageBlockSize());
154  RCP<Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO> > Ac_x = Teuchos::rcp(new Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO>(Ac_t));
155  RCP<Xpetra::CrsMatrix<SC, LO, GO, NO> > Ac_p = Ac_x;
156 
157  // We can now cheat and replace the innards of Ac
158  RCP<Xpetra::CrsMatrixWrap<SC, LO, GO, NO> > Ac_w = Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<SC, LO, GO, NO> >(Teuchos::rcpFromRef(Ac));
159  Ac_w->replaceCrsMatrix(Ac_p);
160 
161  } else {
162  // Mix and match (not supported)
163  TEUCHOS_TEST_FOR_EXCEPTION(1, Exceptions::RuntimeError, "Mix-and-match Crs/BlockCrs Multiply not currently supported");
164  }
165 #endif
166 #else
167  throw(Xpetra::Exceptions::RuntimeError("Xpetra must be compiled with Tpetra."));
168 #endif
169  if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
170  RCP<Teuchos::ParameterList> fillParams = rcp(new Teuchos::ParameterList());
171  fillParams->set("Optimize Storage", doOptimizeStorage);
172  Ac.fillComplete((transposeP) ? P.getRangeMap() : P.getDomainMap(),
173  (transposeR) ? R.getDomainMap() : R.getRangeMap(),
174  fillParams);
175  }
176 
177  // transfer striding information
178  RCP<const Map> domainMap = Teuchos::null;
179  RCP<const Map> rangeMap = Teuchos::null;
180 
181  const std::string stridedViewLabel("stridedMaps");
182  const size_t blkSize = 1;
183  std::vector<size_t> stridingInfo(1, blkSize);
184  LocalOrdinal stridedBlockId = -1;
185 
186  if (R.IsView(stridedViewLabel)) {
187  rangeMap = transposeR ? R.getColMap(stridedViewLabel) : R.getRowMap(stridedViewLabel);
188  } else {
189  rangeMap = transposeR ? R.getDomainMap() : R.getRangeMap();
190  rangeMap = StridedMapFactory::Build(rangeMap, stridingInfo, stridedBlockId);
191  }
192 
193  if (P.IsView(stridedViewLabel)) {
194  domainMap = transposeP ? P.getRowMap(stridedViewLabel) : P.getColMap(stridedViewLabel);
195  } else {
196  domainMap = transposeP ? P.getRangeMap() : P.getDomainMap();
197  domainMap = StridedMapFactory::Build(domainMap, stridingInfo, stridedBlockId);
198  }
199  Ac.CreateView(stridedViewLabel, rangeMap, domainMap);
200  }
201 
202  } // end Multiply
203 
204 }; // end specialization on SC=double, GO=int and NO=EpetraNode
205 
206 // specialization TripleMatrixMultiply for SC=double, GO=long long and NO=EpetraNode
207 template <>
208 class TripleMatrixMultiply<double, int, long long, EpetraNode> {
209  typedef double Scalar;
210  typedef int LocalOrdinal;
211  typedef long long GlobalOrdinal;
212  typedef EpetraNode Node;
213 #include "Xpetra_UseShortNames.hpp"
214 
215  public:
216  static void MultiplyRAP(const Matrix& R, bool transposeR,
217  const Matrix& A, bool transposeA,
218  const Matrix& P, bool transposeP,
219  Matrix& Ac,
220  bool call_FillComplete_on_result = true,
221  bool doOptimizeStorage = true,
222  const std::string& label = std::string(),
223  const RCP<ParameterList>& params = null) {
224  TEUCHOS_TEST_FOR_EXCEPTION(transposeR == false && Ac.getRowMap()->isSameAs(*R.getRowMap()) == false,
225  Exceptions::RuntimeError, "XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as row map of R");
226  TEUCHOS_TEST_FOR_EXCEPTION(transposeR == true && Ac.getRowMap()->isSameAs(*R.getDomainMap()) == false,
227  Exceptions::RuntimeError, "XpetraExt::TripleMatrixMultiply::MultiplyRAP: row map of Ac is not same as domain map of R");
228 
229  TEUCHOS_TEST_FOR_EXCEPTION(!R.isFillComplete(), Exceptions::RuntimeError, "R is not fill-completed");
230  TEUCHOS_TEST_FOR_EXCEPTION(!A.isFillComplete(), Exceptions::RuntimeError, "A is not fill-completed");
231  TEUCHOS_TEST_FOR_EXCEPTION(!P.isFillComplete(), Exceptions::RuntimeError, "P is not fill-completed");
232 
233  bool haveMultiplyDoFillComplete = call_FillComplete_on_result && doOptimizeStorage;
234 
235  if (Ac.getRowMap()->lib() == Xpetra::UseEpetra) {
236  throw(Xpetra::Exceptions::RuntimeError("Xpetra::TripleMatrixMultiply::MultiplyRAP is only implemented for Tpetra"));
237  } else if (Ac.getRowMap()->lib() == Xpetra::UseTpetra) {
238 #ifdef HAVE_XPETRA_TPETRA
239 #if ((defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_OPENMP) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))) || \
240  (!defined(EPETRA_HAVE_OMP) && (!defined(HAVE_TPETRA_INST_SERIAL) || !defined(HAVE_TPETRA_INST_INT_LONG_LONG))))
241  throw(Xpetra::Exceptions::RuntimeError("Xpetra must be compiled with Tpetra <double,int,long long,EpetraNode> ETI enabled."));
242 #else
243  using helpers = Xpetra::Helpers<SC, LO, GO, NO>;
244  if (helpers::isTpetraCrs(R) && helpers::isTpetraCrs(A) && helpers::isTpetraCrs(P)) {
245  // All matrices are Crs
246  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpR = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(R);
247  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(A);
248  const Tpetra::CrsMatrix<SC, LO, GO, NO>& tpP = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraCrs(P);
249  Tpetra::CrsMatrix<SC, LO, GO, NO>& tpAc = Xpetra::Helpers<SC, LO, GO, NO>::Op2NonConstTpetraCrs(Ac);
250 
251  // 18Feb2013 JJH I'm reenabling the code that allows the matrix matrix multiply to do the fillComplete.
252  // Previously, Tpetra's matrix matrix multiply did not support fillComplete.
253  Tpetra::TripleMatrixMultiply::MultiplyRAP(tpR, transposeR, tpA, transposeA, tpP, transposeP, tpAc, haveMultiplyDoFillComplete, label, params);
254  } else if (helpers::isTpetraBlockCrs(R) && helpers::isTpetraBlockCrs(A) && helpers::isTpetraBlockCrs(P)) {
255  // All matrices are BlockCrs (except maybe Ac)
256  // FIXME: For the moment we're just going to clobber the innards of AC, so no reuse. Once we have a reuse kernel,
257  // we'll need to think about refactoring BlockCrs so we can do something smarter here.
258  if (!A.getRowMap()->getComm()->getRank())
259  std::cout << "WARNING: Using inefficient BlockCrs Multiply Placeholder" << std::endl;
260 
261  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpR = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(R);
262  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpA = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(A);
263  const Tpetra::BlockCrsMatrix<SC, LO, GO, NO>& tpP = Xpetra::Helpers<SC, LO, GO, NO>::Op2TpetraBlockCrs(P);
264  // Tpetra::BlockCrsMatrix<SC,LO,GO,NO> & tpAc = Xpetra::Helpers<SC,LO,GO,NO>::Op2NonConstTpetraBlockCrs(Ac);
265 
266  using CRS = Tpetra::CrsMatrix<SC, LO, GO, NO>;
267  RCP<const CRS> Rcrs = Tpetra::convertToCrsMatrix(tpR);
268  RCP<const CRS> Acrs = Tpetra::convertToCrsMatrix(tpA);
269  RCP<const CRS> Pcrs = Tpetra::convertToCrsMatrix(tpP);
270  // RCP<CRS> Accrs = Tpetra::convertToCrsMatrix(tpAc);
271 
272  // FIXME: The lines below only works because we're assuming Ac is Point
273  RCP<CRS> Accrs = Teuchos::rcp(new CRS(Rcrs->getRowMap(), 0));
274  const bool do_fill_complete = true;
275  Tpetra::TripleMatrixMultiply::MultiplyRAP(*Rcrs, transposeR, *Acrs, transposeA, *Pcrs, transposeP, *Accrs, do_fill_complete, label, params);
276 
277  // Temporary output matrix
278  RCP<Tpetra::BlockCrsMatrix<SC, LO, GO, NO> > Ac_t = Tpetra::convertToBlockCrsMatrix(*Accrs, A.GetStorageBlockSize());
279  RCP<Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO> > Ac_x = Teuchos::rcp(new Xpetra::TpetraBlockCrsMatrix<SC, LO, GO, NO>(Ac_t));
280  RCP<Xpetra::CrsMatrix<SC, LO, GO, NO> > Ac_p = Ac_x;
281 
282  // We can now cheat and replace the innards of Ac
283  RCP<Xpetra::CrsMatrixWrap<SC, LO, GO, NO> > Ac_w = Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<SC, LO, GO, NO> >(Teuchos::rcpFromRef(Ac));
284  Ac_w->replaceCrsMatrix(Ac_p);
285  } else {
286  // Mix and match
287  TEUCHOS_TEST_FOR_EXCEPTION(1, Exceptions::RuntimeError, "Mix-and-match Crs/BlockCrs Multiply not currently supported");
288  }
289 
290 #endif
291 #else
292  throw(Xpetra::Exceptions::RuntimeError("Xpetra must be compiled with Tpetra."));
293 #endif
294  if (call_FillComplete_on_result && !haveMultiplyDoFillComplete) {
295  RCP<Teuchos::ParameterList> fillParams = rcp(new Teuchos::ParameterList());
296  fillParams->set("Optimize Storage", doOptimizeStorage);
297  Ac.fillComplete((transposeP) ? P.getRangeMap() : P.getDomainMap(),
298  (transposeR) ? R.getDomainMap() : R.getRangeMap(),
299  fillParams);
300  }
301 
302  // transfer striding information
303  RCP<const Map> domainMap = Teuchos::null;
304  RCP<const Map> rangeMap = Teuchos::null;
305 
306  const std::string stridedViewLabel("stridedMaps");
307  const size_t blkSize = 1;
308  std::vector<size_t> stridingInfo(1, blkSize);
309  LocalOrdinal stridedBlockId = -1;
310 
311  if (R.IsView(stridedViewLabel)) {
312  rangeMap = transposeR ? R.getColMap(stridedViewLabel) : R.getRowMap(stridedViewLabel);
313  } else {
314  rangeMap = transposeR ? R.getDomainMap() : R.getRangeMap();
315  rangeMap = StridedMapFactory::Build(rangeMap, stridingInfo, stridedBlockId);
316  }
317 
318  if (P.IsView(stridedViewLabel)) {
319  domainMap = transposeP ? P.getRowMap(stridedViewLabel) : P.getColMap(stridedViewLabel);
320  } else {
321  domainMap = transposeP ? P.getRangeMap() : P.getDomainMap();
322  domainMap = StridedMapFactory::Build(domainMap, stridingInfo, stridedBlockId);
323  }
324  Ac.CreateView(stridedViewLabel, rangeMap, domainMap);
325  }
326 
327  } // end Multiply
328 
329 }; // end specialization on GO=long long and NO=EpetraNode
330 #endif
331 
332 } // end namespace Xpetra
333 
334 #define XPETRA_TRIPLEMATRIXMULTIPLY_SHORT
335 
336 #endif /* PACKAGES_XPETRA_SUP_UTILS_XPETRA_TRIPLEMATRIXMULTIPLY_DECL_HPP_ */
static void MultiplyRAP(const Matrix &R, bool transposeR, const Matrix &A, bool transposeA, const Matrix &P, bool transposeP, Matrix &Ac, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > &params=null)
virtual const RCP< const Map > & getColMap() const
Returns the Map that describes the column distribution in this matrix. This might be null until fillC...
static void MultiplyRAP(const Matrix &R, bool transposeR, const Matrix &A, bool transposeA, const Matrix &P, bool transposeP, Matrix &Ac, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > &params=null)
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 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.
static RCP< const Tpetra::CrsMatrix< SC, LO, GO, NO > > Op2TpetraCrs(RCP< Matrix > Op)
virtual void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > &params=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)
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)
Tpetra::KokkosCompat::KokkosSerialWrapperNode EpetraNode
void replaceCrsMatrix(RCP< CrsMatrix > &M)
Expert only.
Concrete implementation of Xpetra::Matrix.
static void MultiplyRAP(const Matrix &R, bool transposeR, const Matrix &A, bool transposeA, const Matrix &P, bool transposeP, Matrix &Ac, bool call_FillComplete_on_result=true, bool doOptimizeStorage=true, const std::string &label=std::string(), const RCP< ParameterList > &params=null)
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 RCP< Xpetra::StridedMap< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector< size_t > &stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int >> &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset=0, LocalGlobal lg=Xpetra::GloballyDistributed)
Map constructor with Xpetra-defined contiguous uniform distribution.
Xpetra-specific matrix class.