MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_Details_LinearSolverFactory_def.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
13
14#ifndef MUELU_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
15#define MUELU_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
16
17#include "MueLu_config.hpp"
18#include "Trilinos_Details_LinearSolver.hpp"
19#include "Trilinos_Details_LinearSolverFactory.hpp"
20#include <type_traits>
21
22#include "Tpetra_Operator.hpp"
24
25namespace MueLu {
26namespace Details {
27
28template <class MV, class OP, class NormType>
29class LinearSolver : public Trilinos::Details::LinearSolver<MV, OP, NormType>,
30 virtual public Teuchos::Describable {
31 public:
34
36 virtual ~LinearSolver() {}
37
42 void setMatrix(const Teuchos::RCP<const OP>& A);
43
45 Teuchos::RCP<const OP> getMatrix() const {
46 return A_;
47 }
48
50 void solve(MV& X, const MV& B);
51
53 void setParameters(const Teuchos::RCP<Teuchos::ParameterList>& params);
54
57 void symbolic() {}
58
61 void numeric();
62
64 std::string description() const;
65
67 void
68 describe(Teuchos::FancyOStream& out,
69 const Teuchos::EVerbosityLevel verbLevel =
70 Teuchos::Describable::verbLevel_default) const;
71
72 private:
73 Teuchos::RCP<const OP> A_;
74 Teuchos::RCP<Teuchos::ParameterList> params_;
75};
76
77template <class Scalar, class LO, class GO, class Node>
78class LinearSolver<Tpetra::MultiVector<Scalar, LO, GO, Node>,
79 Tpetra::Operator<Scalar, LO, GO, Node>,
80 typename Teuchos::ScalarTraits<Scalar>::magnitudeType> : public Trilinos::Details::LinearSolver<Tpetra::MultiVector<Scalar, LO, GO, Node>,
81 Tpetra::Operator<Scalar, LO, GO, Node>,
82 typename Teuchos::ScalarTraits<Scalar>::magnitudeType>,
83 virtual public Teuchos::Describable {
84 public:
87 : changedA_(false)
88 , changedParams_(false) {}
89
91 virtual ~LinearSolver() {}
92
97 void setMatrix(const Teuchos::RCP<const Tpetra::Operator<Scalar, LO, GO, Node> >& A) {
98 if (A != A_) {
99 if (solver_ != Teuchos::null)
100 changedA_ = true;
101
102 A_ = A;
103 }
104 }
105
107 Teuchos::RCP<const Tpetra::Operator<Scalar, LO, GO, Node> > getMatrix() const {
108 return A_;
109 }
110
112 void solve(Tpetra::MultiVector<Scalar, LO, GO, Node>& X, const Tpetra::MultiVector<Scalar, LO, GO, Node>& B) {
113 // TODO amk: Do we assume the user has called numeric before solve, or should we call it for them?
114 const char prefix[] = "MueLu::Details::LinearSolver::solve: ";
115 TEUCHOS_TEST_FOR_EXCEPTION(solver_.is_null(), std::runtime_error, prefix << "The solver does not "
116 "exist yet. You must call numeric() before you may call this method.");
117 TEUCHOS_TEST_FOR_EXCEPTION(changedA_, std::runtime_error, prefix << "The matrix A has been reset "
118 "since the last call to numeric(). Please call numeric() again.");
119 TEUCHOS_TEST_FOR_EXCEPTION(changedParams_, std::runtime_error, prefix << "The parameters have been reset "
120 "since the last call to numeric(). Please call numeric() again.");
121
122 solver_->apply(B, X);
123 }
124
126 void setParameters(const Teuchos::RCP<Teuchos::ParameterList>& params) {
127 if (solver_ != Teuchos::null && params != params_)
128 changedParams_ = true;
129
130 params_ = params;
131 }
132
135 void symbolic() {}
136
139 void numeric() {
140 const char prefix[] = "MueLu::Details::LinearSolver::numeric: ";
141
142 // If the solver is up-to-date, leave it alone
143 if (solver_ == Teuchos::null || changedParams_) {
144 TEUCHOS_TEST_FOR_EXCEPTION(A_ == Teuchos::null, std::runtime_error, prefix << "The matrix has not been "
145 "set yet. You must call setMatrix() with a nonnull matrix before you may "
146 "call this method.");
147
148 if (params_ != Teuchos::null)
150 else
152 } else if (changedA_) {
153 TEUCHOS_TEST_FOR_EXCEPTION(A_ == Teuchos::null, std::runtime_error, prefix << "The matrix has not been "
154 "set yet. You must call setMatrix() with a nonnull matrix before you may "
155 "call this method.");
156
157 RCP<const Tpetra::CrsMatrix<Scalar, LO, GO, Node> > helperMat;
158 helperMat = rcp_dynamic_cast<const Tpetra::CrsMatrix<Scalar, LO, GO, Node> >(A_);
159 TEUCHOS_TEST_FOR_EXCEPTION(helperMat.is_null(), std::runtime_error, prefix << "MueLu requires "
160 "a Tpetra::CrsMatrix, but the matrix you provided is of a "
161 "different type. Please provide a Tpetra::CrsMatrix instead.");
162 ReuseTpetraPreconditioner(helperMat, *solver_);
163 }
164
165 changedA_ = false;
166 changedParams_ = false;
167 }
168
170 std::string description() const {
171 using Teuchos::TypeNameTraits;
172 if (solver_.is_null()) {
173 std::ostringstream os;
174 os << "\"MueLu::Details::LinearSolver\": {"
175 << "MV: " << TypeNameTraits<Tpetra::MultiVector<Scalar, LO, GO, Node> >::name()
176 << "OP: " << TypeNameTraits<Tpetra::Operator<Scalar, LO, GO, Node> >::name()
177 << "NormType: " << TypeNameTraits<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>::name()
178 << "}";
179 return os.str();
180 } else {
181 return solver_->GetHierarchy()->description();
182 }
183 }
184
186 void
187 describe(Teuchos::FancyOStream& out,
188 const Teuchos::EVerbosityLevel verbLevel =
189 Teuchos::Describable::verbLevel_default) const {
190 using std::endl;
191 using Teuchos::TypeNameTraits;
192 if (solver_.is_null()) {
193 if (verbLevel > Teuchos::VERB_NONE) {
194 Teuchos::OSTab tab0(out);
195 out << "\"MueLu::Details::LinearSolver\":" << endl;
196 Teuchos::OSTab tab1(out);
197 out << "MV: " << TypeNameTraits<Tpetra::MultiVector<Scalar, LO, GO, Node> >::name() << endl
198 << "OP: " << TypeNameTraits<Tpetra::Operator<Scalar, LO, GO, Node> >::name() << endl
199 << "NormType: " << TypeNameTraits<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>::name() << endl;
200 }
201 } else {
202 solver_->GetHierarchy()->describe(out, verbLevel);
203 }
204 }
205
206 private:
207 Teuchos::RCP<const Tpetra::Operator<Scalar, LO, GO, Node> > A_;
208 Teuchos::RCP<Teuchos::ParameterList> params_;
209 Teuchos::RCP<TpetraOperator<Scalar, LO, GO, Node> > solver_;
212};
213
214template <class MV, class OP, class NormType>
215Teuchos::RCP<Trilinos::Details::LinearSolver<MV, OP, NormType> >
217 getLinearSolver(const std::string& solverName) {
218 using Teuchos::rcp;
220}
221
222template <class MV, class OP, class NormType>
225#ifdef HAVE_TEUCHOSCORE_CXX11
226 typedef std::shared_ptr<MueLu::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
227 // typedef std::shared_ptr<Trilinos::Details::LinearSolverFactory<MV, OP> > base_ptr_type;
228#else
229 typedef Teuchos::RCP<MueLu::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
230 // typedef Teuchos::RCP<Trilinos::Details::LinearSolverFactory<MV, OP> > base_ptr_type;
231#endif // HAVE_TEUCHOSCORE_CXX11
232
234 Trilinos::Details::registerLinearSolverFactory<MV, OP, NormType>("MueLu", factory);
235}
236
237} // namespace Details
238} // namespace MueLu
239
240// Macro for doing explicit instantiation of
241// MueLu::Details::LinearSolverFactory, for Tpetra objects, with
242// given Tpetra template parameters (SC = Scalar, LO = LocalOrdinal,
243// GO = GlobalOrdinal, NT = Node).
244//
245// We don't have to protect use of Tpetra objects here, or include
246// any header files for them, because this is a macro definition.
247#define MUELU_DETAILS_LINEARSOLVERFACTORY_INSTANT(SC, LO, GO, NT) \
248 template class MueLu::Details::LinearSolverFactory<Tpetra::MultiVector<SC, LO, GO, NT>, \
249 Tpetra::Operator<SC, LO, GO, NT>, \
250 typename Tpetra::MultiVector<SC, LO, GO, NT>::mag_type>;
251
252#endif // MUELU_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
Various adapters that will create a MueLu preconditioner that is a Tpetra::Operator.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of Teuchos::Describable::describe.
void solve(Tpetra::MultiVector< Scalar, LO, GO, Node > &X, const Tpetra::MultiVector< Scalar, LO, GO, Node > &B)
Solve the linear system(s) AX=B.
Interface for a "factory" that creates MueLu solvers.
static void registerLinearSolverFactory()
Register this LinearSolverFactory with the central registry.
virtual Teuchos::RCP< Trilinos::Details::LinearSolver< MV, OP, NormType > > getLinearSolver(const std::string &solverName)
Get an instance of a MueLu solver.
Teuchos::RCP< Teuchos::ParameterList > params_
std::string description() const
Implementation of Teuchos::Describable::description.
void symbolic()
Set up any part of the solve that depends on the structure of the input matrix, but not its numerical...
virtual ~LinearSolver()
Destructor (virtual for memory safety).
Teuchos::RCP< const OP > getMatrix() const
Get a pointer to this Solver's matrix.
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > &params)
Set this solver's parameters.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Implementation of Teuchos::Describable::describe.
void solve(MV &X, const MV &B)
Solve the linear system(s) AX=B.
void numeric()
Set up any part of the solve that depends on both the structure and the numerical values of the input...
void setMatrix(const Teuchos::RCP< const OP > &A)
Set the Solver's matrix.
Namespace for MueLu classes and methods.
Teuchos::RCP< MueLu::TpetraOperator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > CreateTpetraPreconditioner(const Teuchos::RCP< Tpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &inA, Teuchos::ParameterList &inParamList)
Helper function to create a MueLu or AMGX preconditioner that can be used by Tpetra....
void ReuseTpetraPreconditioner(const Teuchos::RCP< Tpetra::CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &inA, MueLu::TpetraOperator< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op)
Helper function to reuse an existing MueLu preconditioner.