MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
28 namespace MueLu {
29 
32 template <class Scalar = DefaultScalar,
35  class Node = DefaultNode>
36 class XpetraThyraLinearOp : public Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
37  protected:
38  XpetraThyraLinearOp() = default;
39 
40  public:
42 
43 
46  RCP<ParameterList> params)
47  : A_(A) {
48  throw Exceptions::RuntimeError("Interface not supported");
49  };
50 
52  ~XpetraThyraLinearOp() = default;
53 
55 
58  throw Exceptions::RuntimeError("Interface not supported");
59  }
60 
61  // //! Returns the Tpetra::Map object associated with the range of this operator.
63  throw Exceptions::RuntimeError("Interface not supported");
64  }
65 
67 
76  throw Exceptions::RuntimeError("Interface not supported");
77  }
78 
80  bool hasTransposeApply() const { return false; }
81 
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.
95 template <class LocalOrdinal,
96  class GlobalOrdinal,
97  class Node>
98 class 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 
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 
139  return A_->getDomainMap();
140  }
141 
142  // //! Returns the Tpetra::Map object associated with the range of this operator.
144  return A_->getRangeMap();
145  }
146 
148 
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 
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
Tpetra::KokkosClassic::DefaultNode::DefaultNodeType DefaultNode
MueLu::DefaultNode Node
virtual void update(const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Scalar &beta)=0
MueLu::DefaultScalar Scalar
Tpetra::Details::DefaultTypes::scalar_type DefaultScalar
MueLu::DefaultGlobalOrdinal GlobalOrdinal
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
void residual(const Operator< SC, LO, GO, NO > &Aop, const MultiVector< SC, LO, GO, NO > &X_in, const MultiVector< SC, LO, GO, NO > &B_in, MultiVector< SC, LO, GO, NO > &R_in)