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 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_XPETRA_THYRALINEAROP_HPP
47 #define MUELU_XPETRA_THYRALINEAROP_HPP
48 
49 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
50 
51 #include "MueLu_ConfigDefs.hpp"
52 
53 #include <Xpetra_Operator.hpp>
54 #include <Xpetra_MultiVector.hpp>
55 
56 // Stratimikos
57 #include <Thyra_VectorBase.hpp>
58 #include <Thyra_SolveSupportTypes.hpp>
59 #include <Thyra_LinearOpWithSolveBase.hpp>
60 #include <Teuchos_AbstractFactoryStd.hpp>
61 #include <Stratimikos_LinearSolverBuilder.hpp>
63 
64 namespace MueLu {
65 
68 template <class Scalar = DefaultScalar,
71  class Node = DefaultNode>
72 class XpetraThyraLinearOp : public Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
73  protected:
74  XpetraThyraLinearOp() = default;
75 
76  public:
78 
79 
82  RCP<ParameterList> params)
83  : A_(A) {
84  throw Exceptions::RuntimeError("Interface not supported");
85  };
86 
88  ~XpetraThyraLinearOp() = default;
89 
91 
94  throw Exceptions::RuntimeError("Interface not supported");
95  }
96 
97  // //! Returns the Tpetra::Map object associated with the range of this operator.
99  throw Exceptions::RuntimeError("Interface not supported");
100  }
101 
103 
112  throw Exceptions::RuntimeError("Interface not supported");
113  }
114 
116  bool hasTransposeApply() const { return false; }
117 
122  throw Exceptions::RuntimeError("Interface not supported");
123  }
124 
125  private:
126  RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A_;
127 };
128 
129 // Partial specialization for Scalar == double.
130 // Allows to avoid issues with Stokhos instantiating Thyra objects.
131 template <class LocalOrdinal,
132  class GlobalOrdinal,
133  class Node>
134 class XpetraThyraLinearOp<double, LocalOrdinal, GlobalOrdinal, Node> : public Xpetra::Operator<double, LocalOrdinal, GlobalOrdinal, Node> {
135  using Scalar = double;
136 
137  protected:
138  XpetraThyraLinearOp() = default;
139 
140  public:
142 
143 
146  RCP<ParameterList> params)
147  : A_(A) {
148  // Build Thyra linear algebra objects
149  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());
150 
151  Stratimikos::LinearSolverBuilder<Scalar> linearSolverBuilder;
152  typedef Thyra::PreconditionerFactoryBase<Scalar> Base;
153  typedef Thyra::MueLuPreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node> ImplMueLu;
154  linearSolverBuilder.setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, ImplMueLu>(), "MueLu");
155 
156  linearSolverBuilder.setParameterList(params);
157 
158  // Build a new "solver factory" according to the previously specified parameter list.
159  // RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > solverFactory = Thyra::createLinearSolveStrategy(linearSolverBuilder);
160 
161  auto precFactory = Thyra::createPreconditioningStrategy(linearSolverBuilder);
162  auto prec = precFactory->createPrec();
163 
164  precFactory->initializePrec(Thyra::defaultLinearOpSource(thyraA), prec.get(), Thyra::SUPPORT_SOLVE_UNSPECIFIED);
165  prec_ = prec;
166  };
167 
169  ~XpetraThyraLinearOp() = default;
170 
172 
175  return A_->getDomainMap();
176  }
177 
178  // //! Returns the Tpetra::Map object associated with the range of this operator.
180  return A_->getRangeMap();
181  }
182 
184 
193  RCP<const Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> rcpX = Teuchos::rcpFromRef(X);
194  RCP<const Thyra::MultiVectorBase<Scalar>> thyraX = Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyraMultiVector(rcpX);
195 
196  RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>> rcpY = Teuchos::rcpFromRef(Y);
197  RCP<Thyra::MultiVectorBase<Scalar>> thyraY = Teuchos::rcp_const_cast<Thyra::MultiVectorBase<Scalar>>(Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toThyraMultiVector(rcpY));
198 
199  prec_->getUnspecifiedPrecOp()->apply(Thyra::NOTRANS, *thyraX, thyraY.ptr(), alpha, beta);
200  Y = *Xpetra::ThyraUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::toXpetra(thyraY, Y.getMap()->getComm());
201  }
202 
204  bool hasTransposeApply() const { return false; }
205 
210  using STS = Teuchos::ScalarTraits<Scalar>;
211  R.update(STS::one(), B, STS::zero());
212  this->apply(X, R, Teuchos::NO_TRANS, -STS::one(), STS::one());
213  }
214 
215  private:
216  RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>> A_;
217  RCP<Thyra::PreconditionerBase<Scalar>> prec_;
218 };
219 
220 } // namespace MueLu
221 
222 #endif // defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA)
223 
224 #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)