MueLu Version of the Day
Loading...
Searching...
No Matches
Xpetra_ThyraLinearOp.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef MUELU_XPETRA_THYRALINEAROP_HPP
11#define MUELU_XPETRA_THYRALINEAROP_HPP
12
13#if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
14
15#include "MueLu_ConfigDefs.hpp"
16
17#include <Xpetra_Operator.hpp>
18#include <Xpetra_MultiVector.hpp>
19
20// Stratimikos
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>
27
28namespace MueLu {
29
32template <class Scalar = DefaultScalar,
35 class Node = DefaultNode>
36class XpetraThyraLinearOp : public Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
37 protected:
38 XpetraThyraLinearOp() = default;
39
40 public:
42
43
45 XpetraThyraLinearOp(RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A,
46 RCP<ParameterList> params)
47 : A_(A) {
48 throw Exceptions::RuntimeError("Interface not supported");
49 };
50
52 ~XpetraThyraLinearOp() = default;
53
55
57 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getDomainMap() const {
58 throw Exceptions::RuntimeError("Interface not supported");
59 }
60
61 // //! Returns the Tpetra::Map object associated with the range of this operator.
62 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getRangeMap() const {
63 throw Exceptions::RuntimeError("Interface not supported");
64 }
65
67
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");
77 }
78
80 bool hasTransposeApply() const { return false; }
81
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");
87 }
88
89 private:
90 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A_;
91};
92
93// Partial specialization for Scalar == double.
94// Allows to avoid issues with Stokhos instantiating Thyra objects.
95template <class LocalOrdinal,
96 class GlobalOrdinal,
97 class Node>
98class XpetraThyraLinearOp<double, LocalOrdinal, GlobalOrdinal, Node> : public Xpetra::Operator<double, LocalOrdinal, GlobalOrdinal, Node> {
99 using Scalar = double;
100
101 protected:
102 XpetraThyraLinearOp() = default;
103
104 public:
106
107
109 XpetraThyraLinearOp(RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A,
110 RCP<ParameterList> params)
111 : A_(A) {
112 // Build Thyra linear algebra objects
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());
114
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");
119
120 linearSolverBuilder.setParameterList(params);
121
122 // Build a new "solver factory" according to the previously specified parameter list.
123 // RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > solverFactory = Thyra::createLinearSolveStrategy(linearSolverBuilder);
124
125 auto precFactory = Thyra::createPreconditioningStrategy(linearSolverBuilder);
126 auto prec = precFactory->createPrec();
127
128 precFactory->initializePrec(Thyra::defaultLinearOpSource(thyraA), prec.get(), Thyra::SUPPORT_SOLVE_UNSPECIFIED);
129 prec_ = prec;
130 };
131
133 ~XpetraThyraLinearOp() = default;
134
136
138 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getDomainMap() const {
139 return A_->getDomainMap();
140 }
141
142 // //! Returns the Tpetra::Map object associated with the range of this operator.
143 const Teuchos::RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> getRangeMap() const {
144 return A_->getRangeMap();
145 }
146
148
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);
159
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));
162
163 prec_->getUnspecifiedPrecOp()->apply(Thyra::NOTRANS, *thyraX, thyraY.ptr(), alpha, beta);
164 Y = *Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(thyraY, Y.getMap()->getComm());
165 }
166
168 bool hasTransposeApply() const { return false; }
169
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());
177 }
178
179 private:
180 RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A_;
181 RCP<Thyra::PreconditionerBase<Scalar>> prec_;
182};
183
184} // namespace MueLu
185
186#endif // defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
187
188#endif // MUELU_XPETRA_THYRALINEAROP_HPP
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
MueLu::DefaultNode Node
Namespace for MueLu classes and methods.
Tpetra::KokkosClassic::DefaultNode::DefaultNodeType DefaultNode
Tpetra::Details::DefaultTypes::scalar_type DefaultScalar