101 this->GetOStream(
Warnings0) <<
"MueLu::IfpackSmoother::Setup(): Setup() has already been called" << std::endl;
103 A_ = Factory::Get<RCP<Matrix> >(currentLevel,
"A");
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);
145 this->GetOStream(
Statistics1) << eigRatioString <<
" (computed) = " << ratio << std::endl;
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") {
207 SetupAggregate(currentLevel);
212 ParameterList& precList =
const_cast<ParameterList&
>(this->GetParameterList());
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());
221 prec_ = rcp(factory.
Create(type_, &(*epA), overlap_));
222 TEUCHOS_TEST_FOR_EXCEPTION(prec_.is_null(),
Exceptions::RuntimeError,
"Could not create an Ifpack preconditioner with type = \"" << type_ <<
"\"");
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);
234 this->GetOStream(
Statistics1) <<
"chebyshev: max eigenvalue (calculated by Ifpack)"
235 <<
" = " << lambdaMax << std::endl;
237 TEUCHOS_TEST_FOR_EXCEPTION(lambdaMax == -1.0,
Exceptions::RuntimeError,
"MueLu::IfpackSmoother::Setup(): no maximum eigenvalue estimate");
240 this->GetOStream(
Statistics1) << description() << std::endl;
245 ParameterList& paramList =
const_cast<ParameterList&
>(this->GetParameterList());
247 if (this->IsSetup() ==
true) {
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;
252 this->GetOStream(
Statistics0) <<
"IfpackSmoother: Using Aggregate Smoothing" << std::endl;
254 RCP<Aggregates> aggregates = Factory::Get<RCP<Aggregates> >(currentLevel,
"Aggregates");
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";
286 prec_ = rcp(factory.
Create(type_, &(*A), overlap_));
287 TEUCHOS_TEST_FOR_EXCEPTION(prec_.is_null(),
Exceptions::RuntimeError,
"Could not create an Ifpack preconditioner with type = \"" << type_ <<
"\"");
290 int rv = prec_->Compute();
291 TEUCHOS_TEST_FOR_EXCEPTION(rv,
Exceptions::RuntimeError,
"Ifpack preconditioner with type = \"" << type_ <<
"\" Compute() call failed.");
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;
310 SetPrecParameters(paramList);
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);