12#if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_IFPACK)
14#include <Ifpack_Chebyshev.h>
15#include "Xpetra_MultiVectorFactory.hpp"
20#include "MueLu_Utilities.hpp"
22#include "MueLu_Aggregates.hpp"
47 ParameterList& paramList =
const_cast<ParameterList&
>(this->
GetParameterList());
48 paramList.setParameters(list);
52 prec_->SetParameters(*precList);
80 this->
Input(currentLevel,
"A");
82 if (
type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
83 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
84 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
85 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
86 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
87 type_ ==
"LINESMOOTHING_BLOCKRELAXATION") {
88 this->
Input(currentLevel,
"CoarseNumZLayers");
89 this->
Input(currentLevel,
"LineDetection_VertLineIds");
91 else if (
type_ ==
"AGGREGATE") {
93 this->
Input(currentLevel,
"Aggregates");
101 this->
GetOStream(
Warnings0) <<
"MueLu::IfpackSmoother::Setup(): Setup() has already been called" << std::endl;
105 double lambdaMax = -1.0;
106 if (
type_ ==
"Chebyshev") {
107 std::string maxEigString =
"chebyshev: max eigenvalue";
108 std::string eigRatioString =
"chebyshev: ratio eigenvalue";
111 lambdaMax = Teuchos::getValue<Scalar>(this->
GetParameter(maxEigString));
112 this->
GetOStream(
Statistics1) << maxEigString <<
" (cached with smoother parameter list) = " << lambdaMax << std::endl;
114 }
catch (Teuchos::Exceptions::InvalidParameterName&) {
115 lambdaMax =
A_->GetMaxEigenvalueEstimate();
117 if (lambdaMax != -1.0) {
118 this->
GetOStream(
Statistics1) << maxEigString <<
" (cached with matrix) = " << lambdaMax << std::endl;
119 this->
SetParameter(maxEigString, ParameterEntry(lambdaMax));
124 const Scalar defaultEigRatio = 20;
126 Scalar ratio = defaultEigRatio;
128 ratio = Teuchos::getValue<Scalar>(this->
GetParameter(eigRatioString));
130 }
catch (Teuchos::Exceptions::InvalidParameterName&) {
131 this->
SetParameter(eigRatioString, ParameterEntry(ratio));
139 RCP<const Matrix> fineA = currentLevel.
GetPreviousLevel()->Get<RCP<Matrix> >(
"A");
140 size_t nRowsFine = fineA->getGlobalNumRows();
141 size_t nRowsCoarse =
A_->getGlobalNumRows();
143 ratio = std::max(ratio, as<Scalar>(nRowsFine) / nRowsCoarse);
146 this->
SetParameter(eigRatioString, ParameterEntry(ratio));
150 if (
type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
151 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
152 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
153 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
154 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
155 type_ ==
"LINESMOOTHING_BLOCKRELAXATION") {
156 ParameterList& myparamList =
const_cast<ParameterList&
>(this->
GetParameterList());
158 LO CoarseNumZLayers = currentLevel.
Get<LO>(
"CoarseNumZLayers",
Factory::GetFactory(
"CoarseNumZLayers").get());
159 if (CoarseNumZLayers > 0) {
160 Teuchos::ArrayRCP<LO> TVertLineIdSmoo = currentLevel.
Get<Teuchos::ArrayRCP<LO> >(
"LineDetection_VertLineIds",
Factory::GetFactory(
"LineDetection_VertLineIds").get());
164 for (
size_t k = 0; k < Teuchos::as<size_t>(TVertLineIdSmoo.size()); k++) {
165 if (maxPart < TVertLineIdSmoo[k]) maxPart = TVertLineIdSmoo[k];
168 size_t numLocalRows =
A_->getLocalNumRows();
169 TEUCHOS_TEST_FOR_EXCEPTION(numLocalRows % TVertLineIdSmoo.size() != 0,
Exceptions::RuntimeError,
"MueLu::Ifpack2Smoother::Setup(): the number of local nodes is incompatible with the TVertLineIdsSmoo.");
171 if (numLocalRows == Teuchos::as<size_t>(TVertLineIdSmoo.size())) {
172 myparamList.set(
"partitioner: type",
"user");
173 myparamList.set(
"partitioner: map", &(TVertLineIdSmoo[0]));
174 myparamList.set(
"partitioner: local parts", maxPart + 1);
177 size_t numDofsPerNode = numLocalRows / TVertLineIdSmoo.size();
180 Teuchos::ArrayRCP<LO> partitionerMap(numLocalRows, Teuchos::OrdinalTraits<LocalOrdinal>::invalid());
181 for (
size_t blockRow = 0; blockRow < Teuchos::as<size_t>(TVertLineIdSmoo.size()); ++blockRow)
182 for (
size_t dof = 0; dof < numDofsPerNode; dof++)
183 partitionerMap[blockRow * numDofsPerNode + dof] = TVertLineIdSmoo[blockRow];
184 myparamList.set(
"partitioner: type",
"user");
185 myparamList.set(
"partitioner: map", &(partitionerMap[0]));
186 myparamList.set(
"partitioner: local parts", maxPart + 1);
189 if (
type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
190 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
191 type_ ==
"LINESMOOTHING_BANDEDRELAXATION")
192 type_ =
"block relaxation";
194 type_ =
"block relaxation";
197 this->
GetOStream(
Runtime0) <<
"Line detection failed: fall back to point-wise relaxation" << std::endl;
198 myparamList.remove(
"partitioner: type",
false);
199 myparamList.remove(
"partitioner: map",
false);
200 myparamList.remove(
"partitioner: local parts",
false);
201 type_ =
"point relaxation stand-alone";
206 if (
type_ ==
"AGGREGATE") {
213 if (precList.isParameter(
"partitioner: type") && precList.get<std::string>(
"partitioner: type") ==
"linear" &&
214 !precList.isParameter(
"partitioner: local parts")) {
215 precList.set(
"partitioner: local parts", (
int)
A_->getLocalNumRows() /
A_->GetFixedBlockSize());
229 if (
type_ ==
"Chebyshev" && lambdaMax == -1.0) {
230 Teuchos::RCP<Ifpack_Chebyshev> chebyPrec = rcp_dynamic_cast<Ifpack_Chebyshev>(
prec_);
231 if (chebyPrec != Teuchos::null) {
232 lambdaMax = chebyPrec->GetLambdaMax();
233 A_->SetMaxEigenvalueEstimate(lambdaMax);
235 <<
" = " << lambdaMax << std::endl;
237 TEUCHOS_TEST_FOR_EXCEPTION(lambdaMax == -1.0,
Exceptions::RuntimeError,
"MueLu::IfpackSmoother::Setup(): no maximum eigenvalue estimate");
245 ParameterList& paramList =
const_cast<ParameterList&
>(this->
GetParameterList());
248 this->
GetOStream(
Warnings0) <<
"MueLu::Ifpack2moother::SetupAggregate(): Setup() has already been called" << std::endl;
249 this->
GetOStream(
Warnings0) <<
"MueLu::IfpackSmoother::SetupAggregate(): reuse of this type is not available, reverting to full construction" << std::endl;
255 RCP<const LOMultiVector> vertex2AggId = aggregates->GetVertex2AggId();
256 ArrayRCP<LO> aggregate_ids = rcp_const_cast<LOMultiVector>(vertex2AggId)->getDataNonConst(0);
257 ArrayRCP<LO> dof_ids;
260 if (
A_->GetFixedBlockSize() > 1) {
265 LO blocksize = (LO)
A_->GetFixedBlockSize();
266 dof_ids.resize(aggregate_ids.size() * blocksize);
267 for (LO i = 0; i < (LO)aggregate_ids.size(); i++) {
268 for (LO j = 0; j < (LO)blocksize; j++)
269 dof_ids[i * blocksize + j] = aggregate_ids[i];
272 dof_ids = aggregate_ids;
275 paramList.set(
"partitioner: map", dof_ids.getRawPtr());
276 paramList.set(
"partitioner: type",
"user");
277 paramList.set(
"partitioner: overlap", 0);
278 paramList.set(
"partitioner: local parts", (
int)aggregates->GetNumAggregates());
280 paramList.set(
"partitioner: keep singletons",
true);
283 type_ =
"block relaxation stand-alone";
290 int rv =
prec_->Compute();
299 Teuchos::ParameterList paramList;
300 bool supportInitialGuess =
false;
301 if (
type_ ==
"Chebyshev") {
302 paramList.set(
"chebyshev: zero starting solution", InitialGuessIsZero);
303 supportInitialGuess =
true;
305 }
else if (
type_ ==
"point relaxation stand-alone") {
306 paramList.set(
"relaxation: zero starting solution", InitialGuessIsZero);
307 supportInitialGuess =
true;
313 if (InitialGuessIsZero || supportInitialGuess) {
317 prec_->ApplyInverse(epB, epX);
321 RCP<MultiVector> Correction = MultiVectorFactory::Build(
A_->getDomainMap(), X.getNumVectors());
326 prec_->ApplyInverse(epB, epX);
328 X.update(1.0, *Correction, 1.0);
336 return Teuchos::rcp_dynamic_cast<MueLu::SmootherPrototype<double, int, int, Node> >(smoother);
341 std::ostringstream out;
346 out <<
"{type = " <<
type_ <<
"}";
348 out <<
prec_->Label();
358 out0 <<
"Prec. type: " <<
type_ << std::endl;
361 out0 <<
"Parameter list: " << std::endl;
362 Teuchos::OSTab tab2(out);
364 out0 <<
"Overlap: " <<
overlap_ << std::endl;
368 if (
prec_ != Teuchos::null) {
369 Teuchos::OSTab tab2(out);
370 out << *
prec_ << std::endl;
373 if (verbLevel &
Debug) {
376 <<
"RCP<A_>: " <<
A_ << std::endl
377 <<
"RCP<prec_>: " <<
prec_ << std::endl;
384 return Teuchos::OrdinalTraits<size_t>::invalid();
392#if defined(HAVE_MUELU_EPETRA)
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
Ifpack_Preconditioner * Create(const std::string PrecType, Epetra_RowMatrix *Matrix, const int overlap=0, bool overrideSerialDefault=false)
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.
void Input(Level &level, const std::string &varName) const
T Get(Level &level, const std::string &varName) const
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory().
RCP< ParameterList > RemoveFactoriesFromList(const ParameterList &list) const
Class that encapsulates Ifpack smoothers.
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the preconditioner.
void SetPrecParameters(const Teuchos::ParameterList &list=Teuchos::ParameterList()) const
IfpackSmoother(std::string const &type, Teuchos::ParameterList const ¶mList=Teuchos::ParameterList(), LO const &overlap=0)
Constructor.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
std::string description() const
Return a simple one-line description of this object.
std::string type_
ifpack-specific key phrase that denote smoother type
void Setup(Level ¤tLevel)
Set up the smoother.
RCP< SmootherPrototype > Copy() const
void DeclareInput(Level ¤tLevel) const
Input.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
void SetupAggregate(Level ¤tLevel)
RCP< Matrix > A_
Matrix. Not used directly, but held inside of prec_. So we have to keep an RCP pointer to it!
RCP< Ifpack_Preconditioner > prec_
pointer to Ifpack solver object
LO overlap_
overlap when using the smoother in additive Schwarz mode
void SetParameterList(const Teuchos::ParameterList ¶mList)
Set parameters from a parameter list and return with default values.
Class that holds all level-specific information.
RCP< Level > & GetPreviousLevel()
Previous level.
int GetLevelID() const
Return level number.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
const ParameterEntry & GetParameter(const std::string &name) const
Retrieves a const entry with the name name.
virtual const Teuchos::ParameterList & GetParameterList() const
void SetParameter(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
virtual void SetParameterList(const Teuchos::ParameterList ¶mList)=0
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< MultiVector > Residual(const Xpetra::Operator< Scalar, DefaultLocalOrdinal, DefaultGlobalOrdinal, DefaultNode > &Op, const MultiVector &X, const MultiVector &RHS)
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.
VerbLevel GetVerbLevel() const
Get the verbosity level.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line).
@ Debug
Print additional debugging information.
@ Statistics1
Print more statistics.
@ External
Print external lib objects.
@ Runtime0
One-liner description of what is happening.
@ Parameters0
Print class parameters.
@ Statistics0
Print statistics that do not involve significant additional computation.
@ Parameters1
Print class parameters (more parameters, more verbose).