//! virtual void CallDeclareInput(Level & requestedLevel) const { if (requestedLevel.GetPreviousLevel() == Teuchos::null) { std::ostringstream errStr; errStr << "LevelID = " << requestedLevel.GetLevelID(); throw Exceptions::DependencyError(errStr.str()); } DeclareInput(*requestedLevel.GetPreviousLevel(), requestedLevel); }
//! virtual void CallBuild(Level & requestedLevel) const { #ifdef HAVE_MUELU_DEBUG TEUCHOS_TEST_FOR_EXCEPTION((multipleCallCheck_ == ENABLED) && (multipleCallCheckGlobal_ == ENABLED) && (lastLevel_ == &requestedLevel), Exceptions::RuntimeError, this->ShortClassName() << "::Build() called twice for the same level (levelID=" << requestedLevel.GetLevelID() << "). This is likely due to a configuration error."); if (multipleCallCheck_ == FIRSTCALL) multipleCallCheck_ = ENABLED; lastLevel_ = &requestedLevel; #endif TEUCHOS_TEST_FOR_EXCEPTION(requestedLevel.GetPreviousLevel() == Teuchos::null, Exceptions::RuntimeError, "LevelID = " << requestedLevel.GetLevelID()); Build(*requestedLevel.GetPreviousLevel(), requestedLevel); }
//! virtual void CallBuild(Level& requestedLevel) const { int levelID = requestedLevel.GetLevelID(); #ifdef HAVE_MUELU_DEBUG // We cannot call Build method twice for the same level, but we can call it multiple times for different levels TEUCHOS_TEST_FOR_EXCEPTION((multipleCallCheck_ == ENABLED) && (multipleCallCheckGlobal_ == ENABLED) && (lastLevelID_ == levelID), Exceptions::RuntimeError, this->ShortClassName() << "::Build() called twice for the same level (levelID=" << levelID << "). This is likely due to a configuration error."); if (multipleCallCheck_ == FIRSTCALL) multipleCallCheck_ = ENABLED; lastLevelID_ = levelID; #endif TEUCHOS_TEST_FOR_EXCEPTION(requestedLevel.GetPreviousLevel() == Teuchos::null, Exceptions::RuntimeError, "LevelID = " << levelID); #ifdef HAVE_MUELU_TIMER_SYNCHRONIZATION RCP<const Teuchos::Comm<int> > comm = requestedLevel.GetComm(); if (comm.is_null()) { // Some factories are called before we constructed Ac, and therefore, // before we set the level communicator. For such factories we can get // the comm from the previous level, as all processes go there RCP<Level>& prevLevel = requestedLevel.GetPreviousLevel(); if (!prevLevel.is_null()) comm = prevLevel->GetComm(); } // Synchronization timer std::string syncTimer = this->ShortClassName() + ": Build sync (level=" + toString(requestedLevel.GetLevelID()) + ")"; if (!comm.is_null()) { TimeMonitor timer(*this, syncTimer); comm->barrier(); } #endif Build(*requestedLevel.GetPreviousLevel(), requestedLevel); #ifdef HAVE_MUELU_TIMER_SYNCHRONIZATION // Synchronization timer if (!comm.is_null()) { TimeMonitor timer(*this, syncTimer); comm->barrier(); } #endif GetOStream(Test) << *RemoveFactoriesFromList(GetParameterList()) << std::endl; }
void IfpackSmoother::Setup(Level ¤tLevel) { FactoryMonitor m(*this, "Setup Smoother", currentLevel); if (SmootherPrototype::IsSetup() == true) GetOStream(Warnings0, 0) << "Warning: MueLu::IfpackSmoother::Setup(): Setup() has already been called"; A_ = Factory::Get< RCP<Matrix> >(currentLevel, "A"); double lambdaMax = -1.0; if (type_ == "Chebyshev") { std::string maxEigString = "chebyshev: max eigenvalue"; std::string eigRatioString = "chebyshev: ratio eigenvalue"; try { lambdaMax = Teuchos::getValue<Scalar>(this->GetParameter(maxEigString)); this->GetOStream(Statistics1, 0) << maxEigString << " (cached with smoother parameter list) = " << lambdaMax << std::endl; } catch (Teuchos::Exceptions::InvalidParameterName) { lambdaMax = A_->GetMaxEigenvalueEstimate(); if (lambdaMax != -1.0) { this->GetOStream(Statistics1, 0) << maxEigString << " (cached with matrix) = " << lambdaMax << std::endl; this->SetParameter(maxEigString, ParameterEntry(lambdaMax)); } } // Calculate the eigenvalue ratio const Scalar defaultEigRatio = 20; Scalar ratio = defaultEigRatio; try { ratio = Teuchos::getValue<Scalar>(this->GetParameter(eigRatioString)); } catch (Teuchos::Exceptions::InvalidParameterName) { this->SetParameter(eigRatioString, ParameterEntry(ratio)); } if (currentLevel.GetLevelID()) { // Update ratio to be // ratio = max(number of fine DOFs / number of coarse DOFs, defaultValue) // // NOTE: We don't need to request previous level matrix as we know for sure it was constructed RCP<const Matrix> fineA = currentLevel.GetPreviousLevel()->Get<RCP<Matrix> >("A"); size_t nRowsFine = fineA->getGlobalNumRows(); size_t nRowsCoarse = A_->getGlobalNumRows(); ratio = std::max(ratio, as<Scalar>(nRowsFine)/nRowsCoarse); this->GetOStream(Statistics1, 0) << eigRatioString << " (computed) = " << ratio << std::endl; this->SetParameter(eigRatioString, ParameterEntry(ratio)); } } RCP<Epetra_CrsMatrix> epA = Utils::Op2NonConstEpetraCrs(A_); Ifpack factory; prec_ = rcp(factory.Create(type_, &(*epA), overlap_)); TEUCHOS_TEST_FOR_EXCEPTION(prec_.is_null(), Exceptions::RuntimeError, "Could not create an Ifpack preconditioner with type = \"" << type_ << "\""); SetPrecParameters(); prec_->Compute(); SmootherPrototype::IsSetup(true); if (type_ == "Chebyshev" && lambdaMax == -1.0) { Teuchos::RCP<Ifpack_Chebyshev> chebyPrec = rcp_dynamic_cast<Ifpack_Chebyshev>(prec_); if (chebyPrec != Teuchos::null) { lambdaMax = chebyPrec->GetLambdaMax(); A_->SetMaxEigenvalueEstimate(lambdaMax); this->GetOStream(Statistics1, 0) << "chebyshev: max eigenvalue (calculated by Ifpack)" << " = " << lambdaMax << std::endl; } TEUCHOS_TEST_FOR_EXCEPTION(lambdaMax == -1.0, Exceptions::RuntimeError, "MueLu::IfpackSmoother::Setup(): no maximum eigenvalue estimate"); } this->GetOStream(Statistics0, 0) << description() << std::endl; }
void Ifpack2Smoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetupChebyshev(Level& currentLevel) { if (this->IsSetup() == true) this->GetOStream(Warnings0) << "MueLu::Ifpack2Smoother::Setup(): Setup() has already been called" << std::endl; typedef Teuchos::ScalarTraits<SC> STS; SC negone = -STS::one(); SC lambdaMax = negone; { std::string maxEigString = "chebyshev: max eigenvalue"; std::string eigRatioString = "chebyshev: ratio eigenvalue"; ParameterList& paramList = const_cast<ParameterList&>(this->GetParameterList()); // Get/calculate the maximum eigenvalue if (paramList.isParameter(maxEigString)) { if (paramList.isType<double>(maxEigString)) lambdaMax = paramList.get<double>(maxEigString); else lambdaMax = paramList.get<SC>(maxEigString); this->GetOStream(Statistics1) << maxEigString << " (cached with smoother parameter list) = " << lambdaMax << std::endl; } else { lambdaMax = A_->GetMaxEigenvalueEstimate(); if (lambdaMax != negone) { this->GetOStream(Statistics1) << maxEigString << " (cached with matrix) = " << lambdaMax << std::endl; paramList.set(maxEigString, lambdaMax); } } // Calculate the eigenvalue ratio const SC defaultEigRatio = 20; SC ratio = defaultEigRatio; if (paramList.isParameter(eigRatioString)) { if (paramList.isType<double>(eigRatioString)) ratio = paramList.get<double>(eigRatioString); else ratio = paramList.get<SC>(eigRatioString); } if (currentLevel.GetLevelID()) { // Update ratio to be // ratio = max(number of fine DOFs / number of coarse DOFs, defaultValue) // // NOTE: We don't need to request previous level matrix as we know for sure it was constructed RCP<const Matrix> fineA = currentLevel.GetPreviousLevel()->Get<RCP<Matrix> >("A"); size_t nRowsFine = fineA->getGlobalNumRows(); size_t nRowsCoarse = A_->getGlobalNumRows(); SC levelRatio = as<SC>(as<float>(nRowsFine)/nRowsCoarse); if (STS::magnitude(levelRatio) > STS::magnitude(ratio)) ratio = levelRatio; } this->GetOStream(Statistics1) << eigRatioString << " (computed) = " << ratio << std::endl; paramList.set(eigRatioString, ratio); } RCP<const Tpetra::RowMatrix<SC, LO, GO, NO> > tpA = Utilities::Op2NonConstTpetraRow(A_); prec_ = Ifpack2::Factory::create(type_, tpA, overlap_); SetPrecParameters(); prec_->initialize(); prec_->compute(); if (lambdaMax == negone) { typedef Tpetra::RowMatrix<SC, LO, GO, NO> MatrixType; Teuchos::RCP<Ifpack2::Chebyshev<MatrixType> > chebyPrec = rcp_dynamic_cast<Ifpack2::Chebyshev<MatrixType> >(prec_); if (chebyPrec != Teuchos::null) { lambdaMax = chebyPrec->getLambdaMaxForApply(); A_->SetMaxEigenvalueEstimate(lambdaMax); this->GetOStream(Statistics1) << "chebyshev: max eigenvalue (calculated by Ifpack2)" << " = " << lambdaMax << std::endl; } TEUCHOS_TEST_FOR_EXCEPTION(lambdaMax == negone, Exceptions::RuntimeError, "MueLu::IfpackSmoother::Setup(): no maximum eigenvalue estimate"); } }
//! virtual void CallDeclareInput(Level & requestedLevel) const { TEUCHOS_TEST_FOR_EXCEPTION(requestedLevel.GetPreviousLevel() == Teuchos::null, Exceptions::RuntimeError, "LevelID = " << requestedLevel.GetLevelID()); DeclareInput(*requestedLevel.GetPreviousLevel(), requestedLevel); }