MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_AmesosSmoother.cpp
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#include <algorithm>
11
12#include "MueLu_ConfigDefs.hpp"
13
14#if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_AMESOS)
15
16#include <Epetra_LinearProblem.h>
17
18#include <Amesos_config.h>
19#include <Amesos.h>
20#include <Amesos_BaseSolver.h>
21
23
24#include "MueLu_Level.hpp"
25#include "MueLu_Utilities.hpp"
26#include "MueLu_Monitor.hpp"
27
28namespace MueLu {
29
30template <class Node>
31AmesosSmoother<Node>::AmesosSmoother(const std::string& type, const Teuchos::ParameterList& paramList)
32 : type_(type) {
33 this->SetParameterList(paramList);
34
35 if (!type_.empty()) {
36 // Transform string to "Abcde" notation
37 std::transform(type_.begin(), type_.end(), type_.begin(), ::tolower);
38 std::transform(type_.begin(), ++type_.begin(), type_.begin(), ::toupper);
39 }
40 if (type_ == "Amesos_klu") type_ = "Klu";
41 if (type_ == "Klu2") type_ = "Klu";
42 if (type_ == "Amesos_umfpack") type_ = "Umfpack";
43 if (type_ == "Superlu_dist") type_ = "Superludist";
44 if (type_ == "Amesos_mumps") type_ = "Mumps";
45
46 // Try to come up with something availble
47 // Order corresponds to our preference
48 // TODO: It would be great is Amesos provides directly this kind of logic for us
49 std::string oldtype = type_;
50 if (type_ == "" || Amesos().Query(type_) == false) {
51#if defined(HAVE_AMESOS_SUPERLU)
52 type_ = "Superlu";
53#elif defined(HAVE_AMESOS_KLU)
54 type_ = "Klu";
55#elif defined(HAVE_AMESOS_SUPERLUDIST)
56 type_ = "Superludist";
57#elif defined(HAVE_AMESOS_UMFPACK)
58 type_ = "Umfpack";
59#else
60 this->declareConstructionOutcome(true, "Amesos has been compiled without SuperLU_DIST, SuperLU, Umfpack or Klu. By default, MueLu tries" +
61 "to use one of these libraries. Amesos must be compiled with one of these solvers, " +
62 "or a valid Amesos solver has to be specified explicitly.");
63 return;
64#endif
65 if (oldtype != "")
66 this->GetOStream(Warnings0) << "MueLu::AmesosSmoother: \"" << oldtype << "\" is not available. Using \"" << type_ << "\" instead" << std::endl;
67 else
68 this->GetOStream(Runtime1) << "MueLu::AmesosSmoother: using \"" << type_ << "\"" << std::endl;
69 }
70 this->declareConstructionOutcome(false, "");
71}
72
73template <class Node>
74void AmesosSmoother<Node>::DeclareInput(Level& currentLevel) const {
75 this->Input(currentLevel, "A");
76}
77
78template <class Node>
80 FactoryMonitor m(*this, "Setup Smoother", currentLevel);
81
82 if (SmootherPrototype::IsSetup() == true)
83 this->GetOStream(Warnings0) << "MueLu::AmesosSmoother::Setup(): Setup() has already been called" << std::endl;
84
85 A_ = Factory::Get<RCP<Matrix> >(currentLevel, "A");
86
87 RCP<Epetra_CrsMatrix> epA = Utilities::Op2NonConstEpetraCrs(A_);
88 linearProblem_ = rcp(new Epetra_LinearProblem());
89 linearProblem_->SetOperator(epA.get());
90
91 Amesos factory;
92 prec_ = rcp(factory.Create(type_, *linearProblem_));
93 TEUCHOS_TEST_FOR_EXCEPTION(prec_ == Teuchos::null, Exceptions::RuntimeError, "MueLu::AmesosSmoother::Setup(): Solver '" + type_ + "' not supported by Amesos");
94
95 // set Reindex flag, if A is distributed with non-contiguous maps
96 // unfortunately there is no reindex for Amesos2, yet. So, this only works for Epetra based problems
97 if (A_->getRowMap()->isDistributed() == true && A_->getRowMap()->isContiguous() == false)
98 const_cast<ParameterList&>(this->GetParameterList()).set("Reindex", true);
99
100 const ParameterList& paramList = this->GetParameterList();
101 RCP<ParameterList> precList = this->RemoveFactoriesFromList(paramList);
102
103 prec_->SetParameters(*precList);
104
105 const_cast<ParameterList&>(paramList).setParameters(*precList);
106
107 int r = prec_->NumericFactorization();
108 TEUCHOS_TEST_FOR_EXCEPTION(r != 0, Exceptions::RuntimeError, "MueLu::AmesosSmoother::Setup(): Amesos solver returns value of " + Teuchos::toString(r) + " during NumericFactorization()");
109
111}
112
113template <class Node>
114void AmesosSmoother<Node>::Apply(MultiVector& X, const MultiVector& B, bool InitialGuessIsZero) const {
115 TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, Exceptions::RuntimeError, "MueLu::AmesosSmoother::Apply(): Setup() has not been called");
116
119 // Epetra_LinearProblem takes the right-hand side as a non-const pointer.
120 // I think this const_cast is safe because Amesos won't modify the rhs.
121 Epetra_MultiVector& nonconstB = const_cast<Epetra_MultiVector&>(epB);
122
123 linearProblem_->SetLHS(&epX);
124 linearProblem_->SetRHS(&nonconstB);
125
126 prec_->Solve();
127
128 // Don't keep pointers to our vectors in the Epetra_LinearProblem.
129 linearProblem_->SetLHS(0);
130 linearProblem_->SetRHS(0);
131}
132
133template <class Node>
134RCP<MueLu::SmootherPrototype<double, int, int, Node> > AmesosSmoother<Node>::Copy() const {
135 return rcp(new AmesosSmoother<Node>(*this));
136}
137
138template <class Node>
140 std::ostringstream out;
142 out << "{type = " << type_ << "}";
143 return out.str();
144}
145
146// using MueLu::Describable::describe; // overloading, not hiding
147template <class Node>
148void AmesosSmoother<Node>::print(Teuchos::FancyOStream& out, const VerbLevel verbLevel) const {
150
151 if (verbLevel & Parameters0)
152 out0 << "Prec. type: " << type_ << std::endl;
153
154 if (verbLevel & Parameters1) {
155 out0 << "Parameter list: " << std::endl;
156 Teuchos::OSTab tab2(out);
157 out << this->GetParameterList();
158 }
159
160 if (verbLevel & External)
161 if (prec_ != Teuchos::null) {
162 prec_->PrintStatus();
163 prec_->PrintTiming();
164 }
165
166 if (verbLevel & Debug) {
167 out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl
168 << "-" << std::endl
169 << "RCP<A_>: " << A_ << std::endl
170 << "RCP<linearProblem__>: " << linearProblem_ << std::endl
171 << "RCP<prec_>: " << prec_ << std::endl;
172 }
173}
174
175template <class Node>
177 // FIXME: This is a placeholder
178 return Teuchos::OrdinalTraits<size_t>::invalid();
179}
180
181} // namespace MueLu
182
183// The AmesosSmoother is only templated on the Node, since it is an Epetra only object
184// Therefore we do not need the full ETI instantiations as we do for the other MueLu
185// objects which are instantiated on all template parameters.
186#if defined(HAVE_MUELU_EPETRA)
188#endif
189
190#endif // HAVE_MUELU_EPETRA && HAVE_MUELU_AMESOS
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
Amesos_BaseSolver * Create(const char *ClassType, const Epetra_LinearProblem &LinearProblem)
Class that encapsulates Amesos direct solvers.
AmesosSmoother(const std::string &type="", const Teuchos::ParameterList &paramList=Teuchos::ParameterList())
Constructor.
std::string description() const
Return a simple one-line description of this object.
std::string type_
amesos-specific key phrase that denote smoother type
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
void Setup(Level &currentLevel)
Set up the direct solver. This creates the underlying Amesos solver object according to the parameter...
RCP< SmootherPrototype > Copy() const
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
void DeclareInput(Level &currentLevel) const
Input.
void Apply(MultiVector &X, const MultiVector &B, bool=false) const
Apply the direct solver.
virtual std::string description() const
Return a simple one-line description of this object.
Exception throws to report errors in the internal logical of the program.
Timer to be used in factories. Similar to Monitor but with additional timers.
Class that holds all level-specific information.
virtual void SetParameterList(const Teuchos::ParameterList &paramList)
Set parameters from a parameter list and return with default values.
void declareConstructionOutcome(bool fail, std::string msg)
bool IsSetup() const
Get the state of a smoother prototype.
static RCP< Epetra_MultiVector > MV2NonConstEpetraMV(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > vec)
static RCP< Epetra_CrsMatrix > Op2NonConstEpetraCrs(RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Op)
static RCP< const Epetra_MultiVector > MV2EpetraMV(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > const vec)
Helper utility to pull out the underlying Epetra objects from an Xpetra object.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line)
@ Debug
Print additional debugging information.
@ External
Print external lib objects.
@ Runtime1
Description of what is happening (more verbose)
@ Parameters0
Print class parameters.
@ Parameters1
Print class parameters (more parameters, more verbose)