55#ifndef IFPACK2_ADDITIVESCHWARZ_DEF_HPP
56#define IFPACK2_ADDITIVESCHWARZ_DEF_HPP
58#include "Trilinos_Details_LinearSolverFactory.hpp"
62#include "Ifpack2_Details_LinearSolver.hpp"
63#include "Ifpack2_Details_getParamTryingTypes.hpp"
65#if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2)
66#include "Zoltan2_TpetraRowGraphAdapter.hpp"
67#include "Zoltan2_OrderingProblem.hpp"
68#include "Zoltan2_OrderingSolution.hpp"
72#include "Ifpack2_Parameters.hpp"
73#include "Ifpack2_LocalFilter.hpp"
74#include "Ifpack2_ReorderFilter.hpp"
75#include "Ifpack2_SingletonFilter.hpp"
76#include "Ifpack2_Details_AdditiveSchwarzFilter.hpp"
79#include "Teuchos_DefaultMpiComm.hpp"
82#include "Teuchos_StandardParameterEntryValidators.hpp"
85#include <Tpetra_BlockMultiVector.hpp>
97#ifdef HAVE_IFPACK2_DEBUG
105 using STS = Teuchos::ScalarTraits<typename MV::scalar_type>;
106 using magnitude_type =
typename STS::magnitudeType;
107 using STM = Teuchos::ScalarTraits<magnitude_type>;
109 Teuchos::Array<magnitude_type> norms (X.getNumVectors ());
112 for (
size_t j = 0; j < X.getNumVectors (); ++j) {
113 if (STM::isnaninf (norms[j])) {
127template<
class MatrixType,
class LocalInverseType>
129AdditiveSchwarz<MatrixType, LocalInverseType>::hasInnerPrecName ()
const
131 const char* options[4] = {
132 "inner preconditioner name",
133 "subdomain solver name",
134 "schwarz: inner preconditioner name",
135 "schwarz: subdomain solver name"
137 const int numOptions = 4;
139 for (
int k = 0; k < numOptions && ! match; ++k) {
140 if (List_.isParameter (options[k])) {
148template<
class MatrixType,
class LocalInverseType>
150AdditiveSchwarz<MatrixType, LocalInverseType>::removeInnerPrecName ()
152 const char* options[4] = {
153 "inner preconditioner name",
154 "subdomain solver name",
155 "schwarz: inner preconditioner name",
156 "schwarz: subdomain solver name"
158 const int numOptions = 4;
159 for (
int k = 0; k < numOptions; ++k) {
160 List_.remove (options[k],
false);
165template<
class MatrixType,
class LocalInverseType>
167AdditiveSchwarz<MatrixType, LocalInverseType>::innerPrecName ()
const
169 const char* options[4] = {
170 "inner preconditioner name",
171 "subdomain solver name",
172 "schwarz: inner preconditioner name",
173 "schwarz: subdomain solver name"
175 const int numOptions = 4;
180 for (
int k = 0; k < numOptions && ! match; ++k) {
181 const Teuchos::ParameterEntry* paramEnt =
182 List_.getEntryPtr (options[k]);
183 if (paramEnt !=
nullptr && paramEnt->isType<std::string> ()) {
184 newName = Teuchos::getValue<std::string> (*paramEnt);
188 return match ? newName : defaultInnerPrecName ();
192template<
class MatrixType,
class LocalInverseType>
194AdditiveSchwarz<MatrixType, LocalInverseType>::removeInnerPrecParams ()
196 const char* options[4] = {
197 "inner preconditioner parameters",
198 "subdomain solver parameters",
199 "schwarz: inner preconditioner parameters",
200 "schwarz: subdomain solver parameters"
202 const int numOptions = 4;
205 for (
int k = 0; k < numOptions; ++k) {
206 List_.remove (options[k],
false);
211template<
class MatrixType,
class LocalInverseType>
212std::pair<Teuchos::ParameterList, bool>
213AdditiveSchwarz<MatrixType, LocalInverseType>::innerPrecParams ()
const
215 const char* options[4] = {
216 "inner preconditioner parameters",
217 "subdomain solver parameters",
218 "schwarz: inner preconditioner parameters",
219 "schwarz: subdomain solver parameters"
221 const int numOptions = 4;
222 Teuchos::ParameterList params;
226 for (
int k = 0; k < numOptions && ! match; ++k) {
227 if (List_.isSublist (options[k])) {
228 params = List_.sublist (options[k]);
233 return std::make_pair (params, match);
236template<
class MatrixType,
class LocalInverseType>
238AdditiveSchwarz<MatrixType, LocalInverseType>::defaultInnerPrecName ()
245template<
class MatrixType,
class LocalInverseType>
251template<
class MatrixType,
class LocalInverseType>
254 const int overlapLevel) :
256 OverlapLevel_ (overlapLevel)
259template<
class MatrixType,
class LocalInverseType>
260Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type > >
264 TEUCHOS_TEST_FOR_EXCEPTION(
265 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
266 "getDomainMap: The matrix to precondition is null. You must either pass "
267 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
268 "input, before you may call this method.");
269 return Matrix_->getDomainMap ();
273template<
class MatrixType,
class LocalInverseType>
274Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
277 TEUCHOS_TEST_FOR_EXCEPTION(
278 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
279 "getRangeMap: The matrix to precondition is null. You must either pass "
280 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
281 "input, before you may call this method.");
282 return Matrix_->getRangeMap ();
286template<
class MatrixType,
class LocalInverseType>
296template<
class MatrixType,
class map_type>
297Teuchos::RCP<const map_type>
298pointMapFromMeshMap(
const Teuchos::RCP<const map_type> & meshMap,
const typename MatrixType::local_ordinal_type blockSize)
300 using BMV = Tpetra::BlockMultiVector<
301 typename MatrixType::scalar_type,
302 typename MatrixType::local_ordinal_type,
303 typename MatrixType::global_ordinal_type,
304 typename MatrixType::node_type>;
306 if (blockSize == 1)
return meshMap;
308 return Teuchos::RCP<const map_type>(
new map_type(BMV::makePointMap (*meshMap,blockSize)));
313template<
class MatrixType,
class LocalInverseType>
316apply (
const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &B,
317 Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &Y,
318 Teuchos::ETransp mode,
323 using Teuchos::TimeMonitor;
326 using Teuchos::rcp_dynamic_cast;
327 typedef Teuchos::ScalarTraits<scalar_type> STS;
328 const char prefix[] =
"Ifpack2::AdditiveSchwarz::apply: ";
330 TEUCHOS_TEST_FOR_EXCEPTION
331 (! IsComputed_, std::runtime_error,
332 prefix <<
"isComputed() must be true before you may call apply().");
333 TEUCHOS_TEST_FOR_EXCEPTION
334 (Matrix_.is_null (), std::logic_error, prefix <<
335 "The input matrix A is null, but the preconditioner says that it has "
336 "been computed (isComputed() is true). This should never happen, since "
337 "setMatrix() should always mark the preconditioner as not computed if "
338 "its argument is null. "
339 "Please report this bug to the Ifpack2 developers.");
340 TEUCHOS_TEST_FOR_EXCEPTION
341 (Inverse_.is_null (), std::runtime_error,
342 prefix <<
"The subdomain solver is null. "
343 "This can only happen if you called setInnerPreconditioner() with a null "
344 "input, after calling initialize() or compute(). If you choose to call "
345 "setInnerPreconditioner() with a null input, you must then call it with "
346 "a nonnull input before you may call initialize() or compute().");
347 TEUCHOS_TEST_FOR_EXCEPTION
348 (B.getNumVectors() != Y.getNumVectors(), std::invalid_argument,
349 prefix <<
"B and Y must have the same number of columns. B has " <<
350 B.getNumVectors () <<
" columns, but Y has " << Y.getNumVectors() <<
".");
351 TEUCHOS_TEST_FOR_EXCEPTION
352 (IsOverlapping_ && OverlappingMatrix_.is_null (), std::logic_error,
353 prefix <<
"The overlapping matrix is null. "
354 "This should never happen if IsOverlapping_ is true. "
355 "Please report this bug to the Ifpack2 developers.");
356 TEUCHOS_TEST_FOR_EXCEPTION
357 (! IsOverlapping_ && localMap_.is_null (), std::logic_error,
358 prefix <<
"localMap_ is null. "
359 "This should never happen if IsOverlapping_ is false. "
360 "Please report this bug to the Ifpack2 developers.");
361 TEUCHOS_TEST_FOR_EXCEPTION
362 (alpha != STS::one (), std::logic_error,
363 prefix <<
"Not implemented for alpha != 1.");
364 TEUCHOS_TEST_FOR_EXCEPTION
365 (beta != STS::zero (), std::logic_error,
366 prefix <<
"Not implemented for beta != 0.");
368#ifdef HAVE_IFPACK2_DEBUG
370 const bool bad = anyBad (B);
371 TEUCHOS_TEST_FOR_EXCEPTION
372 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
373 "The 2-norm of the input B is NaN or Inf.");
377#ifdef HAVE_IFPACK2_DEBUG
378 if (! ZeroStartingSolution_) {
379 const bool bad = anyBad (Y);
380 TEUCHOS_TEST_FOR_EXCEPTION
381 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
382 "On input, the initial guess Y has 2-norm NaN or Inf "
383 "(ZeroStartingSolution_ is false).");
387 const std::string timerName (
"Ifpack2::AdditiveSchwarz::apply");
388 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
389 if (timer.is_null ()) {
390 timer = TimeMonitor::getNewCounter (timerName);
392 double startTime = timer->wallTime();
395 TimeMonitor timeMon (*timer);
397 const scalar_type ZERO = Teuchos::ScalarTraits<scalar_type>::zero ();
398 const size_t numVectors = B.getNumVectors ();
402 if (ZeroStartingSolution_) {
407 MV* OverlappingB =
nullptr;
408 MV* OverlappingY =
nullptr;
410 RCP<const map_type> B_and_Y_map = pointMapFromMeshMap<MatrixType>(IsOverlapping_ ?
411 OverlappingMatrix_->getRowMap () : localMap_ , Matrix_->getBlockSize());
412 if (overlapping_B_.get () ==
nullptr ||
413 overlapping_B_->getNumVectors () != numVectors) {
414 overlapping_B_.reset (
new MV (B_and_Y_map, numVectors,
false));
416 if (overlapping_Y_.get () ==
nullptr ||
417 overlapping_Y_->getNumVectors () != numVectors) {
418 overlapping_Y_.reset (
new MV (B_and_Y_map, numVectors,
false));
420 OverlappingB = overlapping_B_.get ();
421 OverlappingY = overlapping_Y_.get ();
424 OverlappingB->putScalar (ZERO);
425 OverlappingY->putScalar (ZERO);
428 RCP<MV> globalOverlappingB;
429 if (! IsOverlapping_) {
430 auto matrixPointRowMap = pointMapFromMeshMap<MatrixType>(Matrix_->getRowMap (),Matrix_->getBlockSize ());
433 OverlappingB->offsetViewNonConst (matrixPointRowMap, 0);
436 if (DistributedImporter_.is_null ()) {
440 DistributedImporter_ =
441 rcp (
new import_type (matrixPointRowMap,
442 Matrix_->getDomainMap ()));
446 if (R_.get () ==
nullptr || R_->getNumVectors () != numVectors) {
447 R_.reset (
new MV (B.getMap (), numVectors,
false));
449 if (C_.get () ==
nullptr || C_->getNumVectors () != numVectors) {
450 C_.reset (
new MV (Y.getMap (), numVectors,
false));
454 Teuchos::ArrayRCP<scalar_type> dataNumOverlapCopies;
455 if (IsOverlapping_ && AvgOverlap_) {
456 if (num_overlap_copies_.get() ==
nullptr) {
457 num_overlap_copies_.reset (
new MV (Y.getMap (), 1,
false));
458 RCP<MV> onesVec(
new MV(OverlappingMatrix_->getRowMap(), 1,
false) );
459 onesVec->putScalar(Teuchos::ScalarTraits<scalar_type>::one());
460 rcp_dynamic_cast<OverlappingRowMatrix<row_matrix_type>> (OverlappingMatrix_)->exportMultiVector (*onesVec, *(num_overlap_copies_.get ()), CombineMode_);
462 dataNumOverlapCopies = num_overlap_copies_.get ()->getDataNonConst(0);
472 for (
int ni=0; ni<NumIterations_; ++ni)
474#ifdef HAVE_IFPACK2_DEBUG
476 const bool bad = anyBad (Y);
477 TEUCHOS_TEST_FOR_EXCEPTION
478 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
479 "At top of iteration " << ni <<
", the 2-norm of Y is NaN or Inf.");
483 Tpetra::deep_copy(*R, B);
488 if (!ZeroStartingSolution_ || ni > 0) {
490 Matrix_->apply (Y, *R, mode, -STS::one(), STS::one());
492#ifdef HAVE_IFPACK2_DEBUG
494 const bool bad = anyBad (*R);
495 TEUCHOS_TEST_FOR_EXCEPTION
496 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
497 "At iteration " << ni <<
", the 2-norm of R (result of computing "
498 "residual with Y) is NaN or Inf.");
504 if (IsOverlapping_) {
505 TEUCHOS_TEST_FOR_EXCEPTION
506 (OverlappingMatrix_.is_null (), std::logic_error, prefix <<
507 "IsOverlapping_ is true, but OverlappingMatrix_, while nonnull, is "
508 "not an OverlappingRowMatrix<row_matrix_type>. Please report this "
509 "bug to the Ifpack2 developers.");
510 OverlappingMatrix_->importMultiVector (*R, *OverlappingB, Tpetra::INSERT);
527#ifdef HAVE_IFPACK2_DEBUG
529 const bool bad = anyBad (*OverlappingB);
530 TEUCHOS_TEST_FOR_EXCEPTION
531 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
532 "At iteration " << ni <<
", result of importMultiVector from R "
533 "to OverlappingB, has 2-norm NaN or Inf.");
537 globalOverlappingB->doImport (*R, *DistributedImporter_, Tpetra::INSERT);
539#ifdef HAVE_IFPACK2_DEBUG
541 const bool bad = anyBad (*globalOverlappingB);
542 TEUCHOS_TEST_FOR_EXCEPTION
543 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
544 "At iteration " << ni <<
", result of doImport from R, has 2-norm "
550#ifdef HAVE_IFPACK2_DEBUG
552 const bool bad = anyBad (*OverlappingB);
553 TEUCHOS_TEST_FOR_EXCEPTION
554 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
555 "At iteration " << ni <<
", right before localApply, the 2-norm of "
556 "OverlappingB is NaN or Inf.");
561 localApply(*OverlappingB, *OverlappingY);
563#ifdef HAVE_IFPACK2_DEBUG
565 const bool bad = anyBad (*OverlappingY);
566 TEUCHOS_TEST_FOR_EXCEPTION
567 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
568 "At iteration " << ni <<
", after localApply and before export / "
569 "copy, the 2-norm of OverlappingY is NaN or Inf.");
573#ifdef HAVE_IFPACK2_DEBUG
575 const bool bad = anyBad (*C);
576 TEUCHOS_TEST_FOR_EXCEPTION
577 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
578 "At iteration " << ni <<
", before export / copy, the 2-norm of C "
584 if (IsOverlapping_) {
585 TEUCHOS_TEST_FOR_EXCEPTION
586 (OverlappingMatrix_.is_null (), std::logic_error, prefix
587 <<
"OverlappingMatrix_ is null when it shouldn't be. "
588 "Please report this bug to the Ifpack2 developers.");
589 OverlappingMatrix_->exportMultiVector (*OverlappingY, *C, CombineMode_);
593 Teuchos::ArrayRCP<scalar_type> dataC = C->getDataNonConst(0);
594 for (
int i = 0; i < (int) C->getMap()->getLocalNumElements(); i++) {
595 dataC[i] = dataC[i]/dataNumOverlapCopies[i];
606 RCP<MV> C_view = C->offsetViewNonConst (OverlappingY->getMap (), 0);
607 Tpetra::deep_copy (*C_view, *OverlappingY);
610#ifdef HAVE_IFPACK2_DEBUG
612 const bool bad = anyBad (*C);
613 TEUCHOS_TEST_FOR_EXCEPTION
614 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
615 "At iteration " << ni <<
", before Y := C + Y, the 2-norm of C "
620#ifdef HAVE_IFPACK2_DEBUG
622 const bool bad = anyBad (Y);
623 TEUCHOS_TEST_FOR_EXCEPTION
624 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
625 "Before Y := C + Y, at iteration " << ni <<
", the 2-norm of Y "
630 Y.update(UpdateDamping_, *C, STS::one());
632#ifdef HAVE_IFPACK2_DEBUG
634 const bool bad = anyBad (Y);
635 TEUCHOS_TEST_FOR_EXCEPTION
636 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
637 "At iteration " << ni <<
", after Y := C + Y, the 2-norm of Y "
645#ifdef HAVE_IFPACK2_DEBUG
647 const bool bad = anyBad (Y);
648 TEUCHOS_TEST_FOR_EXCEPTION
649 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
650 "The 2-norm of the output Y is NaN or Inf.");
656 ApplyTime_ += (timer->wallTime() - startTime);
659template<
class MatrixType,
class LocalInverseType>
662localApply (MV& OverlappingB, MV& OverlappingY)
const
665 using Teuchos::rcp_dynamic_cast;
667 const size_t numVectors = OverlappingB.getNumVectors ();
669 auto additiveSchwarzFilter = rcp_dynamic_cast<Details::AdditiveSchwarzFilter<MatrixType>>(innerMatrix_);
670 if(additiveSchwarzFilter)
677 MV ReducedReorderedB (additiveSchwarzFilter->getRowMap(), numVectors);
678 MV ReducedReorderedY (additiveSchwarzFilter->getRowMap(), numVectors);
679 additiveSchwarzFilter->CreateReducedProblem(OverlappingB, OverlappingY, ReducedReorderedB);
681 Inverse_->solve (ReducedReorderedY, ReducedReorderedB);
683 additiveSchwarzFilter->UpdateLHS(ReducedReorderedY, OverlappingY);
687 if (FilterSingletons_) {
689 MV ReducedB (SingletonMatrix_->getRowMap (), numVectors);
690 MV ReducedY (SingletonMatrix_->getRowMap (), numVectors);
692 RCP<SingletonFilter<row_matrix_type> > singletonFilter =
693 rcp_dynamic_cast<SingletonFilter<row_matrix_type> > (SingletonMatrix_);
694 TEUCHOS_TEST_FOR_EXCEPTION
695 (! SingletonMatrix_.is_null () && singletonFilter.is_null (),
696 std::logic_error,
"Ifpack2::AdditiveSchwarz::localApply: "
697 "SingletonFilter_ is nonnull but is not a SingletonFilter"
698 "<row_matrix_type>. This should never happen. Please report this bug "
699 "to the Ifpack2 developers.");
700 singletonFilter->SolveSingletons (OverlappingB, OverlappingY);
701 singletonFilter->CreateReducedRHS (OverlappingY, OverlappingB, ReducedB);
704 if (! UseReordering_) {
705 Inverse_->solve (ReducedY, ReducedB);
708 RCP<ReorderFilter<row_matrix_type> > rf =
709 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
710 TEUCHOS_TEST_FOR_EXCEPTION
711 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
712 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is "
713 "nonnull but is not a ReorderFilter<row_matrix_type>. This should "
714 "never happen. Please report this bug to the Ifpack2 developers.");
715 MV ReorderedB (ReducedB, Teuchos::Copy);
716 MV ReorderedY (ReducedY, Teuchos::Copy);
717 rf->permuteOriginalToReordered (ReducedB, ReorderedB);
718 Inverse_->solve (ReorderedY, ReorderedB);
719 rf->permuteReorderedToOriginal (ReorderedY, ReducedY);
723 singletonFilter->UpdateLHS (ReducedY, OverlappingY);
727 if (! UseReordering_) {
728 Inverse_->solve (OverlappingY, OverlappingB);
731 MV ReorderedB (OverlappingB, Teuchos::Copy);
732 MV ReorderedY (OverlappingY, Teuchos::Copy);
734 RCP<ReorderFilter<row_matrix_type> > rf =
735 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
736 TEUCHOS_TEST_FOR_EXCEPTION
737 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
738 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is "
739 "nonnull but is not a ReorderFilter<row_matrix_type>. This should "
740 "never happen. Please report this bug to the Ifpack2 developers.");
741 rf->permuteOriginalToReordered (OverlappingB, ReorderedB);
742 Inverse_->solve (ReorderedY, ReorderedB);
743 rf->permuteReorderedToOriginal (ReorderedY, OverlappingY);
750template<
class MatrixType,
class LocalInverseType>
763template<
class MatrixType,
class LocalInverseType>
767 using Tpetra::CombineMode;
768 using Teuchos::ParameterEntry;
769 using Teuchos::ParameterEntryValidator;
770 using Teuchos::ParameterList;
773 using Teuchos::rcp_dynamic_cast;
774 using Teuchos::StringToIntegralParameterEntryValidator;
775 using Details::getParamTryingTypes;
776 const char prefix[] =
"Ifpack2::AdditiveSchwarz: ";
778 if (plist.is_null ()) {
787 TEUCHOS_TEST_FOR_EXCEPTION(
788 plist.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
789 "setParameterList: plist is null. This should never happen, since the "
790 "method should have replaced a null input list with a nonnull empty list "
791 "by this point. Please report this bug to the Ifpack2 developers.");
812 const std::string cmParamName (
"schwarz: combine mode");
813 const ParameterEntry* cmEnt = plist->getEntryPtr (cmParamName);
814 if (cmEnt !=
nullptr) {
815 if (cmEnt->isType<CombineMode> ()) {
816 CombineMode_ = Teuchos::getValue<CombineMode> (*cmEnt);
818 else if (cmEnt->isType<
int> ()) {
819 const int cm = Teuchos::getValue<int> (*cmEnt);
820 CombineMode_ =
static_cast<CombineMode
> (cm);
822 else if (cmEnt->isType<std::string> ()) {
827 const ParameterEntry& validEntry =
829 RCP<const ParameterEntryValidator> v = validEntry.validator ();
830 using vs2e_type = StringToIntegralParameterEntryValidator<CombineMode>;
831 RCP<const vs2e_type> vs2e = rcp_dynamic_cast<const vs2e_type> (v,
true);
833 ParameterEntry& inputEntry = plist->getEntry (cmParamName);
838 if (strncmp(Teuchos::getValue<std::string>(inputEntry).c_str(),
"AVG",3) == 0) {
839 inputEntry.template setValue<std::string>(
"ADD");
842 CombineMode_ = vs2e->getIntegralValue (inputEntry, cmParamName);
849 if (plist->isParameter(
"subdomain solver name")) {
850 if (plist->get<std::string>(
"subdomain solver name") ==
"BLOCK_RELAXATION") {
851 if (plist->isSublist(
"subdomain solver parameters")) {
852 if (plist->sublist(
"subdomain solver parameters").isParameter(
"relaxation: type")) {
853 if (plist->sublist(
"subdomain solver parameters").get<std::string>(
"relaxation: type") ==
"Jacobi" ) {
854 if (plist->sublist(
"subdomain solver parameters").isParameter(
"partitioner: type")) {
855 if (plist->sublist(
"subdomain solver parameters").get<std::string>(
"partitioner: type") ==
"user") {
856 if (CombineMode_ == Tpetra::ADD) plist->sublist(
"subdomain solver parameters").set(
"partitioner: combine mode",
"ADD");
857 if (CombineMode_ == Tpetra::ZERO) plist->sublist(
"subdomain solver parameters").set(
"partitioner: combine mode",
"ZERO");
867 OverlapLevel_ = plist->get (
"schwarz: overlap level", OverlapLevel_);
873 UseReordering_ = plist->get (
"schwarz: use reordering", UseReordering_);
875#if !defined(HAVE_IFPACK2_XPETRA) || !defined(HAVE_IFPACK2_ZOLTAN2)
876 TEUCHOS_TEST_FOR_EXCEPTION(
877 UseReordering_, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::"
878 "setParameters: You specified \"schwarz: use reordering\" = true. "
879 "This is only valid when Trilinos was built with Ifpack2, Xpetra, and "
880 "Zoltan2 enabled. Either Xpetra or Zoltan2 was not enabled in your build "
892 FilterSingletons_ = plist->get (
"schwarz: filter singletons", FilterSingletons_);
895 getParamTryingTypes<scalar_type, scalar_type, double>
896 (UpdateDamping_, *plist,
"schwarz: update damping", prefix);
931 if (! Inverse_.is_null ()) {
934 if (hasInnerPrecName () && innerPrecName () !=
"CUSTOM") {
937 Inverse_ = Teuchos::null;
942 std::pair<ParameterList, bool> result = innerPrecParams ();
946 Inverse_->setParameters (rcp (
new ParameterList (result.first)));
951 NumIterations_ = plist->get (
"schwarz: num iterations", NumIterations_);
952 ZeroStartingSolution_ =
953 plist->get (
"schwarz: zero starting solution", ZeroStartingSolution_);
958template<
class MatrixType,
class LocalInverseType>
959Teuchos::RCP<const Teuchos::ParameterList>
963 using Teuchos::ParameterList;
964 using Teuchos::parameterList;
966 using Teuchos::rcp_const_cast;
968 if (validParams_.is_null ()) {
969 const int overlapLevel = 0;
970 const bool useReordering =
false;
971 const bool filterSingletons =
false;
972 const int numIterations = 1;
973 const bool zeroStartingSolution =
true;
974 const scalar_type updateDamping = Teuchos::ScalarTraits<scalar_type>::one ();
975 ParameterList reorderingSublist;
976 reorderingSublist.set (
"order_method", std::string (
"rcm"));
978 RCP<ParameterList> plist = parameterList (
"Ifpack2::AdditiveSchwarz");
980 Tpetra::setCombineModeParameter (*plist,
"schwarz: combine mode");
981 plist->set (
"schwarz: overlap level", overlapLevel);
982 plist->set (
"schwarz: use reordering", useReordering);
983 plist->set (
"schwarz: reordering list", reorderingSublist);
986 plist->set (
"schwarz: compute condest",
false);
987 plist->set (
"schwarz: filter singletons", filterSingletons);
988 plist->set (
"schwarz: num iterations", numIterations);
989 plist->set (
"schwarz: zero starting solution", zeroStartingSolution);
990 plist->set (
"schwarz: update damping", updateDamping);
1000 validParams_ = rcp_const_cast<const ParameterList> (plist);
1002 return validParams_;
1006template<
class MatrixType,
class LocalInverseType>
1009 using Tpetra::global_size_t;
1012 using Teuchos::SerialComm;
1013 using Teuchos::Time;
1014 using Teuchos::TimeMonitor;
1016 const std::string timerName (
"Ifpack2::AdditiveSchwarz::initialize");
1017 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
1018 if (timer.is_null ()) {
1019 timer = TimeMonitor::getNewCounter (timerName);
1021 double startTime = timer->wallTime();
1024 TimeMonitor timeMon (*timer);
1026 TEUCHOS_TEST_FOR_EXCEPTION(
1027 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1028 "initialize: The matrix to precondition is null. You must either pass "
1029 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
1030 "input, before you may call this method.");
1032 IsInitialized_ =
false;
1033 IsComputed_ =
false;
1034 overlapping_B_.reset (
nullptr);
1035 overlapping_Y_.reset (
nullptr);
1039 RCP<const Teuchos::Comm<int> > comm = Matrix_->getComm ();
1040 RCP<const map_type> rowMap = Matrix_->getRowMap ();
1041 const global_size_t INVALID =
1042 Teuchos::OrdinalTraits<global_size_t>::invalid ();
1046 if (comm->getSize () == 1) {
1048 IsOverlapping_ =
false;
1049 }
else if (OverlapLevel_ != 0) {
1050 IsOverlapping_ =
true;
1053 if (OverlapLevel_ == 0) {
1055 RCP<const SerialComm<int> > localComm (
new SerialComm<int> ());
1059 rcp (
new map_type (INVALID, rowMap->getLocalNumElements (),
1060 indexBase, localComm));
1064 if (IsOverlapping_) {
1065 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"OverlappingRowMatrix construction"));
1071 if (! Inverse_.is_null ()) {
1072 Inverse_->symbolic ();
1077 IsInitialized_ =
true;
1080 InitializeTime_ += (timer->wallTime() - startTime);
1083template<
class MatrixType,
class LocalInverseType>
1086 return IsInitialized_;
1090template<
class MatrixType,
class LocalInverseType>
1094 using Teuchos::Time;
1095 using Teuchos::TimeMonitor;
1097 if (! IsInitialized_) {
1101 TEUCHOS_TEST_FOR_EXCEPTION(
1102 !
isInitialized (), std::logic_error,
"Ifpack2::AdditiveSchwarz::compute: "
1103 "The preconditioner is not yet initialized, "
1104 "even though initialize() supposedly has been called. "
1105 "This should never happen. "
1106 "Please report this bug to the Ifpack2 developers.");
1108 TEUCHOS_TEST_FOR_EXCEPTION(
1109 Inverse_.is_null (), std::runtime_error,
1110 "Ifpack2::AdditiveSchwarz::compute: The subdomain solver is null. "
1111 "This can only happen if you called setInnerPreconditioner() with a null "
1112 "input, after calling initialize() or compute(). If you choose to call "
1113 "setInnerPreconditioner() with a null input, you must then call it with a "
1114 "nonnull input before you may call initialize() or compute().");
1116 const std::string timerName (
"Ifpack2::AdditiveSchwarz::compute");
1117 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
1118 if (timer.is_null ()) {
1119 timer = TimeMonitor::getNewCounter (timerName);
1121 TimeMonitor timeMon (*timer);
1122 double startTime = timer->wallTime();
1126 if (IsOverlapping_) {
1127 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Halo Import"));
1128 OverlappingMatrix_->doExtImport();
1133 if(
auto asf = Teuchos::rcp_dynamic_cast<Details::AdditiveSchwarzFilter<MatrixType>>(innerMatrix_))
1135 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Fill Local Matrix"));
1138 asf->updateMatrixValues();
1145 IsComputed_ =
false;
1146 Inverse_->numeric ();
1152 ComputeTime_ += (timer->wallTime() - startTime);
1157template<
class MatrixType,
class LocalInverseType>
1164template<
class MatrixType,
class LocalInverseType>
1167 return NumInitialize_;
1171template<
class MatrixType,
class LocalInverseType>
1178template<
class MatrixType,
class LocalInverseType>
1185template<
class MatrixType,
class LocalInverseType>
1188 return InitializeTime_;
1192template<
class MatrixType,
class LocalInverseType>
1195 return ComputeTime_;
1199template<
class MatrixType,
class LocalInverseType>
1206template<
class MatrixType,
class LocalInverseType>
1209 std::ostringstream out;
1211 out <<
"\"Ifpack2::AdditiveSchwarz\": {";
1212 if (this->getObjectLabel () !=
"") {
1213 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
1215 out <<
"Initialized: " << (
isInitialized () ?
"true" :
"false")
1216 <<
", Computed: " << (
isComputed () ?
"true" :
"false")
1217 <<
", Iterations: " << NumIterations_
1218 <<
", Overlap level: " << OverlapLevel_
1219 <<
", Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"";
1220 out <<
", Combine mode: \"";
1221 if (CombineMode_ == Tpetra::INSERT) {
1223 }
else if (CombineMode_ == Tpetra::ADD) {
1225 }
else if (CombineMode_ == Tpetra::REPLACE) {
1227 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1229 }
else if (CombineMode_ == Tpetra::ZERO) {
1233 if (Matrix_.is_null ()) {
1234 out <<
", Matrix: null";
1237 out <<
", Global matrix dimensions: ["
1238 << Matrix_->getGlobalNumRows () <<
", "
1239 << Matrix_->getGlobalNumCols () <<
"]";
1241 out <<
", Inner solver: ";
1242 if (! Inverse_.is_null ()) {
1243 Teuchos::RCP<Teuchos::Describable> inv =
1244 Teuchos::rcp_dynamic_cast<Teuchos::Describable> (Inverse_);
1245 if (! inv.is_null ()) {
1246 out <<
"{" << inv->description () <<
"}";
1248 out <<
"{" <<
"Some inner solver" <<
"}";
1259template<
class MatrixType,
class LocalInverseType>
1262describe (Teuchos::FancyOStream& out,
1263 const Teuchos::EVerbosityLevel verbLevel)
const
1265 using Teuchos::OSTab;
1266 using Teuchos::TypeNameTraits;
1269 const int myRank = Matrix_->getComm ()->getRank ();
1270 const int numProcs = Matrix_->getComm ()->getSize ();
1271 const Teuchos::EVerbosityLevel vl =
1272 (verbLevel == Teuchos::VERB_DEFAULT) ? Teuchos::VERB_LOW : verbLevel;
1274 if (vl > Teuchos::VERB_NONE) {
1278 out <<
"\"Ifpack2::AdditiveSchwarz\":";
1282 out <<
"MatrixType: " << TypeNameTraits<MatrixType>::name () << endl;
1283 out <<
"LocalInverseType: " << TypeNameTraits<LocalInverseType>::name () << endl;
1284 if (this->getObjectLabel () !=
"") {
1285 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
1288 out <<
"Overlap level: " << OverlapLevel_ << endl
1289 <<
"Combine mode: \"";
1290 if (CombineMode_ == Tpetra::INSERT) {
1292 }
else if (CombineMode_ == Tpetra::ADD) {
1294 }
else if (CombineMode_ == Tpetra::REPLACE) {
1296 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1298 }
else if (CombineMode_ == Tpetra::ZERO) {
1302 <<
"Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"" << endl;
1305 if (Matrix_.is_null ()) {
1307 out <<
"Matrix: null" << endl;
1312 out <<
"Matrix:" << endl;
1315 Matrix_->getComm ()->barrier ();
1316 Matrix_->describe (out, Teuchos::VERB_LOW);
1322 <<
"Number of apply calls: " <<
getNumApply () << endl
1324 <<
"Total time in seconds for compute: " <<
getComputeTime () << endl
1325 <<
"Total time in seconds for apply: " <<
getApplyTime () << endl;
1328 if (Inverse_.is_null ()) {
1330 out <<
"Subdomain solver: null" << endl;
1334 if (vl < Teuchos::VERB_EXTREME) {
1336 out <<
"Subdomain solver: not null" << endl;
1340 for (
int p = 0; p < numProcs; ++p) {
1342 out <<
"Subdomain solver on Process " << myRank <<
":";
1343 if (Inverse_.is_null ()) {
1344 out <<
"null" << endl;
1346 Teuchos::RCP<Teuchos::Describable> inv =
1347 Teuchos::rcp_dynamic_cast<Teuchos::Describable> (Inverse_);
1348 if (! inv.is_null ()) {
1350 inv->describe (out, vl);
1352 out <<
"null" << endl;
1356 Matrix_->getComm ()->barrier ();
1357 Matrix_->getComm ()->barrier ();
1358 Matrix_->getComm ()->barrier ();
1363 Matrix_->getComm ()->barrier ();
1368template<
class MatrixType,
class LocalInverseType>
1371 Teuchos::FancyOStream fos(Teuchos::rcp(&os,
false));
1372 fos.setOutputToRootOnly(0);
1378template<
class MatrixType,
class LocalInverseType>
1381 return OverlapLevel_;
1385template<
class MatrixType,
class LocalInverseType>
1386void AdditiveSchwarz<MatrixType,LocalInverseType>::setup ()
1389 using Teuchos::MpiComm;
1391 using Teuchos::ArrayRCP;
1392 using Teuchos::ParameterList;
1395 using Teuchos::rcp_dynamic_cast;
1396 using Teuchos::rcpFromRef;
1398 TEUCHOS_TEST_FOR_EXCEPTION(
1399 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1400 "initialize: The matrix to precondition is null. You must either pass "
1401 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
1402 "input, before you may call this method.");
1406 auto matrixCrs = rcp_dynamic_cast<const crs_matrix_type>(Matrix_);
1407 if(!OverlappingMatrix_.is_null() || !matrixCrs.is_null())
1409 ArrayRCP<local_ordinal_type> perm;
1410 ArrayRCP<local_ordinal_type> revperm;
1411 if (UseReordering_) {
1412 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Reordering"));
1413#if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2)
1415 Teuchos::ParameterList zlist = List_.sublist (
"schwarz: reordering list");
1416 ReorderingAlgorithm_ = zlist.get<std::string> (
"order_method",
"rcm");
1418 if(ReorderingAlgorithm_ ==
"user") {
1420 perm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user ordering");
1421 revperm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user reverse ordering");
1425 typedef Tpetra::RowGraph
1426 <local_ordinal_type, global_ordinal_type, node_type> row_graph_type;
1427 typedef Zoltan2::TpetraRowGraphAdapter<row_graph_type> z2_adapter_type;
1428 auto constActiveGraph = Teuchos::rcp_const_cast<const row_graph_type>(
1429 IsOverlapping_ ? OverlappingMatrix_->getGraph() : Matrix_->getGraph());
1430 z2_adapter_type Zoltan2Graph (constActiveGraph);
1432 typedef Zoltan2::OrderingProblem<z2_adapter_type> ordering_problem_type;
1437 RCP<const MpiComm<int> > mpicomm =
1438 rcp_dynamic_cast<const MpiComm<int> > (Matrix_->getComm ());
1439 if (mpicomm == Teuchos::null) {
1440 myRawComm = MPI_COMM_SELF;
1442 myRawComm = * (mpicomm->getRawMpiComm ());
1444 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist, myRawComm);
1446 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist);
1448 MyOrderingProblem.solve ();
1451 typedef Zoltan2::LocalOrderingSolution<local_ordinal_type>
1452 ordering_solution_type;
1454 ordering_solution_type sol (*MyOrderingProblem.getLocalOrderingSolution());
1460 perm = sol.getPermutationRCPConst (
true);
1461 revperm = sol.getPermutationRCPConst ();
1467 TEUCHOS_TEST_FOR_EXCEPTION(
1468 true, std::logic_error,
"Ifpack2::AdditiveSchwarz::setup: "
1469 "The Zoltan2 and Xpetra packages must be enabled in order "
1470 "to support reordering.");
1475 local_ordinal_type numLocalRows = OverlappingMatrix_.is_null() ? matrixCrs->getLocalNumRows() : OverlappingMatrix_->getLocalNumRows();
1479 perm = ArrayRCP<local_ordinal_type>(numLocalRows);
1480 revperm = ArrayRCP<local_ordinal_type>(numLocalRows);
1489 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Filter construction"));
1490 RCP<Details::AdditiveSchwarzFilter<MatrixType>> asf;
1491 if(OverlappingMatrix_.is_null())
1492 asf = rcp(
new Details::AdditiveSchwarzFilter<MatrixType>(matrixCrs, perm, revperm, FilterSingletons_));
1494 asf = rcp(
new Details::AdditiveSchwarzFilter<MatrixType>(OverlappingMatrix_, perm, revperm, FilterSingletons_));
1501 RCP<row_matrix_type> LocalizedMatrix;
1505 RCP<row_matrix_type> ActiveMatrix;
1508 if (! OverlappingMatrix_.is_null ()) {
1516 TEUCHOS_TEST_FOR_EXCEPTION(
1517 LocalizedMatrix.is_null (), std::logic_error,
1518 "Ifpack2::AdditiveSchwarz::setup: LocalizedMatrix is null, after the code "
1519 "that claimed to have created it. This should never be the case. Please "
1520 "report this bug to the Ifpack2 developers.");
1523 ActiveMatrix = LocalizedMatrix;
1526 if (FilterSingletons_) {
1528 ActiveMatrix = SingletonMatrix_;
1532 if (UseReordering_) {
1533#if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2)
1536 Teuchos::ParameterList zlist = List_.sublist (
"schwarz: reordering list");
1537 ReorderingAlgorithm_ = zlist.get<std::string> (
"order_method",
"rcm");
1539 ArrayRCP<local_ordinal_type> perm;
1540 ArrayRCP<local_ordinal_type> revperm;
1542 if(ReorderingAlgorithm_ ==
"user") {
1544 perm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user ordering");
1545 revperm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user reverse ordering");
1549 typedef Tpetra::RowGraph
1551 typedef Zoltan2::TpetraRowGraphAdapter<row_graph_type> z2_adapter_type;
1552 RCP<const row_graph_type> constActiveGraph =
1553 Teuchos::rcp_const_cast<const row_graph_type>(ActiveMatrix->getGraph());
1554 z2_adapter_type Zoltan2Graph (constActiveGraph);
1556 typedef Zoltan2::OrderingProblem<z2_adapter_type> ordering_problem_type;
1561 RCP<const MpiComm<int> > mpicomm =
1562 rcp_dynamic_cast<const MpiComm<int> > (ActiveMatrix->getComm ());
1563 if (mpicomm == Teuchos::null) {
1564 myRawComm = MPI_COMM_SELF;
1566 myRawComm = * (mpicomm->getRawMpiComm ());
1568 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist, myRawComm);
1570 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist);
1572 MyOrderingProblem.solve ();
1575 typedef Zoltan2::LocalOrderingSolution<local_ordinal_type>
1576 ordering_solution_type;
1578 ordering_solution_type sol (*MyOrderingProblem.getLocalOrderingSolution());
1584 perm = sol.getPermutationRCPConst (
true);
1585 revperm = sol.getPermutationRCPConst ();
1589 ReorderedLocalizedMatrix_ = rcp (
new reorder_filter_type (ActiveMatrix, perm, revperm));
1592 ActiveMatrix = ReorderedLocalizedMatrix_;
1596 TEUCHOS_TEST_FOR_EXCEPTION(
1597 true, std::logic_error,
"Ifpack2::AdditiveSchwarz::setup: "
1598 "The Zoltan2 and Xpetra packages must be enabled in order "
1599 "to support reordering.");
1602 innerMatrix_ = ActiveMatrix;
1605 TEUCHOS_TEST_FOR_EXCEPTION(
1606 innerMatrix_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
1607 "setup: Inner matrix is null right before constructing inner solver. "
1608 "Please report this bug to the Ifpack2 developers.");
1611 if (Inverse_.is_null ()) {
1612 const std::string innerName = innerPrecName ();
1613 TEUCHOS_TEST_FOR_EXCEPTION(
1614 innerName ==
"INVALID", std::logic_error,
1615 "Ifpack2::AdditiveSchwarz::initialize: AdditiveSchwarz doesn't "
1616 "know how to create an instance of your LocalInverseType \""
1617 << Teuchos::TypeNameTraits<LocalInverseType>::name () <<
"\". "
1618 "Please talk to the Ifpack2 developers for details.");
1620 TEUCHOS_TEST_FOR_EXCEPTION(
1621 innerName ==
"CUSTOM", std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1622 "initialize: If the \"inner preconditioner name\" parameter (or any "
1623 "alias thereof) has the value \"CUSTOM\", then you must first call "
1624 "setInnerPreconditioner with a nonnull inner preconditioner input before "
1625 "you may call initialize().");
1629 if (! Trilinos::Details::Impl::registeredSomeLinearSolverFactory (
"Ifpack2")) {
1635 typedef typename MV::mag_type MT;
1636 RCP<inner_solver_type> innerPrec =
1637 Trilinos::Details::getLinearSolver<MV, OP, MT> (
"Ifpack2", innerName);
1638 TEUCHOS_TEST_FOR_EXCEPTION(
1639 innerPrec.is_null (), std::logic_error,
1640 "Ifpack2::AdditiveSchwarz::setup: Failed to create inner preconditioner "
1641 "with name \"" << innerName <<
"\".");
1642 innerPrec->setMatrix (innerMatrix_);
1646 std::pair<Teuchos::ParameterList, bool> result = innerPrecParams ();
1647 if (result.second) {
1650 innerPrec->setParameters (rcp (
new ParameterList (result.first)));
1652 Inverse_ = innerPrec;
1654 else if (Inverse_->getMatrix ().getRawPtr () != innerMatrix_.getRawPtr ()) {
1658 Inverse_->setMatrix (innerMatrix_);
1660 TEUCHOS_TEST_FOR_EXCEPTION(
1661 Inverse_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
1662 "setup: Inverse_ is null right after we were supposed to have created it."
1663 " Please report this bug to the Ifpack2 developers.");
1673template<
class MatrixType,
class LocalInverseType>
1680 if (! innerPrec.is_null ()) {
1683 can_change_type* innerSolver =
dynamic_cast<can_change_type*
> (&*innerPrec);
1684 TEUCHOS_TEST_FOR_EXCEPTION(
1685 innerSolver == NULL, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::"
1686 "setInnerPreconditioner: The input preconditioner does not implement the "
1687 "setMatrix() feature. Only input preconditioners that inherit from "
1688 "Ifpack2::Details::CanChangeMatrix implement this feature.");
1705 if(
auto asf = Teuchos::rcp_dynamic_cast<Details::AdditiveSchwarzFilter<MatrixType>>(innerMatrix_))
1706 innerSolver->setMatrix (asf->getFilteredMatrix());
1708 innerSolver->setMatrix (innerMatrix_);
1718 removeInnerPrecName ();
1719 removeInnerPrecParams ();
1720 List_.set (
"inner preconditioner name",
"CUSTOM");
1725 innerPrec->initialize ();
1728 innerPrec->compute ();
1741 Inverse_ = Teuchos::rcp (
new inner_solver_impl_type (innerPrec,
"CUSTOM"));
1744template<
class MatrixType,
class LocalInverseType>
1746setMatrix (
const Teuchos::RCP<const row_matrix_type>& A)
1749 if (A.getRawPtr () != Matrix_.getRawPtr ()) {
1750 IsInitialized_ =
false;
1751 IsComputed_ =
false;
1754 OverlappingMatrix_ = Teuchos::null;
1755 ReorderedLocalizedMatrix_ = Teuchos::null;
1756 innerMatrix_ = Teuchos::null;
1757 SingletonMatrix_ = Teuchos::null;
1758 localMap_ = Teuchos::null;
1759 overlapping_B_.reset (
nullptr);
1760 overlapping_Y_.reset (
nullptr);
1763 DistributedImporter_ = Teuchos::null;
1774#define IFPACK2_ADDITIVESCHWARZ_INSTANT(S,LO,GO,N) \
1775 template class Ifpack2::AdditiveSchwarz< Tpetra::RowMatrix<S, LO, GO, N> >;
void registerLinearSolverFactory()
Register Ifpack2's LinearSolverFactory with the central repository, for all enabled combinations of t...
Definition Ifpack2_Details_registerLinearSolverFactory.cpp:68
Declaration of interface for preconditioners that can change their matrix after construction.
Additive Schwarz domain decomposition for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:296
typename MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:317
std::string description() const
Return a simple one-line description of this object.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1207
virtual bool isInitialized() const
Returns true if the preconditioner has been successfully initialized, false otherwise.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1084
virtual int getOverlapLevel() const
Returns the level of overlap.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1379
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Get a list of the preconditioner's default parameters.
Definition Ifpack2_AdditiveSchwarz_def.hpp:961
typename MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:320
virtual int getNumCompute() const
Returns the number of calls to compute().
Definition Ifpack2_AdditiveSchwarz_def.hpp:1172
virtual int getNumApply() const
Returns the number of calls to apply().
Definition Ifpack2_AdditiveSchwarz_def.hpp:1179
virtual double getComputeTime() const
Returns the time spent in compute().
Definition Ifpack2_AdditiveSchwarz_def.hpp:1193
virtual double getApplyTime() const
Returns the time spent in apply().
Definition Ifpack2_AdditiveSchwarz_def.hpp:1200
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1746
typename MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:323
virtual void initialize()
Computes all (graph-related) data necessary to initialize the preconditioner.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1007
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
Set the preconditioner's parameters.
Definition Ifpack2_AdditiveSchwarz_def.hpp:765
virtual void setInnerPreconditioner(const Teuchos::RCP< Preconditioner< scalar_type, local_ordinal_type, global_ordinal_type, node_type > > &innerPrec)
Set the inner preconditioner.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1675
virtual double getInitializeTime() const
Returns the time spent in initialize().
Definition Ifpack2_AdditiveSchwarz_def.hpp:1186
virtual Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getRangeMap() const
The range Map of this operator.
Definition Ifpack2_AdditiveSchwarz_def.hpp:275
virtual Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getDomainMap() const
The domain Map of this operator.
Definition Ifpack2_AdditiveSchwarz_def.hpp:262
virtual void compute()
Computes all (coefficient) data necessary to apply the preconditioner.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1091
virtual std::ostream & print(std::ostream &os) const
Prints basic information on iostream. This function is used by operator<<.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1369
typename MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:314
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream object.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1262
virtual void setParameters(const Teuchos::ParameterList &plist)
Set the preconditioner's parameters.
Definition Ifpack2_AdditiveSchwarz_def.hpp:752
virtual Teuchos::RCP< const row_matrix_type > getMatrix() const
The input matrix.
Definition Ifpack2_AdditiveSchwarz_def.hpp:287
virtual void apply(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &X, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, scalar_type alpha=Teuchos::ScalarTraits< scalar_type >::one(), scalar_type beta=Teuchos::ScalarTraits< scalar_type >::zero()) const
Apply the preconditioner to X, putting the result in Y.
Definition Ifpack2_AdditiveSchwarz_def.hpp:316
virtual bool isComputed() const
Returns true if the preconditioner has been successfully computed, false otherwise.
Definition Ifpack2_AdditiveSchwarz_def.hpp:1158
virtual int getNumInitialize() const
Returns the number of calls to initialize().
Definition Ifpack2_AdditiveSchwarz_def.hpp:1165
AdditiveSchwarz(const Teuchos::RCP< const row_matrix_type > &A)
Constructor that takes a matrix.
Definition Ifpack2_AdditiveSchwarz_def.hpp:247
Mix-in interface for preconditioners that can change their matrix after construction.
Definition Ifpack2_Details_CanChangeMatrix.hpp:93
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition Ifpack2_Details_LinearSolver_decl.hpp:110
Access only local rows and columns of a sparse matrix.
Definition Ifpack2_LocalFilter_decl.hpp:163
Sparse matrix (Tpetra::RowMatrix subclass) with ghost rows.
Definition Ifpack2_OverlappingRowMatrix_decl.hpp:59
Interface for all Ifpack2 preconditioners.
Definition Ifpack2_Preconditioner.hpp:108
Wraps a Tpetra::RowMatrix in a filter that reorders local rows and columns.
Definition Ifpack2_ReorderFilter_decl.hpp:70
Filter based on matrix entries.
Definition Ifpack2_SingletonFilter_decl.hpp:65
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:74
void getValidParameters(Teuchos::ParameterList ¶ms)
Fills a list which contains all the parameters possibly used by Ifpack2.
Definition Ifpack2_Parameters.cpp:51