10#ifndef THYRA_TPETRA_LINEAR_OP_HPP
11#define THYRA_TPETRA_LINEAR_OP_HPP
13#include "Thyra_TpetraLinearOp_decl.hpp"
14#include "Kokkos_Core.hpp"
15#include "Thyra_TpetraVectorSpace.hpp"
16#include "Thyra_TpetraThyraWrappers.hpp"
17#include "Teuchos_ScalarTraits.hpp"
18#include "Teuchos_TypeNameTraits.hpp"
20#ifdef HAVE_THYRA_TPETRA_EPETRA
21# include "Thyra_EpetraThyraWrappers.hpp"
27#ifdef HAVE_THYRA_TPETRA_EPETRA
33 template<
class Scalar,
class LocalOrdinal,
class GlobalOrdinal>
34class GetTpetraEpetraRowMatrixWrapper {
36 template<
class TpetraMatrixType>
38 RCP<Tpetra::EpetraRowMatrix<TpetraMatrixType> >
39 get(
const RCP<TpetraMatrixType> &tpetraMatrix)
49class GetTpetraEpetraRowMatrixWrapper<double, int, int> {
51 template<
class TpetraMatrixType>
53 RCP<Tpetra::EpetraRowMatrix<TpetraMatrixType> >
54 get(
const RCP<TpetraMatrixType> &tpetraMatrix)
57 new Tpetra::EpetraRowMatrix<TpetraMatrixType>(tpetraMatrix,
70template <
class Scalar>
73convertConjNoTransToTeuchosTransMode()
77 Exceptions::OpNotSupported,
79 ", Tpetra does not support conjugation without transposition."
85template <
class Scalar>
92 case CONJ:
return convertConjNoTransToTeuchosTransMode<Scalar>();
105template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
109template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
110TpetraLinearOp<Scalar,LocalOrdinal,GlobalOrdinal,Node>::~TpetraLinearOp() =
default;
112template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
116 const RCP<Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraOperator
119 initializeImpl(rangeSpace, domainSpace, tpetraOperator);
123template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
127 const RCP<
const Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraOperator
130 initializeImpl(rangeSpace, domainSpace, tpetraOperator);
134template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
138 return tpetraOperator_.getNonconstObj();
142template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
146 return tpetraOperator_;
153template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
161template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
172#ifdef HAVE_THYRA_TPETRA_EPETRA
175template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
187template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
188void TpetraLinearOp<Scalar,LocalOrdinal,GlobalOrdinal,Node>::getEpetraOpView(
189 const Ptr<RCP<const Epetra_Operator> > &epetraOp,
190 const Ptr<EOpTransp> &epetraOpTransp,
191 const Ptr<EApplyEpetraOpAs> &epetraOpApplyAs,
192 const Ptr<EAdjointEpetraOp> &epetraOpAdjointSupport
195 using Teuchos::rcp_dynamic_cast;
196 typedef Tpetra::RowMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpetraRowMatrix_t;
197 if (nonnull(tpetraOperator_)) {
198 if (is_null(epetraOp_)) {
199 epetraOp_ = GetTpetraEpetraRowMatrixWrapper<Scalar,LocalOrdinal,GlobalOrdinal>::get(
200 rcp_dynamic_cast<const TpetraRowMatrix_t>(tpetraOperator_.getConstObj(),
true));
202 *epetraOp = epetraOp_;
204 *epetraOpApplyAs = EPETRA_OP_APPLY_APPLY;
205 *epetraOpAdjointSupport = ( tpetraOperator_->hasTransposeApply()
206 ? EPETRA_OP_ADJOINT_SUPPORTED : EPETRA_OP_ADJOINT_UNSUPPORTED );
209 *epetraOp = Teuchos::null;
220template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
224 if (is_null(tpetraOperator_))
230 if (M_trans ==
CONJ) {
236 return tpetraOperator_->hasTransposeApply();
240template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
249 using Teuchos::rcpFromRef;
250 using Teuchos::rcpFromPtr;
253 typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>
259 ConverterT::getConstTpetraMultiVector(rcpFromRef(X_in));
262 ConverterT::getTpetraMultiVector(rcpFromPtr(Y_inout));
264 const Teuchos::ETransp tTransp = convertToTeuchosTransMode<Scalar>(M_trans);
268 tpetraOperator_->apply(*tX, *tY, tTransp, alpha, beta);
277template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
284template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
291template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
296 using Teuchos::rcpFromRef;
302 Teuchos::rcp_dynamic_cast<Tpetra::RowMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(tpetraOperator_.getNonconstObj(),
true);
304 rowMatrix->leftScale(*row_scaling);
309template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
314 using Teuchos::rcpFromRef;
320 Teuchos::rcp_dynamic_cast<Tpetra::RowMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(tpetraOperator_.getNonconstObj(),
true);
322 rowMatrix->rightScale(*col_scaling);
329template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
332 const RowStatLinearOpBaseUtils::ERowStat rowStat)
const
334 if (is_null(tpetraOperator_))
338 case RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM:
339 case RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM:
348template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
350 const RowStatLinearOpBaseUtils::ERowStat rowStat,
354 typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node>
357 typedef typename STS::magnitudeType MT;
360 if ( (rowStat == RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM) ||
361 (rowStat == RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM) ) {
377 Teuchos::rcp_dynamic_cast<const Tpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(tpetraOperator_.getConstObj(),
true);
382 TEUCHOS_ASSERT(tCrsMatrix->getRowMap()->isSameAs(*tCrsMatrix->getRangeMap()));
383 TEUCHOS_ASSERT(tCrsMatrix->getRowMap()->isSameAs(*tRowSumVec->getMap()));
385 size_t numMyRows = tCrsMatrix->getLocalNumRows();
387 using crs_t = Tpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>;
388 typename crs_t::local_inds_host_view_type indices;
389 typename crs_t::values_host_view_type values;
392 for (
size_t row=0; row < numMyRows; ++row) {
393 MT sum = STM::zero ();
394 tCrsMatrix->getLocalRowView (row, indices, values);
396 for (
int col = 0; col < (int) values.size(); ++col) {
397 sum += STS::magnitude (values[col]);
400 if (rowStat == RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM) {
401 if (sum < STM::sfmin ()) {
403 "Error - Thyra::TpetraLinearOp::getRowStatImpl() - Inverse row sum "
404 <<
"requested for a matrix where one of the rows has a zero row sum!");
405 sum = STM::one () / STM::sfmin ();
408 sum = STM::one () / sum;
412 tRowSumVec->replaceLocalValue (row, Scalar (sum));
418 "Error - Thyra::TpetraLinearOp::getRowStatImpl() - Column sum support not implemented!");
427template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
428template<
class TpetraOperator_t>
441 rangeSpace_ = rangeSpace;
442 domainSpace_ = domainSpace;
443 tpetraOperator_ = tpetraOperator;
447template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
448RCP<TpetraLinearOp<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
452 const RCP<Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraOperator
457 op->initialize(rangeSpace, domainSpace, tpetraOperator);
462template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
467 const RCP<
const Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> > &tpetraOperator
472 op->constInitialize(rangeSpace, domainSpace, tpetraOperator);
479#define THYRATPETRAADAPTERS_TPETRALINEAROP_INSTANT(S, LO, GO, N) \
480 template class Thyra::TpetraLinearOp<S, LO, GO, N>; \
482 template Teuchos::RCP<Thyra::TpetraLinearOp<S, LO, GO, N>> \
483 Thyra::tpetraLinearOp(const Teuchos::RCP<const Thyra::VectorSpaceBase<S>> &, \
484 const Teuchos::RCP<const Thyra::VectorSpaceBase<S>> &, \
485 const Teuchos::RCP<Tpetra::Operator<S, LO, GO, N>> &); \
487 template Teuchos::RCP<const Thyra::TpetraLinearOp<S, LO, GO, N>> \
488 Thyra::constTpetraLinearOp( \
489 const Teuchos::RCP<const Thyra::VectorSpaceBase<S>> &, \
490 const Teuchos::RCP<const Thyra::VectorSpaceBase<S>> &, \
491 const Teuchos::RCP<const Tpetra::Operator<S, LO, GO, N>> &);
Interface for a collection of column vectors called a multi-vector.
Concrete Thyra::LinearOpBase subclass for Tpetra::Operator.
virtual bool rowStatIsSupportedImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat) const
void applyImpl(const Thyra::EOpTransp M_trans, const Thyra::MultiVectorBase< Scalar > &X_in, const Teuchos::Ptr< Thyra::MultiVectorBase< Scalar > > &Y_inout, const Scalar alpha, const Scalar beta) const
bool opSupportedImpl(Thyra::EOpTransp M_trans) const
virtual bool supportsScaleLeftImpl() const
RCP< const Thyra::VectorSpaceBase< Scalar > > range() const
TpetraLinearOp()
Construct to uninitialized.
virtual void getRowStatImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat, const Ptr< VectorBase< Scalar > > &rowStatVec) const
virtual void scaleLeftImpl(const VectorBase< Scalar > &row_scaling)
virtual void scaleRightImpl(const VectorBase< Scalar > &col_scaling)
void initialize(const RCP< const VectorSpaceBase< Scalar > > &rangeSpace, const RCP< const VectorSpaceBase< Scalar > > &domainSpace, const RCP< Tpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraOperator)
Initialize.
RCP< const Tpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getConstTpetraOperator() const
Get embedded const Tpetra::Operator.
void constInitialize(const RCP< const VectorSpaceBase< Scalar > > &rangeSpace, const RCP< const VectorSpaceBase< Scalar > > &domainSpace, const RCP< const Tpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &tpetraOperator)
Initialize.
virtual bool supportsScaleRightImpl() const
RCP< Tpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getTpetraOperator()
Get embedded non-const Tpetra::Operator.
RCP< const Thyra::VectorSpaceBase< Scalar > > domain() const
Abstract interface for finite-dimensional dense vectors.
Abstract interface for objects that represent a space for vectors.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
@ TRANS
Use the transposed operator.
@ NOTRANS
Use the non-transposed operator.
@ CONJTRANS
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types).
@ CONJ
Use the non-transposed operator with complex-conjugate elements (same as NOTRANS for real scalar type...
RCP< const Teuchos::Comm< Ordinal > > convertTpetraToThyraComm(const RCP< const Teuchos::Comm< int > > &tpetraComm)
Given an Tpetra Teuchos::Comm<int> object, return an equivalent Teuchos::Comm<Ordinal> object.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)