42 #ifndef TPETRA_CRSMATRIXSOLVEOP_HPP
43 #define TPETRA_CRSMATRIXSOLVEOP_HPP
50 #include <Tpetra_CrsMatrix.hpp>
90 template <
class Scalar,
91 class MatScalar = Scalar,
93 class GlobalOrdinal = ::Tpetra::Details::DefaultTypes::global_ordinal_type,
96 public Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
99 typedef CrsMatrix<MatScalar, LocalOrdinal, GlobalOrdinal, Node> crs_matrix_type;
101 typedef Map<LocalOrdinal, GlobalOrdinal, Node> map_type;
121 apply (
const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X,
122 MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y,
123 Teuchos::ETransp mode = Teuchos::NO_TRANS,
124 Scalar alpha = Teuchos::ScalarTraits<Scalar>::one (),
125 Scalar beta = Teuchos::ScalarTraits<Scalar>::zero ())
const
127 typedef Teuchos::ScalarTraits<Scalar> STOS;
128 const char prefix[] =
"Tpetra::CrsMatrixSolveOp::apply: ";
130 TEUCHOS_TEST_FOR_EXCEPTION
131 (! matrix_->isFillComplete (), std::runtime_error,
132 prefix <<
"Underlying matrix is not fill complete.");
133 TEUCHOS_TEST_FOR_EXCEPTION
134 (! matrix_->isLowerTriangular () && ! matrix_->isUpperTriangular (),
135 std::runtime_error, prefix <<
"The matrix is neither lower nor upper "
136 "triangular. Remember that in Tpetra, triangular-ness is a local "
137 "(per MPI process) property.");
138 TEUCHOS_TEST_FOR_EXCEPTION
139 (X.getNumVectors () != Y.getNumVectors (), std::invalid_argument,
140 prefix <<
"X and Y must have the same number of columns (vectors). "
141 "X.getNumVectors() = " << X.getNumVectors ()
142 <<
" != Y.getNumVectors() = " << Y.getNumVectors () <<
".");
143 TEUCHOS_TEST_FOR_EXCEPTION
144 (alpha != STOS::one () || beta != STOS::zero (), std::logic_error,
145 prefix <<
"The case alpha != 1 or beta != 0 has not yet been "
146 "implemented. Please speak with the Tpetra developers.");
147 if (mode == Teuchos::NO_TRANS) {
148 applyNonTranspose (X,Y);
149 }
else if (mode == Teuchos::TRANS || mode == Teuchos::CONJ_TRANS) {
150 applyTranspose (X, Y, mode);
152 TEUCHOS_TEST_FOR_EXCEPTION
153 (
true, std::invalid_argument, prefix <<
"The 'mode' argument has an "
154 "invalid value " << mode <<
". Valid values are Teuchos::NO_TRANS="
155 << Teuchos::NO_TRANS <<
", Teuchos::TRANS=" << Teuchos::TRANS <<
", "
156 "and Teuchos::CONJ_TRANS=" << Teuchos::CONJ_TRANS <<
".");
161 bool hasTransposeApply ()
const {
167 Teuchos::RCP<const map_type> getDomainMap ()
const
169 return matrix_->getRangeMap ();
174 Teuchos::RCP<const map_type> getRangeMap ()
const {
175 return matrix_->getDomainMap ();
180 typedef MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> MV;
183 const Teuchos::RCP<const crs_matrix_type> matrix_;
186 mutable Teuchos::RCP<MV> importMV_;
188 mutable Teuchos::RCP<MV> exportMV_;
191 void applyNonTranspose (
const MV& X_in, MV& Y_in)
const
193 using Teuchos::NO_TRANS;
195 typedef Teuchos::ScalarTraits<Scalar> ST;
200 const size_t numVectors = X_in.getNumVectors();
201 Teuchos::RCP<const Import<LocalOrdinal,GlobalOrdinal,Node> > importer =
202 matrix_->getGraph ()->getImporter ();
203 Teuchos::RCP<const Export<LocalOrdinal,GlobalOrdinal,Node> > exporter =
204 matrix_->getGraph ()->getExporter ();
205 Teuchos::RCP<const MV> X;
212 if (importer != null) {
213 if (importMV_ != null && importMV_->getNumVectors () != numVectors) {
216 if (importMV_ == null) {
217 importMV_ = Teuchos::rcp (
new MV (matrix_->getColMap (), numVectors));
220 if (exporter != null) {
221 if (exportMV_ != null && exportMV_->getNumVectors () != numVectors) {
224 if (exportMV_ == null) {
225 exportMV_ = Teuchos::rcp (
new MV (matrix_->getRowMap (), numVectors));
239 if (exporter != null) {
240 exportMV_->doImport (X_in, *exporter,
INSERT);
243 else if (! X_in.isConstantStride ()) {
246 X = Teuchos::rcp (
new MV (X_in));
250 X = Teuchos::rcpFromRef (X_in);
256 if (importer != null) {
257 matrix_->template localSolve<Scalar, Scalar> (*X, *importMV_, NO_TRANS);
259 Y_in.putScalar (ST::zero ());
260 Y_in.doExport (*importMV_, *importer,
ADD);
265 if (! Y_in.isConstantStride ()) {
268 matrix_->template localSolve<Scalar, Scalar> (*X, Y, NO_TRANS);
272 matrix_->template localSolve<Scalar, Scalar> (*X, Y_in, NO_TRANS);
278 void applyTranspose (
const MV& X_in, MV& Y_in,
const Teuchos::ETransp mode)
const
280 typedef Teuchos::ScalarTraits<Scalar> ST;
283 TEUCHOS_TEST_FOR_EXCEPTION
284 (mode != Teuchos::TRANS && mode != Teuchos::CONJ_TRANS, std::logic_error,
285 "Tpetra::CrsMatrixSolveOp::applyTranspose: mode is neither TRANS nor "
286 "CONJ_TRANS. Should never get here! Please report this bug to the "
287 "Tpetra developers.");
289 const size_t numVectors = X_in.getNumVectors();
290 Teuchos::RCP<const Import<LocalOrdinal,GlobalOrdinal,Node> > importer =
291 matrix_->getGraph ()->getImporter ();
292 Teuchos::RCP<const Export<LocalOrdinal,GlobalOrdinal,Node> > exporter =
293 matrix_->getGraph ()->getExporter ();
294 Teuchos::RCP<const MV> X;
301 if (importer != null) {
302 if (importMV_ != null && importMV_->getNumVectors() != numVectors) {
305 if (importMV_ == null) {
306 importMV_ = Teuchos::rcp(
new MV(matrix_->getColMap(),numVectors) );
309 if (exporter != null) {
310 if (exportMV_ != null && exportMV_->getNumVectors() != numVectors) {
313 if (exportMV_ == null) {
314 exportMV_ = Teuchos::rcp(
new MV(matrix_->getRowMap(),numVectors) );
328 if (importer != null) {
329 importMV_->doImport(X_in,*importer,
INSERT);
332 else if (X_in.isConstantStride() ==
false) {
335 X = Teuchos::rcp(
new MV(X_in));
339 X = Teuchos::rcpFromRef (X_in);
346 if (exporter != null) {
347 matrix_->template localSolve<Scalar, Scalar> (*X, *exportMV_,
348 Teuchos::CONJ_TRANS);
350 Y_in.putScalar(ST::zero());
351 Y_in.doExport(*importMV_, *importer,
ADD);
355 if (Y_in.isConstantStride() ==
false) {
358 matrix_->template localSolve<Scalar, Scalar> (*X, Y, Teuchos::CONJ_TRANS);
362 matrix_->template localSolve<Scalar, Scalar> (*X, Y_in, Teuchos::CONJ_TRANS);
375 template<
class OpScalar,
380 Teuchos::RCP<CrsMatrixSolveOp<OpScalar, MatScalar, LocalOrdinal, GlobalOrdinal, Node> >
388 #endif // TPETRA_CRSMATRIXSOLVEOP_HPP
Sparse matrix that presents a row-oriented interface that lets users read or modify entries...
KokkosClassic::DefaultNode::DefaultNodeType node_type
Default value of Node template parameter.
int local_ordinal_type
Default value of LocalOrdinal template parameter.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
Insert new values that don't currently exist.
Sum new values into existing values.
Teuchos::RCP< CrsMatrixSolveOp< OpScalar, MatScalar, LocalOrdinal, GlobalOrdinal, Node > > createCrsMatrixSolveOp(const Teuchos::RCP< const CrsMatrix< MatScalar, LocalOrdinal, GlobalOrdinal, Node > > &A)
Nonmember function that wraps a CrsMatrix in a CrsMatrixSolveOp.
Wrap a CrsMatrix instance's triangular solve in an Operator.