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"
95#ifdef HAVE_IFPACK2_DEBUG
103 using STS = Teuchos::ScalarTraits<typename MV::scalar_type>;
104 using magnitude_type =
typename STS::magnitudeType;
105 using STM = Teuchos::ScalarTraits<magnitude_type>;
107 Teuchos::Array<magnitude_type> norms (X.getNumVectors ());
110 for (
size_t j = 0; j < X.getNumVectors (); ++j) {
111 if (STM::isnaninf (norms[j])) {
125template<
class MatrixType,
class LocalInverseType>
127AdditiveSchwarz<MatrixType, LocalInverseType>::hasInnerPrecName ()
const
129 const char* options[4] = {
130 "inner preconditioner name",
131 "subdomain solver name",
132 "schwarz: inner preconditioner name",
133 "schwarz: subdomain solver name"
135 const int numOptions = 4;
137 for (
int k = 0; k < numOptions && ! match; ++k) {
138 if (List_.isParameter (options[k])) {
146template<
class MatrixType,
class LocalInverseType>
148AdditiveSchwarz<MatrixType, LocalInverseType>::removeInnerPrecName ()
150 const char* options[4] = {
151 "inner preconditioner name",
152 "subdomain solver name",
153 "schwarz: inner preconditioner name",
154 "schwarz: subdomain solver name"
156 const int numOptions = 4;
157 for (
int k = 0; k < numOptions; ++k) {
158 List_.remove (options[k],
false);
163template<
class MatrixType,
class LocalInverseType>
165AdditiveSchwarz<MatrixType, LocalInverseType>::innerPrecName ()
const
167 const char* options[4] = {
168 "inner preconditioner name",
169 "subdomain solver name",
170 "schwarz: inner preconditioner name",
171 "schwarz: subdomain solver name"
173 const int numOptions = 4;
178 for (
int k = 0; k < numOptions && ! match; ++k) {
179 const Teuchos::ParameterEntry* paramEnt =
180 List_.getEntryPtr (options[k]);
181 if (paramEnt !=
nullptr && paramEnt->isType<std::string> ()) {
182 newName = Teuchos::getValue<std::string> (*paramEnt);
186 return match ? newName : defaultInnerPrecName ();
190template<
class MatrixType,
class LocalInverseType>
192AdditiveSchwarz<MatrixType, LocalInverseType>::removeInnerPrecParams ()
194 const char* options[4] = {
195 "inner preconditioner parameters",
196 "subdomain solver parameters",
197 "schwarz: inner preconditioner parameters",
198 "schwarz: subdomain solver parameters"
200 const int numOptions = 4;
203 for (
int k = 0; k < numOptions; ++k) {
204 List_.remove (options[k],
false);
209template<
class MatrixType,
class LocalInverseType>
210std::pair<Teuchos::ParameterList, bool>
211AdditiveSchwarz<MatrixType, LocalInverseType>::innerPrecParams ()
const
213 const char* options[4] = {
214 "inner preconditioner parameters",
215 "subdomain solver parameters",
216 "schwarz: inner preconditioner parameters",
217 "schwarz: subdomain solver parameters"
219 const int numOptions = 4;
220 Teuchos::ParameterList params;
224 for (
int k = 0; k < numOptions && ! match; ++k) {
225 if (List_.isSublist (options[k])) {
226 params = List_.sublist (options[k]);
231 return std::make_pair (params, match);
234template<
class MatrixType,
class LocalInverseType>
236AdditiveSchwarz<MatrixType, LocalInverseType>::defaultInnerPrecName ()
243template<
class MatrixType,
class LocalInverseType>
249template<
class MatrixType,
class LocalInverseType>
252 const int overlapLevel) :
254 OverlapLevel_ (overlapLevel)
257template<
class MatrixType,
class LocalInverseType>
258Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type > >
262 TEUCHOS_TEST_FOR_EXCEPTION(
263 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
264 "getDomainMap: The matrix to precondition is null. You must either pass "
265 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
266 "input, before you may call this method.");
267 return Matrix_->getDomainMap ();
271template<
class MatrixType,
class LocalInverseType>
272Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type> >
275 TEUCHOS_TEST_FOR_EXCEPTION(
276 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
277 "getRangeMap: The matrix to precondition is null. You must either pass "
278 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
279 "input, before you may call this method.");
280 return Matrix_->getRangeMap ();
284template<
class MatrixType,
class LocalInverseType>
291template<
class MatrixType,
class LocalInverseType>
294apply (
const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &B,
295 Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &Y,
296 Teuchos::ETransp mode,
301 using Teuchos::TimeMonitor;
304 using Teuchos::rcp_dynamic_cast;
305 typedef Teuchos::ScalarTraits<scalar_type> STS;
306 const char prefix[] =
"Ifpack2::AdditiveSchwarz::apply: ";
308 TEUCHOS_TEST_FOR_EXCEPTION
309 (! IsComputed_, std::runtime_error,
310 prefix <<
"isComputed() must be true before you may call apply().");
311 TEUCHOS_TEST_FOR_EXCEPTION
312 (Matrix_.is_null (), std::logic_error, prefix <<
313 "The input matrix A is null, but the preconditioner says that it has "
314 "been computed (isComputed() is true). This should never happen, since "
315 "setMatrix() should always mark the preconditioner as not computed if "
316 "its argument is null. "
317 "Please report this bug to the Ifpack2 developers.");
318 TEUCHOS_TEST_FOR_EXCEPTION
319 (Inverse_.is_null (), std::runtime_error,
320 prefix <<
"The subdomain solver is null. "
321 "This can only happen if you called setInnerPreconditioner() with a null "
322 "input, after calling initialize() or compute(). If you choose to call "
323 "setInnerPreconditioner() with a null input, you must then call it with "
324 "a nonnull input before you may call initialize() or compute().");
325 TEUCHOS_TEST_FOR_EXCEPTION
326 (B.getNumVectors() != Y.getNumVectors(), std::invalid_argument,
327 prefix <<
"B and Y must have the same number of columns. B has " <<
328 B.getNumVectors () <<
" columns, but Y has " << Y.getNumVectors() <<
".");
329 TEUCHOS_TEST_FOR_EXCEPTION
330 (IsOverlapping_ && OverlappingMatrix_.is_null (), std::logic_error,
331 prefix <<
"The overlapping matrix is null. "
332 "This should never happen if IsOverlapping_ is true. "
333 "Please report this bug to the Ifpack2 developers.");
334 TEUCHOS_TEST_FOR_EXCEPTION
335 (! IsOverlapping_ && localMap_.is_null (), std::logic_error,
336 prefix <<
"localMap_ is null. "
337 "This should never happen if IsOverlapping_ is false. "
338 "Please report this bug to the Ifpack2 developers.");
339 TEUCHOS_TEST_FOR_EXCEPTION
340 (alpha != STS::one (), std::logic_error,
341 prefix <<
"Not implemented for alpha != 1.");
342 TEUCHOS_TEST_FOR_EXCEPTION
343 (beta != STS::zero (), std::logic_error,
344 prefix <<
"Not implemented for beta != 0.");
346#ifdef HAVE_IFPACK2_DEBUG
348 const bool bad = anyBad (B);
349 TEUCHOS_TEST_FOR_EXCEPTION
350 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
351 "The 2-norm of the input B is NaN or Inf.");
355#ifdef HAVE_IFPACK2_DEBUG
356 if (! ZeroStartingSolution_) {
357 const bool bad = anyBad (Y);
358 TEUCHOS_TEST_FOR_EXCEPTION
359 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
360 "On input, the initial guess Y has 2-norm NaN or Inf "
361 "(ZeroStartingSolution_ is false).");
365 const std::string timerName (
"Ifpack2::AdditiveSchwarz::apply");
366 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
367 if (timer.is_null ()) {
368 timer = TimeMonitor::getNewCounter (timerName);
370 double startTime = timer->wallTime();
373 TimeMonitor timeMon (*timer);
375 const scalar_type ZERO = Teuchos::ScalarTraits<scalar_type>::zero ();
376 const size_t numVectors = B.getNumVectors ();
380 if (ZeroStartingSolution_) {
385 MV* OverlappingB =
nullptr;
386 MV* OverlappingY =
nullptr;
388 RCP<const map_type> B_and_Y_map = IsOverlapping_ ?
389 OverlappingMatrix_->getRowMap () : localMap_;
390 if (overlapping_B_.get () ==
nullptr ||
391 overlapping_B_->getNumVectors () != numVectors) {
392 overlapping_B_.reset (
new MV (B_and_Y_map, numVectors,
false));
394 if (overlapping_Y_.get () ==
nullptr ||
395 overlapping_Y_->getNumVectors () != numVectors) {
396 overlapping_Y_.reset (
new MV (B_and_Y_map, numVectors,
false));
398 OverlappingB = overlapping_B_.get ();
399 OverlappingY = overlapping_Y_.get ();
402 OverlappingB->putScalar (ZERO);
403 OverlappingY->putScalar (ZERO);
406 RCP<MV> globalOverlappingB;
407 if (! IsOverlapping_) {
409 OverlappingB->offsetViewNonConst (Matrix_->getRowMap (), 0);
412 if (DistributedImporter_.is_null ()) {
416 DistributedImporter_ =
417 rcp (
new import_type (Matrix_->getRowMap (),
418 Matrix_->getDomainMap ()));
422 if (R_.get () ==
nullptr || R_->getNumVectors () != numVectors) {
423 R_.reset (
new MV (B.getMap (), numVectors,
false));
425 if (C_.get () ==
nullptr || C_->getNumVectors () != numVectors) {
426 C_.reset (
new MV (Y.getMap (), numVectors,
false));
430 Teuchos::ArrayRCP<scalar_type> dataNumOverlapCopies;
431 if (IsOverlapping_ && AvgOverlap_) {
432 if (num_overlap_copies_.get() ==
nullptr) {
433 num_overlap_copies_.reset (
new MV (Y.getMap (), 1,
false));
434 RCP<MV> onesVec(
new MV(OverlappingMatrix_->getRowMap(), 1,
false) );
435 onesVec->putScalar(Teuchos::ScalarTraits<scalar_type>::one());
436 rcp_dynamic_cast<OverlappingRowMatrix<row_matrix_type>> (OverlappingMatrix_)->exportMultiVector (*onesVec, *(num_overlap_copies_.get ()), CombineMode_);
438 dataNumOverlapCopies = num_overlap_copies_.get ()->getDataNonConst(0);
448 for (
int ni=0; ni<NumIterations_; ++ni)
450#ifdef HAVE_IFPACK2_DEBUG
452 const bool bad = anyBad (Y);
453 TEUCHOS_TEST_FOR_EXCEPTION
454 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
455 "At top of iteration " << ni <<
", the 2-norm of Y is NaN or Inf.");
459 Tpetra::deep_copy(*R, B);
464 if (!ZeroStartingSolution_ || ni > 0) {
466 Matrix_->apply (Y, *R, mode, -STS::one(), STS::one());
468#ifdef HAVE_IFPACK2_DEBUG
470 const bool bad = anyBad (*R);
471 TEUCHOS_TEST_FOR_EXCEPTION
472 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
473 "At iteration " << ni <<
", the 2-norm of R (result of computing "
474 "residual with Y) is NaN or Inf.");
480 if (IsOverlapping_) {
481 TEUCHOS_TEST_FOR_EXCEPTION
482 (OverlappingMatrix_.is_null (), std::logic_error, prefix <<
483 "IsOverlapping_ is true, but OverlappingMatrix_, while nonnull, is "
484 "not an OverlappingRowMatrix<row_matrix_type>. Please report this "
485 "bug to the Ifpack2 developers.");
486 OverlappingMatrix_->importMultiVector (*R, *OverlappingB, Tpetra::INSERT);
503#ifdef HAVE_IFPACK2_DEBUG
505 const bool bad = anyBad (*OverlappingB);
506 TEUCHOS_TEST_FOR_EXCEPTION
507 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
508 "At iteration " << ni <<
", result of importMultiVector from R "
509 "to OverlappingB, has 2-norm NaN or Inf.");
513 globalOverlappingB->doImport (*R, *DistributedImporter_, Tpetra::INSERT);
515#ifdef HAVE_IFPACK2_DEBUG
517 const bool bad = anyBad (*globalOverlappingB);
518 TEUCHOS_TEST_FOR_EXCEPTION
519 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
520 "At iteration " << ni <<
", result of doImport from R, has 2-norm "
526#ifdef HAVE_IFPACK2_DEBUG
528 const bool bad = anyBad (*OverlappingB);
529 TEUCHOS_TEST_FOR_EXCEPTION
530 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
531 "At iteration " << ni <<
", right before localApply, the 2-norm of "
532 "OverlappingB is NaN or Inf.");
537 localApply(*OverlappingB, *OverlappingY);
539#ifdef HAVE_IFPACK2_DEBUG
541 const bool bad = anyBad (*OverlappingY);
542 TEUCHOS_TEST_FOR_EXCEPTION
543 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
544 "At iteration " << ni <<
", after localApply and before export / "
545 "copy, the 2-norm of OverlappingY is NaN or Inf.");
549#ifdef HAVE_IFPACK2_DEBUG
551 const bool bad = anyBad (*C);
552 TEUCHOS_TEST_FOR_EXCEPTION
553 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
554 "At iteration " << ni <<
", before export / copy, the 2-norm of C "
560 if (IsOverlapping_) {
561 TEUCHOS_TEST_FOR_EXCEPTION
562 (OverlappingMatrix_.is_null (), std::logic_error, prefix
563 <<
"OverlappingMatrix_ is null when it shouldn't be. "
564 "Please report this bug to the Ifpack2 developers.");
565 OverlappingMatrix_->exportMultiVector (*OverlappingY, *C, CombineMode_);
569 Teuchos::ArrayRCP<scalar_type> dataC = C->getDataNonConst(0);
570 for (
int i = 0; i < (int) C->getMap()->getLocalNumElements(); i++) {
571 dataC[i] = dataC[i]/dataNumOverlapCopies[i];
582 RCP<MV> C_view = C->offsetViewNonConst (OverlappingY->getMap (), 0);
583 Tpetra::deep_copy (*C_view, *OverlappingY);
586#ifdef HAVE_IFPACK2_DEBUG
588 const bool bad = anyBad (*C);
589 TEUCHOS_TEST_FOR_EXCEPTION
590 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
591 "At iteration " << ni <<
", before Y := C + Y, the 2-norm of C "
596#ifdef HAVE_IFPACK2_DEBUG
598 const bool bad = anyBad (Y);
599 TEUCHOS_TEST_FOR_EXCEPTION
600 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
601 "Before Y := C + Y, at iteration " << ni <<
", the 2-norm of Y "
606 Y.update(UpdateDamping_, *C, STS::one());
608#ifdef HAVE_IFPACK2_DEBUG
610 const bool bad = anyBad (Y);
611 TEUCHOS_TEST_FOR_EXCEPTION
612 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
613 "At iteration " << ni <<
", after Y := C + Y, the 2-norm of Y "
621#ifdef HAVE_IFPACK2_DEBUG
623 const bool bad = anyBad (Y);
624 TEUCHOS_TEST_FOR_EXCEPTION
625 (bad, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
626 "The 2-norm of the output Y is NaN or Inf.");
632 ApplyTime_ += (timer->wallTime() - startTime);
635template<
class MatrixType,
class LocalInverseType>
638localApply (MV& OverlappingB, MV& OverlappingY)
const
641 using Teuchos::rcp_dynamic_cast;
643 const size_t numVectors = OverlappingB.getNumVectors ();
645 auto additiveSchwarzFilter = rcp_dynamic_cast<Details::AdditiveSchwarzFilter<MatrixType>>(innerMatrix_);
646 if(additiveSchwarzFilter)
653 MV ReducedReorderedB (additiveSchwarzFilter->getRowMap(), numVectors);
654 MV ReducedReorderedY (additiveSchwarzFilter->getRowMap(), numVectors);
655 additiveSchwarzFilter->CreateReducedProblem(OverlappingB, OverlappingY, ReducedReorderedB);
657 Inverse_->solve (ReducedReorderedY, ReducedReorderedB);
659 additiveSchwarzFilter->UpdateLHS(ReducedReorderedY, OverlappingY);
663 if (FilterSingletons_) {
665 MV ReducedB (SingletonMatrix_->getRowMap (), numVectors);
666 MV ReducedY (SingletonMatrix_->getRowMap (), numVectors);
668 RCP<SingletonFilter<row_matrix_type> > singletonFilter =
669 rcp_dynamic_cast<SingletonFilter<row_matrix_type> > (SingletonMatrix_);
670 TEUCHOS_TEST_FOR_EXCEPTION
671 (! SingletonMatrix_.is_null () && singletonFilter.is_null (),
672 std::logic_error,
"Ifpack2::AdditiveSchwarz::localApply: "
673 "SingletonFilter_ is nonnull but is not a SingletonFilter"
674 "<row_matrix_type>. This should never happen. Please report this bug "
675 "to the Ifpack2 developers.");
676 singletonFilter->SolveSingletons (OverlappingB, OverlappingY);
677 singletonFilter->CreateReducedRHS (OverlappingY, OverlappingB, ReducedB);
680 if (! UseReordering_) {
681 Inverse_->solve (ReducedY, ReducedB);
684 RCP<ReorderFilter<row_matrix_type> > rf =
685 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
686 TEUCHOS_TEST_FOR_EXCEPTION
687 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
688 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is "
689 "nonnull but is not a ReorderFilter<row_matrix_type>. This should "
690 "never happen. Please report this bug to the Ifpack2 developers.");
691 MV ReorderedB (ReducedB, Teuchos::Copy);
692 MV ReorderedY (ReducedY, Teuchos::Copy);
693 rf->permuteOriginalToReordered (ReducedB, ReorderedB);
694 Inverse_->solve (ReorderedY, ReorderedB);
695 rf->permuteReorderedToOriginal (ReorderedY, ReducedY);
699 singletonFilter->UpdateLHS (ReducedY, OverlappingY);
703 if (! UseReordering_) {
704 Inverse_->solve (OverlappingY, OverlappingB);
707 MV ReorderedB (OverlappingB, Teuchos::Copy);
708 MV ReorderedY (OverlappingY, Teuchos::Copy);
710 RCP<ReorderFilter<row_matrix_type> > rf =
711 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
712 TEUCHOS_TEST_FOR_EXCEPTION
713 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
714 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is "
715 "nonnull but is not a ReorderFilter<row_matrix_type>. This should "
716 "never happen. Please report this bug to the Ifpack2 developers.");
717 rf->permuteOriginalToReordered (OverlappingB, ReorderedB);
718 Inverse_->solve (ReorderedY, ReorderedB);
719 rf->permuteReorderedToOriginal (ReorderedY, OverlappingY);
726template<
class MatrixType,
class LocalInverseType>
734 this->setParameterList (Teuchos::rcpFromRef (List_));
739template<
class MatrixType,
class LocalInverseType>
743 using Tpetra::CombineMode;
744 using Teuchos::ParameterEntry;
745 using Teuchos::ParameterEntryValidator;
746 using Teuchos::ParameterList;
749 using Teuchos::rcp_dynamic_cast;
750 using Teuchos::StringToIntegralParameterEntryValidator;
751 using Details::getParamTryingTypes;
752 const char prefix[] =
"Ifpack2::AdditiveSchwarz: ";
754 if (plist.is_null ()) {
757 this->setParameterList (rcp (
new ParameterList ()));
763 TEUCHOS_TEST_FOR_EXCEPTION(
764 plist.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
765 "setParameterList: plist is null. This should never happen, since the "
766 "method should have replaced a null input list with a nonnull empty list "
767 "by this point. Please report this bug to the Ifpack2 developers.");
788 const std::string cmParamName (
"schwarz: combine mode");
789 const ParameterEntry* cmEnt = plist->getEntryPtr (cmParamName);
790 if (cmEnt !=
nullptr) {
791 if (cmEnt->isType<CombineMode> ()) {
792 CombineMode_ = Teuchos::getValue<CombineMode> (*cmEnt);
794 else if (cmEnt->isType<
int> ()) {
795 const int cm = Teuchos::getValue<int> (*cmEnt);
796 CombineMode_ =
static_cast<CombineMode
> (cm);
798 else if (cmEnt->isType<std::string> ()) {
803 const ParameterEntry& validEntry =
805 RCP<const ParameterEntryValidator> v = validEntry.validator ();
806 using vs2e_type = StringToIntegralParameterEntryValidator<CombineMode>;
807 RCP<const vs2e_type> vs2e = rcp_dynamic_cast<const vs2e_type> (v,
true);
809 ParameterEntry& inputEntry = plist->getEntry (cmParamName);
814 if (strncmp(Teuchos::getValue<std::string>(inputEntry).c_str(),
"AVG",3) == 0) {
815 inputEntry.template setValue<std::string>(
"ADD");
818 CombineMode_ = vs2e->getIntegralValue (inputEntry, cmParamName);
825 if (plist->isParameter(
"subdomain solver name")) {
826 if (plist->get<std::string>(
"subdomain solver name") ==
"BLOCK_RELAXATION") {
827 if (plist->isSublist(
"subdomain solver parameters")) {
828 if (plist->sublist(
"subdomain solver parameters").isParameter(
"relaxation: type")) {
829 if (plist->sublist(
"subdomain solver parameters").get<std::string>(
"relaxation: type") ==
"Jacobi" ) {
830 if (plist->sublist(
"subdomain solver parameters").isParameter(
"partitioner: type")) {
831 if (plist->sublist(
"subdomain solver parameters").get<std::string>(
"partitioner: type") ==
"user") {
832 if (CombineMode_ == Tpetra::ADD) plist->sublist(
"subdomain solver parameters").set(
"partitioner: combine mode",
"ADD");
833 if (CombineMode_ == Tpetra::ZERO) plist->sublist(
"subdomain solver parameters").set(
"partitioner: combine mode",
"ZERO");
843 OverlapLevel_ = plist->get (
"schwarz: overlap level", OverlapLevel_);
849 UseReordering_ = plist->get (
"schwarz: use reordering", UseReordering_);
851#if !defined(HAVE_IFPACK2_XPETRA) || !defined(HAVE_IFPACK2_ZOLTAN2)
852 TEUCHOS_TEST_FOR_EXCEPTION(
853 UseReordering_, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::"
854 "setParameters: You specified \"schwarz: use reordering\" = true. "
855 "This is only valid when Trilinos was built with Ifpack2, Xpetra, and "
856 "Zoltan2 enabled. Either Xpetra or Zoltan2 was not enabled in your build "
868 FilterSingletons_ = plist->get (
"schwarz: filter singletons", FilterSingletons_);
871 getParamTryingTypes<scalar_type, scalar_type, double>
872 (UpdateDamping_, *plist,
"schwarz: update damping", prefix);
907 if (! Inverse_.is_null ()) {
910 if (hasInnerPrecName () && innerPrecName () !=
"CUSTOM") {
913 Inverse_ = Teuchos::null;
918 std::pair<ParameterList, bool> result = innerPrecParams ();
922 Inverse_->setParameters (rcp (
new ParameterList (result.first)));
927 NumIterations_ = plist->get (
"schwarz: num iterations", NumIterations_);
928 ZeroStartingSolution_ =
929 plist->get (
"schwarz: zero starting solution", ZeroStartingSolution_);
934template<
class MatrixType,
class LocalInverseType>
935Teuchos::RCP<const Teuchos::ParameterList>
939 using Teuchos::ParameterList;
940 using Teuchos::parameterList;
942 using Teuchos::rcp_const_cast;
944 if (validParams_.is_null ()) {
945 const int overlapLevel = 0;
946 const bool useReordering =
false;
947 const bool filterSingletons =
false;
948 const int numIterations = 1;
949 const bool zeroStartingSolution =
true;
950 const scalar_type updateDamping = Teuchos::ScalarTraits<scalar_type>::one ();
951 ParameterList reorderingSublist;
952 reorderingSublist.set (
"order_method", std::string (
"rcm"));
954 RCP<ParameterList> plist = parameterList (
"Ifpack2::AdditiveSchwarz");
956 Tpetra::setCombineModeParameter (*plist,
"schwarz: combine mode");
957 plist->set (
"schwarz: overlap level", overlapLevel);
958 plist->set (
"schwarz: use reordering", useReordering);
959 plist->set (
"schwarz: reordering list", reorderingSublist);
962 plist->set (
"schwarz: compute condest",
false);
963 plist->set (
"schwarz: filter singletons", filterSingletons);
964 plist->set (
"schwarz: num iterations", numIterations);
965 plist->set (
"schwarz: zero starting solution", zeroStartingSolution);
966 plist->set (
"schwarz: update damping", updateDamping);
976 validParams_ = rcp_const_cast<const ParameterList> (plist);
982template<
class MatrixType,
class LocalInverseType>
985 using Tpetra::global_size_t;
988 using Teuchos::SerialComm;
990 using Teuchos::TimeMonitor;
992 const std::string timerName (
"Ifpack2::AdditiveSchwarz::initialize");
993 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
994 if (timer.is_null ()) {
995 timer = TimeMonitor::getNewCounter (timerName);
997 double startTime = timer->wallTime();
1000 TimeMonitor timeMon (*timer);
1002 TEUCHOS_TEST_FOR_EXCEPTION(
1003 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1004 "initialize: The matrix to precondition is null. You must either pass "
1005 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
1006 "input, before you may call this method.");
1008 IsInitialized_ =
false;
1009 IsComputed_ =
false;
1010 overlapping_B_.reset (
nullptr);
1011 overlapping_Y_.reset (
nullptr);
1015 RCP<const Teuchos::Comm<int> > comm = Matrix_->getComm ();
1016 RCP<const map_type> rowMap = Matrix_->getRowMap ();
1017 const global_size_t INVALID =
1018 Teuchos::OrdinalTraits<global_size_t>::invalid ();
1022 if (comm->getSize () == 1) {
1024 IsOverlapping_ =
false;
1025 }
else if (OverlapLevel_ != 0) {
1026 IsOverlapping_ =
true;
1029 if (OverlapLevel_ == 0) {
1031 RCP<const SerialComm<int> > localComm (
new SerialComm<int> ());
1035 rcp (
new map_type (INVALID, rowMap->getLocalNumElements (),
1036 indexBase, localComm));
1040 if (IsOverlapping_) {
1041 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"OverlappingRowMatrix construction"));
1047 if (! Inverse_.is_null ()) {
1048 Inverse_->symbolic ();
1053 IsInitialized_ =
true;
1056 InitializeTime_ += (timer->wallTime() - startTime);
1059template<
class MatrixType,
class LocalInverseType>
1062 return IsInitialized_;
1066template<
class MatrixType,
class LocalInverseType>
1070 using Teuchos::Time;
1071 using Teuchos::TimeMonitor;
1073 if (! IsInitialized_) {
1077 TEUCHOS_TEST_FOR_EXCEPTION(
1078 ! isInitialized (), std::logic_error,
"Ifpack2::AdditiveSchwarz::compute: "
1079 "The preconditioner is not yet initialized, "
1080 "even though initialize() supposedly has been called. "
1081 "This should never happen. "
1082 "Please report this bug to the Ifpack2 developers.");
1084 TEUCHOS_TEST_FOR_EXCEPTION(
1085 Inverse_.is_null (), std::runtime_error,
1086 "Ifpack2::AdditiveSchwarz::compute: The subdomain solver is null. "
1087 "This can only happen if you called setInnerPreconditioner() with a null "
1088 "input, after calling initialize() or compute(). If you choose to call "
1089 "setInnerPreconditioner() with a null input, you must then call it with a "
1090 "nonnull input before you may call initialize() or compute().");
1092 const std::string timerName (
"Ifpack2::AdditiveSchwarz::compute");
1093 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
1094 if (timer.is_null ()) {
1095 timer = TimeMonitor::getNewCounter (timerName);
1097 TimeMonitor timeMon (*timer);
1098 double startTime = timer->wallTime();
1102 if (IsOverlapping_) {
1103 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Halo Import"));
1104 OverlappingMatrix_->doExtImport();
1109 if(
auto asf = Teuchos::rcp_dynamic_cast<Details::AdditiveSchwarzFilter<MatrixType>>(innerMatrix_))
1111 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Fill Local Matrix"));
1114 asf->updateMatrixValues();
1121 IsComputed_ =
false;
1122 Inverse_->numeric ();
1128 ComputeTime_ += (timer->wallTime() - startTime);
1133template<
class MatrixType,
class LocalInverseType>
1140template<
class MatrixType,
class LocalInverseType>
1143 return NumInitialize_;
1147template<
class MatrixType,
class LocalInverseType>
1154template<
class MatrixType,
class LocalInverseType>
1161template<
class MatrixType,
class LocalInverseType>
1164 return InitializeTime_;
1168template<
class MatrixType,
class LocalInverseType>
1171 return ComputeTime_;
1175template<
class MatrixType,
class LocalInverseType>
1182template<
class MatrixType,
class LocalInverseType>
1185 std::ostringstream out;
1187 out <<
"\"Ifpack2::AdditiveSchwarz\": {";
1188 if (this->getObjectLabel () !=
"") {
1189 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
1191 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false")
1192 <<
", Computed: " << (isComputed () ?
"true" :
"false")
1193 <<
", Iterations: " << NumIterations_
1194 <<
", Overlap level: " << OverlapLevel_
1195 <<
", Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"";
1196 out <<
", Combine mode: \"";
1197 if (CombineMode_ == Tpetra::INSERT) {
1199 }
else if (CombineMode_ == Tpetra::ADD) {
1201 }
else if (CombineMode_ == Tpetra::REPLACE) {
1203 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1205 }
else if (CombineMode_ == Tpetra::ZERO) {
1209 if (Matrix_.is_null ()) {
1210 out <<
", Matrix: null";
1213 out <<
", Global matrix dimensions: ["
1214 << Matrix_->getGlobalNumRows () <<
", "
1215 << Matrix_->getGlobalNumCols () <<
"]";
1217 out <<
", Inner solver: ";
1218 if (! Inverse_.is_null ()) {
1219 Teuchos::RCP<Teuchos::Describable> inv =
1220 Teuchos::rcp_dynamic_cast<Teuchos::Describable> (Inverse_);
1221 if (! inv.is_null ()) {
1222 out <<
"{" << inv->description () <<
"}";
1224 out <<
"{" <<
"Some inner solver" <<
"}";
1235template<
class MatrixType,
class LocalInverseType>
1238describe (Teuchos::FancyOStream& out,
1239 const Teuchos::EVerbosityLevel verbLevel)
const
1241 using Teuchos::OSTab;
1242 using Teuchos::TypeNameTraits;
1245 const int myRank = Matrix_->getComm ()->getRank ();
1246 const int numProcs = Matrix_->getComm ()->getSize ();
1247 const Teuchos::EVerbosityLevel vl =
1248 (verbLevel == Teuchos::VERB_DEFAULT) ? Teuchos::VERB_LOW : verbLevel;
1250 if (vl > Teuchos::VERB_NONE) {
1254 out <<
"\"Ifpack2::AdditiveSchwarz\":";
1258 out <<
"MatrixType: " << TypeNameTraits<MatrixType>::name () << endl;
1259 out <<
"LocalInverseType: " << TypeNameTraits<LocalInverseType>::name () << endl;
1260 if (this->getObjectLabel () !=
"") {
1261 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
1264 out <<
"Overlap level: " << OverlapLevel_ << endl
1265 <<
"Combine mode: \"";
1266 if (CombineMode_ == Tpetra::INSERT) {
1268 }
else if (CombineMode_ == Tpetra::ADD) {
1270 }
else if (CombineMode_ == Tpetra::REPLACE) {
1272 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1274 }
else if (CombineMode_ == Tpetra::ZERO) {
1278 <<
"Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"" << endl;
1281 if (Matrix_.is_null ()) {
1283 out <<
"Matrix: null" << endl;
1288 out <<
"Matrix:" << endl;
1291 Matrix_->getComm ()->barrier ();
1292 Matrix_->describe (out, Teuchos::VERB_LOW);
1296 out <<
"Number of initialize calls: " << getNumInitialize () << endl
1297 <<
"Number of compute calls: " << getNumCompute () << endl
1298 <<
"Number of apply calls: " << getNumApply () << endl
1299 <<
"Total time in seconds for initialize: " << getInitializeTime () << endl
1300 <<
"Total time in seconds for compute: " << getComputeTime () << endl
1301 <<
"Total time in seconds for apply: " << getApplyTime () << endl;
1304 if (Inverse_.is_null ()) {
1306 out <<
"Subdomain solver: null" << endl;
1310 if (vl < Teuchos::VERB_EXTREME) {
1312 out <<
"Subdomain solver: not null" << endl;
1316 for (
int p = 0; p < numProcs; ++p) {
1318 out <<
"Subdomain solver on Process " << myRank <<
":";
1319 if (Inverse_.is_null ()) {
1320 out <<
"null" << endl;
1322 Teuchos::RCP<Teuchos::Describable> inv =
1323 Teuchos::rcp_dynamic_cast<Teuchos::Describable> (Inverse_);
1324 if (! inv.is_null ()) {
1326 inv->describe (out, vl);
1328 out <<
"null" << endl;
1332 Matrix_->getComm ()->barrier ();
1333 Matrix_->getComm ()->barrier ();
1334 Matrix_->getComm ()->barrier ();
1339 Matrix_->getComm ()->barrier ();
1344template<
class MatrixType,
class LocalInverseType>
1347 Teuchos::FancyOStream fos(Teuchos::rcp(&os,
false));
1348 fos.setOutputToRootOnly(0);
1354template<
class MatrixType,
class LocalInverseType>
1357 return OverlapLevel_;
1361template<
class MatrixType,
class LocalInverseType>
1365 using Teuchos::MpiComm;
1367 using Teuchos::ArrayRCP;
1368 using Teuchos::ParameterList;
1371 using Teuchos::rcp_dynamic_cast;
1372 using Teuchos::rcpFromRef;
1374 TEUCHOS_TEST_FOR_EXCEPTION(
1375 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1376 "initialize: The matrix to precondition is null. You must either pass "
1377 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
1378 "input, before you may call this method.");
1382 auto matrixCrs = rcp_dynamic_cast<const crs_matrix_type>(Matrix_);
1383 if(!OverlappingMatrix_.is_null() || !matrixCrs.is_null())
1385 ArrayRCP<local_ordinal_type> perm;
1386 ArrayRCP<local_ordinal_type> revperm;
1387 if (UseReordering_) {
1388 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Reordering"));
1389#if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2)
1391 Teuchos::ParameterList zlist = List_.sublist (
"schwarz: reordering list");
1392 ReorderingAlgorithm_ = zlist.get<std::string> (
"order_method",
"rcm");
1394 if(ReorderingAlgorithm_ ==
"user") {
1396 perm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user ordering");
1397 revperm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user reverse ordering");
1401 typedef Tpetra::RowGraph
1402 <local_ordinal_type, global_ordinal_type, node_type> row_graph_type;
1403 typedef Zoltan2::TpetraRowGraphAdapter<row_graph_type> z2_adapter_type;
1404 auto constActiveGraph = Teuchos::rcp_const_cast<const row_graph_type>(
1405 IsOverlapping_ ? OverlappingMatrix_->getGraph() : Matrix_->getGraph());
1406 z2_adapter_type Zoltan2Graph (constActiveGraph);
1408 typedef Zoltan2::OrderingProblem<z2_adapter_type> ordering_problem_type;
1413 RCP<const MpiComm<int> > mpicomm =
1414 rcp_dynamic_cast<const MpiComm<int> > (Matrix_->getComm ());
1415 if (mpicomm == Teuchos::null) {
1416 myRawComm = MPI_COMM_SELF;
1418 myRawComm = * (mpicomm->getRawMpiComm ());
1420 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist, myRawComm);
1422 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist);
1424 MyOrderingProblem.solve ();
1427 typedef Zoltan2::LocalOrderingSolution<local_ordinal_type>
1428 ordering_solution_type;
1430 ordering_solution_type sol (*MyOrderingProblem.getLocalOrderingSolution());
1436 perm = sol.getPermutationRCPConst (
true);
1437 revperm = sol.getPermutationRCPConst ();
1443 TEUCHOS_TEST_FOR_EXCEPTION(
1444 true, std::logic_error,
"Ifpack2::AdditiveSchwarz::setup: "
1445 "The Zoltan2 and Xpetra packages must be enabled in order "
1446 "to support reordering.");
1451 local_ordinal_type numLocalRows = OverlappingMatrix_.is_null() ? matrixCrs->getLocalNumRows() : OverlappingMatrix_->getLocalNumRows();
1455 perm = ArrayRCP<local_ordinal_type>(numLocalRows);
1456 revperm = ArrayRCP<local_ordinal_type>(numLocalRows);
1457 for(local_ordinal_type i = 0; i < numLocalRows; i++)
1465 Teuchos::TimeMonitor t(*Teuchos::TimeMonitor::getNewTimer(
"Filter construction"));
1466 RCP<Details::AdditiveSchwarzFilter<MatrixType>> asf;
1467 if(OverlappingMatrix_.is_null())
1468 asf = rcp(
new Details::AdditiveSchwarzFilter<MatrixType>(matrixCrs, perm, revperm, FilterSingletons_));
1470 asf = rcp(
new Details::AdditiveSchwarzFilter<MatrixType>(OverlappingMatrix_, perm, revperm, FilterSingletons_));
1477 RCP<row_matrix_type> LocalizedMatrix;
1481 RCP<row_matrix_type> ActiveMatrix;
1484 if (! OverlappingMatrix_.is_null ()) {
1485 LocalizedMatrix = rcp (
new LocalFilter<row_matrix_type> (OverlappingMatrix_));
1488 LocalizedMatrix = rcp (
new LocalFilter<row_matrix_type> (Matrix_));
1492 TEUCHOS_TEST_FOR_EXCEPTION(
1493 LocalizedMatrix.is_null (), std::logic_error,
1494 "Ifpack2::AdditiveSchwarz::setup: LocalizedMatrix is null, after the code "
1495 "that claimed to have created it. This should never be the case. Please "
1496 "report this bug to the Ifpack2 developers.");
1499 ActiveMatrix = LocalizedMatrix;
1502 if (FilterSingletons_) {
1503 SingletonMatrix_ = rcp (
new SingletonFilter<row_matrix_type> (LocalizedMatrix));
1504 ActiveMatrix = SingletonMatrix_;
1508 if (UseReordering_) {
1509#if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2)
1511 typedef ReorderFilter<row_matrix_type> reorder_filter_type;
1512 Teuchos::ParameterList zlist = List_.sublist (
"schwarz: reordering list");
1513 ReorderingAlgorithm_ = zlist.get<std::string> (
"order_method",
"rcm");
1515 ArrayRCP<local_ordinal_type> perm;
1516 ArrayRCP<local_ordinal_type> revperm;
1518 if(ReorderingAlgorithm_ ==
"user") {
1520 perm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user ordering");
1521 revperm = zlist.get<Teuchos::ArrayRCP<local_ordinal_type> >(
"user reverse ordering");
1525 typedef Tpetra::RowGraph
1526 <local_ordinal_type, global_ordinal_type, node_type> row_graph_type;
1527 typedef Zoltan2::TpetraRowGraphAdapter<row_graph_type> z2_adapter_type;
1528 RCP<const row_graph_type> constActiveGraph =
1529 Teuchos::rcp_const_cast<const row_graph_type>(ActiveMatrix->getGraph());
1530 z2_adapter_type Zoltan2Graph (constActiveGraph);
1532 typedef Zoltan2::OrderingProblem<z2_adapter_type> ordering_problem_type;
1537 RCP<const MpiComm<int> > mpicomm =
1538 rcp_dynamic_cast<const MpiComm<int> > (ActiveMatrix->getComm ());
1539 if (mpicomm == Teuchos::null) {
1540 myRawComm = MPI_COMM_SELF;
1542 myRawComm = * (mpicomm->getRawMpiComm ());
1544 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist, myRawComm);
1546 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist);
1548 MyOrderingProblem.solve ();
1551 typedef Zoltan2::LocalOrderingSolution<local_ordinal_type>
1552 ordering_solution_type;
1554 ordering_solution_type sol (*MyOrderingProblem.getLocalOrderingSolution());
1560 perm = sol.getPermutationRCPConst (
true);
1561 revperm = sol.getPermutationRCPConst ();
1565 ReorderedLocalizedMatrix_ = rcp (
new reorder_filter_type (ActiveMatrix, perm, revperm));
1568 ActiveMatrix = ReorderedLocalizedMatrix_;
1572 TEUCHOS_TEST_FOR_EXCEPTION(
1573 true, std::logic_error,
"Ifpack2::AdditiveSchwarz::setup: "
1574 "The Zoltan2 and Xpetra packages must be enabled in order "
1575 "to support reordering.");
1578 innerMatrix_ = ActiveMatrix;
1581 TEUCHOS_TEST_FOR_EXCEPTION(
1582 innerMatrix_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
1583 "setup: Inner matrix is null right before constructing inner solver. "
1584 "Please report this bug to the Ifpack2 developers.");
1587 if (Inverse_.is_null ()) {
1588 const std::string innerName = innerPrecName ();
1589 TEUCHOS_TEST_FOR_EXCEPTION(
1590 innerName ==
"INVALID", std::logic_error,
1591 "Ifpack2::AdditiveSchwarz::initialize: AdditiveSchwarz doesn't "
1592 "know how to create an instance of your LocalInverseType \""
1593 << Teuchos::TypeNameTraits<LocalInverseType>::name () <<
"\". "
1594 "Please talk to the Ifpack2 developers for details.");
1596 TEUCHOS_TEST_FOR_EXCEPTION(
1597 innerName ==
"CUSTOM", std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1598 "initialize: If the \"inner preconditioner name\" parameter (or any "
1599 "alias thereof) has the value \"CUSTOM\", then you must first call "
1600 "setInnerPreconditioner with a nonnull inner preconditioner input before "
1601 "you may call initialize().");
1605 if (! Trilinos::Details::Impl::registeredSomeLinearSolverFactory (
"Ifpack2")) {
1611 typedef typename MV::mag_type MT;
1612 RCP<inner_solver_type> innerPrec =
1613 Trilinos::Details::getLinearSolver<MV, OP, MT> (
"Ifpack2", innerName);
1614 TEUCHOS_TEST_FOR_EXCEPTION(
1615 innerPrec.is_null (), std::logic_error,
1616 "Ifpack2::AdditiveSchwarz::setup: Failed to create inner preconditioner "
1617 "with name \"" << innerName <<
"\".");
1618 innerPrec->setMatrix (innerMatrix_);
1622 std::pair<Teuchos::ParameterList, bool> result = innerPrecParams ();
1623 if (result.second) {
1626 innerPrec->setParameters (rcp (
new ParameterList (result.first)));
1628 Inverse_ = innerPrec;
1630 else if (Inverse_->getMatrix ().getRawPtr () != innerMatrix_.getRawPtr ()) {
1634 Inverse_->setMatrix (innerMatrix_);
1636 TEUCHOS_TEST_FOR_EXCEPTION(
1637 Inverse_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
1638 "setup: Inverse_ is null right after we were supposed to have created it."
1639 " Please report this bug to the Ifpack2 developers.");
1649template<
class MatrixType,
class LocalInverseType>
1656 if (! innerPrec.is_null ()) {
1659 can_change_type* innerSolver =
dynamic_cast<can_change_type*
> (&*innerPrec);
1660 TEUCHOS_TEST_FOR_EXCEPTION(
1661 innerSolver == NULL, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::"
1662 "setInnerPreconditioner: The input preconditioner does not implement the "
1663 "setMatrix() feature. Only input preconditioners that inherit from "
1664 "Ifpack2::Details::CanChangeMatrix implement this feature.");
1681 if(
auto asf = Teuchos::rcp_dynamic_cast<Details::AdditiveSchwarzFilter<MatrixType>>(innerMatrix_))
1682 innerSolver->setMatrix (asf->getFilteredMatrix());
1684 innerSolver->setMatrix (innerMatrix_);
1694 removeInnerPrecName ();
1695 removeInnerPrecParams ();
1696 List_.set (
"inner preconditioner name",
"CUSTOM");
1700 if (isInitialized ()) {
1701 innerPrec->initialize ();
1703 if (isComputed ()) {
1704 innerPrec->compute ();
1717 Inverse_ = Teuchos::rcp (
new inner_solver_impl_type (innerPrec,
"CUSTOM"));
1720template<
class MatrixType,
class LocalInverseType>
1722setMatrix (
const Teuchos::RCP<const row_matrix_type>& A)
1725 if (A.getRawPtr () != Matrix_.getRawPtr ()) {
1726 IsInitialized_ =
false;
1727 IsComputed_ =
false;
1730 OverlappingMatrix_ = Teuchos::null;
1731 ReorderedLocalizedMatrix_ = Teuchos::null;
1732 innerMatrix_ = Teuchos::null;
1733 SingletonMatrix_ = Teuchos::null;
1734 localMap_ = Teuchos::null;
1735 overlapping_B_.reset (
nullptr);
1736 overlapping_Y_.reset (
nullptr);
1739 DistributedImporter_ = Teuchos::null;
1750#define IFPACK2_ADDITIVESCHWARZ_INSTANT(S,LO,GO,N) \
1751 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:1183
virtual bool isInitialized() const
Returns true if the preconditioner has been successfully initialized, false otherwise.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1060
virtual int getOverlapLevel() const
Returns the level of overlap.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1355
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Get a list of the preconditioner's default parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:937
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:1148
virtual int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1155
virtual double getComputeTime() const
Returns the time spent in compute().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1169
virtual double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1176
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1722
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:983
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
Set the preconditioner's parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:741
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:1651
virtual double getInitializeTime() const
Returns the time spent in initialize().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1162
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:273
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:260
virtual void compute()
Computes all (coefficient) data necessary to apply the preconditioner.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1067
virtual std::ostream & print(std::ostream &os) const
Prints basic information on iostream. This function is used by operator<<.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1345
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:1238
virtual void setParameters(const Teuchos::ParameterList &plist)
Set the preconditioner's parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:728
virtual Teuchos::RCP< const row_matrix_type > getMatrix() const
The input matrix.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:285
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:294
virtual bool isComputed() const
Returns true if the preconditioner has been successfully computed, false otherwise.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1134
virtual int getNumInitialize() const
Returns the number of calls to initialize().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1141
AdditiveSchwarz(const Teuchos::RCP< const row_matrix_type > &A)
Constructor that takes a matrix.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:245
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
Sparse matrix (Tpetra::RowMatrix subclass) with ghost rows.
Definition: Ifpack2_OverlappingRowMatrix_decl.hpp:59
Interface for all Ifpack2 preconditioners.
Definition: Ifpack2_Preconditioner.hpp:108
void registerLinearSolverFactory()
Ifpack2 implementation details.
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