void TopRAPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(Level & fineLevel, Level & coarseLevel) const { if ((PFact_ != Teuchos::null) && (PFact_ != NoFactory::getRCP())) { RCP<Operator> oP = coarseLevel.Get<RCP<Operator> >("P", PFact_.get()); RCP<Matrix> P = rcp_dynamic_cast<Matrix>(oP); if (!P.is_null()) coarseLevel.Set("P", P, NoFactory::get()); else coarseLevel.Set("P", oP, NoFactory::get()); coarseLevel.AddKeepFlag ("P", NoFactory::get(), MueLu::Final); // FIXME2: Order of Remove/Add matter (data removed otherwise). Should do something about this coarseLevel.RemoveKeepFlag("P", NoFactory::get(), MueLu::UserData); // FIXME: This is a hack, I should change behavior of Level::Set() instead. FIXME3: Should not be removed if flag was there already } if ((RFact_ != Teuchos::null) && (RFact_ != NoFactory::getRCP()) ) { RCP<Operator> oR = coarseLevel.Get<RCP<Operator> >("R", RFact_.get()); RCP<Matrix> R = rcp_dynamic_cast<Matrix>(oR); if (!R.is_null()) coarseLevel.Set("R", R, NoFactory::get()); else coarseLevel.Set("R", oR, NoFactory::get()); coarseLevel.AddKeepFlag ("R", NoFactory::get(), MueLu::Final); coarseLevel.RemoveKeepFlag("R", NoFactory::get(), MueLu::UserData); // FIXME: This is a hack } if ((AcFact_ != Teuchos::null) && (AcFact_ != NoFactory::getRCP())) { RCP<Operator> oA = coarseLevel.Get<RCP<Operator> >("A", AcFact_.get()); RCP<Matrix> A = rcp_dynamic_cast<Matrix>(oA); if (!A.is_null()) coarseLevel.Set("A", A, NoFactory::get()); else coarseLevel.Set("A", oA, NoFactory::get()); coarseLevel.AddKeepFlag ("A", NoFactory::get(), MueLu::Final); coarseLevel.RemoveKeepFlag("A", NoFactory::get(), MueLu::UserData); // FIXME: This is a hack } }
void TopSmootherFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Build(Level & level) const { if (preSmootherFact_.is_null() && postSmootherFact_.is_null()) return; // NOTE 1: We need to set at least some keep flag for the smoothers, otherwise it is going to be removed as soon as all requests are released. // We choose to set the Final flag for the data. In addition, we allow this data to be retrieved by only using the name by the means // of using NoFactory. However, any data set with NoFactory gets UserData flag by default. We don't really want that flag, so we remove it. // NOTE 2: some smoother factories are tricky (see comments in MueLu::SmootherFactory // Sometimes, we don't know whether the factory is able to generate "PreSmoother" or "PostSmoother" // For the SmootherFactory, however, we are able to check that. if (!preSmootherFact_.is_null()) { // Checking for null is not sufficient, as SmootherFactory(null, something) does not generate "PreSmoother" bool isAble = true; RCP<const SmootherFactory> s = rcp_dynamic_cast<const SmootherFactory>(preSmootherFact_); if (!s.is_null()) { RCP<SmootherPrototype> pre, post; s->GetSmootherPrototypes(pre, post); if (pre.is_null()) isAble = false; } else { // We assume that if presmoother factory is not SmootherFactory, it *is* able to generate "PreSmoother" } if (isAble) { RCP<SmootherBase> Pre = level.Get<RCP<SmootherBase> >("PreSmoother", preSmootherFact_.get()); level.Set ("PreSmoother", Pre, NoFactory::get()); level.AddKeepFlag ("PreSmoother", NoFactory::get(), MueLu::Final); level.RemoveKeepFlag("PreSmoother", NoFactory::get(), MueLu::UserData); } } if (!postSmootherFact_.is_null()) { // Checking for null is not sufficient, as SmootherFactory(something, null) does not generate "PostSmoother" bool isAble = true; RCP<const SmootherFactory> s = rcp_dynamic_cast<const SmootherFactory>(postSmootherFact_); if (!s.is_null()) { RCP<SmootherPrototype> pre, post; s->GetSmootherPrototypes(pre, post); if (post.is_null()) isAble = false; } else { // We assume that if presmoother factory is not SmootherFactory, it *is* able to generate "PreSmoother" } if (isAble) { RCP<SmootherBase> Post = level.Get<RCP<SmootherBase> >("PostSmoother", postSmootherFact_.get()); level.Set ("PostSmoother", Post, NoFactory::get()); level.AddKeepFlag ("PostSmoother", NoFactory::get(), MueLu::Final); level.RemoveKeepFlag("PostSmoother", NoFactory::get(), MueLu::UserData); } } }
void TopRAPFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Build(Level & fineLevel, Level & coarseLevel) const { if (PFact_ != Teuchos::null) { RCP<Matrix> P = coarseLevel.Get<RCP<Matrix> >("P", PFact_.get()); coarseLevel.Set ("P", P, NoFactory::get()); coarseLevel.AddKeepFlag ("P", NoFactory::get(), MueLu::Final); // FIXME2: Order of Remove/Add matter (data removed otherwise). Should do something about this coarseLevel.RemoveKeepFlag("P", NoFactory::get(), MueLu::UserData); // FIXME: This is a hack, I should change behavior of Level::Set() instead. FIXME3: Should not be removed if flag was there already } if (RFact_ != Teuchos::null) { RCP<Matrix> R = coarseLevel.Get<RCP<Matrix> >("R", RFact_.get()); coarseLevel.Set ("R", R, NoFactory::get()); coarseLevel.AddKeepFlag ("R", NoFactory::get(), MueLu::Final); coarseLevel.RemoveKeepFlag("R", NoFactory::get(), MueLu::UserData); // FIXME: This is a hack } if ((AcFact_ != Teuchos::null) && (AcFact_ != NoFactory::getRCP())) { RCP<Matrix> Ac = coarseLevel.Get<RCP<Matrix> >("A", AcFact_.get()); coarseLevel.Set ("A", Ac, NoFactory::get()); coarseLevel.AddKeepFlag ("A", NoFactory::get(), MueLu::Final); coarseLevel.RemoveKeepFlag("A", NoFactory::get(), MueLu::UserData); // FIXME: This is a hack } }
void TogglePFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::DeclareInput(Level &fineLevel, Level &coarseLevel) const { // request/release "P" and coarse level "Nullspace" for (std::vector<RCP<const FactoryBase> >::const_iterator it = prolongatorFacts_.begin(); it != prolongatorFacts_.end(); ++it) { coarseLevel.DeclareInput("P", (*it).get(), this); // request/release "P" (dependencies are not affected) (*it)->CallDeclareInput(coarseLevel); // request dependencies } for (std::vector<RCP<const FactoryBase> >::const_iterator it = nspFacts_.begin(); it != nspFacts_.end(); ++it) { coarseLevel.DeclareInput("Nullspace", (*it).get(), this); // request/release coarse "Nullspace" (dependencies are not affected) (*it)->CallDeclareInput(coarseLevel); // request dependencies } // The factory needs the information about the number of z-layers. While this information is // provided by the user for the finest level, the factory itself is responsible to provide the // corresponding information on the coarser levels. Since a factory cannot be dependent on itself // we use the NoFactory class as generator class, but remove the UserData keep flag, such that // "NumZLayers" is part of the request/release mechanism. // Please note, that this prevents us from having several (independent) CoarsePFactory instances! // TODO: allow factory to dependent on self-generated data for TwoLevelFactories -> introduce ExpertRequest/Release in Level fineLevel.DeclareInput("NumZLayers", NoFactory::get(), this); fineLevel.RemoveKeepFlag("NumZLayers", NoFactory::get(), MueLu::UserData); hasDeclaredInput_ = true; }