10 #ifndef MUELU_IFPACK2SMOOTHER_DEF_HPP
11 #define MUELU_IFPACK2SMOOTHER_DEF_HPP
15 #if defined(HAVE_MUELU_IFPACK2)
19 #include <Tpetra_RowMatrix.hpp>
21 #include <Ifpack2_Chebyshev.hpp>
22 #include <Ifpack2_Hiptmair.hpp>
23 #include <Ifpack2_RILUK.hpp>
24 #include <Ifpack2_Relaxation.hpp>
25 #include <Ifpack2_ILUT.hpp>
26 #include <Ifpack2_BlockRelaxation.hpp>
27 #include <Ifpack2_Factory.hpp>
28 #include <Ifpack2_Parameters.hpp>
32 #include <Xpetra_CrsMatrixWrap.hpp>
33 #include <Xpetra_TpetraBlockCrsMatrix.hpp>
36 #include <Xpetra_MultiVectorFactory.hpp>
37 #include <Xpetra_TpetraMultiVector.hpp>
39 #include <Tpetra_BlockCrsMatrix_Helpers.hpp>
43 #include "MueLu_Utilities.hpp"
45 #include "MueLu_Aggregates.hpp"
47 #ifdef HAVE_MUELU_INTREPID2
50 #include "Intrepid2_Basis.hpp"
51 #include "Kokkos_DynRankView.hpp"
56 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
61 bool isSupported = Ifpack2::Factory::isSupported<tRowMatrix>(
type_) || (
type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
62 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
63 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
64 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
65 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
66 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION" ||
67 type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
68 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
69 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
70 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
71 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
72 type_ ==
"LINESMOOTHING_BLOCKRELAXATION" ||
73 type_ ==
"TOPOLOGICAL" ||
74 type_ ==
"AGGREGATE");
80 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
91 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
93 std::string prefix = this->ShortClassName() +
": SetPrecParameters";
102 precList->
set(
"timer for apply", this->IsPrint(
Timings));
104 if (!precList.
is_null() && precList->
isParameter(
"partitioner: type") && precList->
get<std::string>(
"partitioner: type") ==
"linear" &&
105 !precList->
isParameter(
"partitioner: local parts")) {
106 LO matrixBlockSize = 1;
107 int lclSize = A_->getRangeMap()->getLocalNumElements();
110 lclSize = matA->getLocalNumRows();
111 matrixBlockSize = matA->GetFixedBlockSize();
113 precList->
set(
"partitioner: local parts", lclSize / matrixBlockSize);
121 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
123 this->Input(currentLevel,
"A");
125 if (type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
126 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
127 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
128 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
129 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
130 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION" ||
131 type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
132 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
133 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
134 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
135 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
136 type_ ==
"LINESMOOTHING_BLOCKRELAXATION") {
137 this->Input(currentLevel,
"CoarseNumZLayers");
138 this->Input(currentLevel,
"LineDetection_VertLineIds");
139 }
else if (type_ ==
"BLOCK RELAXATION" ||
140 type_ ==
"BLOCK_RELAXATION" ||
141 type_ ==
"BLOCKRELAXATION" ||
143 type_ ==
"BANDED_RELAXATION" ||
144 type_ ==
"BANDED RELAXATION" ||
145 type_ ==
"BANDEDRELAXATION" ||
147 type_ ==
"TRIDI_RELAXATION" ||
148 type_ ==
"TRIDI RELAXATION" ||
149 type_ ==
"TRIDIRELAXATION" ||
150 type_ ==
"TRIDIAGONAL_RELAXATION" ||
151 type_ ==
"TRIDIAGONAL RELAXATION" ||
152 type_ ==
"TRIDIAGONALRELAXATION") {
156 precList.
get<std::string>(
"partitioner: type") ==
"line") {
157 this->Input(currentLevel,
"Coordinates");
159 }
else if (type_ ==
"TOPOLOGICAL") {
161 this->Input(currentLevel,
"pcoarsen: element to node map");
162 }
else if (type_ ==
"AGGREGATE") {
164 this->Input(currentLevel,
"Aggregates");
165 }
else if (type_ ==
"HIPTMAIR") {
167 this->Input(currentLevel,
"NodeMatrix");
168 this->Input(currentLevel,
"D0");
172 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
175 A_ = Factory::Get<RCP<Operator>>(currentLevel,
"A");
180 if (paramList.isParameter(
"smoother: use blockcrsmatrix storage") && paramList.get<
bool>(
"smoother: use blockcrsmatrix storage")) {
184 blocksize = matA->GetFixedBlockSize();
190 throw std::runtime_error(
"Ifpack2Smoother: Cannot convert matrix A to CrsMatrixWrap object.");
193 throw std::runtime_error(
"Ifpack2Smoother: Cannot extract CrsMatrix from matrix A.");
197 throw std::runtime_error(
"Ifpack2Smoother: Cannot extract CrsMatrix or BlockCrsMatrix from matrix A.");
198 this->GetOStream(
Statistics0) <<
"Ifpack2Smoother: Using (native) BlockCrsMatrix storage with blocksize " << blocksize << std::endl;
199 paramList.remove(
"smoother: use blockcrsmatrix storage");
205 this->GetOStream(
Statistics0) <<
"Ifpack2Smoother: Using BlockCrsMatrix storage with blocksize " << blocksize << std::endl;
207 paramList.remove(
"smoother: use blockcrsmatrix storage");
212 if (type_ ==
"SCHWARZ")
213 SetupSchwarz(currentLevel);
215 else if (type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
216 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
217 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
218 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
219 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
220 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION" ||
221 type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
222 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
223 type_ ==
"LINESMOOTHING_BANDEDRELAXATION" ||
224 type_ ==
"LINESMOOTHING_BLOCK_RELAXATION" ||
225 type_ ==
"LINESMOOTHING_BLOCK RELAXATION" ||
226 type_ ==
"LINESMOOTHING_BLOCKRELAXATION")
227 SetupLineSmoothing(currentLevel);
229 else if (type_ ==
"BLOCK_RELAXATION" ||
230 type_ ==
"BLOCK RELAXATION" ||
231 type_ ==
"BLOCKRELAXATION" ||
233 type_ ==
"BANDED_RELAXATION" ||
234 type_ ==
"BANDED RELAXATION" ||
235 type_ ==
"BANDEDRELAXATION" ||
237 type_ ==
"TRIDI_RELAXATION" ||
238 type_ ==
"TRIDI RELAXATION" ||
239 type_ ==
"TRIDIRELAXATION" ||
240 type_ ==
"TRIDIAGONAL_RELAXATION" ||
241 type_ ==
"TRIDIAGONAL RELAXATION" ||
242 type_ ==
"TRIDIAGONALRELAXATION")
243 SetupBlockRelaxation(currentLevel);
245 else if (type_ ==
"CHEBYSHEV")
246 SetupChebyshev(currentLevel);
248 else if (type_ ==
"TOPOLOGICAL") {
249 #ifdef HAVE_MUELU_INTREPID2
250 SetupTopological(currentLevel);
254 }
else if (type_ ==
"AGGREGATE")
255 SetupAggregate(currentLevel);
257 else if (type_ ==
"HIPTMAIR")
258 SetupHiptmair(currentLevel);
261 SetupGeneric(currentLevel);
266 this->GetOStream(
Statistics1) << description() << std::endl;
269 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
273 bool reusePreconditioner =
false;
274 if (this->IsSetup() ==
true) {
276 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupSchwarz(): Setup() has already been called, assuming reuse" << std::endl;
278 bool isTRowMatrix =
true;
283 isTRowMatrix =
false;
287 if (!prec.
is_null() && isTRowMatrix) {
289 reusePreconditioner =
true;
291 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupSchwarz(): reuse of this type is not available "
292 "(either failed cast to CanChangeMatrix, or to Tpetra Row Matrix), reverting to full construction"
297 if (!reusePreconditioner) {
300 bool isBlockedMatrix =
false;
303 std::string sublistName =
"subdomain solver parameters";
315 std::string partName =
"partitioner: type";
321 if (subList.
isParameter(partName) && subList.
get<std::string>(partName) ==
"vanka user") {
322 isBlockedMatrix =
true;
326 "Matrix A must be of type BlockedCrsMatrix.");
328 size_t numVels = bA->getMatrix(0, 0)->getLocalNumRows();
329 size_t numPres = bA->getMatrix(1, 0)->getLocalNumRows();
330 size_t numRows = rcp_dynamic_cast<Matrix>(A_,
true)->getLocalNumRows();
334 size_t numBlocks = 0;
335 for (
size_t rowOfB = numVels; rowOfB < numVels + numPres; ++rowOfB)
336 blockSeeds[rowOfB] = numBlocks++;
340 "Matrix A must be of type BlockedCrsMatrix.");
342 merged2Mat = bA2->Merge();
346 bool haveBoundary =
false;
347 for (
LO i = 0; i < boundaryNodes.
size(); i++)
348 if (boundaryNodes[i]) {
352 blockSeeds[i] = numBlocks;
358 subList.
set(
"partitioner: type",
"user");
359 subList.
set(
"partitioner: map", blockSeeds);
360 subList.
set(
"partitioner: local parts", as<int>(numBlocks));
365 isBlockedMatrix =
true;
366 merged2Mat = bA->Merge();
372 if (isBlockedMatrix ==
true)
386 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
390 if (this->IsSetup() ==
true) {
391 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupAggregate(): Setup() has already been called" << std::endl;
392 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupAggregate(): reuse of this type is not available, reverting to full construction" << std::endl;
395 this->GetOStream(
Statistics0) <<
"Ifpack2Smoother: Using Aggregate Smoothing" << std::endl;
397 RCP<Aggregates> aggregates = Factory::Get<RCP<Aggregates>>(currentLevel,
"Aggregates");
400 ArrayRCP<LO> aggregate_ids = rcp_const_cast<LOMultiVector>(vertex2AggId)->getDataNonConst(0);
407 blocksize = matA->GetFixedBlockSize();
409 dof_ids.
resize(aggregate_ids.
size() * blocksize);
410 for (
LO i = 0; i < (
LO)aggregate_ids.
size(); i++) {
411 for (
LO j = 0; j < (
LO)blocksize; j++)
412 dof_ids[i * blocksize + j] = aggregate_ids[i];
415 dof_ids = aggregate_ids;
418 paramList.
set(
"partitioner: map", dof_ids);
419 paramList.
set(
"partitioner: type",
"user");
420 paramList.
set(
"partitioner: overlap", 0);
425 type_ =
"BLOCKRELAXATION";
432 #ifdef HAVE_MUELU_INTREPID2
433 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
443 if (this->IsSetup() ==
true) {
444 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupTopological(): Setup() has already been called" << std::endl;
445 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupTopological(): reuse of this type is not available, reverting to full construction" << std::endl;
448 ParameterList& paramList =
const_cast<ParameterList&
>(this->GetParameterList());
450 typedef typename Node::device_type::execution_space ES;
452 typedef Kokkos::DynRankView<LocalOrdinal, typename Node::device_type> FCO;
458 const Teuchos::RCP<FCO> elemToNode = Factory::Get<Teuchos::RCP<FCO>>(currentLevel,
"pcoarsen: element to node map");
460 string basisString = paramList.
get<
string>(
"pcoarsen: hi basis");
466 auto basis = MueLuIntrepid::BasisFactory<double, ES>(basisString, degree);
468 string topologyTypeString = paramList.get<
string>(
"smoother: neighborhood type");
470 if (topologyTypeString ==
"node")
472 else if (topologyTypeString ==
"edge")
474 else if (topologyTypeString ==
"face")
476 else if (topologyTypeString ==
"cell")
477 dimension = basis->getBaseCellTopology().getDimension();
479 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"Unrecognized smoother neighborhood type. Supported types are node, edge, face.");
480 RCP<Matrix> matA = rcp_dynamic_cast<Matrix>(A_,
true);
481 vector<vector<LocalOrdinal>> seeds;
486 int myNodeCount = matA->getRowMap()->getLocalNumElements();
487 ArrayRCP<LocalOrdinal> nodeSeeds(myNodeCount, lo_invalid);
488 int localPartitionNumber = 0;
490 nodeSeeds[seed] = localPartitionNumber++;
493 paramList.remove(
"smoother: neighborhood type");
494 paramList.remove(
"pcoarsen: hi basis");
496 paramList.set(
"partitioner: map", nodeSeeds);
497 paramList.set(
"partitioner: type",
"user");
498 paramList.set(
"partitioner: overlap", 1);
499 paramList.set(
"partitioner: local parts",
int(seeds[dimension].size()));
503 type_ =
"BLOCKRELAXATION";
511 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
513 if (this->IsSetup() ==
true) {
514 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupLineSmoothing(): Setup() has already been called" << std::endl;
515 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupLineSmoothing(): reuse of this type is not available, reverting to full construction" << std::endl;
520 LO CoarseNumZLayers = Factory::Get<LO>(currentLevel,
"CoarseNumZLayers");
521 if (CoarseNumZLayers > 0) {
522 Teuchos::ArrayRCP<LO> TVertLineIdSmoo = Factory::Get<Teuchos::ArrayRCP<LO>>(currentLevel,
"LineDetection_VertLineIds");
526 for (
size_t k = 0; k < Teuchos::as<size_t>(TVertLineIdSmoo.
size()); k++) {
527 if (maxPart < TVertLineIdSmoo[k]) maxPart = TVertLineIdSmoo[k];
529 RCP<Matrix> matA = rcp_dynamic_cast<Matrix>(A_,
true);
530 size_t numLocalRows = matA->getLocalNumRows();
533 "MueLu::Ifpack2Smoother::Setup(): the number of local nodes is incompatible with the TVertLineIdsSmoo.");
538 int actualDofsPerNode = numLocalRows / TVertLineIdSmoo.
size();
539 LO matrixBlockSize = matA->GetFixedBlockSize();
540 if (matrixBlockSize > 1 && actualDofsPerNode > 1) {
542 "MueLu::Ifpack2Smoother::Setup(): A is a block matrix but its block size and DOFs/node from partitioner disagree");
543 }
else if (matrixBlockSize > 1) {
544 actualDofsPerNode = matrixBlockSize;
546 myparamList.
set(
"partitioner: PDE equations", actualDofsPerNode);
548 if (numLocalRows == Teuchos::as<size_t>(TVertLineIdSmoo.
size())) {
549 myparamList.
set(
"partitioner: type",
"user");
550 myparamList.
set(
"partitioner: map", TVertLineIdSmoo);
551 myparamList.
set(
"partitioner: local parts", maxPart + 1);
553 if (myparamList.
isParameter(
"partitioner: block size") &&
554 myparamList.
get<
int>(
"partitioner: block size") != -1) {
555 int block_size = myparamList.
get<
int>(
"partitioner: block size");
557 "MueLu::Ifpack2Smoother::Setup(): the number of local nodes is incompatible with the specified block size.");
558 numLocalRows /= block_size;
562 size_t numDofsPerNode = numLocalRows / TVertLineIdSmoo.
size();
566 for (
size_t blockRow = 0; blockRow < Teuchos::as<size_t>(TVertLineIdSmoo.
size()); ++blockRow)
567 for (
size_t dof = 0; dof < numDofsPerNode; dof++)
568 partitionerMap[blockRow * numDofsPerNode + dof] = TVertLineIdSmoo[blockRow];
569 myparamList.
set(
"partitioner: type",
"user");
570 myparamList.
set(
"partitioner: map", partitionerMap);
571 myparamList.
set(
"partitioner: local parts", maxPart + 1);
574 if (type_ ==
"LINESMOOTHING_BANDED_RELAXATION" ||
575 type_ ==
"LINESMOOTHING_BANDED RELAXATION" ||
576 type_ ==
"LINESMOOTHING_BANDEDRELAXATION")
577 type_ =
"BANDEDRELAXATION";
578 else if (type_ ==
"LINESMOOTHING_TRIDI_RELAXATION" ||
579 type_ ==
"LINESMOOTHING_TRIDI RELAXATION" ||
580 type_ ==
"LINESMOOTHING_TRIDIRELAXATION" ||
581 type_ ==
"LINESMOOTHING_TRIDIAGONAL_RELAXATION" ||
582 type_ ==
"LINESMOOTHING_TRIDIAGONAL RELAXATION" ||
583 type_ ==
"LINESMOOTHING_TRIDIAGONALRELAXATION")
584 type_ =
"TRIDIAGONALRELAXATION";
586 type_ =
"BLOCKRELAXATION";
589 this->GetOStream(
Runtime0) <<
"Line detection failed: fall back to point-wise relaxation" << std::endl;
590 myparamList.
remove(
"partitioner: type",
false);
591 myparamList.
remove(
"partitioner: map",
false);
592 myparamList.
remove(
"partitioner: local parts",
false);
593 type_ =
"RELAXATION";
604 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
614 bool reusePreconditioner =
false;
615 if (this->IsSetup() ==
true) {
617 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupBlockRelaxation(): Setup() has already been called, assuming reuse" << std::endl;
622 reusePreconditioner =
true;
624 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupBlockRelaxation(): reuse of this type is not available (failed cast to CanChangeMatrix), "
625 "reverting to full construction"
630 if (!reusePreconditioner) {
633 if (myparamList.
isParameter(
"partitioner: type") &&
634 myparamList.
get<std::string>(
"partitioner: type") ==
"line") {
636 Factory::Get<Teuchos::RCP<Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO,
NO>>>(currentLevel,
"Coordinates");
640 size_t lclSize = A_->getRangeMap()->getLocalNumElements();
642 lclSize = matA->getLocalNumRows();
643 size_t numDofsPerNode = lclSize / xCoordinates->getMap()->getLocalNumElements();
644 myparamList.
set(
"partitioner: coordinates", coordinates);
645 myparamList.
set(
"partitioner: PDE equations", (
int)numDofsPerNode);
656 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
666 bool reusePreconditioner =
false;
668 if (this->IsSetup() ==
true) {
670 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupChebyshev(): Setup() has already been called, assuming reuse" << std::endl;
675 reusePreconditioner =
true;
677 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupChebyshev(): reuse of this type is not available (failed cast to CanChangeMatrix), "
678 "reverting to full construction"
685 SC negone = -STS::one();
686 SC lambdaMax = SetupChebyshevEigenvalues(currentLevel,
"A",
"", paramList);
688 if (!reusePreconditioner) {
703 if (lambdaMax == negone) {
707 if (chebyPrec != Teuchos::null) {
708 lambdaMax = chebyPrec->getLambdaMaxForApply();
711 matA->SetMaxEigenvalueEstimate(lambdaMax);
712 this->GetOStream(
Statistics1) <<
"chebyshev: max eigenvalue (calculated by Ifpack2)"
713 <<
" = " << lambdaMax << std::endl;
719 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
728 bool reusePreconditioner =
false;
729 if (this->IsSetup() ==
true) {
731 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupHiptmair(): Setup() has already been called, assuming reuse" << std::endl;
736 reusePreconditioner =
true;
738 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupHiptmair(): reuse of this type is not available (failed cast to CanChangeMatrix), "
739 "reverting to full construction"
747 std::string smoother1 = paramList.
get(
"hiptmair: smoother type 1",
"CHEBYSHEV");
748 std::string smoother2 = paramList.
get(
"hiptmair: smoother type 2",
"CHEBYSHEV");
749 SC lambdaMax11 = negone;
751 if (smoother1 ==
"CHEBYSHEV") {
753 lambdaMax11 = SetupChebyshevEigenvalues(currentLevel,
"A",
"EdgeMatrix ", list1);
755 if (smoother2 ==
"CHEBYSHEV") {
757 SetupChebyshevEigenvalues(currentLevel,
"NodeMatrix",
"NodeMatrix ", list2);
771 newlist.
set(
"P", tD0);
772 newlist.
set(
"PtAP", tNodeMatrix);
773 if (!reusePreconditioner) {
775 SetPrecParameters(newlist);
782 if (smoother1 ==
"CHEBYSHEV" && lambdaMax11 == negone) {
783 using Teuchos::rcp_dynamic_cast;
786 if (hiptmairPrec != Teuchos::null) {
788 if (chebyPrec != Teuchos::null) {
792 matA->SetMaxEigenvalueEstimate(lambdaMax11);
793 this->GetOStream(
Statistics1) <<
"chebyshev: max eigenvalue (calculated by Ifpack2)"
794 <<
" = " << lambdaMax11 << std::endl;
801 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
805 SC negone = -STS::one();
807 RCP<Matrix> matA = rcp_dynamic_cast<Matrix>(currentA);
808 SC lambdaMax = negone;
810 std::string maxEigString =
"chebyshev: max eigenvalue";
811 std::string eigRatioString =
"chebyshev: ratio eigenvalue";
815 if (paramList.
isType<
double>(maxEigString))
816 lambdaMax = paramList.
get<
double>(maxEigString);
818 lambdaMax = paramList.
get<
SC>(maxEigString);
819 this->GetOStream(
Statistics1) << label << maxEigString <<
" (cached with smoother parameter list) = " << lambdaMax << std::endl;
821 matA->SetMaxEigenvalueEstimate(lambdaMax);
824 lambdaMax = matA->GetMaxEigenvalueEstimate();
825 if (lambdaMax != negone) {
826 this->GetOStream(
Statistics1) << label << maxEigString <<
" (cached with matrix) = " << lambdaMax << std::endl;
827 paramList.
set(maxEigString, lambdaMax);
832 const SC defaultEigRatio = 20;
834 SC ratio = defaultEigRatio;
836 if (paramList.
isType<
double>(eigRatioString))
837 ratio = paramList.
get<
double>(eigRatioString);
839 ratio = paramList.
get<
SC>(eigRatioString);
847 size_t nRowsFine = fineA->getDomainMap()->getGlobalNumElements();
848 size_t nRowsCoarse = currentA->getDomainMap()->getGlobalNumElements();
850 SC levelRatio = as<SC>(as<double>(nRowsFine) / nRowsCoarse);
851 if (STS::magnitude(levelRatio) > STS::magnitude(ratio))
855 this->GetOStream(
Statistics1) << label << eigRatioString <<
" (computed) = " << ratio << std::endl;
856 paramList.
set(eigRatioString, ratio);
858 if (paramList.
isParameter(
"chebyshev: use rowsumabs diagonal scaling")) {
859 this->GetOStream(
Runtime1) <<
"chebyshev: using rowsumabs diagonal scaling" << std::endl;
860 bool doScale =
false;
861 doScale = paramList.
get<
bool>(
"chebyshev: use rowsumabs diagonal scaling");
862 paramList.
remove(
"chebyshev: use rowsumabs diagonal scaling");
864 std::string paramName =
"chebyshev: rowsumabs diagonal replacement tolerance";
866 chebyReplaceTol = paramList.
get<
double>(paramName);
867 paramList.
remove(paramName);
870 paramName =
"chebyshev: rowsumabs diagonal replacement value";
872 chebyReplaceVal = paramList.
get<
double>(paramName);
873 paramList.
remove(paramName);
875 bool chebyReplaceSingleEntryRowWithZero =
false;
876 paramName =
"chebyshev: rowsumabs replace single entry row with zero";
878 chebyReplaceSingleEntryRowWithZero = paramList.
get<
bool>(paramName);
879 paramList.
remove(paramName);
881 bool useAverageAbsDiagVal =
false;
882 paramName =
"chebyshev: rowsumabs use automatic diagonal tolerance";
884 useAverageAbsDiagVal = paramList.
get<
bool>(paramName);
885 paramList.
remove(paramName);
889 const bool doReciprocal =
true;
899 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
908 bool reusePreconditioner =
false;
909 if (this->IsSetup() ==
true) {
911 this->GetOStream(
Runtime1) <<
"MueLu::Ifpack2Smoother::SetupGeneric(): Setup() has already been called, assuming reuse" << std::endl;
916 reusePreconditioner =
true;
918 this->GetOStream(
Warnings0) <<
"MueLu::Ifpack2Smoother::SetupGeneric(): reuse of this type is not available (failed cast to CanChangeMatrix), "
919 "reverting to full construction"
924 if (!reusePreconditioner) {
933 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
944 bool supportInitialGuess =
false;
947 if (prec_->supportsZeroStartingSolution()) {
948 prec_->setZeroStartingSolution(InitialGuessIsZero);
949 supportInitialGuess =
true;
950 }
else if (type_ ==
"SCHWARZ") {
951 paramList.
set(
"schwarz: zero starting solution", InitialGuessIsZero);
957 supportInitialGuess =
true;
967 if (InitialGuessIsZero || supportInitialGuess) {
970 prec_->apply(tpB, tpX);
976 std::string prefix = this->ShortClassName() +
": Apply: ";
981 RCP<MultiVector> Correction = MultiVectorFactory::Build(A_->getDomainMap(), X.getNumVectors());
986 prec_->apply(tpB, tpX);
988 X.update(TST::one(), *Correction, TST::one());
992 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
999 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1001 std::ostringstream out;
1003 out << prec_->description();
1006 out <<
"{type = " << type_ <<
"}";
1011 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1016 out0 <<
"Prec. type: " << type_ << std::endl;
1019 out0 <<
"Parameter list: " << std::endl;
1021 out << this->GetParameterList();
1022 out0 <<
"Overlap: " << overlap_ << std::endl;
1026 if (prec_ != Teuchos::null) {
1028 out << *prec_ << std::endl;
1031 if (verbLevel &
Debug) {
1034 <<
"RCP<prec_>: " << prec_ << std::endl;
1038 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1043 if (!pr.
is_null())
return pr->getNodeSmootherComplexity();
1046 if (!pc.
is_null())
return pc->getNodeSmootherComplexity();
1049 if (!pb.
is_null())
return pb->getNodeSmootherComplexity();
1052 if (!pi.
is_null())
return pi->getNodeSmootherComplexity();
1055 if (!pk.
is_null())
return pk->getNodeSmootherComplexity();
1062 #endif // HAVE_MUELU_IFPACK2
1063 #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)
static RCP< const Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > MV2TpetraMV(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node >> const vec)
Helper utility to pull out the underlying Tpetra objects from an Xpetra object.
KOKKOS_INLINE_FUNCTION LO GetNumAggregates() const
static magnitudeType eps()
Print external lib objects.
T & get(const std::string &name, T def_value)
static RCP< Tpetra::RowMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Op2NonConstTpetraRow(RCP< Xpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node >> Op)
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.
static RCP< Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > MV2NonConstTpetraMV(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node >> vec)
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