void addMueLuToStratimikosBuilder(Stratimikos::DefaultLinearSolverBuilder & builder, const std::string & stratName) { TEUCHOS_TEST_FOR_EXCEPTION(builder.getValidParameters()->sublist("Preconditioner Types").isParameter(stratName),std::logic_error, "MueLu::addMueLuToStratimikosBuilder cannot add \"" + stratName +"\" because it is already included in builder!"); // use default constructor to add Teko::StratimikosFactory builder.setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>,Thyra::MueLuPreconditionerFactory>(), stratName); }
void addTekoToStratimikosBuilder(Stratimikos::DefaultLinearSolverBuilder & builder, const Teuchos::RCP<Teko::RequestHandler> & rh, const std::string & stratName) { TEUCHOS_TEST_FOR_EXCEPTION(builder.getValidParameters()->sublist("Preconditioner Types").isParameter(stratName),std::logic_error, "Teko::addTekoToStratimikosBuilder cannot add \"" + stratName +"\" because it is already included in builder!"); // build an instance of a Teuchos::AbsractFactory<Thyra::PFB> so request handler is passed onto // the resulting StratimikosFactory Teuchos::RCP<TekoFactoryBuilder> tekoFactoryBuilder = Teuchos::rcp(new TekoFactoryBuilder(rh)); builder.setPreconditioningStrategyFactory(tekoFactoryBuilder,stratName); }
TEUCHOS_UNIT_TEST(tStratimikosFactory, test_Defaults) { using Teuchos::RCP; using Teuchos::ParameterList; // build global (or serial communicator) #ifdef HAVE_MPI Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif // build epetra operator RCP<Epetra_Operator> eA = buildSystem(comm,5); RCP<Thyra::LinearOpBase<double> > tA = Thyra::nonconstEpetraLinearOp(eA); // build stratimikos factory, adding Teko's version Stratimikos::DefaultLinearSolverBuilder stratFactory; stratFactory.setPreconditioningStrategyFactory( Teuchos::abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>,Teko::StratimikosFactory>(), "Teko"); RCP<const ParameterList> validParams = stratFactory.getValidParameters(); stratFactory.setParameterList(Teuchos::rcp(new Teuchos::ParameterList(*validParams))); // print out Teko's parameter list and fail if it doesn't exist! TEST_NOTHROW(validParams->sublist("Preconditioner Types").sublist("Teko").print(out, ParameterList::PrintOptions().showDoc(true).indent(2).showTypes(true))); // build teko preconditioner factory RCP<Thyra::PreconditionerFactoryBase<double> > precFactory = stratFactory.createPreconditioningStrategy("Teko"); // make sure factory is built TEST_ASSERT(precFactory!=Teuchos::null); // build preconditioner RCP<Thyra::PreconditionerBase<double> > prec = Thyra::prec<double>(*precFactory,tA); TEST_ASSERT(prec!=Teuchos::null); // build an operator to test against RCP<const Teko::InverseLibrary> invLib = Teko::InverseLibrary::buildFromStratimikos(); RCP<const Teko::InverseFactory> invFact = invLib->getInverseFactory("Amesos"); Teko::LinearOp testOp = Teko::buildInverse(*invFact,tA); Teko::LinearOp precOp = prec->getUnspecifiedPrecOp(); TEST_ASSERT(precOp!=Teuchos::null); Thyra::LinearOpTester<double> tester; tester.show_all_tests(true); tester.set_all_error_tol(0); TEST_ASSERT(tester.compare(*precOp,*testOp,Teuchos::ptrFromRef(out))); }
void Piro::RythmosSolver<Scalar>::initialize( #endif const Teuchos::RCP<Teuchos::ParameterList> &appParams, const Teuchos::RCP< Thyra::ModelEvaluator<Scalar> > &in_model, const Teuchos::RCP<Rythmos::IntegrationObserverBase<Scalar> > &observer) { using Teuchos::ParameterList; using Teuchos::parameterList; using Teuchos::RCP; using Teuchos::rcp; // set some internals model = in_model; num_p = in_model->Np(); num_g = in_model->Ng(); // *out << "\nA) Get the base parameter list ...\n"; // if (appParams->isSublist("Rythmos")) { RCP<Teuchos::ParameterList> rythmosPL = sublist(appParams, "Rythmos", true); rythmosPL->validateParameters(*getValidRythmosParameters(),0); { const std::string verbosity = rythmosPL->get("Verbosity Level", "VERB_DEFAULT"); if (verbosity == "VERB_NONE") solnVerbLevel = Teuchos::VERB_NONE; else if (verbosity == "VERB_DEFAULT") solnVerbLevel = Teuchos::VERB_DEFAULT; else if (verbosity == "VERB_LOW") solnVerbLevel = Teuchos::VERB_LOW; else if (verbosity == "VERB_MEDIUM") solnVerbLevel = Teuchos::VERB_MEDIUM; else if (verbosity == "VERB_HIGH") solnVerbLevel = Teuchos::VERB_HIGH; else if (verbosity == "VERB_EXTREME") solnVerbLevel = Teuchos::VERB_EXTREME; else TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,"Unknown verbosity option specified in Piro_RythmosSolver."); } t_initial = rythmosPL->get("Initial Time", 0.0); t_final = rythmosPL->get("Final Time", 0.1); const std::string stepperType = rythmosPL->get("Stepper Type", "Backward Euler"); // *out << "\nC) Create and initalize the forward model ...\n"; // *out << "\nD) Create the stepper and integrator for the forward problem ...\n"; // if (rythmosPL->get<std::string>("Nonlinear Solver Type") == "Rythmos") { Teuchos::RCP<Rythmos::TimeStepNonlinearSolver<Scalar> > rythmosTimeStepSolver = Rythmos::timeStepNonlinearSolver<Scalar>(); if (rythmosPL->getEntryPtr("NonLinear Solver")) { RCP<Teuchos::ParameterList> nonlinePL = sublist(rythmosPL, "NonLinear Solver", true); rythmosTimeStepSolver->setParameterList(nonlinePL); } fwdTimeStepSolver = rythmosTimeStepSolver; } else if (rythmosPL->get<std::string>("Nonlinear Solver Type") == "NOX") { #ifdef HAVE_PIRO_NOX Teuchos::RCP<Thyra::NOXNonlinearSolver> nox_solver = Teuchos::rcp(new Thyra::NOXNonlinearSolver); Teuchos::RCP<Teuchos::ParameterList> nox_params = Teuchos::rcp(new Teuchos::ParameterList); *nox_params = appParams->sublist("NOX"); nox_solver->setParameterList(nox_params); fwdTimeStepSolver = nox_solver; #else TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,"Requested NOX solver for a Rythmos Transient solve, Trilinos was not built with NOX enabled. Please rebuild Trilinos or use the native Rythmos nonlinear solver."); #endif } if (stepperType == "Backward Euler") { fwdStateStepper = Rythmos::backwardEulerStepper<Scalar> (model, fwdTimeStepSolver); fwdStateStepper->setParameterList(sublist(rythmosPL, "Rythmos Stepper", true)); } else if (stepperType == "Forward Euler") { fwdStateStepper = Rythmos::forwardEulerStepper<Scalar> (model); fwdStateStepper->setParameterList(sublist(rythmosPL, "Rythmos Stepper", true)); } else if (stepperType == "Explicit RK") { fwdStateStepper = Rythmos::explicitRKStepper<Scalar>(model); fwdStateStepper->setParameterList(sublist(rythmosPL, "Rythmos Stepper", true)); } else if (stepperType == "BDF") { Teuchos::RCP<Teuchos::ParameterList> BDFparams = Teuchos::sublist(rythmosPL, "Rythmos Stepper", true); Teuchos::RCP<Teuchos::ParameterList> BDFStepControlPL = Teuchos::sublist(BDFparams,"Step Control Settings"); fwdStateStepper = Teuchos::rcp( new Rythmos::ImplicitBDFStepper<Scalar>(model,fwdTimeStepSolver,BDFparams) ); fwdStateStepper->setInitialCondition(model->getNominalValues()); } else { // first (before failing) check to see if the user has added stepper factory typename std::map<std::string,Teuchos::RCP<Piro::RythmosStepperFactory<Scalar> > >::const_iterator stepFactItr = stepperFactories.find(stepperType); if(stepFactItr!=stepperFactories.end()) { // the user has added it, hot dog lets build a new stepper! Teuchos::RCP<Teuchos::ParameterList> stepperParams = Teuchos::sublist(rythmosPL, "Rythmos Stepper", true); // build the stepper using the factory fwdStateStepper = stepFactItr->second->buildStepper(model,fwdTimeStepSolver,stepperParams); // the user decided to override the model being used (let them) if(fwdStateStepper->getModel()!=model && fwdStateStepper->getModel()!=Teuchos::null) { model = Teuchos::rcp_const_cast<Thyra::ModelEvaluator<Scalar> >(fwdStateStepper->getModel()); num_p = in_model->Np(); num_g = in_model->Ng(); } } else { TEUCHOS_TEST_FOR_EXCEPTION( true, Teuchos::Exceptions::InvalidParameter, std::endl << "Error! Piro::RythmosSolver: Invalid Steper Type: " << stepperType << std::endl); } } // Step control strategy { // If the stepper can accept a step control strategy, then attempt to build one. RCP<Rythmos::StepControlStrategyAcceptingStepperBase<Scalar> > scsa_stepper = Teuchos::rcp_dynamic_cast<Rythmos::StepControlStrategyAcceptingStepperBase<Scalar> >(fwdStateStepper); if (Teuchos::nonnull(scsa_stepper)) { const std::string step_control_strategy = rythmosPL->get("Step Control Strategy Type", "None"); if (step_control_strategy == "None") { // don't do anything, stepper will build default } else if (step_control_strategy == "ImplicitBDFRamping") { const RCP<Rythmos::ImplicitBDFStepperRampingStepControl<Scalar> > rscs = rcp(new Rythmos::ImplicitBDFStepperRampingStepControl<Scalar>); const RCP<ParameterList> p = parameterList(rythmosPL->sublist("Rythmos Step Control Strategy")); rscs->setParameterList(p); scsa_stepper->setStepControlStrategy(rscs); } else { // first (before failing) check to see if the user has added step control factory typename std::map<std::string,Teuchos::RCP<Piro::RythmosStepControlFactory<Scalar> > >::const_iterator stepControlFactItr = stepControlFactories.find(step_control_strategy); if (stepControlFactItr != stepControlFactories.end()) { const RCP<Rythmos::StepControlStrategyBase<Scalar> > rscs = stepControlFactItr->second->buildStepControl(); const RCP<ParameterList> p = parameterList(rythmosPL -> sublist("Rythmos Step Control Strategy")); rscs->setParameterList(p); scsa_stepper->setStepControlStrategy(rscs); } else { TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Error! Piro::RythmosSolver: Invalid step control strategy type: " << step_control_strategy << std::endl); } } } } { const RCP<Teuchos::ParameterList> integrationControlPL = Teuchos::sublist(rythmosPL, "Rythmos Integration Control", true); RCP<Rythmos::DefaultIntegrator<Scalar> > defaultIntegrator; if (rythmosPL->get("Rythmos Integration Control Strategy", "Simple") == "Simple") { defaultIntegrator = Rythmos::controlledDefaultIntegrator<Scalar>(Rythmos::simpleIntegrationControlStrategy<Scalar>(integrationControlPL)); } else if(rythmosPL->get<std::string>("Rythmos Integration Control Strategy") == "Ramping") { defaultIntegrator = Rythmos::controlledDefaultIntegrator<Scalar>(Rythmos::rampingIntegrationControlStrategy<Scalar>(integrationControlPL)); } fwdStateIntegrator = defaultIntegrator; } fwdStateIntegrator->setParameterList(sublist(rythmosPL, "Rythmos Integrator", true)); if (Teuchos::nonnull(observer)) { fwdStateIntegrator->setIntegrationObserver(observer); } } else if (appParams->isSublist("Rythmos Solver")) { /** New parameter list format **/ RCP<Teuchos::ParameterList> rythmosSolverPL = sublist(appParams, "Rythmos Solver", true); RCP<Teuchos::ParameterList> rythmosPL = sublist(rythmosSolverPL, "Rythmos", true); { const std::string verbosity = rythmosSolverPL->get("Verbosity Level", "VERB_DEFAULT"); if (verbosity == "VERB_NONE") solnVerbLevel = Teuchos::VERB_NONE; else if (verbosity == "VERB_DEFAULT") solnVerbLevel = Teuchos::VERB_DEFAULT; else if (verbosity == "VERB_LOW") solnVerbLevel = Teuchos::VERB_LOW; else if (verbosity == "VERB_MEDIUM") solnVerbLevel = Teuchos::VERB_MEDIUM; else if (verbosity == "VERB_HIGH") solnVerbLevel = Teuchos::VERB_HIGH; else if (verbosity == "VERB_EXTREME") solnVerbLevel = Teuchos::VERB_EXTREME; else TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Unknown verbosity option specified in Piro_RythmosSolver."); } t_initial = rythmosPL->sublist("Integrator Settings").get("Initial Time", 0.0); t_final = rythmosPL->sublist("Integrator Settings").get("Final Time", 0.1); const std::string stepperType = rythmosPL->sublist("Stepper Settings") .sublist("Stepper Selection").get("Stepper Type", "Backward Euler"); // // *out << "\nB) Create the Stratimikos linear solver factory ...\n"; // // This is the linear solve strategy that will be used to solve for the // linear system with the W. // Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder; #ifdef HAVE_PIRO_IFPACK2 typedef Thyra::PreconditionerFactoryBase<double> Base; #ifdef ALBANY_BUILD typedef Thyra::Ifpack2PreconditionerFactory<Tpetra::CrsMatrix<double, LocalOrdinal, GlobalOrdinal, Node> > Impl; #else typedef Thyra::Ifpack2PreconditionerFactory<Tpetra::CrsMatrix<double> > Impl; #endif linearSolverBuilder.setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, Impl>(), "Ifpack2"); #endif #ifdef HAVE_PIRO_MUELU #ifdef ALBANY_BUILD Stratimikos::enableMueLu<LocalOrdinal, GlobalOrdinal, Node>(linearSolverBuilder); #else Stratimikos::enableMueLu(linearSolverBuilder); #endif #endif linearSolverBuilder.setParameterList(sublist(rythmosSolverPL, "Stratimikos", true)); rythmosSolverPL->validateParameters(*getValidRythmosSolverParameters(),0); RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory = createLinearSolveStrategy(linearSolverBuilder); // *out << "\nC) Create and initalize the forward model ...\n"; // // C.1) Create the underlying EpetraExt::ModelEvaluator // already constructed as "model". Decorate if needed. // TODO: Generelize to any explicit method, option to invert mass matrix if (stepperType == "Explicit RK") { if (rythmosSolverPL->get("Invert Mass Matrix", false)) { Teuchos::RCP<Thyra::ModelEvaluator<Scalar> > origModel = model; rythmosSolverPL->get("Lump Mass Matrix", false); //JF line does not do anything model = Teuchos::rcp(new Piro::InvertMassMatrixDecorator<Scalar>( sublist(rythmosSolverPL,"Stratimikos", true), origModel, true,rythmosSolverPL->get("Lump Mass Matrix", false),false)); } } // C.2) Create the Thyra-wrapped ModelEvaluator thyraModel = rcp(new Thyra::DefaultModelEvaluatorWithSolveFactory<Scalar>(model, lowsFactory)); const RCP<const Thyra::VectorSpaceBase<double> > x_space = thyraModel->get_x_space(); // *out << "\nD) Create the stepper and integrator for the forward problem ...\n"; // fwdTimeStepSolver = Rythmos::timeStepNonlinearSolver<double>(); if (rythmosSolverPL->getEntryPtr("NonLinear Solver")) { const RCP<Teuchos::ParameterList> nonlinePL = sublist(rythmosSolverPL, "NonLinear Solver", true); fwdTimeStepSolver->setParameterList(nonlinePL); } // Force Default Integrator since this is needed for Observers rythmosPL->sublist("Integrator Settings").sublist("Integrator Selection"). set("Integrator Type","Default Integrator"); RCP<Rythmos::IntegratorBuilder<double> > ib = Rythmos::integratorBuilder<double>(); ib->setParameterList(rythmosPL); Thyra::ModelEvaluatorBase::InArgs<double> ic = thyraModel->getNominalValues(); RCP<Rythmos::IntegratorBase<double> > integrator = ib->create(thyraModel,ic,fwdTimeStepSolver); fwdStateIntegrator = Teuchos::rcp_dynamic_cast<Rythmos::DefaultIntegrator<double> >(integrator,true); fwdStateStepper = fwdStateIntegrator->getNonconstStepper(); if (Teuchos::nonnull(observer)) fwdStateIntegrator->setIntegrationObserver(observer); } else { TEUCHOS_TEST_FOR_EXCEPTION( appParams->isSublist("Rythmos") || appParams->isSublist("Rythmos Solver"), Teuchos::Exceptions::InvalidParameter, std::endl << "Error! Piro::RythmosSolver: must have either Rythmos or Rythmos Solver sublist "); } isInitialized = true; }
TEUCHOS_UNIT_TEST(tStratimikosFactory, test_multi_use) { using Teuchos::RCP; using Teuchos::ParameterList; // build global (or serial communicator) #ifdef HAVE_MPI Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif // build epetra operator RCP<Epetra_Operator> eA = buildSystem(comm,5); RCP<Thyra::LinearOpBase<double> > tA = Thyra::nonconstEpetraLinearOp(eA); // build stratimikos factory, adding Teko's version Stratimikos::DefaultLinearSolverBuilder stratFactory; stratFactory.setPreconditioningStrategyFactory( Teuchos::abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>,Teko::StratimikosFactory>(), "Teko"); RCP<const ParameterList> validParams = stratFactory.getValidParameters(); stratFactory.setParameterList(Teuchos::rcp(new Teuchos::ParameterList(*validParams))); // print out Teko's parameter list and fail if it doesn't exist! TEST_NOTHROW(validParams->sublist("Preconditioner Types").sublist("Teko").print(out, ParameterList::PrintOptions().showDoc(true).indent(2).showTypes(true))); // build teko preconditioner factory RCP<Thyra::PreconditionerFactoryBase<double> > precFactory = stratFactory.createPreconditioningStrategy("Teko"); // make sure factory is built TEST_ASSERT(precFactory!=Teuchos::null); // try using a different preconditioner each time RCP<Thyra::PreconditionerBase<double> > prec; for(int i=0;i<2;i++) { prec = precFactory->createPrec(); RCP<const Thyra::LinearOpSourceBase<double> > losb = rcp(new Thyra::DefaultLinearOpSource<double>(tA)); precFactory->initializePrec(losb,prec.get()); RCP<Teko::StratimikosFactory> stratFact = rcp_dynamic_cast<Teko::StratimikosFactory>(precFactory); const std::vector<int> & decomp = stratFact->getDecomposition(); TEST_EQUALITY(decomp.size(),1); TEST_EQUALITY(decomp[0],1); } // try using a single preconditioner multiple times prec = precFactory->createPrec(); for(int i=0;i<2;i++) { RCP<const Thyra::LinearOpSourceBase<double> > losb = rcp(new Thyra::DefaultLinearOpSource<double>(tA)); precFactory->initializePrec(losb,prec.get()); RCP<Teko::StratimikosFactory> stratFact = rcp_dynamic_cast<Teko::StratimikosFactory>(precFactory); const std::vector<int> & decomp = stratFact->getDecomposition(); TEST_EQUALITY(decomp.size(),1); TEST_EQUALITY(decomp[0],1); } }
TEUCHOS_UNIT_TEST(tStratimikosFactory, test_BlockGaussSeidel) { using Teuchos::RCP; using Teuchos::ParameterList; // build global (or serial communicator) #ifdef HAVE_MPI Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif // build epetra operator RCP<Epetra_Operator> eA = buildStridedSystem(comm,5); RCP<Thyra::LinearOpBase<double> > tA = Thyra::nonconstEpetraLinearOp(eA); // build stratimikos factory, adding Teko's version Stratimikos::DefaultLinearSolverBuilder stratFactory; stratFactory.setPreconditioningStrategyFactory( Teuchos::abstractFactoryStd<Thyra::PreconditionerFactoryBase<double>,Teko::StratimikosFactory>(), "Teko"); RCP<ParameterList> params = Teuchos::rcp(new ParameterList(*stratFactory.getValidParameters())); ParameterList & tekoList = params->sublist("Preconditioner Types").sublist("Teko"); tekoList.set("Write Block Operator", false); tekoList.set("Test Block Operator", false); tekoList.set("Strided Blocking","1 1"); tekoList.set("Inverse Type","BGS"); ParameterList & ifl = tekoList.sublist("Inverse Factory Library"); ifl.sublist("BGS").set("Type","Block Gauss-Seidel"); ifl.sublist("BGS").set("Inverse Type","Amesos"); // RCP<Thyra::PreconditionerFactoryBase<double> > precFactory // = stratFactory.createPreconditioningStrategy("Teko"); // build operator to test against Teko::LinearOp testOp; { Teuchos::ParameterList iflCopy(ifl); RCP<Epetra_Operator> strided_eA = Teuchos::rcp(new Teko::Epetra::StridedEpetraOperator(2,eA)); RCP<Teko::InverseLibrary> invLib = Teko::InverseLibrary::buildFromParameterList(iflCopy); RCP<const Teko::InverseFactory> invFact = invLib->getInverseFactory("BGS"); RCP<Teko::Epetra::InverseFactoryOperator> invFactOp = Teuchos::rcp(new Teko::Epetra::InverseFactoryOperator(invFact)); invFactOp->buildInverseOperator(strided_eA); testOp = Thyra::epetraLinearOp(invFactOp,Thyra::NOTRANS,Thyra::EPETRA_OP_APPLY_APPLY_INVERSE); } stratFactory.setParameterList(params); RCP<Thyra::PreconditionerFactoryBase<double> > precFactory = stratFactory.createPreconditioningStrategy("Teko"); // build teko preconditioner factory RCP<Thyra::PreconditionerBase<double> > prec = Thyra::prec<double>(*precFactory,tA); Teko::LinearOp precOp = prec->getUnspecifiedPrecOp(); TEST_ASSERT(precOp!=Teuchos::null); Thyra::LinearOpTester<double> tester; tester.show_all_tests(true); tester.set_all_error_tol(0); TEST_ASSERT(tester.compare(*precOp,*testOp,Teuchos::ptrFromRef(out))); }