10#ifndef MUELU_XPETRA_THYRALINEAROP_HPP
11#define MUELU_XPETRA_THYRALINEAROP_HPP
13#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
17#include <Xpetra_Operator.hpp>
18#include <Xpetra_MultiVector.hpp>
21#include <Thyra_VectorBase.hpp>
22#include <Thyra_SolveSupportTypes.hpp>
23#include <Thyra_LinearOpWithSolveBase.hpp>
24#include <Teuchos_AbstractFactoryStd.hpp>
25#include <Stratimikos_LinearSolverBuilder.hpp>
36class XpetraThyraLinearOp :
public Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
38 XpetraThyraLinearOp() =
default;
45 XpetraThyraLinearOp(RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A,
46 RCP<ParameterList> params)
48 throw Exceptions::RuntimeError(
"Interface not supported");
52 ~XpetraThyraLinearOp() =
default;
57 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getDomainMap()
const {
58 throw Exceptions::RuntimeError(
"Interface not supported");
62 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getRangeMap()
const {
63 throw Exceptions::RuntimeError(
"Interface not supported");
71 void apply(
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& X,
72 Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Y,
73 Teuchos::ETransp mode = Teuchos::NO_TRANS,
74 Scalar alpha = Teuchos::ScalarTraits<Scalar>::one(),
75 Scalar beta = Teuchos::ScalarTraits<Scalar>::one())
const {
76 throw Exceptions::RuntimeError(
"Interface not supported");
80 bool hasTransposeApply()
const {
return false; }
83 void residual(
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& X,
84 const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& B,
85 Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& R)
const {
86 throw Exceptions::RuntimeError(
"Interface not supported");
90 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A_;
102 XpetraThyraLinearOp() =
default;
109 XpetraThyraLinearOp(RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A,
110 RCP<ParameterList> params)
113 RCP<const Thyra::LinearOpBase<Scalar>> thyraA = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyra(Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<Scalar, LocalOrdinal, GlobalOrdinal, Node>>(A)->getCrsMatrix());
115 Stratimikos::LinearSolverBuilder<Scalar> linearSolverBuilder;
116 typedef Thyra::PreconditionerFactoryBase<Scalar> Base;
117 typedef Thyra::MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node> ImplMueLu;
118 linearSolverBuilder.setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, ImplMueLu>(),
"MueLu");
120 linearSolverBuilder.setParameterList(params);
125 auto precFactory = Thyra::createPreconditioningStrategy(linearSolverBuilder);
126 auto prec = precFactory->createPrec();
128 precFactory->initializePrec(Thyra::defaultLinearOpSource(thyraA), prec.get(), Thyra::SUPPORT_SOLVE_UNSPECIFIED);
133 ~XpetraThyraLinearOp() =
default;
138 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getDomainMap()
const {
139 return A_->getDomainMap();
143 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getRangeMap()
const {
144 return A_->getRangeMap();
152 void apply(
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& X,
153 Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Y,
154 Teuchos::ETransp mode = Teuchos::NO_TRANS,
155 Scalar alpha = Teuchos::ScalarTraits<Scalar>::one(),
156 Scalar beta = Teuchos::ScalarTraits<Scalar>::one())
const {
157 RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> rcpX = Teuchos::rcpFromRef(X);
158 RCP<const Thyra::MultiVectorBase<Scalar>> thyraX = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyraMultiVector(rcpX);
160 RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> rcpY = Teuchos::rcpFromRef(Y);
161 RCP<Thyra::MultiVectorBase<Scalar>> thyraY = Teuchos::rcp_const_cast<Thyra::MultiVectorBase<Scalar>>(Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyraMultiVector(rcpY));
163 prec_->getUnspecifiedPrecOp()->apply(Thyra::NOTRANS, *thyraX, thyraY.ptr(), alpha, beta);
164 Y = *Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(thyraY, Y.getMap()->getComm());
168 bool hasTransposeApply()
const {
return false; }
171 void residual(
const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& X,
172 const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& B,
173 Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& R)
const {
174 using STS = Teuchos::ScalarTraits<Scalar>;
175 R.update(STS::one(), B, STS::zero());
176 this->apply(X, R, Teuchos::NO_TRANS, -STS::one(), STS::one());
180 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A_;
181 RCP<Thyra::PreconditionerBase<Scalar>> prec_;
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
Namespace for MueLu classes and methods.
Tpetra::KokkosClassic::DefaultNode::DefaultNodeType DefaultNode
Tpetra::Details::DefaultTypes::scalar_type DefaultScalar