void UzawaSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Setup(Level ¤tLevel) { FactoryMonitor m(*this, "Setup blocked Uzawa Smoother", currentLevel); if (SmootherPrototype::IsSetup() == true) this->GetOStream(Warnings0) << "MueLu::UzawaSmoother::Setup(): Setup() has already been called"; // extract blocked operator A from current level A_ = Factory::Get<RCP<Matrix> > (currentLevel, "A"); RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_); TEUCHOS_TEST_FOR_EXCEPTION(bA == Teuchos::null, Exceptions::BadCast, "MueLu::UzawaSmoother::Setup: input matrix A is not of type BlockedCrsMatrix! error."); // store map extractors rangeMapExtractor_ = bA->getRangeMapExtractor(); domainMapExtractor_ = bA->getDomainMapExtractor(); // Store the blocks in local member variables Teuchos::RCP<CrsMatrix> A00 = bA->getMatrix(0, 0); Teuchos::RCP<CrsMatrix> A01 = bA->getMatrix(0, 1); Teuchos::RCP<CrsMatrix> A10 = bA->getMatrix(1, 0); Teuchos::RCP<CrsMatrix> A11 = bA->getMatrix(1, 1); Teuchos::RCP<CrsMatrixWrap> Op00 = Teuchos::rcp(new CrsMatrixWrap(A00)); Teuchos::RCP<CrsMatrixWrap> Op01 = Teuchos::rcp(new CrsMatrixWrap(A01)); Teuchos::RCP<CrsMatrixWrap> Op10 = Teuchos::rcp(new CrsMatrixWrap(A10)); Teuchos::RCP<CrsMatrixWrap> Op11 = Teuchos::rcp(new CrsMatrixWrap(A11)); F_ = Teuchos::rcp_dynamic_cast<Matrix>(Op00); G_ = Teuchos::rcp_dynamic_cast<Matrix>(Op01); D_ = Teuchos::rcp_dynamic_cast<Matrix>(Op10); Z_ = Teuchos::rcp_dynamic_cast<Matrix>(Op11); // TODO move this to BlockedCrsMatrix->getMatrix routine... F_->CreateView("stridedMaps", bA->getRangeMap(0), bA->getDomainMap(0)); G_->CreateView("stridedMaps", bA->getRangeMap(0), bA->getDomainMap(1)); D_->CreateView("stridedMaps", bA->getRangeMap(1), bA->getDomainMap(0)); Z_->CreateView("stridedMaps", bA->getRangeMap(1), bA->getDomainMap(1)); // Set the Smoother // carefully switch to the SubFactoryManagers (defined by the users) { RCP<const FactoryManagerBase> velpredictFactManager = FactManager_.at(0); SetFactoryManager currentSFM (rcpFromRef(currentLevel), velpredictFactManager); velPredictSmoo_ = currentLevel.Get< RCP<SmootherBase> >("PreSmoother",velpredictFactManager->GetFactory("Smoother").get()); } { RCP<const FactoryManagerBase> schurFactManager = FactManager_.at(1); SetFactoryManager currentSFM (rcpFromRef(currentLevel), schurFactManager); schurCompSmoo_ = currentLevel.Get< RCP<SmootherBase> >("PreSmoother", schurFactManager->GetFactory("Smoother").get()); } SmootherPrototype::IsSetup(true); }
TopSmootherFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::TopSmootherFactory(RCP<const FactoryManagerBase> parentFactoryManager, const std::string& varName) { TEUCHOS_TEST_FOR_EXCEPTION(varName != "CoarseSolver" && varName != "Smoother", Exceptions::RuntimeError, "varName should be either \"CoarseSolver\" or \"Smoother\""); if (varName == "CoarseSolver") { // For coarsest level, we only need one smoother (so that we don't call direct solver twice) // If a user wants to do something weird there (like, solve coarsest system by using 2 forward // GS and 1 backward GS), one can use MergedSmoother preSmootherFact_ = parentFactoryManager->GetFactory("CoarseSolver"); } else { preSmootherFact_ = parentFactoryManager->GetFactory("PreSmoother"); postSmootherFact_ = parentFactoryManager->GetFactory("PostSmoother"); } }
TopSmootherFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TopSmootherFactory(RCP<const FactoryManagerBase> parentFactoryManager, const std::string& varName) { TEUCHOS_TEST_FOR_EXCEPTION(varName != "CoarseSolver" && varName != "Smoother", Exceptions::RuntimeError, "varName should be either \"CoarseSolver\" or \"Smoother\""); if (varName == "CoarseSolver") { // For coarsest level, we only need one smoother/solver // If a user wants to do something weird there (like, solve coarsest system by using 2 forward // GS and 1 backward GS), one can use MergedSmoother RCP<const FactoryBase> coarseSolverFactory = parentFactoryManager->GetFactory("CoarseSolver"); RCP<const SmootherFactory> coarseSmootherFactory = Teuchos::rcp_dynamic_cast<const SmootherFactory>(coarseSolverFactory); if (coarseSmootherFactory != Teuchos::null) { RCP<SmootherPrototype> preProto; RCP<SmootherPrototype> postProto; coarseSmootherFactory->GetSmootherPrototypes(preProto, postProto); if (preProto == postProto) preSmootherFact_ = parentFactoryManager->GetFactory("CoarseSolver"); else { // check whether pre- and/or post-smoothing is desired on coarsest level if(preProto != Teuchos::null) preSmootherFact_ = parentFactoryManager->GetFactory("CoarseSolver"); if(postProto != Teuchos::null) postSmootherFact_ = parentFactoryManager->GetFactory("CoarseSolver"); } } else // default handling: get default direct solver as presmoother on coarsest level preSmootherFact_ = parentFactoryManager->GetFactory("CoarseSolver"); } else { preSmootherFact_ = parentFactoryManager->GetFactory("PreSmoother"); postSmootherFact_ = parentFactoryManager->GetFactory("PostSmoother"); } }
void SimpleSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Setup(Level ¤tLevel) { //********************************************* // Setup routine can be summarized in 4 steps: // - Set the map extractors // - Set the blocks // - Create and set the inverse of the diagonal of F // - Set the smoother for the Schur Complement FactoryMonitor m(*this, "Setup blocked SIMPLE Smoother", currentLevel); if (SmootherPrototype::IsSetup() == true) this->GetOStream(Warnings0) << "MueLu::SimpleSmoother::Setup(): Setup() has already been called"; // extract blocked operator A from current level A_ = Factory::Get<RCP<Matrix> > (currentLevel, "A"); RCP<BlockedCrsMatrix> bA = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(A_); TEUCHOS_TEST_FOR_EXCEPTION(bA == Teuchos::null, Exceptions::BadCast, "MueLu::SimpleSmoother::Setup: input matrix A is not of type BlockedCrsMatrix! error."); // store map extractors rangeMapExtractor_ = bA->getRangeMapExtractor(); domainMapExtractor_ = bA->getDomainMapExtractor(); // Store the blocks in local member variables Teuchos::RCP<CrsMatrix> A00 = bA->getMatrix(0, 0); Teuchos::RCP<CrsMatrix> A01 = bA->getMatrix(0, 1); Teuchos::RCP<CrsMatrix> A10 = bA->getMatrix(1, 0); Teuchos::RCP<CrsMatrix> A11 = bA->getMatrix(1, 1); Teuchos::RCP<CrsMatrixWrap> Op00 = Teuchos::rcp(new CrsMatrixWrap(A00)); Teuchos::RCP<CrsMatrixWrap> Op01 = Teuchos::rcp(new CrsMatrixWrap(A01)); Teuchos::RCP<CrsMatrixWrap> Op10 = Teuchos::rcp(new CrsMatrixWrap(A10)); Teuchos::RCP<CrsMatrixWrap> Op11 = Teuchos::rcp(new CrsMatrixWrap(A11)); F_ = Teuchos::rcp_dynamic_cast<Matrix>(Op00); G_ = Teuchos::rcp_dynamic_cast<Matrix>(Op01); D_ = Teuchos::rcp_dynamic_cast<Matrix>(Op10); Z_ = Teuchos::rcp_dynamic_cast<Matrix>(Op11); // TODO move this to BlockedCrsMatrix->getMatrix routine... F_->CreateView("stridedMaps", bA->getRangeMap(0), bA->getDomainMap(0)); G_->CreateView("stridedMaps", bA->getRangeMap(0), bA->getDomainMap(1)); D_->CreateView("stridedMaps", bA->getRangeMap(1), bA->getDomainMap(0)); Z_->CreateView("stridedMaps", bA->getRangeMap(1), bA->getDomainMap(1)); const ParameterList & pL = Factory::GetParameterList(); bool bSIMPLEC = pL.get<bool>("UseSIMPLEC"); // Create the inverse of the diagonal of F RCP<Vector> diagFVector = VectorFactory::Build(F_->getRowMap()); if(!bSIMPLEC) { F_->getLocalDiagCopy(*diagFVector); // extract diagonal of F diagFVector->reciprocal(*diagFVector); // build reciprocal } else { const RCP<const Map> rowmap = F_->getRowMap(); size_t locSize = rowmap->getNodeNumElements(); Teuchos::ArrayRCP<SC> diag = diagFVector->getDataNonConst(0); Teuchos::ArrayView<const LO> cols; Teuchos::ArrayView<const SC> vals; for (size_t i=0; i<locSize; ++i) { // loop over rows F_->getLocalRowView(i,cols,vals); Scalar absRowSum = Teuchos::ScalarTraits<Scalar>::zero(); for (LO j=0; j<cols.size(); ++j) { // loop over cols absRowSum += Teuchos::ScalarTraits<Scalar>::magnitude(vals[j]); } diag[i] = absRowSum; } diagFVector->reciprocal(*diagFVector); // build reciprocal } diagFinv_ = diagFVector; // Set the Smoother // carefully switch to the SubFactoryManagers (defined by the users) { RCP<const FactoryManagerBase> velpredictFactManager = FactManager_.at(0); SetFactoryManager currentSFM (rcpFromRef(currentLevel), velpredictFactManager); velPredictSmoo_ = currentLevel.Get< RCP<SmootherBase> >("PreSmoother",velpredictFactManager->GetFactory("Smoother").get()); } { RCP<const FactoryManagerBase> schurFactManager = FactManager_.at(1); SetFactoryManager currentSFM (rcpFromRef(currentLevel), schurFactManager); schurCompSmoo_ = currentLevel.Get< RCP<SmootherBase> >("PreSmoother", schurFactManager->GetFactory("Smoother").get()); } SmootherPrototype::IsSetup(true); }
TopRAPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::TopRAPFactory(RCP<const FactoryManagerBase> parentFactoryManagerFine, RCP<const FactoryManagerBase> parentFactoryManagerCoarse) : PFact_ (parentFactoryManagerCoarse->GetFactory("P")), RFact_ (parentFactoryManagerCoarse->GetFactory("R")), AcFact_(parentFactoryManagerCoarse->GetFactory("A")) { }
void HierarchyUtils<Scalar, LocalOrdinal, GlobalOrdinal, Node>::AddNonSerializableDataToHierarchy(HierarchyManager& HM, Hierarchy& H, const ParameterList& paramList) { for (ParameterList::ConstIterator it = paramList.begin(); it != paramList.end(); it++) { const std::string& levelName = it->first; // Check for mach of the form "level X" where X is a positive integer if (paramList.isSublist(levelName) && levelName.find("level ") == 0 && levelName.size() > 6) { int levelID = strtol(levelName.substr(6).c_str(), 0, 0); if (levelID > 0) { // Do enough level adding so we can be sure to add the data to the right place for (int i = H.GetNumLevels(); i <= levelID; i++) H.AddNewLevel(); } RCP<Level> level = H.GetLevel(levelID); RCP<FactoryManager> M = Teuchos::rcp_dynamic_cast<FactoryManager>(HM.GetFactoryManager(levelID)); TEUCHOS_TEST_FOR_EXCEPTION(M.is_null(), Exceptions::InvalidArgument, "MueLu::Utils::AddNonSerializableDataToHierarchy: cannot get FactoryManager"); // Grab the level sublist & loop over parameters const ParameterList& levelList = paramList.sublist(levelName); for (ParameterList::ConstIterator it2 = levelList.begin(); it2 != levelList.end(); it2++) { const std::string& name = it2->first; TEUCHOS_TEST_FOR_EXCEPTION(name != "A" && name != "P" && name != "R" && name != "Nullspace" && name != "Coordinates" && !IsParamMuemexVariable(name), Exceptions::InvalidArgument, "MueLu::Utils::AddNonSerializableDataToHierarchy: parameter list contains unknown data type"); if (name == "A") { level->Set(name, Teuchos::getValue<RCP<Matrix > > (it2->second),NoFactory::get()); M->SetFactory(name, NoFactory::getRCP()); // TAW: not sure about this: be aware that this affects all levels // However, A is accessible through NoFactory anyway, so it should // be fine here. } else if( name == "P" || name == "R") { level->AddKeepFlag(name,NoFactory::get(),MueLu::UserData); level->Set(name, Teuchos::getValue<RCP<Matrix > > (it2->second), M->GetFactory(name).get()); } else if (name == "Nullspace") { level->AddKeepFlag(name,NoFactory::get(),MueLu::UserData); level->Set(name, Teuchos::getValue<RCP<MultiVector > >(it2->second), NoFactory::get()); //M->SetFactory(name, NoFactory::getRCP()); // TAW: generally it is a bad idea to overwrite the factory manager data here // One should do this only in very special cases } else if(name == "Coordinates") //Scalar of Coordinates MV is always double { level->AddKeepFlag(name,NoFactory::get(),MueLu::UserData); level->Set(name, Teuchos::getValue<RCP<Xpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> > >(it2->second), NoFactory::get()); //M->SetFactory(name, NoFactory::getRCP()); // TAW: generally it is a bad idea to overwrite the factory manager data here } #ifdef HAVE_MUELU_MATLAB else { //Custom variable for Muemex size_t typeNameStart = name.find_first_not_of(' '); size_t typeNameEnd = name.find(' ', typeNameStart); std::string typeName = name.substr(typeNameStart, typeNameEnd - typeNameStart); std::transform(typeName.begin(), typeName.end(), typeName.begin(), ::tolower); level->AddKeepFlag(name, NoFactory::get(), MueLu::UserData); if(typeName == "matrix") level->Set(name, Teuchos::getValue<RCP<Matrix> >(it2->second), NoFactory::get()); else if(typeName == "multivector") level->Set(name, Teuchos::getValue<RCP<MultiVector> >(it2->second), NoFactory::get()); else if(typeName == "map") level->Set(name, Teuchos::getValue<RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > >(it2->second), NoFactory::get()); else if(typeName == "ordinalvector") level->Set(name, Teuchos::getValue<RCP<Xpetra::Vector<LocalOrdinal, LocalOrdinal, GlobalOrdinal, Node> > >(it2->second), NoFactory::get()); else if(typeName == "scalar") level->Set(name, Teuchos::getValue<Scalar>(it2->second), NoFactory::get()); else if(typeName == "double") level->Set(name, Teuchos::getValue<double>(it2->second), NoFactory::get()); else if(typeName == "complex") level->Set(name, Teuchos::getValue<std::complex<double> >(it2->second), NoFactory::get()); else if(typeName == "int") level->Set(name, Teuchos::getValue<int>(it2->second), NoFactory::get()); else if(typeName == "string") level->Set(name, Teuchos::getValue<std::string>(it2->second), NoFactory::get()); } #endif } } } }
TopRAPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::TopRAPFactory(RCP<const FactoryManagerBase> parentFactoryManager) : PFact_(parentFactoryManager->GetFactory("P")), RFact_(parentFactoryManager->GetFactory("R")), AcFact_(parentFactoryManager->GetFactory("A")) { }