10 #ifndef MUELU_IFPACK2SMOOTHER_DEF_HPP
11 #define MUELU_IFPACK2SMOOTHER_DEF_HPP
16 #if defined(HAVE_MUELU_IFPACK2)
20 #include <Tpetra_RowMatrix.hpp>
22 #include <Ifpack2_Chebyshev.hpp>
23 #include <Ifpack2_Hiptmair.hpp>
24 #include <Ifpack2_RILUK.hpp>
25 #include <Ifpack2_Relaxation.hpp>
26 #include <Ifpack2_ILUT.hpp>
27 #include <Ifpack2_BlockRelaxation.hpp>
28 #include <Ifpack2_Factory.hpp>
29 #include <Ifpack2_Parameters.hpp>
33 #include <Xpetra_CrsMatrixWrap.hpp>
34 #include <Xpetra_TpetraBlockCrsMatrix.hpp>
37 #include <Xpetra_MultiVectorFactory.hpp>
38 #include <Xpetra_TpetraMultiVector.hpp>
40 #include <Tpetra_BlockCrsMatrix_Helpers.hpp>
44 #include "MueLu_Utilities.hpp"
46 #include "MueLu_Aggregates.hpp"
48 #ifdef HAVE_MUELU_INTREPID2
51 #include "Intrepid2_Basis.hpp"
52 #include "Kokkos_DynRankView.hpp"
57 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
67 bool isSupported = Ifpack2::Factory::isSupported<tRowMatrix>(
type_) || (
type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
68 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
69 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
70 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
71 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
72 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION" ||
73 type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
74 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
75 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
76 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
77 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
78 type_ ==
"LINESMOOTHING_BLOCKRELAXATION" ||
79 type_ ==
"TOPOLOGICAL" ||
80 type_ ==
"AGGREGATE");
86 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
97 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
99 std::string prefix = this->ShortClassName() +
": SetPrecParameters";
105 RCP<ParameterList> precList = this->RemoveFactoriesFromList(this->GetParameterList());
108 precList->
set(
"timer for apply", this->IsPrint(
Timings));
110 if (!precList.
is_null() && precList->
isParameter(
"partitioner: type") && precList->
get<std::string>(
"partitioner: type") ==
"linear" &&
111 !precList->
isParameter(
"partitioner: local parts")) {
112 LO matrixBlockSize = 1;
113 int lclSize = A_->getRangeMap()->getLocalNumElements();
116 lclSize = matA->getLocalNumRows();
117 matrixBlockSize = matA->GetFixedBlockSize();
119 precList->
set(
"partitioner: local parts", lclSize / matrixBlockSize);
127 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
129 this->Input(currentLevel,
"A");
131 if (type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
132 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
133 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
134 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
135 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
136 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION" ||
137 type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
138 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
139 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
140 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
141 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
142 type_ ==
"LINESMOOTHING_BLOCKRELAXATION") {
143 this->Input(currentLevel,
"CoarseNumZLayers");
144 this->Input(currentLevel,
"LineDetection_VertLineIds");
145 }
else if (type_ ==
"BLOCK RELAXATION" ||
146 type_ ==
"BLOCK_RELAXATION" ||
147 type_ ==
"BLOCKRELAXATION" ||
149 type_ ==
"BANDED_RELAXATION" ||
150 type_ ==
"BANDED RELAXATION" ||
151 type_ ==
"BANDEDRELAXATION" ||
153 type_ ==
"TRIDI_RELAXATION" ||
154 type_ ==
"TRIDI RELAXATION" ||
155 type_ ==
"TRIDIRELAXATION" ||
156 type_ ==
"TRIDIAGONAL_RELAXATION" ||
157 type_ ==
"TRIDIAGONAL RELAXATION" ||
158 type_ ==
"TRIDIAGONALRELAXATION") {
162 precList.
get<std::string>(
"partitioner: type") ==
"line") {
163 this->Input(currentLevel,
"Coordinates");
165 }
else if (type_ ==
"TOPOLOGICAL") {
167 this->Input(currentLevel,
"pcoarsen: element to node map");
168 }
else if (type_ ==
"AGGREGATE") {
170 this->Input(currentLevel,
"Aggregates");
171 }
else if (type_ ==
"HIPTMAIR") {
173 this->Input(currentLevel,
"NodeMatrix");
174 this->Input(currentLevel,
"D0");
178 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
181 A_ = Factory::Get<RCP<Operator>>(currentLevel,
"A");
186 if (paramList.isParameter(
"smoother: use blockcrsmatrix storage") && paramList.get<
bool>(
"smoother: use blockcrsmatrix storage")) {
190 blocksize = matA->GetFixedBlockSize();
196 throw std::runtime_error(
"Ifpack2Smoother: Cannot convert matrix A to CrsMatrixWrap object.");
199 throw std::runtime_error(
"Ifpack2Smoother: Cannot extract CrsMatrix from matrix A.");
203 throw std::runtime_error(
"Ifpack2Smoother: Cannot extract CrsMatrix or BlockCrsMatrix from matrix A.");
204 this->GetOStream(
Statistics0) <<
"Ifpack2Smoother: Using (native) BlockCrsMatrix storage with blocksize " << blocksize << std::endl;
205 paramList.remove(
"smoother: use blockcrsmatrix storage");
211 this->GetOStream(
Statistics0) <<
"Ifpack2Smoother: Using BlockCrsMatrix storage with blocksize " << blocksize << std::endl;
213 paramList.remove(
"smoother: use blockcrsmatrix storage");
218 if (type_ ==
"SCHWARZ")
219 SetupSchwarz(currentLevel);
221 else if (type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
222 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
223 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
224 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
225 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
226 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION" ||
227 type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
228 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
229 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
230 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
231 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
232 type_ ==
"LINESMOOTHING_BLOCKRELAXATION")
233 SetupLineSmoothing(currentLevel);
235 else if (type_ ==
"BLOCK_RELAXATION" ||
236 type_ ==
"BLOCK RELAXATION" ||
237 type_ ==
"BLOCKRELAXATION" ||
239 type_ ==
"BANDED_RELAXATION" ||
240 type_ ==
"BANDED RELAXATION" ||
241 type_ ==
"BANDEDRELAXATION" ||
243 type_ ==
"TRIDI_RELAXATION" ||
244 type_ ==
"TRIDI RELAXATION" ||
245 type_ ==
"TRIDIRELAXATION" ||
246 type_ ==
"TRIDIAGONAL_RELAXATION" ||
247 type_ ==
"TRIDIAGONAL RELAXATION" ||
248 type_ ==
"TRIDIAGONALRELAXATION")
249 SetupBlockRelaxation(currentLevel);
251 else if (type_ ==
"CHEBYSHEV")
252 SetupChebyshev(currentLevel);
254 else if (type_ ==
"TOPOLOGICAL") {
255 #ifdef HAVE_MUELU_INTREPID2
256 SetupTopological(currentLevel);
260 }
else if (type_ ==
"AGGREGATE")
261 SetupAggregate(currentLevel);
263 else if (type_ ==
"HIPTMAIR")
264 SetupHiptmair(currentLevel);
267 SetupGeneric(currentLevel);
272 this->GetOStream(
Statistics1) << description() << std::endl;
275 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
279 bool reusePreconditioner =
false;
280 if (this->IsSetup() ==
true) {
282 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupSchwarz(): Setup() has already been called, assuming reuse" << std::endl;
284 bool isTRowMatrix =
true;
287 tA = Xpetra::toTpetraRowMatrix(A_);
289 isTRowMatrix =
false;
293 if (!prec.
is_null() && isTRowMatrix) {
295 reusePreconditioner =
true;
297 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupSchwarz(): reuse of this type is not available "
298 "(either failed cast to CanChangeMatrix, or to Tpetra Row Matrix), reverting to full construction"
303 if (!reusePreconditioner) {
306 bool isBlockedMatrix =
false;
309 std::string sublistName =
"subdomain solver parameters";
321 std::string partName =
"partitioner: type";
327 if (subList.
isParameter(partName) && subList.
get<std::string>(partName) ==
"vanka user") {
328 isBlockedMatrix =
true;
332 "Matrix A must be of type BlockedCrsMatrix.");
334 size_t numVels = bA->getMatrix(0, 0)->getLocalNumRows();
335 size_t numPres = bA->getMatrix(1, 0)->getLocalNumRows();
336 size_t numRows = rcp_dynamic_cast<Matrix>(A_,
true)->getLocalNumRows();
340 size_t numBlocks = 0;
341 for (
size_t rowOfB = numVels; rowOfB < numVels + numPres; ++rowOfB)
342 blockSeeds[rowOfB] = numBlocks++;
346 "Matrix A must be of type BlockedCrsMatrix.");
348 merged2Mat = bA2->Merge();
352 bool haveBoundary =
false;
353 for (
LO i = 0; i < boundaryNodes.
size(); i++)
354 if (boundaryNodes[i]) {
358 blockSeeds[i] = numBlocks;
364 subList.
set(
"partitioner: type",
"user");
365 subList.
set(
"partitioner: map", blockSeeds);
366 subList.
set(
"partitioner: local parts", as<int>(numBlocks));
371 isBlockedMatrix =
true;
372 merged2Mat = bA->Merge();
378 if (isBlockedMatrix ==
true)
379 tA = Xpetra::toTpetraRowMatrix(merged2Mat);
381 tA = Xpetra::toTpetraRowMatrix(A_);
392 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
396 if (this->IsSetup() ==
true) {
397 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupAggregate(): Setup() has already been called" << std::endl;
398 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupAggregate(): reuse of this type is not available, reverting to full construction" << std::endl;
401 this->GetOStream(
Statistics0) <<
"Ifpack2Smoother: Using Aggregate Smoothing" << std::endl;
403 RCP<Aggregates> aggregates = Factory::Get<RCP<Aggregates>>(currentLevel,
"Aggregates");
406 ArrayRCP<LO> aggregate_ids = rcp_const_cast<LOMultiVector>(vertex2AggId)->getDataNonConst(0);
413 blocksize = matA->GetFixedBlockSize();
415 dof_ids.
resize(aggregate_ids.
size() * blocksize);
416 for (
LO i = 0; i < (
LO)aggregate_ids.
size(); i++) {
417 for (
LO j = 0; j < (
LO)blocksize; j++)
418 dof_ids[i * blocksize + j] = aggregate_ids[i];
421 dof_ids = aggregate_ids;
424 paramList.
set(
"partitioner: map", dof_ids);
425 paramList.
set(
"partitioner: type",
"user");
426 paramList.
set(
"partitioner: overlap", 0);
431 type_ =
"BLOCKRELAXATION";
438 #ifdef HAVE_MUELU_INTREPID2
439 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
449 if (this->IsSetup() ==
true) {
450 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupTopological(): Setup() has already been called" << std::endl;
451 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupTopological(): reuse of this type is not available, reverting to full construction" << std::endl;
454 ParameterList& paramList =
const_cast<ParameterList&
>(this->GetParameterList());
456 typedef typename Node::device_type::execution_space ES;
458 typedef Kokkos::DynRankView<LocalOrdinal, typename Node::device_type> FCO;
464 const Teuchos::RCP<FCO> elemToNode = Factory::Get<Teuchos::RCP<FCO>>(currentLevel,
"pcoarsen: element to node map");
466 string basisString = paramList.
get<
string>(
"pcoarsen: hi basis");
472 auto basis = MueLuIntrepid::BasisFactory<double, ES>(basisString, degree);
474 string topologyTypeString = paramList.get<
string>(
"smoother: neighborhood type");
476 if (topologyTypeString ==
"node")
478 else if (topologyTypeString ==
"edge")
480 else if (topologyTypeString ==
"face")
482 else if (topologyTypeString ==
"cell")
483 dimension = basis->getBaseCellTopology().getDimension();
485 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unrecognized smoother neighborhood type. Supported types are node, edge, face.");
486 RCP<Matrix> matA = rcp_dynamic_cast<Matrix>(A_,
true);
487 vector<vector<LocalOrdinal>> seeds;
492 int myNodeCount = matA->getRowMap()->getLocalNumElements();
493 ArrayRCP<LocalOrdinal> nodeSeeds(myNodeCount, lo_invalid);
494 int localPartitionNumber = 0;
496 nodeSeeds[seed] = localPartitionNumber++;
499 paramList.remove(
"smoother: neighborhood type");
500 paramList.remove(
"pcoarsen: hi basis");
502 paramList.set(
"partitioner: map", nodeSeeds);
503 paramList.set(
"partitioner: type",
"user");
504 paramList.set(
"partitioner: overlap", 1);
505 paramList.set(
"partitioner: local parts",
int(seeds[dimension].size()));
507 RCP<const Tpetra::RowMatrix<SC, LO, GO, NO>> tA = Xpetra::toTpetraRowMatrix(A_);
509 type_ =
"BLOCKRELAXATION";
517 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
519 if (this->IsSetup() ==
true) {
520 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupLineSmoothing(): Setup() has already been called" << std::endl;
521 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupLineSmoothing(): reuse of this type is not available, reverting to full construction" << std::endl;
526 LO CoarseNumZLayers = Factory::Get<LO>(currentLevel,
"CoarseNumZLayers");
527 if (CoarseNumZLayers > 0) {
528 Teuchos::ArrayRCP<LO> TVertLineIdSmoo = Factory::Get<Teuchos::ArrayRCP<LO>>(currentLevel,
"LineDetection_VertLineIds");
532 for (
size_t k = 0; k < Teuchos::as<size_t>(TVertLineIdSmoo.
size()); k++) {
533 if (maxPart < TVertLineIdSmoo[k]) maxPart = TVertLineIdSmoo[k];
535 RCP<Matrix> matA = rcp_dynamic_cast<Matrix>(A_,
true);
536 size_t numLocalRows = matA->getLocalNumRows();
539 "MueLu::Ifpack2Smoother::Setup(): the number of local nodes is incompatible with the TVertLineIdsSmoo.");
544 int actualDofsPerNode = numLocalRows / TVertLineIdSmoo.
size();
545 LO matrixBlockSize = matA->GetFixedBlockSize();
546 if (matrixBlockSize > 1 && actualDofsPerNode > 1) {
548 "MueLu::Ifpack2Smoother::Setup(): A is a block matrix but its block size and DOFs/node from partitioner disagree");
549 }
else if (matrixBlockSize > 1) {
550 actualDofsPerNode = matrixBlockSize;
552 myparamList.
set(
"partitioner: PDE equations", actualDofsPerNode);
554 if (numLocalRows == Teuchos::as<size_t>(TVertLineIdSmoo.
size())) {
555 myparamList.
set(
"partitioner: type",
"user");
556 myparamList.
set(
"partitioner: map", TVertLineIdSmoo);
557 myparamList.
set(
"partitioner: local parts", maxPart + 1);
559 if (myparamList.
isParameter(
"partitioner: block size") &&
560 myparamList.
get<
int>(
"partitioner: block size") != -1) {
561 int block_size = myparamList.
get<
int>(
"partitioner: block size");
563 "MueLu::Ifpack2Smoother::Setup(): the number of local nodes is incompatible with the specified block size.");
564 numLocalRows /= block_size;
568 size_t numDofsPerNode = numLocalRows / TVertLineIdSmoo.
size();
572 for (
size_t blockRow = 0; blockRow < Teuchos::as<size_t>(TVertLineIdSmoo.
size()); ++blockRow)
573 for (
size_t dof = 0; dof < numDofsPerNode; dof++)
574 partitionerMap[blockRow * numDofsPerNode + dof] = TVertLineIdSmoo[blockRow];
575 myparamList.
set(
"partitioner: type",
"user");
576 myparamList.
set(
"partitioner: map", partitionerMap);
577 myparamList.
set(
"partitioner: local parts", maxPart + 1);
580 if (type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
581 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
582 type_ ==
"LINESMOOTHING_BANDEDRELAXATION")
583 type_ =
"BANDEDRELAXATION";
584 else if (type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
585 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
586 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
587 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
588 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
589 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION")
590 type_ =
"TRIDIAGONALRELAXATION";
592 type_ =
"BLOCKRELAXATION";
595 this->GetOStream(
Runtime0) <<
"Line detection failed: fall back to point-wise relaxation" << std::endl;
596 myparamList.
remove(
"partitioner: type",
false);
597 myparamList.
remove(
"partitioner: map",
false);
598 myparamList.
remove(
"partitioner: local parts",
false);
599 type_ =
"RELAXATION";
610 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
620 bool reusePreconditioner =
false;
621 if (this->IsSetup() ==
true) {
623 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupBlockRelaxation(): Setup() has already been called, assuming reuse" << std::endl;
628 reusePreconditioner =
true;
630 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupBlockRelaxation(): reuse of this type is not available (failed cast to CanChangeMatrix), "
631 "reverting to full construction"
636 if (!reusePreconditioner) {
639 if (myparamList.
isParameter(
"partitioner: type") &&
640 myparamList.
get<std::string>(
"partitioner: type") ==
"line") {
642 Factory::Get<Teuchos::RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO,
NO>>>(currentLevel,
"Coordinates");
646 size_t lclSize = A_->getRangeMap()->getLocalNumElements();
648 lclSize = matA->getLocalNumRows();
649 size_t numDofsPerNode = lclSize / xCoordinates->getMap()->getLocalNumElements();
650 myparamList.
set(
"partitioner: coordinates", coordinates);
651 myparamList.
set(
"partitioner: PDE equations", (
int)numDofsPerNode);
662 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
672 bool reusePreconditioner =
false;
674 if (this->IsSetup() ==
true) {
676 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupChebyshev(): Setup() has already been called, assuming reuse" << std::endl;
681 reusePreconditioner =
true;
683 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupChebyshev(): reuse of this type is not available (failed cast to CanChangeMatrix), "
684 "reverting to full construction"
691 SC negone = -STS::one();
692 SC lambdaMax = SetupChebyshevEigenvalues(currentLevel,
"A",
"", paramList);
694 if (!reusePreconditioner) {
709 if (lambdaMax == negone) {
713 if (chebyPrec != Teuchos::null) {
714 lambdaMax = chebyPrec->getLambdaMaxForApply();
717 matA->SetMaxEigenvalueEstimate(lambdaMax);
718 this->GetOStream(
Statistics1) <<
"chebyshev: max eigenvalue (calculated by Ifpack2)"
719 <<
" = " << lambdaMax << std::endl;
725 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
734 bool reusePreconditioner =
false;
735 if (this->IsSetup() ==
true) {
737 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupHiptmair(): Setup() has already been called, assuming reuse" << std::endl;
742 reusePreconditioner =
true;
744 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupHiptmair(): reuse of this type is not available (failed cast to CanChangeMatrix), "
745 "reverting to full construction"
753 std::string smoother1 = paramList.
get(
"hiptmair: smoother type 1",
"CHEBYSHEV");
754 std::string smoother2 = paramList.
get(
"hiptmair: smoother type 2",
"CHEBYSHEV");
755 SC lambdaMax11 = negone;
757 if (smoother1 ==
"CHEBYSHEV") {
759 lambdaMax11 = SetupChebyshevEigenvalues(currentLevel,
"A",
"EdgeMatrix ", list1);
761 if (smoother2 ==
"CHEBYSHEV") {
763 SetupChebyshevEigenvalues(currentLevel,
"NodeMatrix",
"NodeMatrix ", list2);
777 newlist.
set(
"P", tD0);
778 newlist.
set(
"PtAP", tNodeMatrix);
779 if (!reusePreconditioner) {
781 SetPrecParameters(newlist);
788 if (smoother1 ==
"CHEBYSHEV" && lambdaMax11 == negone) {
789 using Teuchos::rcp_dynamic_cast;
792 if (hiptmairPrec != Teuchos::null) {
794 if (chebyPrec != Teuchos::null) {
798 matA->SetMaxEigenvalueEstimate(lambdaMax11);
799 this->GetOStream(
Statistics1) <<
"chebyshev: max eigenvalue (calculated by Ifpack2)"
800 <<
" = " << lambdaMax11 << std::endl;
807 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
811 SC negone = -STS::one();
813 RCP<Matrix> matA = rcp_dynamic_cast<Matrix>(currentA);
814 SC lambdaMax = negone;
816 std::string maxEigString =
"chebyshev: max eigenvalue";
817 std::string eigRatioString =
"chebyshev: ratio eigenvalue";
821 if (paramList.
isType<
double>(maxEigString))
822 lambdaMax = paramList.
get<
double>(maxEigString);
824 lambdaMax = paramList.
get<
SC>(maxEigString);
825 this->GetOStream(
Statistics1) << label << maxEigString <<
" (cached with smoother parameter list) = " << lambdaMax << std::endl;
827 matA->SetMaxEigenvalueEstimate(lambdaMax);
830 lambdaMax = matA->GetMaxEigenvalueEstimate();
831 if (lambdaMax != negone) {
832 this->GetOStream(
Statistics1) << label << maxEigString <<
" (cached with matrix) = " << lambdaMax << std::endl;
833 paramList.
set(maxEigString, lambdaMax);
838 const SC defaultEigRatio = 20;
840 SC ratio = defaultEigRatio;
842 if (paramList.
isType<
double>(eigRatioString))
843 ratio = paramList.
get<
double>(eigRatioString);
845 ratio = paramList.
get<
SC>(eigRatioString);
853 size_t nRowsFine = fineA->getDomainMap()->getGlobalNumElements();
854 size_t nRowsCoarse = currentA->getDomainMap()->getGlobalNumElements();
856 SC levelRatio = as<SC>(as<double>(nRowsFine) / nRowsCoarse);
857 if (STS::magnitude(levelRatio) > STS::magnitude(ratio))
861 this->GetOStream(
Statistics1) << label << eigRatioString <<
" (computed) = " << ratio << std::endl;
862 paramList.
set(eigRatioString, ratio);
864 if (paramList.
isParameter(
"chebyshev: use rowsumabs diagonal scaling")) {
865 this->GetOStream(
Runtime1) <<
"chebyshev: using rowsumabs diagonal scaling" << std::endl;
866 bool doScale =
false;
867 doScale = paramList.
get<
bool>(
"chebyshev: use rowsumabs diagonal scaling");
868 paramList.
remove(
"chebyshev: use rowsumabs diagonal scaling");
870 std::string paramName =
"chebyshev: rowsumabs diagonal replacement tolerance";
872 chebyReplaceTol = paramList.
get<
double>(paramName);
873 paramList.
remove(paramName);
876 paramName =
"chebyshev: rowsumabs diagonal replacement value";
878 chebyReplaceVal = paramList.
get<
double>(paramName);
879 paramList.
remove(paramName);
881 bool chebyReplaceSingleEntryRowWithZero =
false;
882 paramName =
"chebyshev: rowsumabs replace single entry row with zero";
884 chebyReplaceSingleEntryRowWithZero = paramList.
get<
bool>(paramName);
885 paramList.
remove(paramName);
887 bool useAverageAbsDiagVal =
false;
888 paramName =
"chebyshev: rowsumabs use automatic diagonal tolerance";
890 useAverageAbsDiagVal = paramList.
get<
bool>(paramName);
891 paramList.
remove(paramName);
895 const bool doReciprocal =
true;
905 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
914 bool reusePreconditioner =
false;
915 if (this->IsSetup() ==
true) {
917 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupGeneric(): Setup() has already been called, assuming reuse" << std::endl;
922 reusePreconditioner =
true;
924 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupGeneric(): reuse of this type is not available (failed cast to CanChangeMatrix), "
925 "reverting to full construction"
930 if (!reusePreconditioner) {
939 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
949 bool supportInitialGuess =
false;
951 if (prec_->supportsZeroStartingSolution()) {
952 prec_->setZeroStartingSolution(InitialGuessIsZero);
953 supportInitialGuess =
true;
954 }
else if (type_ ==
"SCHWARZ") {
956 paramList.
set(
"schwarz: zero starting solution", InitialGuessIsZero);
962 supportInitialGuess =
true;
972 if (InitialGuessIsZero || supportInitialGuess) {
975 prec_->apply(tpB, tpX);
981 std::string prefix = this->ShortClassName() +
": Apply: ";
986 RCP<MultiVector> Correction = MultiVectorFactory::Build(A_->getDomainMap(), X.getNumVectors());
991 prec_->apply(tpB, tpX);
993 X.update(TST::one(), *Correction, TST::one());
997 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1004 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1006 std::ostringstream out;
1008 out << prec_->description();
1011 out <<
"{type = " << type_ <<
"}";
1016 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1021 out0 <<
"Prec. type: " << type_ << std::endl;
1024 out0 <<
"Parameter list: " << std::endl;
1026 out << this->GetParameterList();
1027 out0 <<
"Overlap: " << overlap_ << std::endl;
1031 if (prec_ != Teuchos::null) {
1033 out << *prec_ << std::endl;
1036 if (verbLevel &
Debug) {
1039 <<
"RCP<prec_>: " << prec_ << std::endl;
1043 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1048 if (!pr.
is_null())
return pr->getNodeSmootherComplexity();
1051 if (!pc.
is_null())
return pc->getNodeSmootherComplexity();
1054 if (!pb.
is_null())
return pb->getNodeSmootherComplexity();
1057 if (!pi.
is_null())
return pi->getNodeSmootherComplexity();
1060 if (!pk.
is_null())
return pk->getNodeSmootherComplexity();
1067 #endif // HAVE_MUELU_IFPACK2
1068 #endif // MUELU_IFPACK2SMOOTHER_DEF_HPP
void DeclareInput(Level ¤tLevel) const
Input.
Important warning messages (one line)
void SetupGeneric(Level ¤tLevel)
Exception indicating invalid cast attempted.
High level timing information (use Teuchos::TimeMonitor::summarize() to print)
MueLu::DefaultLocalOrdinal LocalOrdinal
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level->Get< RCP<Matrix> >("A", factory) if factory == NULL => use default factory.
void FindGeometricSeedOrdinals(Teuchos::RCP< Basis > basis, const LOFieldContainer &elementToNodeMap, std::vector< std::vector< LocalOrdinal > > &seeds, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &rowMap, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &columnMap)
KOKKOS_INLINE_FUNCTION LO GetNumAggregates() const
static magnitudeType eps()
Print external lib objects.
T & get(const std::string &name, T def_value)
friend class Ifpack2Smoother
Constructor.
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Print additional debugging information.
One-liner description of what is happening.
void SetParameterList(const Teuchos::ParameterList ¶mList)
Set parameters from a parameter list and return with default values.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Integrates Teuchos::TimeMonitor with MueLu verbosity system.
std::string type_
ifpack2-specific key phrase that denote smoother type
void SetupBlockRelaxation(Level ¤tLevel)
void resize(const size_type n, const T &val=T())
bool isParameter(const std::string &name) const
void SetupSchwarz(Level ¤tLevel)
void SetupLineSmoothing(Level ¤tLevel)
Print statistics that do not involve significant additional computation.
bool remove(std::string const &name, bool throwIfNotExists=true)
static RCP< MultiVector > Residual(const Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op, const MultiVector &X, const MultiVector &RHS)
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
virtual void SetParameterList(const Teuchos::ParameterList ¶mList)
Set parameters from a parameter list and return with default values.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
RCP< SmootherPrototype > Copy() const
void declareConstructionOutcome(bool fail, std::string msg)
Class that holds all level-specific information.
bool isSublist(const std::string &name) const
void Setup(Level ¤tLevel)
Set up the smoother.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
static Teuchos::ArrayRCP< const bool > DetectDirichletRows(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Magnitude &tol=Teuchos::ScalarTraits< Magnitude >::zero(), bool count_twos_as_dirichlet=false)
Detect Dirichlet rows.
void SetupHiptmair(Level ¤tLevel)
void SetupTopological(Level ¤tLevel)
std::string description() const
Return a simple one-line description of this object.
bool IsSetup() const
Get the state of a smoother prototype.
static Teuchos::RCP< Preconditioner< typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type > > create(const std::string &precType, const Teuchos::RCP< const MatrixType > &matrix)
const RCP< LOMultiVector > & GetVertex2AggId() const
Returns constant vector that maps local node IDs to local aggregates IDs.
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
ParameterList & setParameters(const ParameterList &source)
Print all timing information.
void SetPrecParameters(const Teuchos::ParameterList &list=Teuchos::ParameterList()) const
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
RCP< const Tpetra::CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > toTpetra(const RCP< const CrsGraph< LocalOrdinal, GlobalOrdinal, Node > > &graph)
RCP< Level > & GetPreviousLevel()
Previous level.
MatrixType::scalar_type getLambdaMaxForApply() const
void SetupAggregate(Level ¤tLevel)
bool isType(const std::string &name) const
RCP< Tpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getTpetra_Vector() const
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the preconditioner.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Teuchos::RCP< BlockCrsMatrix< Scalar, LO, GO, Node > > convertToBlockCrsMatrix(const Tpetra::CrsMatrix< Scalar, LO, GO, Node > &pointMatrix, const LO &blockSize, bool use_local_ID=true)
int GetLevelID() const
Return level number.
Print class parameters (more parameters, more verbose)
Exception throws to report errors in the internal logical of the program.
void SetupChebyshev(Level ¤tLevel)
#define TEUCHOS_ASSERT(assertion_test)
Description of what is happening (more verbose)
Class that encapsulates Ifpack2 smoothers.
static Teuchos::RCP< Vector > GetLumpedMatrixDiagonal(Matrix const &A, const bool doReciprocal=false, Magnitude tol=Teuchos::ScalarTraits< Scalar >::magnitude(Teuchos::ScalarTraits< Scalar >::zero()), Scalar valReplacement=Teuchos::ScalarTraits< Scalar >::zero(), const bool replaceSingleEntryRowWithZero=false, const bool useAverageAbsDiagVal=false)
Extract Matrix Diagonal of lumped matrix.
virtual std::string description() const
Return a simple one-line description of this object.
std::string toString(const T &t)
Scalar SetupChebyshevEigenvalues(Level ¤tLevel, const std::string &matrixName, const std::string &label, Teuchos::ParameterList ¶mList) const