48 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_IFPACK)
50 #include <Ifpack_Chebyshev.h>
51 #include "Xpetra_MultiVectorFactory.hpp"
56 #include "MueLu_Utilities.hpp"
63 : type_(type), overlap_(overlap)
75 prec_->SetParameters(const_cast<ParameterList&>(this->GetParameterList()));
81 ParameterList& paramList = const_cast<ParameterList&>(this->GetParameterList());
82 paramList.setParameters(list);
84 RCP<ParameterList> precList = this->RemoveFactoriesFromList(this->GetParameterList());
86 prec_->SetParameters(*precList);
112 template <
class Node>
114 this->Input(currentLevel,
"A");
116 if (type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
117 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
118 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
119 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
120 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
121 type_ ==
"LINESMOOTHING_BLOCKRELAXATION") {
122 this->Input(currentLevel,
"CoarseNumZLayers");
123 this->Input(currentLevel,
"LineDetection_VertLineIds");
127 template <
class Node>
131 this->GetOStream(
Warnings0) <<
"MueLu::IfpackSmoother::Setup(): Setup() has already been called" << std::endl;
133 A_ = Factory::Get< RCP<Matrix> >(currentLevel,
"A");
135 double lambdaMax = -1.0;
136 if (type_ ==
"Chebyshev") {
137 std::string maxEigString =
"chebyshev: max eigenvalue";
138 std::string eigRatioString =
"chebyshev: ratio eigenvalue";
141 lambdaMax = Teuchos::getValue<Scalar>(this->GetParameter(maxEigString));
142 this->GetOStream(
Statistics1) << maxEigString <<
" (cached with smoother parameter list) = " << lambdaMax << std::endl;
144 }
catch (Teuchos::Exceptions::InvalidParameterName) {
145 lambdaMax = A_->GetMaxEigenvalueEstimate();
147 if (lambdaMax != -1.0) {
148 this->GetOStream(
Statistics1) << maxEigString <<
" (cached with matrix) = " << lambdaMax << std::endl;
149 this->SetParameter(maxEigString, ParameterEntry(lambdaMax));
154 const Scalar defaultEigRatio = 20;
156 Scalar ratio = defaultEigRatio;
158 ratio = Teuchos::getValue<Scalar>(this->GetParameter(eigRatioString));
160 }
catch (Teuchos::Exceptions::InvalidParameterName) {
161 this->SetParameter(eigRatioString, ParameterEntry(ratio));
164 if (currentLevel.GetLevelID()) {
169 RCP<const Matrix> fineA = currentLevel.GetPreviousLevel()->Get<RCP<Matrix> >(
"A");
170 size_t nRowsFine = fineA->getGlobalNumRows();
171 size_t nRowsCoarse = A_->getGlobalNumRows();
173 ratio = std::max(ratio, as<Scalar>(nRowsFine)/nRowsCoarse);
175 this->GetOStream(
Statistics1) << eigRatioString <<
" (computed) = " << ratio << std::endl;
176 this->SetParameter(eigRatioString, ParameterEntry(ratio));
180 if (type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
181 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
182 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
183 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
184 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
185 type_ ==
"LINESMOOTHING_BLOCKRELAXATION" ) {
186 ParameterList& myparamList = const_cast<ParameterList&>(this->GetParameterList());
188 LO CoarseNumZLayers = currentLevel.Get<LO>(
"CoarseNumZLayers",
Factory::GetFactory(
"CoarseNumZLayers").get());
189 if (CoarseNumZLayers > 0) {
190 Teuchos::ArrayRCP<LO> TVertLineIdSmoo = currentLevel.Get< Teuchos::ArrayRCP<LO> >(
"LineDetection_VertLineIds",
Factory::GetFactory(
"LineDetection_VertLineIds").get());
194 for(
size_t k = 0; k < Teuchos::as<size_t>(TVertLineIdSmoo.size()); k++) {
195 if(maxPart < TVertLineIdSmoo[k]) maxPart = TVertLineIdSmoo[k];
198 size_t numLocalRows = A_->getNodeNumRows();
199 TEUCHOS_TEST_FOR_EXCEPTION(numLocalRows % TVertLineIdSmoo.size() != 0,
Exceptions::RuntimeError,
"MueLu::Ifpack2Smoother::Setup(): the number of local nodes is incompatible with the TVertLineIdsSmoo.");
201 if (numLocalRows == Teuchos::as<size_t>(TVertLineIdSmoo.size())) {
202 myparamList.set(
"partitioner: type",
"user");
203 myparamList.set(
"partitioner: map",&(TVertLineIdSmoo[0]));
204 myparamList.set(
"partitioner: local parts",maxPart+1);
207 size_t numDofsPerNode = numLocalRows / TVertLineIdSmoo.size();
210 Teuchos::ArrayRCP<LO> partitionerMap(numLocalRows, Teuchos::OrdinalTraits<LocalOrdinal>::invalid());
211 for (
size_t blockRow = 0; blockRow < Teuchos::as<size_t>(TVertLineIdSmoo.size()); ++blockRow)
212 for (
size_t dof = 0; dof < numDofsPerNode; dof++)
213 partitionerMap[blockRow * numDofsPerNode + dof] = TVertLineIdSmoo[blockRow];
214 myparamList.set(
"partitioner: type",
"user");
215 myparamList.set(
"partitioner: map",&(partitionerMap[0]));
216 myparamList.set(
"partitioner: local parts",maxPart + 1);
219 if (type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
220 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
221 type_ ==
"LINESMOOTHING_BANDEDRELAXATION")
222 type_ =
"block relaxation";
224 type_ =
"block relaxation";
227 this->GetOStream(
Runtime0) <<
"Line detection failed: fall back to point-wise relaxation" << std::endl;
228 myparamList.remove(
"partitioner: type",
false);
229 myparamList.remove(
"partitioner: map",
false);
230 myparamList.remove(
"partitioner: local parts",
false);
231 type_ =
"point relaxation stand-alone";
239 prec_ = rcp(factory.
Create(type_, &(*epA), overlap_));
240 TEUCHOS_TEST_FOR_EXCEPTION(prec_.is_null(),
Exceptions::RuntimeError,
"Could not create an Ifpack preconditioner with type = \"" << type_ <<
"\"");
246 if (type_ ==
"Chebyshev" && lambdaMax == -1.0) {
247 Teuchos::RCP<Ifpack_Chebyshev> chebyPrec = rcp_dynamic_cast<Ifpack_Chebyshev>(prec_);
248 if (chebyPrec != Teuchos::null) {
249 lambdaMax = chebyPrec->GetLambdaMax();
250 A_->SetMaxEigenvalueEstimate(lambdaMax);
251 this->GetOStream(
Statistics1) <<
"chebyshev: max eigenvalue (calculated by Ifpack)" <<
" = " << lambdaMax << std::endl;
253 TEUCHOS_TEST_FOR_EXCEPTION(lambdaMax == -1.0,
Exceptions::RuntimeError,
"MueLu::IfpackSmoother::Setup(): no maximum eigenvalue estimate");
256 this->GetOStream(
Statistics1) << description() << std::endl;
259 template <
class Node>
264 Teuchos::ParameterList paramList;
265 bool supportInitialGuess =
false;
266 if (type_ ==
"Chebyshev") {
267 paramList.set(
"chebyshev: zero starting solution", InitialGuessIsZero);
268 supportInitialGuess =
true;
270 }
else if (type_ ==
"point relaxation stand-alone") {
271 paramList.set(
"relaxation: zero starting solution", InitialGuessIsZero);
272 supportInitialGuess =
true;
275 SetPrecParameters(paramList);
278 if (InitialGuessIsZero || supportInitialGuess) {
282 prec_->ApplyInverse(epB, epX);
286 RCP<MultiVector> Correction = MultiVectorFactory::Build(A_->getDomainMap(), X.getNumVectors());
291 prec_->ApplyInverse(epB, epX);
293 X.update(1.0, *Correction, 1.0);
297 template <
class Node>
300 smoother->SetParameterList(this->GetParameterList());
304 template <
class Node>
306 std::ostringstream out;
309 if (prec_ == Teuchos::null || this->GetVerbLevel() ==
Test) {
311 out <<
"{type = " << type_ <<
"}";
313 out << prec_->Label();
318 template <
class Node>
323 out0 <<
"Prec. type: " << type_ << std::endl;
326 out0 <<
"Parameter list: " << std::endl;
327 Teuchos::OSTab tab2(out);
328 out << this->GetParameterList();
329 out0 <<
"Overlap: " << overlap_ << std::endl;
333 if (prec_ != Teuchos::null) {
334 Teuchos::OSTab tab2(out);
335 out << *prec_ << std::endl;
338 if (verbLevel &
Debug) {
341 <<
"RCP<A_>: " << A_ << std::endl
342 <<
"RCP<prec_>: " << prec_ << std::endl;
346 template <
class Node>
349 return Teuchos::OrdinalTraits<size_t>::invalid();
358 #if defined(HAVE_MUELU_EPETRA)