diff --git a/packages/ifpack2/src/Ifpack2_Hiptmair_def.hpp b/packages/ifpack2/src/Ifpack2_Hiptmair_def.hpp index 3c122ce9b581..9dd9ae3d80e2 100644 --- a/packages/ifpack2/src/Ifpack2_Hiptmair_def.hpp +++ b/packages/ifpack2/src/Ifpack2_Hiptmair_def.hpp @@ -441,14 +441,19 @@ std::string Hiptmair::description () const << "Computed: " << (isComputed () ? "true" : "false") << ", "; if (A_.is_null ()) { - os << "Matrix: null"; + os << "Matrix: null, "; } else { os << "Matrix: not null" << ", Global matrix dimensions: [" - << A_->getGlobalNumRows () << ", " << A_->getGlobalNumCols () << "]"; + << A_->getGlobalNumRows () << ", " << A_->getGlobalNumCols () << "], "; } + os << "Smoother 1: "; + os << ifpack2_prec1_->description() << ", "; + os << "Smoother 2: "; + os << ifpack2_prec2_->description(); + os << "}"; return os.str (); } @@ -490,6 +495,10 @@ describe (Teuchos::FancyOStream &out, } else { A_->describe (out, vl); } + out << "Smoother 1: "; + ifpack2_prec1_->describe(out, vl); + out << "Smoother 2: "; + ifpack2_prec2_->describe(out, vl); } } diff --git a/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_decl.hpp b/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_decl.hpp index ea7b7f3f1182..6362cc3d7f93 100644 --- a/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_decl.hpp +++ b/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_decl.hpp @@ -87,12 +87,6 @@ #include "Xpetra_VectorFactory_fwd.hpp" #include "Xpetra_CrsMatrixWrap_fwd.hpp" -#if defined(HAVE_MUELU_IFPACK2) && (!defined(HAVE_MUELU_EPETRA)) -#define MUELU_REFMAXWELL_CAN_USE_HIPTMAIR -#include "Ifpack2_Preconditioner.hpp" -#include "Ifpack2_Hiptmair.hpp" -#endif - // Stratimikos #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA) #include @@ -407,10 +401,6 @@ namespace MueLu { Teuchos::RCP HierarchyH_, Hierarchy22_; Teuchos::RCP PreSmoother_, PostSmoother_; Teuchos::RCP PreSmootherData_, PostSmootherData_; -#if defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - Teuchos::RCP > hiptmairPreSmoother_, hiptmairPostSmoother_; -#endif - bool useHiptmairSmoothing_; #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_THYRA) RCP > thyraPrecH_, thyraPrec22_; #endif diff --git a/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_def.hpp b/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_def.hpp index 7e90187db01a..a237f620ed2d 100644 --- a/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_def.hpp +++ b/packages/muelu/adapters/xpetra/MueLu_RefMaxwell_def.hpp @@ -1022,131 +1022,73 @@ namespace MueLu { template void RefMaxwell::setFineLevelSmoother() { - if (parameterList_.isType("smoother: type") && - parameterList_.get("smoother: type") == "hiptmair" && - SM_Matrix_->getDomainMap()->lib() == Xpetra::UseTpetra && - A22_->getDomainMap()->lib() == Xpetra::UseTpetra && - D0_Matrix_->getDomainMap()->lib() == Xpetra::UseTpetra) { -#if defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - ParameterList hiptmairPreList, hiptmairPostList, smootherPreList, smootherPostList; - - if (smootherList_.isSublist("smoother: pre params")) - smootherPreList = smootherList_.sublist("smoother: pre params"); - else if (smootherList_.isSublist("smoother: params")) - smootherPreList = smootherList_.sublist("smoother: params"); - hiptmairPreList.set("hiptmair: smoother type 1", - smootherPreList.get("hiptmair: smoother type 1", "CHEBYSHEV")); - hiptmairPreList.set("hiptmair: smoother type 2", - smootherPreList.get("hiptmair: smoother type 2", "CHEBYSHEV")); - if(smootherPreList.isSublist("hiptmair: smoother list 1")) - hiptmairPreList.set("hiptmair: smoother list 1", smootherPreList.sublist("hiptmair: smoother list 1")); - if(smootherPreList.isSublist("hiptmair: smoother list 2")) - hiptmairPreList.set("hiptmair: smoother list 2", smootherPreList.sublist("hiptmair: smoother list 2")); - hiptmairPreList.set("hiptmair: pre or post", - smootherPreList.get("hiptmair: pre or post", "pre")); - hiptmairPreList.set("hiptmair: zero starting solution", - smootherPreList.get("hiptmair: zero starting solution", true)); - - if (smootherList_.isSublist("smoother: post params")) - smootherPostList = smootherList_.sublist("smoother: post params"); - else if (smootherList_.isSublist("smoother: params")) - smootherPostList = smootherList_.sublist("smoother: params"); - hiptmairPostList.set("hiptmair: smoother type 1", - smootherPostList.get("hiptmair: smoother type 1", "CHEBYSHEV")); - hiptmairPostList.set("hiptmair: smoother type 2", - smootherPostList.get("hiptmair: smoother type 2", "CHEBYSHEV")); - if(smootherPostList.isSublist("hiptmair: smoother list 1")) - hiptmairPostList.set("hiptmair: smoother list 1", smootherPostList.sublist("hiptmair: smoother list 1")); - if(smootherPostList.isSublist("hiptmair: smoother list 2")) - hiptmairPostList.set("hiptmair: smoother list 2", smootherPostList.sublist("hiptmair: smoother list 2")); - hiptmairPostList.set("hiptmair: pre or post", - smootherPostList.get("hiptmair: pre or post", "post")); - hiptmairPostList.set("hiptmair: zero starting solution", - smootherPostList.get("hiptmair: zero starting solution", false)); - - typedef Tpetra::RowMatrix TROW; - RCP EdgeMatrix = Utilities::Op2NonConstTpetraRow(SM_Matrix_); - RCP NodeMatrix = Utilities::Op2NonConstTpetraRow(A22_); - RCP PMatrix = Utilities::Op2NonConstTpetraRow(D0_Matrix_); - - hiptmairPreSmoother_ = rcp( new Ifpack2::Hiptmair(EdgeMatrix,NodeMatrix,PMatrix) ); - hiptmairPreSmoother_ -> setParameters(hiptmairPreList); - hiptmairPreSmoother_ -> initialize(); - hiptmairPreSmoother_ -> compute(); - hiptmairPostSmoother_ = rcp( new Ifpack2::Hiptmair(EdgeMatrix,NodeMatrix,PMatrix) ); - hiptmairPostSmoother_ -> setParameters(hiptmairPostList); - hiptmairPostSmoother_ -> initialize(); - hiptmairPostSmoother_ -> compute(); - useHiptmairSmoothing_ = true; -#else - throw(Xpetra::Exceptions::RuntimeError("MueLu must be compiled with Ifpack2 for Hiptmair smoothing.")); -#endif // defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - } else { - - Level level; - RCP factoryHandler = rcp(new FactoryManager()); - level.SetFactoryManager(factoryHandler); - level.SetLevelID(0); - level.setObjectLabel("RefMaxwell (1,1)"); - level.Set("A",SM_Matrix_); - level.setlib(SM_Matrix_->getDomainMap()->lib()); - - if (parameterList_.isType("smoother: pre type") && parameterList_.isType("smoother: post type")) { - std::string preSmootherType = parameterList_.get("smoother: pre type"); - std::string postSmootherType = parameterList_.get("smoother: post type"); - - ParameterList preSmootherList, postSmootherList; - if (parameterList_.isSublist("smoother: pre params")) - preSmootherList = parameterList_.sublist("smoother: pre params"); - if (parameterList_.isSublist("smoother: post params")) - postSmootherList = parameterList_.sublist("smoother: post params"); - - RCP preSmootherPrototype = rcp(new TrilinosSmoother(preSmootherType, preSmootherList)); - RCP postSmootherPrototype = rcp(new TrilinosSmoother(postSmootherType, postSmootherList)); - RCP smootherFact = rcp(new SmootherFactory(preSmootherPrototype, postSmootherPrototype)); - - level.Request("PreSmoother",smootherFact.get()); - level.Request("PostSmoother",smootherFact.get()); - if (enable_reuse_) { - ParameterList smootherFactoryParams; - smootherFactoryParams.set("keep smoother data", true); - smootherFact->SetParameterList(smootherFactoryParams); - level.Request("PreSmoother data", smootherFact.get()); - level.Request("PostSmoother data", smootherFact.get()); - if (!PreSmootherData_.is_null()) - level.Set("PreSmoother data", PreSmootherData_, smootherFact.get()); - if (!PostSmootherData_.is_null()) - level.Set("PostSmoother data", PostSmootherData_, smootherFact.get()); - } - smootherFact->Build(level); - PreSmoother_ = level.Get >("PreSmoother",smootherFact.get()); - PostSmoother_ = level.Get >("PostSmoother",smootherFact.get()); - if (enable_reuse_) { - PreSmootherData_ = level.Get >("PreSmoother data",smootherFact.get()); - PostSmootherData_ = level.Get >("PostSmoother data",smootherFact.get()); - } - } else { - std::string smootherType = parameterList_.get("smoother: type", "CHEBYSHEV"); - RCP smootherPrototype = rcp(new TrilinosSmoother(smootherType, smootherList_)); - RCP smootherFact = rcp(new SmootherFactory(smootherPrototype)); - level.Request("PreSmoother",smootherFact.get()); - if (enable_reuse_) { - ParameterList smootherFactoryParams; - smootherFactoryParams.set("keep smoother data", true); - smootherFact->SetParameterList(smootherFactoryParams); - level.Request("PreSmoother data", smootherFact.get()); - if (!PreSmootherData_.is_null()) - level.Set("PreSmoother data", PreSmootherData_, smootherFact.get()); - } - smootherFact->Build(level); - PreSmoother_ = level.Get >("PreSmoother",smootherFact.get()); - PostSmoother_ = PreSmoother_; - if (enable_reuse_) - PreSmootherData_ = level.Get >("PreSmoother data",smootherFact.get()); + Level level; + RCP factoryHandler = rcp(new FactoryManager()); + level.SetFactoryManager(factoryHandler); + level.SetLevelID(0); + level.setObjectLabel("RefMaxwell (1,1)"); + level.Set("A",SM_Matrix_); + level.setlib(SM_Matrix_->getDomainMap()->lib()); + // For Hiptmair + level.Set("NodeMatrix", A22_); + level.Set("D0", D0_Matrix_); + + if (parameterList_.isType("smoother: pre type") && parameterList_.isType("smoother: post type")) { + std::string preSmootherType = parameterList_.get("smoother: pre type"); + std::string postSmootherType = parameterList_.get("smoother: post type"); + + ParameterList preSmootherList, postSmootherList; + if (parameterList_.isSublist("smoother: pre params")) + preSmootherList = parameterList_.sublist("smoother: pre params"); + if (parameterList_.isSublist("smoother: post params")) + postSmootherList = parameterList_.sublist("smoother: post params"); + + RCP preSmootherPrototype = rcp(new TrilinosSmoother(preSmootherType, preSmootherList)); + RCP postSmootherPrototype = rcp(new TrilinosSmoother(postSmootherType, postSmootherList)); + RCP smootherFact = rcp(new SmootherFactory(preSmootherPrototype, postSmootherPrototype)); + + level.Request("PreSmoother",smootherFact.get()); + level.Request("PostSmoother",smootherFact.get()); + if (enable_reuse_) { + ParameterList smootherFactoryParams; + smootherFactoryParams.set("keep smoother data", true); + smootherFact->SetParameterList(smootherFactoryParams); + level.Request("PreSmoother data", smootherFact.get()); + level.Request("PostSmoother data", smootherFact.get()); + if (!PreSmootherData_.is_null()) + level.Set("PreSmoother data", PreSmootherData_, smootherFact.get()); + if (!PostSmootherData_.is_null()) + level.Set("PostSmoother data", PostSmootherData_, smootherFact.get()); + } + smootherFact->Build(level); + PreSmoother_ = level.Get >("PreSmoother",smootherFact.get()); + PostSmoother_ = level.Get >("PostSmoother",smootherFact.get()); + if (enable_reuse_) { + PreSmootherData_ = level.Get >("PreSmoother data",smootherFact.get()); + PostSmootherData_ = level.Get >("PostSmoother data",smootherFact.get()); } - useHiptmairSmoothing_ = false; + } else { + std::string smootherType = parameterList_.get("smoother: type", "CHEBYSHEV"); + + RCP smootherPrototype = rcp(new TrilinosSmoother(smootherType, smootherList_)); + RCP smootherFact = rcp(new SmootherFactory(smootherPrototype)); + level.Request("PreSmoother",smootherFact.get()); + if (enable_reuse_) { + ParameterList smootherFactoryParams; + smootherFactoryParams.set("keep smoother data", true); + smootherFact->SetParameterList(smootherFactoryParams); + level.Request("PreSmoother data", smootherFact.get()); + if (!PreSmootherData_.is_null()) + level.Set("PreSmoother data", PreSmootherData_, smootherFact.get()); + } + smootherFact->Build(level); + PreSmoother_ = level.Get >("PreSmoother",smootherFact.get()); + PostSmoother_ = PreSmoother_; + if (enable_reuse_) + PreSmootherData_ = level.Get >("PreSmoother data",smootherFact.get()); } + } @@ -2455,15 +2397,7 @@ namespace MueLu { RCP tmSm = getTimer("MueLu RefMaxwell: smoothing"); -#if defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - if (useHiptmairSmoothing_) { - Tpetra::MultiVector tX = Utilities::MV2NonConstTpetraMV(X); - Tpetra::MultiVector tRHS = Utilities::MV2TpetraMV(RHS); - hiptmairPreSmoother_->apply(tRHS, tX); - } - else -#endif - PreSmoother_->Apply(X, RHS, use_as_preconditioner_); + PreSmoother_->Apply(X, RHS, use_as_preconditioner_); } // do solve for the 2x2 block system @@ -2487,31 +2421,14 @@ namespace MueLu { RCP tmSm = getTimer("MueLu RefMaxwell: smoothing"); -#if defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - if (useHiptmairSmoothing_) { - Tpetra::MultiVector tX = Utilities::MV2NonConstTpetraMV(X); - Tpetra::MultiVector tRHS = Utilities::MV2TpetraMV(RHS); - hiptmairPreSmoother_->apply(tRHS, tX); - } - else -#endif - PreSmoother_->Apply(X, RHS, false); + PreSmoother_->Apply(X, RHS, false); } solve22(RHS,X); { // apply post-smoothing RCP tmSm = getTimer("MueLu RefMaxwell: smoothing"); -#if defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - if (useHiptmairSmoothing_) - { - Tpetra::MultiVector tX = Utilities::MV2NonConstTpetraMV(X); - Tpetra::MultiVector tRHS = Utilities::MV2TpetraMV(RHS); - hiptmairPostSmoother_->apply(tRHS, tX); - } - else -#endif - PostSmoother_->Apply(X, RHS, false); + PostSmoother_->Apply(X, RHS, false); } solveH(RHS,X); } else if(mode_=="none") { @@ -2524,16 +2441,7 @@ namespace MueLu { RCP tmSm = getTimer("MueLu RefMaxwell: smoothing"); -#if defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - if (useHiptmairSmoothing_) - { - Tpetra::MultiVector tX = Utilities::MV2NonConstTpetraMV(X); - Tpetra::MultiVector tRHS = Utilities::MV2TpetraMV(RHS); - hiptmairPostSmoother_->apply(tRHS, tX); - } - else -#endif - PostSmoother_->Apply(X, RHS, false); + PostSmoother_->Apply(X, RHS, false); } } @@ -2687,19 +2595,6 @@ namespace MueLu { oss << std::endl; -#if defined(MUELU_REFMAXWELL_CAN_USE_HIPTMAIR) - if (useHiptmairSmoothing_) { - if (hiptmairPreSmoother_ != null && hiptmairPreSmoother_ == hiptmairPostSmoother_) - oss << "Smoother both : " << hiptmairPreSmoother_->description() << std::endl; - else { - oss << "Smoother pre : " - << (hiptmairPreSmoother_ != null ? hiptmairPreSmoother_->description() : "no smoother") << std::endl; - oss << "Smoother post : " - << (hiptmairPostSmoother_ != null ? hiptmairPostSmoother_->description() : "no smoother") << std::endl; - } - - } else -#endif { if (PreSmoother_ != null && PreSmoother_ == PostSmoother_) oss << "Smoother both : " << PreSmoother_->description() << std::endl; diff --git a/packages/muelu/src/Interface/MueLu_ML2MueLuParameterTranslator.cpp b/packages/muelu/src/Interface/MueLu_ML2MueLuParameterTranslator.cpp index bb97346845e6..c04c25577fc6 100644 --- a/packages/muelu/src/Interface/MueLu_ML2MueLuParameterTranslator.cpp +++ b/packages/muelu/src/Interface/MueLu_ML2MueLuParameterTranslator.cpp @@ -93,6 +93,12 @@ namespace MueLu { else my_name = "\"smoother: " + PreOrPost + " type\""; mueluss << "" << std::endl; + } else if ( valuestr == "hiptmair" ) { + std::string my_name; + if ( PreOrPost == "both" ) my_name = "\"" + pname + "\""; + else my_name = "\"smoother: " + PreOrPost + " type\""; + mueluss << "" << std::endl; + } else if ( valuestr == "ifpack" ) { std::string my_name = "\"" + pname + "\""; if ( paramList.isParameter("smoother: ifpack type") ) { @@ -180,6 +186,66 @@ namespace MueLu { else { mueluss << "" << std::endl; } } + if ( valuestr == "hiptmair" ) { + std::string subSmootherType = "Chebyshev"; + if (paramList.isParameter("subsmoother: type")) + subSmootherType = paramList.get("subsmoother: type"); + std::string subSmootherIfpackType; + if (subSmootherType == "Chebyshev") + subSmootherIfpackType = "CHEBYSHEV"; + else if (subSmootherType == "Jacobi" || subSmootherType == "Gauss-Seidel" || subSmootherType == "symmetric Gauss-Seidel") { + if (subSmootherType == "symmetric Gauss-Seidel") subSmootherType = "Symmetric Gauss-Seidel"; // FIXME + subSmootherIfpackType = "RELAXATION"; + } else + TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::MLParameterListTranslator: unknown smoother type. '" << subSmootherType << "' not supported by MueLu."); + + mueluss << "" << std::endl; + mueluss << "" << std::endl; + + mueluss << "" << std::endl; + if (subSmootherType == "Chebyshev") { + if (paramList.isParameter("subsmoother: edge sweeps")) { + mueluss << "("subsmoother: edge sweeps") << "\"/>" << std::endl; + adaptingParamList.remove("subsmoother: edge sweeps", false); + } + if (paramList.isParameter("subsmoother: Chebyshev alpha")) { + mueluss << "("subsmoother: Chebyshev alpha") << "\"/>" << std::endl; + } + } else { + if (paramList.isParameter("subsmoother: edge sweeps")) { + mueluss << "("subsmoother: edge sweeps") << "\"/>" << std::endl; + adaptingParamList.remove("subsmoother: edge sweeps", false); + } + if (paramList.isParameter("subsmoother: SGS damping factor")) { + mueluss << "("subsmoother: SGS damping factor") << "\"/>" << std::endl; + } + } + mueluss << "" << std::endl; + + mueluss << "" << std::endl; + if (subSmootherType == "Chebyshev") { + if (paramList.isParameter("subsmoother: node sweeps")) { + mueluss << "("subsmoother: node sweeps") << "\"/>" << std::endl; + adaptingParamList.remove("subsmoother: node sweeps", false); + } + if (paramList.isParameter("subsmoother: Chebyshev alpha")) { + mueluss << "("subsmoother: Chebyshev alpha") << "\"/>" << std::endl; + adaptingParamList.remove("subsmoother: Chebyshev alpha", false); + } + } else { + if (paramList.isParameter("subsmoother: node sweeps")) { + mueluss << "("subsmoother: node sweeps") << "\"/>" << std::endl; + adaptingParamList.remove("subsmoother: node sweeps", false); + } + if (paramList.isParameter("subsmoother: SGS damping factor")) { + mueluss << "("subsmoother: SGS damping factor") << "\"/>" << std::endl; + adaptingParamList.remove("subsmoother: SGS damping factor", false); + } + } + mueluss << "" << std::endl; + + } + // parameters for ILU based preconditioners if ( valuestr == "ifpack") { diff --git a/packages/muelu/src/Interface/MueLu_MLParameterListInterpreter_def.hpp b/packages/muelu/src/Interface/MueLu_MLParameterListInterpreter_def.hpp index 911681414b3d..7840d7e593ec 100644 --- a/packages/muelu/src/Interface/MueLu_MLParameterListInterpreter_def.hpp +++ b/packages/muelu/src/Interface/MueLu_MLParameterListInterpreter_def.hpp @@ -694,6 +694,43 @@ namespace MueLu { } + smooProto = rcp( new TrilinosSmoother(ifpackType, smootherParamList, 0) ); + smooProto->SetFactory("A", AFact); + + } else if (type == "Hiptmair") { + ifpackType = "HIPTMAIR"; + std::string subSmootherType = "Chebyshev"; + if (paramList.isParameter("subsmoother: type")) + subSmootherType = paramList.get("subsmoother: type"); + std::string subSmootherIfpackType; + if (subSmootherType == "Chebyshev") + subSmootherIfpackType = "CHEBYSHEV"; + else if (subSmootherType == "Jacobi" || subSmootherType == "Gauss-Seidel" || subSmootherType == "symmetric Gauss-Seidel") { + if (subSmootherType == "symmetric Gauss-Seidel") subSmootherType = "Symmetric Gauss-Seidel"; // FIXME + subSmootherIfpackType = "RELAXATION"; + } else + TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: unknown smoother type. '" << subSmootherType << "' not supported by MueLu."); + + smootherParamList.set("hiptmair: smoother type 1", subSmootherIfpackType); + smootherParamList.set("hiptmair: smoother type 2", subSmootherIfpackType); + + auto smoother1ParamList = smootherParamList.sublist("hiptmair: smoother list 1"); + auto smoother2ParamList = smootherParamList.sublist("hiptmair: smoother list 2"); + + if (subSmootherType == "Chebyshev") { + MUELU_COPY_PARAM(paramList, "subsmoother: edge sweeps", int, 2, smoother1ParamList, "chebyshev: degree"); + MUELU_COPY_PARAM(paramList, "subsmoother: node sweeps", int, 2, smoother2ParamList, "chebyshev: degree"); + + MUELU_COPY_PARAM(paramList, "subsmoother: Chebyshev", double, 20, smoother1ParamList, "chebyshev: ratio eigenvalue"); + MUELU_COPY_PARAM(paramList, "subsmoother: Chebyshev", double, 20, smoother2ParamList, "chebyshev: ratio eigenvalue"); + } else { + MUELU_COPY_PARAM(paramList, "subsmoother: edge sweeps", int, 2, smoother1ParamList, "relaxation: sweeps"); + MUELU_COPY_PARAM(paramList, "subsmoother: node sweeps", int, 2, smoother2ParamList, "relaxation: sweeps"); + + MUELU_COPY_PARAM(paramList, "subsmoother: SGS damping factor", double, 0.8, smoother2ParamList, "relaxation: damping factor"); + } + + smooProto = rcp( new TrilinosSmoother(ifpackType, smootherParamList, 0) ); smooProto->SetFactory("A", AFact);