55 #ifndef IFPACK2_ADDITIVESCHWARZ_DEF_HPP
56 #define IFPACK2_ADDITIVESCHWARZ_DEF_HPP
62 #include "Ifpack2_Details_LinearSolver.hpp"
64 #if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2)
65 #include "Zoltan2_TpetraRowGraphAdapter.hpp"
66 #include "Zoltan2_OrderingProblem.hpp"
67 #include "Zoltan2_OrderingSolution.hpp"
71 #include "Ifpack2_LocalFilter.hpp"
72 #include "Ifpack2_OverlappingRowMatrix.hpp"
73 #include "Ifpack2_Parameters.hpp"
74 #include "Ifpack2_ReorderFilter.hpp"
75 #include "Ifpack2_SingletonFilter.hpp"
81 #include "Teuchos_StandardParameterEntryValidators.hpp"
98 template<
class MatrixType,
class LocalInverseType>
100 AdditiveSchwarz<MatrixType, LocalInverseType>::hasInnerPrecName ()
const
102 const char* options[4] = {
103 "inner preconditioner name",
104 "subdomain solver name",
105 "schwarz: inner preconditioner name",
106 "schwarz: subdomain solver name"
108 const int numOptions = 4;
110 for (
int k = 0; k < numOptions && ! match; ++k) {
111 if (List_.isParameter (options[k])) {
119 template<
class MatrixType,
class LocalInverseType>
121 AdditiveSchwarz<MatrixType, LocalInverseType>::removeInnerPrecName ()
123 const char* options[4] = {
124 "inner preconditioner name",
125 "subdomain solver name",
126 "schwarz: inner preconditioner name",
127 "schwarz: subdomain solver name"
129 const int numOptions = 4;
130 for (
int k = 0; k < numOptions; ++k) {
131 List_.remove (options[k],
false);
136 template<
class MatrixType,
class LocalInverseType>
138 AdditiveSchwarz<MatrixType, LocalInverseType>::innerPrecName ()
const
140 const char* options[4] = {
141 "inner preconditioner name",
142 "subdomain solver name",
143 "schwarz: inner preconditioner name",
144 "schwarz: subdomain solver name"
146 const int numOptions = 4;
151 for (
int k = 0; k < numOptions && ! match; ++k) {
152 if (List_.isParameter (options[k])) {
158 newName = List_.get<std::string> (options[k]);
163 return match ? newName : defaultInnerPrecName ();
167 template<
class MatrixType,
class LocalInverseType>
169 AdditiveSchwarz<MatrixType, LocalInverseType>::removeInnerPrecParams ()
171 const char* options[4] = {
172 "inner preconditioner parameters",
173 "subdomain solver parameters",
174 "schwarz: inner preconditioner parameters",
175 "schwarz: subdomain solver parameters"
177 const int numOptions = 4;
180 for (
int k = 0; k < numOptions; ++k) {
181 List_.remove (options[k],
false);
186 template<
class MatrixType,
class LocalInverseType>
187 std::pair<Teuchos::ParameterList, bool>
188 AdditiveSchwarz<MatrixType, LocalInverseType>::innerPrecParams ()
const
190 const char* options[4] = {
191 "inner preconditioner parameters",
192 "subdomain solver parameters",
193 "schwarz: inner preconditioner parameters",
194 "schwarz: subdomain solver parameters"
196 const int numOptions = 4;
201 for (
int k = 0; k < numOptions && ! match; ++k) {
202 if (List_.isSublist (options[k])) {
203 params = List_.
sublist (options[k]);
208 return std::make_pair (params, match);
212 template<
class MatrixType,
class LocalInverseType>
214 AdditiveSchwarz<MatrixType, LocalInverseType>::defaultInnerPrecName ()
222 template<
class MatrixType,
class LocalInverseType>
226 IsInitialized_ (false),
228 IsOverlapping_ (false),
230 CombineMode_ (Tpetra::ZERO),
231 UseReordering_ (false),
232 ReorderingAlgorithm_ (
"none"),
233 FilterSingletons_ (false),
235 ZeroStartingSolution_(true),
236 UpdateDamping_(Teuchos::ScalarTraits<
scalar_type>::one()),
240 InitializeTime_ (0.0),
248 template<
class MatrixType,
class LocalInverseType>
251 const int overlapLevel) :
253 IsInitialized_ (false),
255 IsOverlapping_ (false),
256 OverlapLevel_ (overlapLevel),
257 CombineMode_ (Tpetra::ZERO),
258 UseReordering_ (false),
259 ReorderingAlgorithm_ (
"none"),
260 FilterSingletons_ (false),
262 ZeroStartingSolution_(true),
263 UpdateDamping_(Teuchos::ScalarTraits<
scalar_type>::one()),
267 InitializeTime_ (0.0),
276 template<
class MatrixType,
class LocalInverseType>
280 template<
class MatrixType,
class LocalInverseType>
285 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
286 "getDomainMap: The matrix to precondition is null. You must either pass "
287 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
288 "input, before you may call this method.");
289 return Matrix_->getDomainMap ();
293 template<
class MatrixType,
class LocalInverseType>
298 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
299 "getRangeMap: The matrix to precondition is null. You must either pass "
300 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
301 "input, before you may call this method.");
302 return Matrix_->getRangeMap ();
306 template<
class MatrixType,
class LocalInverseType>
313 template<
class MatrixType,
class LocalInverseType>
316 apply (
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,
326 using Teuchos::rcp_dynamic_cast;
328 const char prefix[] =
"Ifpack2::AdditiveSchwarz::apply: ";
331 (! IsComputed_, std::runtime_error,
332 prefix <<
"isComputed() must be true before you may call apply().");
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.");
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().");
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() <<
".");
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.");
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.");
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
375 for (
size_t j = 0; j < B.getNumVectors (); ++j) {
376 if (STM::isnaninf (norms[j])) {
381 TEUCHOS_TEST_FOR_EXCEPTION
382 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
383 "The 2-norm of the input B is NaN or Inf.");
385 #endif // HAVE_IFPACK2_DEBUG
387 #ifdef HAVE_IFPACK2_DEBUG
388 if (! ZeroStartingSolution_) {
394 for (
size_t j = 0; j < Y.getNumVectors (); ++j) {
395 if (STM::isnaninf (norms[j])) {
400 TEUCHOS_TEST_FOR_EXCEPTION
401 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
402 "On input, the initial guess Y has 2-norm NaN or Inf "
403 "(ZeroStartingSolution_ is false).");
405 #endif // HAVE_IFPACK2_DEBUG
407 const std::string timerName (
"Ifpack2::AdditiveSchwarz::apply");
408 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
409 if (timer.is_null ()) {
410 timer = TimeMonitor::getNewCounter (timerName);
414 TimeMonitor timeMon (*timer);
418 const size_t numVectors = B.getNumVectors ();
422 if (ZeroStartingSolution_) {
427 RCP<MV> OverlappingB,OverlappingY;
428 RCP<MV> globalOverlappingB;
429 if (IsOverlapping_) {
431 OverlappingB =
rcp (
new MV (OverlappingMatrix_->getRowMap (), numVectors));
432 OverlappingY =
rcp (
new MV (OverlappingMatrix_->getRowMap (), numVectors));
441 OverlappingB =
rcp (
new MV (localMap_, numVectors));
442 OverlappingY =
rcp (
new MV (localMap_, numVectors));
445 OverlappingB->offsetViewNonConst (Matrix_->getRowMap (), 0);
448 if (DistributedImporter_.is_null ()) {
452 DistributedImporter_ =
453 rcp (
new import_type (Matrix_->getRowMap (),
454 Matrix_->getDomainMap ()));
458 RCP<MV> R =
rcp(
new MV(B.getMap(),numVectors));
459 RCP<MV> C =
rcp(
new MV(Y.getMap(),numVectors));
461 for (
int ni=0; ni<NumIterations_; ++ni)
463 #ifdef HAVE_IFPACK2_DEBUG
471 j < Y.getNumVectors (); ++j) {
472 if (STM::isnaninf (norms[j])) {
477 TEUCHOS_TEST_FOR_EXCEPTION
478 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
479 "At top of iteration " << ni <<
", the 2-norm of Y is NaN or Inf.");
481 #endif // HAVE_IFPACK2_DEBUG
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
499 for (
size_t j = 0; j < R->getNumVectors (); ++j) {
500 if (STM::isnaninf (norms[j])) {
505 TEUCHOS_TEST_FOR_EXCEPTION
506 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
507 "At iteration " << ni <<
", the 2-norm of R (result of computing "
508 "residual with Y) is NaN or Inf.");
510 #endif // HAVE_IFPACK2_DEBUG
514 RCP<overlap_mat_type> overlapMatrix;
515 if (IsOverlapping_) {
516 overlapMatrix = rcp_dynamic_cast<overlap_mat_type> (OverlappingMatrix_);
517 TEUCHOS_TEST_FOR_EXCEPTION
518 (overlapMatrix.is_null (), std::logic_error, prefix <<
519 "IsOverlapping_ is true, but OverlappingMatrix_, while nonnull, is "
520 "not an OverlappingRowMatrix<row_matrix_type>. Please report this "
521 "bug to the Ifpack2 developers.");
525 if (IsOverlapping_) {
526 TEUCHOS_TEST_FOR_EXCEPTION
527 (overlapMatrix.is_null (), std::logic_error, prefix
528 <<
"overlapMatrix is null when it shouldn't be. "
529 "Please report this bug to the Ifpack2 developers.");
530 overlapMatrix->importMultiVector (*R, *OverlappingB, Tpetra::INSERT);
547 #ifdef HAVE_IFPACK2_DEBUG
552 OverlappingB->norm2 (norms ());
555 j < OverlappingB->getNumVectors (); ++j) {
556 if (STM::isnaninf (norms[j])) {
561 TEUCHOS_TEST_FOR_EXCEPTION
562 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
563 "At iteration " << ni <<
", result of importMultiVector from R "
564 "to OverlappingB, has 2-norm NaN or Inf.");
566 #endif // HAVE_IFPACK2_DEBUG
568 globalOverlappingB->doImport (*R, *DistributedImporter_, Tpetra::INSERT);
570 #ifdef HAVE_IFPACK2_DEBUG
575 globalOverlappingB->norm2 (norms ());
578 j < globalOverlappingB->getNumVectors (); ++j) {
579 if (STM::isnaninf (norms[j])) {
584 TEUCHOS_TEST_FOR_EXCEPTION
585 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
586 "At iteration " << ni <<
", result of doImport from R, has 2-norm "
589 #endif // HAVE_IFPACK2_DEBUG
592 #ifdef HAVE_IFPACK2_DEBUG
597 OverlappingB->norm2 (norms ());
600 j < OverlappingB->getNumVectors (); ++j) {
601 if (STM::isnaninf (norms[j])) {
606 TEUCHOS_TEST_FOR_EXCEPTION
607 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
608 "At iteration " << ni <<
", right before localApply, the 2-norm of "
609 "OverlappingB is NaN or Inf.");
611 #endif // HAVE_IFPACK2_DEBUG
614 localApply(*OverlappingB, *OverlappingY);
616 #ifdef HAVE_IFPACK2_DEBUG
621 OverlappingY->norm2 (norms ());
624 j < OverlappingY->getNumVectors (); ++j) {
625 if (STM::isnaninf (norms[j])) {
630 TEUCHOS_TEST_FOR_EXCEPTION
631 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
632 "At iteration " << ni <<
", after localApply and before export / "
633 "copy, the 2-norm of OverlappingY is NaN or Inf.");
635 #endif // HAVE_IFPACK2_DEBUG
637 #ifdef HAVE_IFPACK2_DEBUG
645 j < C->getNumVectors (); ++j) {
646 if (STM::isnaninf (norms[j])) {
651 TEUCHOS_TEST_FOR_EXCEPTION
652 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
653 "At iteration " << ni <<
", before export / copy, the 2-norm of C "
656 #endif // HAVE_IFPACK2_DEBUG
659 if (IsOverlapping_) {
660 TEUCHOS_TEST_FOR_EXCEPTION
661 (overlapMatrix.is_null (), std::logic_error, prefix
662 <<
"overlapMatrix is null when it shouldn't be. "
663 "Please report this bug to the Ifpack2 developers.");
664 overlapMatrix->exportMultiVector (*OverlappingY, *C, CombineMode_);
673 RCP<MV> C_view = C->offsetViewNonConst (OverlappingY->getMap (), 0);
674 Tpetra::deep_copy (*C_view, *OverlappingY);
677 #ifdef HAVE_IFPACK2_DEBUG
685 j < C->getNumVectors (); ++j) {
686 if (STM::isnaninf (norms[j])) {
691 TEUCHOS_TEST_FOR_EXCEPTION
692 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
693 "At iteration " << ni <<
", before Y := C + Y, the 2-norm of C "
696 #endif // HAVE_IFPACK2_DEBUG
698 #ifdef HAVE_IFPACK2_DEBUG
706 j < Y.getNumVectors (); ++j) {
707 if (STM::isnaninf (norms[j])) {
712 TEUCHOS_TEST_FOR_EXCEPTION
713 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
714 "Before Y := C + Y, at iteration " << ni <<
", the 2-norm of Y "
717 #endif // HAVE_IFPACK2_DEBUG
719 Y.update(UpdateDamping_, *C, STS::one());
721 #ifdef HAVE_IFPACK2_DEBUG
728 for (
size_t j = 0; j < Y.getNumVectors (); ++j) {
729 if (STM::isnaninf (norms[j])) {
734 TEUCHOS_TEST_FOR_EXCEPTION
735 ( ! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
736 "At iteration " << ni <<
", after Y := C + Y, the 2-norm of Y "
739 #endif // HAVE_IFPACK2_DEBUG
744 #ifdef HAVE_IFPACK2_DEBUG
751 for (
size_t j = 0; j < Y.getNumVectors (); ++j) {
752 if (STM::isnaninf (norms[j])) {
757 TEUCHOS_TEST_FOR_EXCEPTION
758 ( ! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: "
759 "The 2-norm of the output Y is NaN or Inf.");
761 #endif // HAVE_IFPACK2_DEBUG
767 ApplyTime_ = timer->totalElapsedTime ();
770 template<
class MatrixType,
class LocalInverseType>
773 localApply(MV &OverlappingB, MV &OverlappingY)
const
776 using Teuchos::rcp_dynamic_cast;
778 const size_t numVectors = OverlappingB.getNumVectors ();
779 if (FilterSingletons_) {
781 MV ReducedB (SingletonMatrix_->getRowMap (), numVectors);
782 MV ReducedY (SingletonMatrix_->getRowMap (), numVectors);
784 RCP<SingletonFilter<row_matrix_type> > singletonFilter =
787 (! SingletonMatrix_.is_null () && singletonFilter.is_null (),
788 std::logic_error,
"Ifpack2::AdditiveSchwarz::localApply: "
789 "SingletonFilter_ is nonnull but is not a SingletonFilter"
790 "<row_matrix_type>. This should never happen. Please report this bug "
791 "to the Ifpack2 developers.");
792 singletonFilter->SolveSingletons (OverlappingB, OverlappingY);
793 singletonFilter->CreateReducedRHS (OverlappingY, OverlappingB, ReducedB);
796 if (! UseReordering_) {
797 Inverse_->solve (ReducedY, ReducedB);
800 RCP<ReorderFilter<row_matrix_type> > rf =
801 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
803 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
804 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is "
805 "nonnull but is not a ReorderFilter<row_matrix_type>. This should "
806 "never happen. Please report this bug to the Ifpack2 developers.");
809 rf->permuteOriginalToReordered (ReducedB, ReorderedB);
810 Inverse_->solve (ReorderedY, ReorderedB);
811 rf->permuteReorderedToOriginal (ReorderedY, ReducedY);
815 singletonFilter->UpdateLHS (ReducedY, OverlappingY);
820 if (! UseReordering_) {
821 Inverse_->solve (OverlappingY, OverlappingB);
827 RCP<ReorderFilter<row_matrix_type> > rf =
828 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
830 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
831 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is "
832 "nonnull but is not a ReorderFilter<row_matrix_type>. This should "
833 "never happen. Please report this bug to the Ifpack2 developers.");
834 rf->permuteOriginalToReordered (OverlappingB, ReorderedB);
835 Inverse_->solve (ReorderedY, ReorderedB);
836 rf->permuteReorderedToOriginal (ReorderedY, OverlappingY);
842 template<
class MatrixType,
class LocalInverseType>
850 this->setParameterList (Teuchos::rcpFromRef (List_));
855 template<
class MatrixType,
class LocalInverseType>
859 using Tpetra::CombineMode;
860 using Teuchos::getIntegralValue;
866 using Teuchos::rcp_dynamic_cast;
872 this->setParameterList (
rcp (
new ParameterList ()));
879 plist.
is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
880 "setParameterList: plist is null. This should never happen, since the "
881 "method should have replaced a null input list with a nonnull empty list "
882 "by this point. Please report this bug to the Ifpack2 developers.");
903 bool gotCombineMode =
false;
905 CombineMode_ = getIntegralValue<Tpetra::CombineMode> (List_,
"schwarz: combine mode");
906 gotCombineMode =
true;
911 gotCombineMode =
true;
920 if (! gotCombineMode) {
922 CombineMode_ = plist->
get (
"schwarz: combine mode", CombineMode_);
923 gotCombineMode =
true;
931 if (! gotCombineMode) {
932 const ParameterEntry& validEntry =
934 RCP<const ParameterEntryValidator> v = validEntry.validator ();
935 typedef StringToIntegralParameterEntryValidator<CombineMode> vs2e_type;
936 RCP<const vs2e_type> vs2e = rcp_dynamic_cast<
const vs2e_type> (v,
true);
938 const ParameterEntry& inputEntry = plist->
getEntry (
"schwarz: combine mode");
939 CombineMode_ = vs2e->getIntegralValue (inputEntry,
"schwarz: combine mode");
940 gotCombineMode =
true;
942 (void) gotCombineMode;
944 OverlapLevel_ = plist->
get (
"schwarz: overlap level", OverlapLevel_);
950 UseReordering_ = plist->
get (
"schwarz: use reordering", UseReordering_);
952 #if !defined(HAVE_IFPACK2_XPETRA) || !defined(HAVE_IFPACK2_ZOLTAN2)
954 UseReordering_, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::"
955 "setParameters: You specified \"schwarz: use reordering\" = true. "
956 "This is only valid when Trilinos was built with Ifpack2, Xpetra, and "
957 "Zoltan2 enabled. Either Xpetra or Zoltan2 was not enabled in your build "
969 FilterSingletons_ = plist->
get (
"schwarz: filter singletons", FilterSingletons_);
972 UpdateDamping_ = Teuchos::as<scalar_type>(plist->
get(
"schwarz: update damping",UpdateDamping_));
1007 if (! Inverse_.is_null ()) {
1010 if (hasInnerPrecName () && innerPrecName () !=
"CUSTOM") {
1013 Inverse_ = Teuchos::null;
1018 std::pair<Teuchos::ParameterList, bool> result = innerPrecParams ();
1019 if (result.second) {
1022 Inverse_->setParameters (
rcp (
new ParameterList (result.first)));
1027 NumIterations_ = plist->
get<
int>(
"schwarz: num iterations", NumIterations_);
1028 ZeroStartingSolution_ = plist->
get<
bool>(
"schwarz: zero starting solution", ZeroStartingSolution_);
1033 template<
class MatrixType,
class LocalInverseType>
1039 using Teuchos::parameterList;
1041 using Teuchos::rcp_const_cast;
1043 if (validParams_.is_null ()) {
1044 const int overlapLevel = 0;
1045 const bool useReordering =
false;
1046 const bool filterSingletons =
false;
1047 const int numIterations = 1;
1048 const bool zeroStartingSolution =
true;
1049 const double updateDamping = 1;
1050 ParameterList reorderingSublist;
1051 reorderingSublist.set (
"order_method", std::string (
"rcm"));
1053 RCP<ParameterList> plist = parameterList (
"Ifpack2::AdditiveSchwarz");
1055 Tpetra::setCombineModeParameter (*plist,
"schwarz: combine mode");
1056 plist->set (
"schwarz: overlap level", overlapLevel);
1057 plist->set (
"schwarz: use reordering", useReordering);
1058 plist->set (
"schwarz: reordering list", reorderingSublist);
1061 plist->set (
"schwarz: compute condest",
false);
1062 plist->set (
"schwarz: filter singletons", filterSingletons);
1063 plist->set (
"schwarz: num iterations", numIterations);
1064 plist->set (
"schwarz: zero starting solution", zeroStartingSolution);
1065 plist->set (
"schwarz: update damping", updateDamping);
1075 validParams_ = rcp_const_cast<
const ParameterList> (plist);
1077 return validParams_;
1081 template<
class MatrixType,
class LocalInverseType>
1084 using Tpetra::global_size_t;
1091 const std::string timerName (
"Ifpack2::AdditiveSchwarz::initialize");
1092 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
1093 if (timer.is_null ()) {
1094 timer = TimeMonitor::getNewCounter (timerName);
1098 TimeMonitor timeMon (*timer);
1101 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1102 "initialize: The matrix to precondition is null. You must either pass "
1103 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
1104 "input, before you may call this method.");
1106 IsInitialized_ =
false;
1107 IsComputed_ =
false;
1109 RCP<const Teuchos::Comm<int> > comm = Matrix_->getComm ();
1110 RCP<const map_type> rowMap = Matrix_->getRowMap ();
1111 const global_size_t INVALID =
1116 if (comm->getSize () == 1) {
1118 IsOverlapping_ =
false;
1119 }
else if (OverlapLevel_ != 0) {
1120 IsOverlapping_ =
true;
1123 if (OverlapLevel_ == 0) {
1125 RCP<const SerialComm<int> > localComm (
new SerialComm<int> ());
1129 rcp (
new map_type (INVALID, rowMap->getNodeNumElements (),
1130 indexBase, localComm));
1134 if (IsOverlapping_) {
1140 if (! Inverse_.is_null ()) {
1141 Inverse_->symbolic ();
1146 IsInitialized_ =
true;
1151 InitializeTime_ = timer->totalElapsedTime ();
1155 template<
class MatrixType,
class LocalInverseType>
1158 return IsInitialized_;
1162 template<
class MatrixType,
class LocalInverseType>
1169 if (! IsInitialized_) {
1174 ! isInitialized (), std::logic_error,
"Ifpack2::AdditiveSchwarz::compute: "
1175 "The preconditioner is not yet initialized, "
1176 "even though initialize() supposedly has been called. "
1177 "This should never happen. "
1178 "Please report this bug to the Ifpack2 developers.");
1181 Inverse_.is_null (), std::runtime_error,
1182 "Ifpack2::AdditiveSchwarz::compute: The subdomain solver is null. "
1183 "This can only happen if you called setInnerPreconditioner() with a null "
1184 "input, after calling initialize() or compute(). If you choose to call "
1185 "setInnerPreconditioner() with a null input, you must then call it with a "
1186 "nonnull input before you may call initialize() or compute().");
1188 const std::string timerName (
"Ifpack2::AdditiveSchwarz::compute");
1189 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
1190 if (timer.is_null ()) {
1191 timer = TimeMonitor::getNewCounter (timerName);
1195 TimeMonitor timeMon (*timer);
1197 IsComputed_ =
false;
1198 Inverse_->numeric ();
1206 ComputeTime_ = timer->totalElapsedTime ();
1211 template<
class MatrixType,
class LocalInverseType>
1218 template<
class MatrixType,
class LocalInverseType>
1221 return NumInitialize_;
1225 template<
class MatrixType,
class LocalInverseType>
1232 template<
class MatrixType,
class LocalInverseType>
1239 template<
class MatrixType,
class LocalInverseType>
1242 return InitializeTime_;
1246 template<
class MatrixType,
class LocalInverseType>
1249 return ComputeTime_;
1253 template<
class MatrixType,
class LocalInverseType>
1260 template<
class MatrixType,
class LocalInverseType>
1263 std::ostringstream out;
1265 out <<
"\"Ifpack2::AdditiveSchwarz\": {";
1266 if (this->getObjectLabel () !=
"") {
1267 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
1269 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false")
1270 <<
", Computed: " << (isComputed () ?
"true" :
"false")
1271 <<
", Iterations: " << NumIterations_
1272 <<
", Overlap level: " << OverlapLevel_
1273 <<
", Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"";
1274 out <<
", Combine mode: \"";
1275 if (CombineMode_ == Tpetra::INSERT) {
1277 }
else if (CombineMode_ == Tpetra::ADD) {
1279 }
else if (CombineMode_ == Tpetra::REPLACE) {
1281 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1283 }
else if (CombineMode_ == Tpetra::ZERO) {
1287 if (Matrix_.is_null ()) {
1288 out <<
", Matrix: null";
1291 out <<
", Global matrix dimensions: ["
1292 << Matrix_->getGlobalNumRows () <<
", "
1293 << Matrix_->getGlobalNumCols () <<
"]";
1295 out <<
", Inner solver: ";
1296 if (! Inverse_.is_null ()) {
1302 out <<
"{" <<
"Some inner solver" <<
"}";
1313 template<
class MatrixType,
class LocalInverseType>
1323 const int myRank = Matrix_->getComm ()->getRank ();
1324 const int numProcs = Matrix_->getComm ()->getSize ();
1332 out <<
"\"Ifpack2::AdditiveSchwarz\":";
1336 out <<
"MatrixType: " << TypeNameTraits<MatrixType>::name () << endl;
1337 out <<
"LocalInverseType: " << TypeNameTraits<LocalInverseType>::name () << endl;
1338 if (this->getObjectLabel () !=
"") {
1339 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
1342 out <<
"Overlap level: " << OverlapLevel_ << endl
1343 <<
"Combine mode: \"";
1344 if (CombineMode_ == Tpetra::INSERT) {
1346 }
else if (CombineMode_ == Tpetra::ADD) {
1348 }
else if (CombineMode_ == Tpetra::REPLACE) {
1350 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1352 }
else if (CombineMode_ == Tpetra::ZERO) {
1356 <<
"Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"" << endl;
1359 if (Matrix_.is_null ()) {
1361 out <<
"Matrix: null" << endl;
1366 out <<
"Matrix:" << endl;
1369 Matrix_->getComm ()->barrier ();
1374 out <<
"Number of initialize calls: " << getNumInitialize () << endl
1375 <<
"Number of compute calls: " << getNumCompute () << endl
1376 <<
"Number of apply calls: " << getNumApply () << endl
1377 <<
"Total time in seconds for initialize: " << getInitializeTime () << endl
1378 <<
"Total time in seconds for compute: " << getComputeTime () << endl
1379 <<
"Total time in seconds for apply: " << getApplyTime () << endl;
1382 if (Inverse_.is_null ()) {
1384 out <<
"Subdomain solver: null" << endl;
1390 out <<
"Subdomain solver: not null" << endl;
1394 for (
int p = 0; p < numProcs; ++p) {
1396 out <<
"Subdomain solver on Process " << myRank <<
":";
1397 if (Inverse_.is_null ()) {
1398 out <<
"null" << endl;
1406 out <<
"null" << endl;
1410 Matrix_->getComm ()->barrier ();
1411 Matrix_->getComm ()->barrier ();
1412 Matrix_->getComm ()->barrier ();
1417 Matrix_->getComm ()->barrier ();
1422 template<
class MatrixType,
class LocalInverseType>
1432 template<
class MatrixType,
class LocalInverseType>
1435 return OverlapLevel_;
1439 template<
class MatrixType,
class LocalInverseType>
1443 using Teuchos::MpiComm;
1449 using Teuchos::rcp_dynamic_cast;
1450 using Teuchos::rcpFromRef;
1453 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1454 "initialize: The matrix to precondition is null. You must either pass "
1455 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull "
1456 "input, before you may call this method.");
1459 RCP<row_matrix_type> LocalizedMatrix;
1463 RCP<row_matrix_type> ActiveMatrix;
1466 if (! OverlappingMatrix_.is_null ()) {
1470 LocalizedMatrix =
rcp (
new LocalFilter<row_matrix_type> (Matrix_));
1475 LocalizedMatrix.is_null (), std::logic_error,
1476 "Ifpack2::AdditiveSchwarz::setup: LocalizedMatrix is null, after the code "
1477 "that claimed to have created it. This should never be the case. Please "
1478 "report this bug to the Ifpack2 developers.");
1481 ActiveMatrix = LocalizedMatrix;
1484 if (FilterSingletons_) {
1485 SingletonMatrix_ =
rcp (
new SingletonFilter<row_matrix_type> (LocalizedMatrix));
1486 ActiveMatrix = SingletonMatrix_;
1490 if (UseReordering_) {
1491 #if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2)
1493 typedef ReorderFilter<row_matrix_type> reorder_filter_type;
1495 ReorderingAlgorithm_ = zlist.
get<std::string> (
"order_method",
"rcm");
1497 ArrayRCP<local_ordinal_type> perm;
1498 ArrayRCP<local_ordinal_type> revperm;
1500 if(ReorderingAlgorithm_ ==
"user") {
1507 typedef Tpetra::RowGraph
1508 <local_ordinal_type, global_ordinal_type, node_type> row_graph_type;
1509 typedef Zoltan2::TpetraRowGraphAdapter<row_graph_type> z2_adapter_type;
1510 RCP<const row_graph_type> constActiveGraph =
1511 Teuchos::rcp_const_cast<
const row_graph_type>(ActiveMatrix->getGraph());
1512 z2_adapter_type Zoltan2Graph (constActiveGraph);
1514 typedef Zoltan2::OrderingProblem<z2_adapter_type> ordering_problem_type;
1519 RCP<const MpiComm<int> > mpicomm =
1520 rcp_dynamic_cast<
const MpiComm<int> > (ActiveMatrix->getComm ());
1521 if (mpicomm == Teuchos::null) {
1522 myRawComm = MPI_COMM_SELF;
1524 myRawComm = * (mpicomm->getRawMpiComm ());
1526 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist, myRawComm);
1528 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist);
1530 MyOrderingProblem.solve ();
1533 typedef Zoltan2::LocalOrderingSolution<local_ordinal_type>
1534 ordering_solution_type;
1536 ordering_solution_type sol (*MyOrderingProblem.getLocalOrderingSolution());
1542 perm = sol.getPermutationRCPConst (
true);
1543 revperm = sol.getPermutationRCPConst ();
1547 ReorderedLocalizedMatrix_ =
rcp (
new reorder_filter_type (ActiveMatrix, perm, revperm));
1550 ActiveMatrix = ReorderedLocalizedMatrix_;
1555 true, std::logic_error,
"Ifpack2::AdditiveSchwarz::setup: "
1556 "The Zoltan2 and Xpetra packages must be enabled in order "
1557 "to support reordering.");
1561 innerMatrix_ = ActiveMatrix;
1564 innerMatrix_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
1565 "setup: Inner matrix is null right before constructing inner solver. "
1566 "Please report this bug to the Ifpack2 developers.");
1569 if (Inverse_.is_null ()) {
1570 const std::string innerName = innerPrecName ();
1572 innerName ==
"INVALID", std::logic_error,
1573 "Ifpack2::AdditiveSchwarz::initialize: AdditiveSchwarz doesn't "
1574 "know how to create an instance of your LocalInverseType \""
1576 "Please talk to the Ifpack2 developers for details.");
1579 innerName ==
"CUSTOM", std::runtime_error,
"Ifpack2::AdditiveSchwarz::"
1580 "initialize: If the \"inner preconditioner name\" parameter (or any "
1581 "alias thereof) has the value \"CUSTOM\", then you must first call "
1582 "setInnerPreconditioner with a nonnull inner preconditioner input before "
1583 "you may call initialize().");
1588 Ifpack2::Details::registerLinearSolverFactory ();
1593 typedef typename MV::mag_type MT;
1594 RCP<inner_solver_type> innerPrec =
1595 Trilinos::Details::getLinearSolver<MV, OP, MT> (
"Ifpack2", innerName);
1597 innerPrec.is_null (), std::logic_error,
1598 "Ifpack2::AdditiveSchwarz::setup: Failed to create inner preconditioner "
1599 "with name \"" << innerName <<
"\".");
1600 innerPrec->setMatrix (innerMatrix_);
1604 std::pair<Teuchos::ParameterList, bool> result = innerPrecParams ();
1605 if (result.second) {
1608 innerPrec->setParameters (rcp (
new ParameterList (result.first)));
1610 Inverse_ = innerPrec;
1612 else if (Inverse_->getMatrix ().getRawPtr () != innerMatrix_.getRawPtr ()) {
1616 Inverse_->setMatrix (innerMatrix_);
1619 Inverse_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::"
1620 "setup: Inverse_ is null right after we were supposed to have created it."
1621 " Please report this bug to the Ifpack2 developers.");
1631 template<
class MatrixType,
class LocalInverseType>
1635 global_ordinal_type,
1638 if (! innerPrec.is_null ()) {
1641 can_change_type* innerSolver =
dynamic_cast<can_change_type*
> (&*innerPrec);
1643 innerSolver == NULL, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::"
1644 "setInnerPreconditioner: The input preconditioner does not implement the "
1645 "setMatrix() feature. Only input preconditioners that inherit from "
1646 "Ifpack2::Details::CanChangeMatrix implement this feature.");
1663 innerSolver->setMatrix (innerMatrix_);
1673 removeInnerPrecName ();
1674 removeInnerPrecParams ();
1675 List_.set (
"inner preconditioner name",
"CUSTOM");
1679 if (isInitialized ()) {
1680 innerPrec->initialize ();
1682 if (isComputed ()) {
1683 innerPrec->compute ();
1695 global_ordinal_type,
node_type> inner_solver_impl_type;
1696 Inverse_ =
Teuchos::rcp (
new inner_solver_impl_type (innerPrec,
"CUSTOM"));
1699 template<
class MatrixType,
class LocalInverseType>
1704 if (A.
getRawPtr () != Matrix_.getRawPtr ()) {
1705 IsInitialized_ =
false;
1706 IsComputed_ =
false;
1709 OverlappingMatrix_ = Teuchos::null;
1710 ReorderedLocalizedMatrix_ = Teuchos::null;
1711 innerMatrix_ = Teuchos::null;
1712 SingletonMatrix_ = Teuchos::null;
1713 localMap_ = Teuchos::null;
1714 DistributedImporter_ = Teuchos::null;
1725 #define IFPACK2_ADDITIVESCHWARZ_INSTANT(S,LO,GO,N) \
1726 template class Ifpack2::AdditiveSchwarz< Tpetra::RowMatrix<S, LO, GO, N> >;
1728 #endif // IFPACK2_ADDITIVESCHWARZ_DECL_HPP
Mix-in interface for preconditioners that can change their matrix after construction.
Definition: Ifpack2_Details_CanChangeMatrix.hpp:93
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &plist)
Set the preconditioner's parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:857
virtual void compute()
Computes all (coefficient) data necessary to apply the preconditioner.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1163
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
basic_OSTab< char > OSTab
virtual int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1233
T & get(const std::string &name, T def_value)
virtual bool isInitialized() const
Returns true if the preconditioner has been successfully initialized, false otherwise.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1156
virtual double getInitializeTime() const
Returns the time spent in initialize().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1240
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
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:1316
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:282
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:321
virtual double getComputeTime() const
Returns the time spent in compute().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1247
virtual ~AdditiveSchwarz()
Destructor.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:277
Teuchos::ScalarTraits< scalar_type >::magnitudeType magnitude_type
The type of the magnitude (absolute value) of a matrix entry.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:324
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1261
virtual std::ostream & print(std::ostream &os) const
Prints basic information on iostream. This function is used by operator<<.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1423
AdditiveSchwarz(const Teuchos::RCP< const row_matrix_type > &A)
Constructor that takes a matrix.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:224
virtual double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1254
virtual void initialize()
Computes all (graph-related) data necessary to initialize the preconditioner.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1082
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:318
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:312
bool registeredSomeLinearSolverFactory(const std::string &packageName)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
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:1633
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition: Ifpack2_Details_LinearSolver_decl.hpp:105
virtual std::string description() const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Get a list of the preconditioner's default parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1036
Interface for all Ifpack2 preconditioners.
Definition: Ifpack2_Preconditioner.hpp:107
virtual Teuchos::RCP< const row_matrix_type > getMatrix() const
The input matrix.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:307
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
Declaration of interface for preconditioners that can change their matrix after construction.
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:295
virtual void setParameters(const Teuchos::ParameterList &plist)
Set the preconditioner's parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:844
virtual int getNumCompute() const
Returns the number of calls to compute().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1226
Sparse matrix (Tpetra::RowMatrix subclass) with ghost rows.
Definition: Ifpack2_OverlappingRowMatrix_decl.hpp:58
Additive Schwarz domain decomposition for Tpetra sparse matrices.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:281
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
virtual bool isComputed() const
Returns true if the preconditioner has been successfully computed, false otherwise.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1212
Access only local rows and columns of a sparse matrix.
Definition: Ifpack2_LocalFilter_decl.hpp:160
ParameterEntry & getEntry(const std::string &name)
void registerLinearSolverFactory()
Filter based on matrix entries.
Definition: Ifpack2_SingletonFilter_decl.hpp:64
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1701
void getValidParameters(Teuchos::ParameterList ¶ms)
Fills a list which contains all the parameters possibly used by Ifpack2.
Definition: Ifpack2_Parameters.cpp:50
virtual int getOverlapLevel() const
Returns the level of overlap.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1433
virtual void describe(FancyOStream &out, const EVerbosityLevel verbLevel=verbLevel_default) const
virtual int getNumInitialize() const
Returns the number of calls to initialize().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1219