14#ifndef MUELU_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
15#define MUELU_DETAILS_LINEARSOLVERFACTORY_DEF_HPP
17#include "MueLu_config.hpp"
18#include "Trilinos_Details_LinearSolver.hpp"
19#include "Trilinos_Details_LinearSolverFactory.hpp"
22#include "Tpetra_Operator.hpp"
28template <
class MV,
class OP,
class NormType>
29class LinearSolver :
public Trilinos::Details::LinearSolver<MV, OP, NormType>,
30 virtual public Teuchos::Describable {
69 const Teuchos::EVerbosityLevel verbLevel =
70 Teuchos::Describable::verbLevel_default)
const;
73 Teuchos::RCP<const OP>
A_;
74 Teuchos::RCP<Teuchos::ParameterList>
params_;
78#if defined(HAVE_MUELU_SERIAL) and defined(HAVE_MUELU_EPETRA)
80class LinearSolver<Epetra_MultiVector, Epetra_Operator, double> :
public Trilinos::Details::LinearSolver<Epetra_MultiVector, Epetra_Operator, double>,
81 virtual public Teuchos::Describable {
86 , changedParams_(
false) {}
95 void setMatrix(
const Teuchos::RCP<const Epetra_Operator>& A) {
96 const char prefix[] =
"MueLu::Details::LinearSolver::setMatrix: ";
99 if (solver_ != Teuchos::null)
102 A_ = rcp_dynamic_cast<const Epetra_CrsMatrix>(A);
103 TEUCHOS_TEST_FOR_EXCEPTION(
A_.is_null(), std::runtime_error, prefix <<
"MueLu requires "
104 "an Epetra_CrsMatrix, but the matrix you provided is of a "
105 "different type. Please provide an Epetra_CrsMatrix instead.");
110 Teuchos::RCP<const Epetra_Operator>
getMatrix()
const {
115 void solve(Epetra_MultiVector& X,
const Epetra_MultiVector& B) {
117 const char prefix[] =
"MueLu::Details::LinearSolver::solve: ";
118 TEUCHOS_TEST_FOR_EXCEPTION(solver_.is_null(), std::runtime_error, prefix <<
"The solver does not "
119 "exist yet. You must call numeric() before you may call this method.");
120 TEUCHOS_TEST_FOR_EXCEPTION(changedA_, std::runtime_error, prefix <<
"The matrix A has been reset "
121 "since the last call to numeric(). Please call numeric() again.");
122 TEUCHOS_TEST_FOR_EXCEPTION(changedParams_, std::runtime_error, prefix <<
"The parameters have been reset "
123 "since the last call to numeric(). Please call numeric() again.");
125 int err = solver_->ApplyInverse(B, X);
127 TEUCHOS_TEST_FOR_EXCEPTION(err != 0, std::runtime_error, prefix <<
"EpetraOperator::ApplyInverse returned "
128 "nonzero error code "
133 void setParameters(
const Teuchos::RCP<Teuchos::ParameterList>& params) {
134 if (solver_ != Teuchos::null && params !=
params_)
135 changedParams_ =
true;
147 const char prefix[] =
"MueLu::Details::LinearSolver::numeric: ";
150 if (solver_ == Teuchos::null || changedA_ || changedParams_) {
152 changedParams_ =
false;
154 TEUCHOS_TEST_FOR_EXCEPTION(
A_ == Teuchos::null, std::runtime_error, prefix <<
"The matrix has not been "
155 "set yet. You must call setMatrix() with a nonnull matrix before you may "
156 "call this method.");
161 solver_ = CreateEpetraPreconditioner(rcp_const_cast<Epetra_CrsMatrix>(
A_), *
params_);
163 solver_ = CreateEpetraPreconditioner(rcp_const_cast<Epetra_CrsMatrix>(
A_));
169 if (solver_.is_null()) {
170 return "\"MueLu::Details::LinearSolver\": {MV: Epetra_MultiVector, OP: Epetra_Operator, NormType: double}";
172 return solver_->GetHierarchy()->description();
178 describe(Teuchos::FancyOStream& out,
179 const Teuchos::EVerbosityLevel verbLevel =
180 Teuchos::Describable::verbLevel_default)
const {
182 if (solver_.is_null()) {
183 if (verbLevel > Teuchos::VERB_NONE) {
184 Teuchos::OSTab tab0(out);
185 out <<
"\"MueLu::Details::LinearSolver\":" << endl;
186 Teuchos::OSTab tab1(out);
187 out <<
"MV: Epetra_MultiVector" << endl
188 <<
"OP: Epetra_Operator" << endl
189 <<
"NormType: double" << endl;
192 solver_->GetHierarchy()->describe(out, verbLevel);
197 Teuchos::RCP<const Epetra_CrsMatrix>
A_;
198 Teuchos::RCP<Teuchos::ParameterList>
params_;
199 Teuchos::RCP<EpetraOperator> solver_;
205template <
class Scalar,
class LO,
class GO,
class Node>
207 Tpetra::Operator<Scalar, LO, GO, Node>,
208 typename Teuchos::ScalarTraits<Scalar>::magnitudeType> :
public Trilinos::Details::LinearSolver<Tpetra::MultiVector<Scalar, LO, GO, Node>,
209 Tpetra::Operator<Scalar, LO, GO, Node>,
210 typename Teuchos::ScalarTraits<Scalar>::magnitudeType>,
211 virtual public Teuchos::Describable {
216 , changedParams_(false) {}
225 void setMatrix(
const Teuchos::RCP<
const Tpetra::Operator<Scalar, LO, GO, Node> >& A) {
227 if (solver_ != Teuchos::null)
235 Teuchos::RCP<const Tpetra::Operator<Scalar, LO, GO, Node> >
getMatrix()
const {
240 void solve(Tpetra::MultiVector<Scalar, LO, GO, Node>& X,
const Tpetra::MultiVector<Scalar, LO, GO, Node>& B) {
242 const char prefix[] =
"MueLu::Details::LinearSolver::solve: ";
243 TEUCHOS_TEST_FOR_EXCEPTION(solver_.is_null(), std::runtime_error, prefix <<
"The solver does not "
244 "exist yet. You must call numeric() before you may call this method.");
245 TEUCHOS_TEST_FOR_EXCEPTION(changedA_, std::runtime_error, prefix <<
"The matrix A has been reset "
246 "since the last call to numeric(). Please call numeric() again.");
247 TEUCHOS_TEST_FOR_EXCEPTION(changedParams_, std::runtime_error, prefix <<
"The parameters have been reset "
248 "since the last call to numeric(). Please call numeric() again.");
250 solver_->apply(B, X);
255 if (solver_ != Teuchos::null && params !=
params_)
256 changedParams_ =
true;
268 const char prefix[] =
"MueLu::Details::LinearSolver::numeric: ";
271 if (solver_ == Teuchos::null || changedParams_) {
272 TEUCHOS_TEST_FOR_EXCEPTION(
A_ == Teuchos::null, std::runtime_error, prefix <<
"The matrix has not been "
273 "set yet. You must call setMatrix() with a nonnull matrix before you may "
274 "call this method.");
282 }
else if (changedA_) {
283 TEUCHOS_TEST_FOR_EXCEPTION(
A_ == Teuchos::null, std::runtime_error, prefix <<
"The matrix has not been "
284 "set yet. You must call setMatrix() with a nonnull matrix before you may "
285 "call this method.");
289 RCP<const Tpetra::CrsMatrix<Scalar, LO, GO, Node> > helperMat;
290 helperMat = rcp_dynamic_cast<const Tpetra::CrsMatrix<Scalar, LO, GO, Node> >(
A_);
291 TEUCHOS_TEST_FOR_EXCEPTION(helperMat.is_null(), std::runtime_error, prefix <<
"MueLu requires "
292 "a Tpetra::CrsMatrix, but the matrix you provided is of a "
293 "different type. Please provide a Tpetra::CrsMatrix instead.");
298 changedParams_ =
false;
303 using Teuchos::TypeNameTraits;
304 if (solver_.is_null()) {
305 std::ostringstream os;
306 os <<
"\"MueLu::Details::LinearSolver\": {"
307 <<
"MV: " << TypeNameTraits<Tpetra::MultiVector<Scalar, LO, GO, Node> >::name()
308 <<
"OP: " << TypeNameTraits<Tpetra::Operator<Scalar, LO, GO, Node> >::name()
309 <<
"NormType: " << TypeNameTraits<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>::name()
313 return solver_->GetHierarchy()->description();
320 const Teuchos::EVerbosityLevel verbLevel =
321 Teuchos::Describable::verbLevel_default)
const {
323 using Teuchos::TypeNameTraits;
324 if (solver_.is_null()) {
325 if (verbLevel > Teuchos::VERB_NONE) {
326 Teuchos::OSTab tab0(out);
327 out <<
"\"MueLu::Details::LinearSolver\":" << endl;
328 Teuchos::OSTab tab1(out);
329 out <<
"MV: " << TypeNameTraits<Tpetra::MultiVector<Scalar, LO, GO, Node> >::name() << endl
330 <<
"OP: " << TypeNameTraits<Tpetra::Operator<Scalar, LO, GO, Node> >::name() << endl
331 <<
"NormType: " << TypeNameTraits<typename Teuchos::ScalarTraits<Scalar>::magnitudeType>::name() << endl;
334 solver_->GetHierarchy()->describe(out, verbLevel);
339 Teuchos::RCP<const Tpetra::Operator<Scalar, LO, GO, Node> >
A_;
341 Teuchos::RCP<TpetraOperator<Scalar, LO, GO, Node> >
solver_;
346template <
class MV,
class OP,
class NormType>
347Teuchos::RCP<Trilinos::Details::LinearSolver<MV, OP, NormType> >
354template <
class MV,
class OP,
class NormType>
357#ifdef HAVE_TEUCHOSCORE_CXX11
358 typedef std::shared_ptr<MueLu::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
361 typedef Teuchos::RCP<MueLu::Details::LinearSolverFactory<MV, OP, NormType> > ptr_type;
366 Trilinos::Details::registerLinearSolverFactory<MV, OP, NormType>(
"MueLu", factory);
379#define MUELU_DETAILS_LINEARSOLVERFACTORY_INSTANT(SC, LO, GO, NT) \
380 template class MueLu::Details::LinearSolverFactory<Tpetra::MultiVector<SC, LO, GO, NT>, \
381 Tpetra::Operator<SC, LO, GO, NT>, \
382 typename Tpetra::MultiVector<SC, LO, GO, NT>::mag_type>;
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 setMatrix(const Teuchos::RCP< const Tpetra::Operator< Scalar, LO, GO, Node > > &A)
Set the Solver's matrix.
Teuchos::RCP< TpetraOperator< Scalar, LO, GO, Node > > solver_
void symbolic()
Set up any part of the solve that depends on the structure of the input matrix, but not its numerical...
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Set this solver's parameters.
Teuchos::RCP< const Tpetra::Operator< Scalar, LO, GO, Node > > getMatrix() const
Get a pointer to this Solver's matrix.
void solve(Tpetra::MultiVector< Scalar, LO, GO, Node > &X, const Tpetra::MultiVector< Scalar, LO, GO, Node > &B)
Solve the linear system(s) AX=B.
virtual ~LinearSolver()
Destructor (virtual for memory safety).
Teuchos::RCP< Teuchos::ParameterList > params_
void numeric()
Set up any part of the solve that depends on both the structure and the numerical values of the input...
std::string description() const
Implementation of Teuchos::Describable::description.
LinearSolver()
Constructor.
Teuchos::RCP< const Tpetra::Operator< Scalar, LO, GO, Node > > A_
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 > A_
Teuchos::RCP< const OP > getMatrix() const
Get a pointer to this Solver's matrix.
void setParameters(const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
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...
LinearSolver()
Constructor.
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.