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),
239 InitializeTime_ (0.0),
247 template<
class MatrixType,
class LocalInverseType>
250 const int overlapLevel) :
252 IsInitialized_ (false),
254 IsOverlapping_ (false),
255 OverlapLevel_ (overlapLevel),
256 CombineMode_ (Tpetra::ZERO),
257 UseReordering_ (false),
258 ReorderingAlgorithm_ (
"none"),
259 FilterSingletons_ (false),
261 ZeroStartingSolution_(true),
265 InitializeTime_ (0.0),
274 template<
class MatrixType,
class LocalInverseType>
278 template<
class MatrixType,
class LocalInverseType>
283 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::" 284 "getDomainMap: The matrix to precondition is null. You must either pass " 285 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull " 286 "input, before you may call this method.");
287 return Matrix_->getDomainMap ();
291 template<
class MatrixType,
class LocalInverseType>
296 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::" 297 "getRangeMap: The matrix to precondition is null. You must either pass " 298 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull " 299 "input, before you may call this method.");
300 return Matrix_->getRangeMap ();
304 template<
class MatrixType,
class LocalInverseType>
311 template<
class MatrixType,
class LocalInverseType>
314 apply (
const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &B,
315 Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type> &Y,
324 using Teuchos::rcp_dynamic_cast;
326 const char prefix[] =
"Ifpack2::AdditiveSchwarz::apply: ";
329 (! IsComputed_, std::runtime_error,
330 prefix <<
"isComputed() must be true before you may call apply().");
332 (Matrix_.is_null (), std::logic_error, prefix <<
333 "The input matrix A is null, but the preconditioner says that it has " 334 "been computed (isComputed() is true). This should never happen, since " 335 "setMatrix() should always mark the preconditioner as not computed if " 336 "its argument is null. " 337 "Please report this bug to the Ifpack2 developers.");
339 (Inverse_.is_null (), std::runtime_error,
340 prefix <<
"The subdomain solver is null. " 341 "This can only happen if you called setInnerPreconditioner() with a null " 342 "input, after calling initialize() or compute(). If you choose to call " 343 "setInnerPreconditioner() with a null input, you must then call it with " 344 "a nonnull input before you may call initialize() or compute().");
346 (B.getNumVectors() != Y.getNumVectors(), std::invalid_argument,
347 prefix <<
"B and Y must have the same number of columns. B has " <<
348 B.getNumVectors () <<
" columns, but Y has " << Y.getNumVectors() <<
".");
350 (IsOverlapping_ && OverlappingMatrix_.is_null (), std::logic_error,
351 prefix <<
"The overlapping matrix is null. " 352 "This should never happen if IsOverlapping_ is true. " 353 "Please report this bug to the Ifpack2 developers.");
355 (! IsOverlapping_ && localMap_.is_null (), std::logic_error,
356 prefix <<
"localMap_ is null. " 357 "This should never happen if IsOverlapping_ is false. " 358 "Please report this bug to the Ifpack2 developers.");
360 (alpha != STS::one (), std::logic_error,
361 prefix <<
"Not implemented for alpha != 1.");
363 (beta != STS::zero (), std::logic_error,
364 prefix <<
"Not implemented for beta != 0.");
366 #ifdef HAVE_IFPACK2_DEBUG 373 for (
size_t j = 0; j < B.getNumVectors (); ++j) {
374 if (STM::isnaninf (norms[j])) {
380 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 381 "The 2-norm of the input B is NaN or Inf.");
383 #endif // HAVE_IFPACK2_DEBUG 385 #ifdef HAVE_IFPACK2_DEBUG 386 if (! ZeroStartingSolution_) {
392 for (
size_t j = 0; j < Y.getNumVectors (); ++j) {
393 if (STM::isnaninf (norms[j])) {
399 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 400 "On input, the initial guess Y has 2-norm NaN or Inf " 401 "(ZeroStartingSolution_ is false).");
403 #endif // HAVE_IFPACK2_DEBUG 405 const std::string timerName (
"Ifpack2::AdditiveSchwarz::apply");
406 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
407 if (timer.is_null ()) {
408 timer = TimeMonitor::getNewCounter (timerName);
412 TimeMonitor timeMon (*timer);
416 const size_t numVectors = B.getNumVectors ();
420 if (ZeroStartingSolution_) {
425 RCP<MV> OverlappingB,OverlappingY;
426 RCP<MV> globalOverlappingB;
427 if (IsOverlapping_) {
429 OverlappingB =
rcp (
new MV (OverlappingMatrix_->getRowMap (), numVectors));
430 OverlappingY =
rcp (
new MV (OverlappingMatrix_->getRowMap (), numVectors));
439 OverlappingB =
rcp (
new MV (localMap_, numVectors));
440 OverlappingY =
rcp (
new MV (localMap_, numVectors));
443 OverlappingB->offsetViewNonConst (Matrix_->getRowMap (), 0);
446 if (DistributedImporter_.is_null ()) {
450 DistributedImporter_ =
451 rcp (
new import_type (Matrix_->getRowMap (),
452 Matrix_->getDomainMap ()));
456 RCP<MV> R =
rcp(
new MV(B.getMap(),numVectors));
457 RCP<MV> C =
rcp(
new MV(Y.getMap(),numVectors));
459 for (
int ni=0; ni<NumIterations_; ++ni)
461 #ifdef HAVE_IFPACK2_DEBUG 469 j < Y.getNumVectors (); ++j) {
470 if (STM::isnaninf (norms[j])) {
476 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 477 "At top of iteration " << ni <<
", the 2-norm of Y is NaN or Inf.");
479 #endif // HAVE_IFPACK2_DEBUG 481 Tpetra::deep_copy(*R, B);
486 if (!ZeroStartingSolution_ || ni > 0) {
488 Matrix_->apply (Y, *R, mode, -STS::one(), STS::one());
490 #ifdef HAVE_IFPACK2_DEBUG 497 for (
size_t j = 0; j < R->getNumVectors (); ++j) {
498 if (STM::isnaninf (norms[j])) {
504 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 505 "At iteration " << ni <<
", the 2-norm of R (result of computing " 506 "residual with Y) is NaN or Inf.");
508 #endif // HAVE_IFPACK2_DEBUG 512 RCP<overlap_mat_type> overlapMatrix;
513 if (IsOverlapping_) {
514 overlapMatrix = rcp_dynamic_cast<overlap_mat_type> (OverlappingMatrix_);
516 (overlapMatrix.is_null (), std::logic_error, prefix <<
517 "IsOverlapping_ is true, but OverlappingMatrix_, while nonnull, is " 518 "not an OverlappingRowMatrix<row_matrix_type>. Please report this " 519 "bug to the Ifpack2 developers.");
523 if (IsOverlapping_) {
525 (overlapMatrix.is_null (), std::logic_error, prefix
526 <<
"overlapMatrix is null when it shouldn't be. " 527 "Please report this bug to the Ifpack2 developers.");
528 overlapMatrix->importMultiVector (*R, *OverlappingB, Tpetra::INSERT);
545 #ifdef HAVE_IFPACK2_DEBUG 550 OverlappingB->norm2 (norms ());
553 j < OverlappingB->getNumVectors (); ++j) {
554 if (STM::isnaninf (norms[j])) {
560 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 561 "At iteration " << ni <<
", result of importMultiVector from R " 562 "to OverlappingB, has 2-norm NaN or Inf.");
564 #endif // HAVE_IFPACK2_DEBUG 566 globalOverlappingB->doImport (*R, *DistributedImporter_, Tpetra::INSERT);
568 #ifdef HAVE_IFPACK2_DEBUG 573 globalOverlappingB->norm2 (norms ());
576 j < globalOverlappingB->getNumVectors (); ++j) {
577 if (STM::isnaninf (norms[j])) {
583 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 584 "At iteration " << ni <<
", result of doImport from R, has 2-norm " 587 #endif // HAVE_IFPACK2_DEBUG 590 #ifdef HAVE_IFPACK2_DEBUG 595 OverlappingB->norm2 (norms ());
598 j < OverlappingB->getNumVectors (); ++j) {
599 if (STM::isnaninf (norms[j])) {
605 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 606 "At iteration " << ni <<
", right before localApply, the 2-norm of " 607 "OverlappingB is NaN or Inf.");
609 #endif // HAVE_IFPACK2_DEBUG 612 localApply(*OverlappingB, *OverlappingY);
614 #ifdef HAVE_IFPACK2_DEBUG 619 OverlappingY->norm2 (norms ());
622 j < OverlappingY->getNumVectors (); ++j) {
623 if (STM::isnaninf (norms[j])) {
629 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 630 "At iteration " << ni <<
", after localApply and before export / " 631 "copy, the 2-norm of OverlappingY is NaN or Inf.");
633 #endif // HAVE_IFPACK2_DEBUG 635 #ifdef HAVE_IFPACK2_DEBUG 643 j < C->getNumVectors (); ++j) {
644 if (STM::isnaninf (norms[j])) {
650 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 651 "At iteration " << ni <<
", before export / copy, the 2-norm of C " 654 #endif // HAVE_IFPACK2_DEBUG 657 if (IsOverlapping_) {
659 (overlapMatrix.is_null (), std::logic_error, prefix
660 <<
"overlapMatrix is null when it shouldn't be. " 661 "Please report this bug to the Ifpack2 developers.");
662 overlapMatrix->exportMultiVector (*OverlappingY, *C, CombineMode_);
671 RCP<MV> C_view = C->offsetViewNonConst (OverlappingY->getMap (), 0);
672 Tpetra::deep_copy (*C_view, *OverlappingY);
675 #ifdef HAVE_IFPACK2_DEBUG 683 j < C->getNumVectors (); ++j) {
684 if (STM::isnaninf (norms[j])) {
690 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 691 "At iteration " << ni <<
", before Y := C + Y, the 2-norm of C " 694 #endif // HAVE_IFPACK2_DEBUG 696 #ifdef HAVE_IFPACK2_DEBUG 704 j < Y.getNumVectors (); ++j) {
705 if (STM::isnaninf (norms[j])) {
711 (! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 712 "Before Y := C + Y, at iteration " << ni <<
", the 2-norm of Y " 715 #endif // HAVE_IFPACK2_DEBUG 717 Y.update(STS::one(), *C, STS::one());
719 #ifdef HAVE_IFPACK2_DEBUG 726 for (
size_t j = 0; j < Y.getNumVectors (); ++j) {
727 if (STM::isnaninf (norms[j])) {
733 ( ! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 734 "At iteration " << ni <<
", after Y := C + Y, the 2-norm of Y " 737 #endif // HAVE_IFPACK2_DEBUG 742 #ifdef HAVE_IFPACK2_DEBUG 749 for (
size_t j = 0; j < Y.getNumVectors (); ++j) {
750 if (STM::isnaninf (norms[j])) {
756 ( ! good, std::runtime_error,
"Ifpack2::AdditiveSchwarz::apply: " 757 "The 2-norm of the output Y is NaN or Inf.");
759 #endif // HAVE_IFPACK2_DEBUG 765 ApplyTime_ = timer->totalElapsedTime ();
768 template<
class MatrixType,
class LocalInverseType>
771 localApply(MV &OverlappingB, MV &OverlappingY)
const 774 using Teuchos::rcp_dynamic_cast;
776 const size_t numVectors = OverlappingB.getNumVectors ();
777 if (FilterSingletons_) {
779 MV ReducedB (SingletonMatrix_->getRowMap (), numVectors);
780 MV ReducedY (SingletonMatrix_->getRowMap (), numVectors);
782 RCP<SingletonFilter<row_matrix_type> > singletonFilter =
785 (! SingletonMatrix_.is_null () && singletonFilter.is_null (),
786 std::logic_error,
"Ifpack2::AdditiveSchwarz::localApply: " 787 "SingletonFilter_ is nonnull but is not a SingletonFilter" 788 "<row_matrix_type>. This should never happen. Please report this bug " 789 "to the Ifpack2 developers.");
790 singletonFilter->SolveSingletons (OverlappingB, OverlappingY);
791 singletonFilter->CreateReducedRHS (OverlappingY, OverlappingB, ReducedB);
794 if (! UseReordering_) {
795 Inverse_->solve (ReducedY, ReducedB);
798 RCP<ReorderFilter<row_matrix_type> > rf =
799 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
801 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
802 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is " 803 "nonnull but is not a ReorderFilter<row_matrix_type>. This should " 804 "never happen. Please report this bug to the Ifpack2 developers.");
805 MV ReorderedB (ReducedB, Teuchos::Copy);
806 MV ReorderedY (ReducedY, Teuchos::Copy);
807 rf->permuteOriginalToReordered (ReducedB, ReorderedB);
808 Inverse_->solve (ReorderedY, ReorderedB);
809 rf->permuteReorderedToOriginal (ReorderedY, ReducedY);
813 singletonFilter->UpdateLHS (ReducedY, OverlappingY);
818 if (! UseReordering_) {
819 Inverse_->solve (OverlappingY, OverlappingB);
822 MV ReorderedB (OverlappingB, Teuchos::Copy);
823 MV ReorderedY (OverlappingY, Teuchos::Copy);
825 RCP<ReorderFilter<row_matrix_type> > rf =
826 rcp_dynamic_cast<ReorderFilter<row_matrix_type> > (ReorderedLocalizedMatrix_);
828 (! ReorderedLocalizedMatrix_.is_null () && rf.is_null (), std::logic_error,
829 "Ifpack2::AdditiveSchwarz::localApply: ReorderedLocalizedMatrix_ is " 830 "nonnull but is not a ReorderFilter<row_matrix_type>. This should " 831 "never happen. Please report this bug to the Ifpack2 developers.");
832 rf->permuteOriginalToReordered (OverlappingB, ReorderedB);
833 Inverse_->solve (ReorderedY, ReorderedB);
834 rf->permuteReorderedToOriginal (ReorderedY, OverlappingY);
840 template<
class MatrixType,
class LocalInverseType>
848 this->setParameterList (Teuchos::rcpFromRef (List_));
853 template<
class MatrixType,
class LocalInverseType>
857 using Tpetra::CombineMode;
858 using Teuchos::getIntegralValue;
864 using Teuchos::rcp_dynamic_cast;
870 this->setParameterList (
rcp (
new ParameterList ()));
877 plist.
is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::" 878 "setParameterList: plist is null. This should never happen, since the " 879 "method should have replaced a null input list with a nonnull empty list " 880 "by this point. Please report this bug to the Ifpack2 developers.");
901 bool gotCombineMode =
false;
903 CombineMode_ = getIntegralValue<Tpetra::CombineMode> (List_,
"schwarz: combine mode");
904 gotCombineMode =
true;
909 gotCombineMode =
true;
918 if (! gotCombineMode) {
920 CombineMode_ = plist->
get (
"schwarz: combine mode", CombineMode_);
921 gotCombineMode =
true;
929 if (! gotCombineMode) {
930 const ParameterEntry& validEntry =
932 RCP<const ParameterEntryValidator> v = validEntry.validator ();
933 typedef StringToIntegralParameterEntryValidator<CombineMode> vs2e_type;
934 RCP<const vs2e_type> vs2e = rcp_dynamic_cast<
const vs2e_type> (v,
true);
936 const ParameterEntry& inputEntry = plist->
getEntry (
"schwarz: combine mode");
937 CombineMode_ = vs2e->getIntegralValue (inputEntry,
"schwarz: combine mode");
938 gotCombineMode =
true;
940 (void) gotCombineMode;
942 OverlapLevel_ = plist->
get (
"schwarz: overlap level", OverlapLevel_);
948 UseReordering_ = plist->
get (
"schwarz: use reordering", UseReordering_);
950 #if !defined(HAVE_IFPACK2_XPETRA) || !defined(HAVE_IFPACK2_ZOLTAN2) 952 UseReordering_, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::" 953 "setParameters: You specified \"schwarz: use reordering\" = true. " 954 "This is only valid when Trilinos was built with Ifpack2, Xpetra, and " 955 "Zoltan2 enabled. Either Xpetra or Zoltan2 was not enabled in your build " 967 FilterSingletons_ = plist->
get (
"schwarz: filter singletons", FilterSingletons_);
1002 if (! Inverse_.is_null ()) {
1005 if (hasInnerPrecName () && innerPrecName () !=
"CUSTOM") {
1008 Inverse_ = Teuchos::null;
1013 std::pair<Teuchos::ParameterList, bool> result = innerPrecParams ();
1014 if (result.second) {
1017 Inverse_->setParameters (
rcp (
new ParameterList (result.first)));
1022 NumIterations_ = plist->
get<
int>(
"schwarz: num iterations", NumIterations_);
1023 ZeroStartingSolution_ = plist->
get<
bool>(
"schwarz: zero starting solution", ZeroStartingSolution_);
1028 template<
class MatrixType,
class LocalInverseType>
1034 using Teuchos::parameterList;
1036 using Teuchos::rcp_const_cast;
1038 if (validParams_.is_null ()) {
1039 const int overlapLevel = 0;
1040 const bool useReordering =
false;
1041 const bool filterSingletons =
false;
1042 const int numIterations = 1;
1043 const bool zeroStartingSolution =
true;
1044 ParameterList reorderingSublist;
1045 reorderingSublist.set (
"order_method", std::string (
"rcm"));
1047 RCP<ParameterList> plist = parameterList (
"Ifpack2::AdditiveSchwarz");
1049 Tpetra::setCombineModeParameter (*plist,
"schwarz: combine mode");
1050 plist->set (
"schwarz: overlap level", overlapLevel);
1051 plist->set (
"schwarz: use reordering", useReordering);
1052 plist->set (
"schwarz: reordering list", reorderingSublist);
1055 plist->set (
"schwarz: compute condest",
false);
1056 plist->set (
"schwarz: filter singletons", filterSingletons);
1057 plist->set (
"schwarz: num iterations", numIterations);
1058 plist->set (
"schwarz: zero starting solution", zeroStartingSolution);
1068 validParams_ = rcp_const_cast<
const ParameterList> (plist);
1070 return validParams_;
1074 template<
class MatrixType,
class LocalInverseType>
1077 using Tpetra::global_size_t;
1084 const std::string timerName (
"Ifpack2::AdditiveSchwarz::initialize");
1085 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
1086 if (timer.is_null ()) {
1087 timer = TimeMonitor::getNewCounter (timerName);
1091 TimeMonitor timeMon (*timer);
1094 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::" 1095 "initialize: The matrix to precondition is null. You must either pass " 1096 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull " 1097 "input, before you may call this method.");
1099 IsInitialized_ =
false;
1100 IsComputed_ =
false;
1102 RCP<const Teuchos::Comm<int> > comm = Matrix_->getComm ();
1103 RCP<const map_type> rowMap = Matrix_->getRowMap ();
1104 RCP<node_type> node = Matrix_->getNode ();
1105 const global_size_t INVALID =
1110 if (comm->getSize () == 1) {
1112 IsOverlapping_ =
false;
1113 }
else if (OverlapLevel_ != 0) {
1114 IsOverlapping_ =
true;
1117 if (OverlapLevel_ == 0) {
1119 RCP<const SerialComm<int> > localComm (
new SerialComm<int> ());
1123 rcp (
new map_type (INVALID, rowMap->getNodeNumElements (),
1124 indexBase, localComm, node));
1128 if (IsOverlapping_) {
1134 if (! Inverse_.is_null ()) {
1135 Inverse_->symbolic ();
1140 IsInitialized_ =
true;
1145 InitializeTime_ = timer->totalElapsedTime ();
1149 template<
class MatrixType,
class LocalInverseType>
1152 return IsInitialized_;
1156 template<
class MatrixType,
class LocalInverseType>
1163 if (! IsInitialized_) {
1168 ! isInitialized (), std::logic_error,
"Ifpack2::AdditiveSchwarz::compute: " 1169 "The preconditioner is not yet initialized, " 1170 "even though initialize() supposedly has been called. " 1171 "This should never happen. " 1172 "Please report this bug to the Ifpack2 developers.");
1175 Inverse_.is_null (), std::runtime_error,
1176 "Ifpack2::AdditiveSchwarz::compute: The subdomain solver is null. " 1177 "This can only happen if you called setInnerPreconditioner() with a null " 1178 "input, after calling initialize() or compute(). If you choose to call " 1179 "setInnerPreconditioner() with a null input, you must then call it with a " 1180 "nonnull input before you may call initialize() or compute().");
1182 const std::string timerName (
"Ifpack2::AdditiveSchwarz::compute");
1183 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
1184 if (timer.is_null ()) {
1185 timer = TimeMonitor::getNewCounter (timerName);
1189 TimeMonitor timeMon (*timer);
1191 IsComputed_ =
false;
1192 Inverse_->numeric ();
1200 ComputeTime_ = timer->totalElapsedTime ();
1205 template<
class MatrixType,
class LocalInverseType>
1212 template<
class MatrixType,
class LocalInverseType>
1215 return NumInitialize_;
1219 template<
class MatrixType,
class LocalInverseType>
1226 template<
class MatrixType,
class LocalInverseType>
1233 template<
class MatrixType,
class LocalInverseType>
1236 return InitializeTime_;
1240 template<
class MatrixType,
class LocalInverseType>
1243 return ComputeTime_;
1247 template<
class MatrixType,
class LocalInverseType>
1254 template<
class MatrixType,
class LocalInverseType>
1257 std::ostringstream out;
1259 out <<
"\"Ifpack2::AdditiveSchwarz\": {";
1260 if (this->getObjectLabel () !=
"") {
1261 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
1263 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false")
1264 <<
", Computed: " << (isComputed () ?
"true" :
"false")
1265 <<
", Iterations: " << NumIterations_
1266 <<
", Overlap level: " << OverlapLevel_
1267 <<
", Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"";
1268 out <<
", Combine mode: \"";
1269 if (CombineMode_ == Tpetra::INSERT) {
1271 }
else if (CombineMode_ == Tpetra::ADD) {
1273 }
else if (CombineMode_ == Tpetra::REPLACE) {
1275 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1277 }
else if (CombineMode_ == Tpetra::ZERO) {
1281 if (Matrix_.is_null ()) {
1282 out <<
", Matrix: null";
1285 out <<
", Global matrix dimensions: [" 1286 << Matrix_->getGlobalNumRows () <<
", " 1287 << Matrix_->getGlobalNumCols () <<
"]";
1289 out <<
", Inner solver: ";
1290 if (! Inverse_.is_null ()) {
1296 out <<
"{" <<
"Some inner solver" <<
"}";
1307 template<
class MatrixType,
class LocalInverseType>
1317 const int myRank = Matrix_->getComm ()->getRank ();
1318 const int numProcs = Matrix_->getComm ()->getSize ();
1326 out <<
"\"Ifpack2::AdditiveSchwarz\":";
1330 out <<
"MatrixType: " << TypeNameTraits<MatrixType>::name () << endl;
1331 out <<
"LocalInverseType: " << TypeNameTraits<LocalInverseType>::name () << endl;
1332 if (this->getObjectLabel () !=
"") {
1333 out <<
"Label: \"" << this->getObjectLabel () <<
"\"" << endl;
1336 out <<
"Overlap level: " << OverlapLevel_ << endl
1337 <<
"Combine mode: \"";
1338 if (CombineMode_ == Tpetra::INSERT) {
1340 }
else if (CombineMode_ == Tpetra::ADD) {
1342 }
else if (CombineMode_ == Tpetra::REPLACE) {
1344 }
else if (CombineMode_ == Tpetra::ABSMAX) {
1346 }
else if (CombineMode_ == Tpetra::ZERO) {
1350 <<
"Subdomain reordering: \"" << ReorderingAlgorithm_ <<
"\"" << endl;
1353 if (Matrix_.is_null ()) {
1355 out <<
"Matrix: null" << endl;
1360 out <<
"Matrix:" << endl;
1363 Matrix_->getComm ()->barrier ();
1368 out <<
"Number of initialize calls: " << getNumInitialize () << endl
1369 <<
"Number of compute calls: " << getNumCompute () << endl
1370 <<
"Number of apply calls: " << getNumApply () << endl
1371 <<
"Total time in seconds for initialize: " << getInitializeTime () << endl
1372 <<
"Total time in seconds for compute: " << getComputeTime () << endl
1373 <<
"Total time in seconds for apply: " << getApplyTime () << endl;
1376 if (Inverse_.is_null ()) {
1378 out <<
"Subdomain solver: null" << endl;
1384 out <<
"Subdomain solver: not null" << endl;
1388 for (
int p = 0; p < numProcs; ++p) {
1390 out <<
"Subdomain solver on Process " << myRank <<
":";
1391 if (Inverse_.is_null ()) {
1392 out <<
"null" << endl;
1400 out <<
"null" << endl;
1404 Matrix_->getComm ()->barrier ();
1405 Matrix_->getComm ()->barrier ();
1406 Matrix_->getComm ()->barrier ();
1411 Matrix_->getComm ()->barrier ();
1416 template<
class MatrixType,
class LocalInverseType>
1426 template<
class MatrixType,
class LocalInverseType>
1429 return OverlapLevel_;
1433 template<
class MatrixType,
class LocalInverseType>
1437 using Teuchos::MpiComm;
1443 using Teuchos::rcp_dynamic_cast;
1444 using Teuchos::rcpFromRef;
1447 Matrix_.is_null (), std::runtime_error,
"Ifpack2::AdditiveSchwarz::" 1448 "initialize: The matrix to precondition is null. You must either pass " 1449 "a nonnull matrix to the constructor, or call setMatrix() with a nonnull " 1450 "input, before you may call this method.");
1453 RCP<row_matrix_type> LocalizedMatrix;
1457 RCP<row_matrix_type> ActiveMatrix;
1460 if (! OverlappingMatrix_.is_null ()) {
1464 LocalizedMatrix =
rcp (
new LocalFilter<row_matrix_type> (Matrix_));
1469 LocalizedMatrix.is_null (), std::logic_error,
1470 "Ifpack2::AdditiveSchwarz::setup: LocalizedMatrix is null, after the code " 1471 "that claimed to have created it. This should never be the case. Please " 1472 "report this bug to the Ifpack2 developers.");
1475 ActiveMatrix = LocalizedMatrix;
1478 if (FilterSingletons_) {
1479 SingletonMatrix_ =
rcp (
new SingletonFilter<row_matrix_type> (LocalizedMatrix));
1480 ActiveMatrix = SingletonMatrix_;
1484 if (UseReordering_) {
1485 #if defined(HAVE_IFPACK2_XPETRA) && defined(HAVE_IFPACK2_ZOLTAN2) 1487 typedef ReorderFilter<row_matrix_type> reorder_filter_type;
1489 ReorderingAlgorithm_ = zlist.
get<std::string> (
"order_method",
"rcm");
1491 ArrayRCP<local_ordinal_type> perm;
1492 ArrayRCP<local_ordinal_type> revperm;
1494 if(ReorderingAlgorithm_ ==
"user") {
1501 typedef Tpetra::RowGraph
1502 <local_ordinal_type, global_ordinal_type, node_type> row_graph_type;
1503 typedef Zoltan2::TpetraRowGraphAdapter<row_graph_type> z2_adapter_type;
1504 RCP<const row_graph_type> constActiveGraph =
1505 Teuchos::rcp_const_cast<
const row_graph_type>(ActiveMatrix->getGraph());
1506 z2_adapter_type Zoltan2Graph (constActiveGraph);
1508 typedef Zoltan2::OrderingProblem<z2_adapter_type> ordering_problem_type;
1513 RCP<const MpiComm<int> > mpicomm =
1514 rcp_dynamic_cast<
const MpiComm<int> > (ActiveMatrix->getComm ());
1515 if (mpicomm == Teuchos::null) {
1516 myRawComm = MPI_COMM_SELF;
1518 myRawComm = * (mpicomm->getRawMpiComm ());
1520 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist, myRawComm);
1522 ordering_problem_type MyOrderingProblem (&Zoltan2Graph, &zlist);
1524 MyOrderingProblem.solve ();
1527 typedef Zoltan2::LocalOrderingSolution<local_ordinal_type>
1528 ordering_solution_type;
1530 ordering_solution_type sol (*MyOrderingProblem.getLocalOrderingSolution());
1536 perm = sol.getPermutationRCPConst (
true);
1537 revperm = sol.getPermutationRCPConst ();
1541 ReorderedLocalizedMatrix_ =
rcp (
new reorder_filter_type (ActiveMatrix, perm, revperm));
1544 ActiveMatrix = ReorderedLocalizedMatrix_;
1549 true, std::logic_error,
"Ifpack2::AdditiveSchwarz::setup: " 1550 "The Zoltan2 and Xpetra packages must be enabled in order " 1551 "to support reordering.");
1555 innerMatrix_ = ActiveMatrix;
1558 innerMatrix_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::" 1559 "setup: Inner matrix is null right before constructing inner solver. " 1560 "Please report this bug to the Ifpack2 developers.");
1563 if (Inverse_.is_null ()) {
1564 const std::string innerName = innerPrecName ();
1566 innerName ==
"INVALID", std::logic_error,
1567 "Ifpack2::AdditiveSchwarz::initialize: AdditiveSchwarz doesn't " 1568 "know how to create an instance of your LocalInverseType \"" 1570 "Please talk to the Ifpack2 developers for details.");
1573 innerName ==
"CUSTOM", std::runtime_error,
"Ifpack2::AdditiveSchwarz::" 1574 "initialize: If the \"inner preconditioner name\" parameter (or any " 1575 "alias thereof) has the value \"CUSTOM\", then you must first call " 1576 "setInnerPreconditioner with a nonnull inner preconditioner input before " 1577 "you may call initialize().");
1587 typedef typename MV::mag_type MT;
1588 RCP<inner_solver_type> innerPrec =
1589 Trilinos::Details::getLinearSolver<MV, OP, MT> (
"Ifpack2", innerName);
1591 innerPrec.is_null (), std::logic_error,
1592 "Ifpack2::AdditiveSchwarz::setup: Failed to create inner preconditioner " 1593 "with name \"" << innerName <<
"\".");
1594 innerPrec->setMatrix (innerMatrix_);
1598 std::pair<Teuchos::ParameterList, bool> result = innerPrecParams ();
1599 if (result.second) {
1602 innerPrec->setParameters (rcp (
new ParameterList (result.first)));
1604 Inverse_ = innerPrec;
1606 else if (Inverse_->getMatrix ().getRawPtr () != innerMatrix_.getRawPtr ()) {
1610 Inverse_->setMatrix (innerMatrix_);
1613 Inverse_.is_null (), std::logic_error,
"Ifpack2::AdditiveSchwarz::" 1614 "setup: Inverse_ is null right after we were supposed to have created it." 1615 " Please report this bug to the Ifpack2 developers.");
1625 template<
class MatrixType,
class LocalInverseType>
1632 if (! innerPrec.is_null ()) {
1635 can_change_type* innerSolver =
dynamic_cast<can_change_type*
> (&*innerPrec);
1637 innerSolver == NULL, std::invalid_argument,
"Ifpack2::AdditiveSchwarz::" 1638 "setInnerPreconditioner: The input preconditioner does not implement the " 1639 "setMatrix() feature. Only input preconditioners that inherit from " 1640 "Ifpack2::Details::CanChangeMatrix implement this feature.");
1657 innerSolver->setMatrix (innerMatrix_);
1667 removeInnerPrecName ();
1668 removeInnerPrecParams ();
1669 List_.set (
"inner preconditioner name",
"CUSTOM");
1673 if (isInitialized ()) {
1674 innerPrec->initialize ();
1676 if (isComputed ()) {
1677 innerPrec->compute ();
1690 Inverse_ = Teuchos::rcp (
new inner_solver_impl_type (innerPrec,
"CUSTOM"));
1693 template<
class MatrixType,
class LocalInverseType>
1698 if (A.
getRawPtr () != Matrix_.getRawPtr ()) {
1699 IsInitialized_ =
false;
1700 IsComputed_ =
false;
1703 OverlappingMatrix_ = Teuchos::null;
1704 ReorderedLocalizedMatrix_ = Teuchos::null;
1705 innerMatrix_ = Teuchos::null;
1706 SingletonMatrix_ = Teuchos::null;
1707 localMap_ = Teuchos::null;
1708 DistributedImporter_ = Teuchos::null;
1719 #define IFPACK2_ADDITIVESCHWARZ_INSTANT(S,LO,GO,N) \ 1720 template class Ifpack2::AdditiveSchwarz< Tpetra::RowMatrix<S, LO, GO, N> >; 1722 #endif // IFPACK2_ADDITIVESCHWARZ_DECL_HPP 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:280
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:855
virtual void compute()
Computes all (coefficient) data necessary to apply the preconditioner.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1157
void registerLinearSolverFactory()
Register Ifpack2's LinearSolverFactory with the central repository, for all enabled combinations of t...
Definition: Ifpack2_Details_registerLinearSolverFactory.cpp:68
basic_OSTab< char > OSTab
virtual double getInitializeTime() const
Returns the time spent in initialize().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1234
virtual double getComputeTime() const
Returns the time spent in compute().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1241
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:321
virtual Teuchos::RCP< const row_matrix_type > getMatrix() const
The input matrix.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:305
virtual double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1248
virtual ~AdditiveSchwarz()
Destructor.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:275
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:1255
virtual std::string description() const
AdditiveSchwarz(const Teuchos::RCP< const row_matrix_type > &A)
Constructor that takes a matrix.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:224
virtual void initialize()
Computes all (graph-related) data necessary to initialize the preconditioner.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1075
Ifpack2 implementation details.
virtual bool isInitialized() const
Returns true if the preconditioner has been successfully initialized, false otherwise.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1150
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)
virtual int getOverlapLevel() const
Returns the level of overlap.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1427
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:1627
virtual int getNumCompute() const
Returns the number of calls to compute().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1220
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition: Ifpack2_Details_LinearSolver_decl.hpp:105
Interface for all Ifpack2 preconditioners.
Definition: Ifpack2_Preconditioner.hpp:107
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:293
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Get a list of the preconditioner's default parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1031
Declaration of interface for preconditioners that can change their matrix after construction.
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:1310
virtual std::ostream & print(std::ostream &os) const
Prints basic information on iostream. This function is used by operator<<.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1417
virtual void setParameters(const Teuchos::ParameterList &plist)
Set the preconditioner's parameters.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:842
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
virtual bool isComputed() const
Returns true if the preconditioner has been successfully computed, false otherwise.
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1206
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Access only local rows and columns of a sparse matrix.
Definition: Ifpack2_LocalFilter_decl.hpp:160
virtual void describe(FancyOStream &out, const EVerbosityLevel verbLevel=verbLevel_default) const
Preconditioners and smoothers for Tpetra sparse matrices.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:72
void registerLinearSolverFactory(const std::string &packageName, const Teuchos::RCP< LinearSolverFactory< MV, OP, NormType > > &factory)
ParameterEntry & getEntry(const std::string &name)
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:1695
void getValidParameters(Teuchos::ParameterList ¶ms)
Fills a list which contains all the parameters possibly used by Ifpack2.
Definition: Ifpack2_Parameters.cpp:50
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:315
virtual int getNumInitialize() const
Returns the number of calls to initialize().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1213
virtual int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_AdditiveSchwarz_def.hpp:1227
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:314