int main_(Teuchos::CommandLineProcessor &clp, Xpetra::UnderlyingLib lib, int argc, char *argv[]) { #include <MueLu_UseShortNames.hpp> using Teuchos::RCP; using Teuchos::rcp; // // MPI initialization // Teuchos::oblackholestream blackhole; bool success = false; bool verbose = true; try { RCP< const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm(); // // Process command line arguments // Galeri::Xpetra::Parameters<GO> matrixParameters(clp, 81); // manage parameters of the test case Xpetra::Parameters xpetraParameters(clp); // manage parameters of xpetra switch (clp.parse(argc,argv)) { case Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED: return EXIT_SUCCESS; case Teuchos::CommandLineProcessor::PARSE_ERROR: case Teuchos::CommandLineProcessor::PARSE_UNRECOGNIZED_OPTION: return EXIT_FAILURE; case Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL: break; default:; } if (comm->getRank() == 0) std::cout << xpetraParameters << matrixParameters; // // Setup test case (Ax = b) // // Distribution RCP<const Map> map = MapFactory::Build(lib, matrixParameters.GetNumGlobalElements(), 0, comm); // Matrix RCP<Galeri::Xpetra::Problem<Map,CrsMatrixWrap,MultiVector> > Pr = Galeri::Xpetra::BuildProblem<SC, LO, GO, Map, CrsMatrixWrap, MultiVector>(matrixParameters.GetMatrixType(), map, matrixParameters.GetParameterList()); RCP<Matrix> A = Pr->BuildMatrix(); // User defined nullspace RCP<MultiVector> nullSpace = VectorFactory::Build(map,1); nullSpace->putScalar((SC) 1.0); // Define B RCP<Vector> X = VectorFactory::Build(map,1); RCP<Vector> B = VectorFactory::Build(map,1); X->setSeed(846930886); X->randomize(); A->apply(*X, *B, Teuchos::NO_TRANS, (SC)1.0, (SC)0.0); // X = 0 X->putScalar((SC) 0.0); // // Create a multigrid configuration // // Transfer operators RCP<TentativePFactory> TentativePFact = rcp( new TentativePFactory() ); RCP<SaPFactory> SaPFact = rcp( new SaPFactory() ); RCP<TransPFactory> RFact = rcp( new TransPFactory()); FactoryManager M; M.SetFactory("Ptent", TentativePFact); M.SetFactory("P", SaPFact); M.SetFactory("R", RFact); M.SetFactory("Smoother", Teuchos::null); //skips smoother setup M.SetFactory("CoarseSolver", Teuchos::null); //skips coarsest solve setup // // Multigrid setup phase // int startLevel = 0; int maxLevels = 10; std::cout << "=============== Setup transfers only ====================" << std::endl; Hierarchy H; H.SetDefaultVerbLevel(MueLu::Medium); RCP<Level> finestLevel = H.GetLevel(); finestLevel->Set("A", A); finestLevel->Set("Nullspace", nullSpace); // Indicate which Hierarchy operators we want to keep H.Keep("P", SaPFact.get()); //SaPFact is the generating factory for P. H.Keep("R", RFact.get()); //RFact is the generating factory for R. H.Keep("Ptent", TentativePFact.get()); //SaPFact is the generating factory for P. H.Setup(M,startLevel,maxLevels); std::cout << "=============== Setup smoothers only ====================" << std::endl; // Create a new A. RCP<Matrix> newA = Pr->BuildMatrix(); finestLevel->Set("A", newA); // Create Gauss-Seidel smoother. std::string ifpackType = "RELAXATION"; Teuchos::ParameterList ifpackList; ifpackList.set("relaxation: sweeps", (LO) 3); ifpackList.set("relaxation: damping factor", (SC) 1.0); RCP<SmootherPrototype> smootherPrototype = rcp(new TrilinosSmoother(ifpackType, ifpackList)); M.SetFactory("Smoother", rcp(new SmootherFactory(smootherPrototype))); // Create coarsest solver. RCP<SmootherPrototype> coarseSolverPrototype = rcp( new DirectSolver() ); RCP<SmootherFactory> coarseSolverFact = rcp( new SmootherFactory(coarseSolverPrototype, Teuchos::null) ); M.SetFactory("CoarseSolver", coarseSolverFact); // Note that we pass the number of levels back in. H.Setup(M,startLevel, H.GetNumLevels()); std::cout << "=============== Solve ====================" << std::endl; // // Solve Ax = B // LO nIts = 9; H.Iterate(*B, *X, nIts); // // Print relative residual norm // typename Teuchos::ScalarTraits<SC>::magnitudeType residualNorms = Utilities::ResidualNorm(*A, *X, *B)[0]; if (comm->getRank() == 0) { std::ios::fmtflags f(std::cout.flags()); std::cout << "||Residual|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(20) << residualNorms << std::endl; std::cout.flags(f); } success = true; } TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success); return ( success ? EXIT_SUCCESS : EXIT_FAILURE ); }
void AdaptiveSaMLParameterListInterpreter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetupHierarchy(Hierarchy & H) const { // set fine level null space // usually this null space is provided from outside (by the user) using // the ML parameter lists. if (this->nullspace_ != NULL) { RCP<Level> fineLevel = H.GetLevel(0); const RCP<const Map> rowMap = fineLevel->Get< RCP<Matrix> >("A")->getRowMap(); RCP<MultiVector> nullspace = MultiVectorFactory::Build(rowMap, nullspaceDim_, true); for ( size_t i=0; i < Teuchos::as<size_t>(nullspaceDim_); i++) { Teuchos::ArrayRCP<Scalar> nullspacei = nullspace->getDataNonConst(i); const size_t myLength = nullspace->getLocalLength(); for (size_t j = 0; j < myLength; j++) { nullspacei[j] = nullspace_[i*myLength + j]; } } fineLevel->Set("Nullspace", nullspace); } // keep aggregates H.Keep("Aggregates", HierarchyManager::GetFactoryManager(0)->GetFactory("Aggregates").get()); /////////////////////////////// // build hierarchy for initialization SetupInitHierarchy(H); { // do some iterations with the built hierarchy to improve the null space Teuchos::RCP<MueLu::Level> Finest = H.GetLevel(0); // get finest level,MueLu::NoFactory::get() Teuchos::RCP<MultiVector> nspVector2 = Finest->Get<Teuchos::RCP<MultiVector> >("Nullspace"); Xpetra::IO<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Write("orig_nsp.vec", *nspVector2); RCP<Matrix> Op = Finest->Get<RCP<Matrix> >("A"); Xpetra::IO<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Write("A.mat", *Op); Teuchos::RCP<MultiVector> homogRhsVec = MultiVectorFactory::Build(nspVector2->getMap(),nspVector2->getNumVectors(),true); homogRhsVec->putScalar(0.0); // do 1 multigrid cycle for improving the null space by "solving" // A B_f = 0 // where A is the system matrix and B_f the fine level null space vectors H.Iterate(*homogRhsVec, *nspVector2, 1, false); // store improved fine level null space Finest->Set("Nullspace",nspVector2); Xpetra::IO<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Write("new_nsp.vec", *nspVector2); //H.Delete("CoarseSolver", init_levelManagers_[0]->GetFactory("CoarseSolver").get()); } { // do some clean up. // remove all old default factories. Build new ones for the second build. // this is a little bit tricky to understand for(size_t k=0; k < HierarchyManager::getNumFactoryManagers(); k++) { HierarchyManager::GetFactoryManager(k)->Clean(); //Teuchos::rcp_dynamic_cast<const SingleLevelFactoryBase>(HierarchyManager::GetFactoryManager(k)->GetFactory("Smoother"))->DisableMultipleCallCheck(); // after changing to MLParamterListInterpreter functions } // not sure about this. i only need it if Smoother is defined explicitely (not using default smoother) // need this: otherwise RAPFactory::Build is complaining on level 0 // and TentativePFactory::Build is complaining on level 1 Teuchos::rcp_dynamic_cast<const TwoLevelFactoryBase>(HierarchyManager::GetFactoryManager(0)->GetFactory("A"))->DisableMultipleCallCheck(); Teuchos::rcp_dynamic_cast<const TwoLevelFactoryBase>(HierarchyManager::GetFactoryManager(1)->GetFactory("P"))->DisableMultipleCallCheck(); Teuchos::rcp_dynamic_cast<const TwoLevelFactoryBase>(HierarchyManager::GetFactoryManager(1)->GetFactory("Ptent"))->DisableMultipleCallCheck(); HierarchyManager::SetupHierarchy(H); } }