30 #include "EpetraExt_DiagonalTransientModel.hpp" 
   31 #include "Rythmos_BackwardEulerStepper.hpp" 
   32 #include "Rythmos_ImplicitBDFStepper.hpp" 
   33 #include "Rythmos_ImplicitRKStepper.hpp" 
   34 #include "Rythmos_ForwardSensitivityStepper.hpp" 
   35 #include "Rythmos_TimeStepNonlinearSolver.hpp" 
   36 #include "Rythmos_DefaultIntegrator.hpp" 
   37 #include "Rythmos_SimpleIntegrationControlStrategy.hpp" 
   38 #include "Rythmos_StepperAsModelEvaluator.hpp" 
   39 #include "Rythmos_RKButcherTableauBuilder.hpp" 
   40 #include "Stratimikos_DefaultLinearSolverBuilder.hpp" 
   41 #include "Thyra_EpetraModelEvaluator.hpp" 
   42 #include "Thyra_DirectionalFiniteDiffCalculator.hpp" 
   43 #include "Thyra_TestingTools.hpp" 
   44 #include "Teuchos_StandardCatchMacros.hpp" 
   45 #include "Teuchos_GlobalMPISession.hpp" 
   46 #include "Teuchos_DefaultComm.hpp" 
   47 #include "Teuchos_VerboseObject.hpp" 
   48 #include "Teuchos_XMLParameterListHelpers.hpp" 
   49 #include "Teuchos_CommandLineProcessor.hpp" 
   50 #include "Teuchos_VerbosityLevelCommandLineProcessorHelpers.hpp" 
   51 #include "Teuchos_as.hpp" 
   54 #  include "Epetra_MpiComm.h" 
   56 #  include "Epetra_SerialComm.h" 
   63 const std::string TimeStepNonlinearSolver_name = 
"TimeStepNonlinearSolver";
 
   65 const std::string Stratimikos_name = 
"Stratimikos";
 
   67 const std::string DiagonalTransientModel_name = 
"DiagonalTransientModel";
 
   69 const std::string RythmosStepper_name = 
"Rythmos Stepper";
 
   71 const std::string RythmosIntegrator_name = 
"Rythmos Integrator";
 
   73 const std::string FdCalc_name = 
"FD Calc";
 
   76 Teuchos::RCP<const Teuchos::ParameterList>
 
   79   using Teuchos::RCP; 
using Teuchos::ParameterList;
 
   80   static RCP<const ParameterList> validPL;
 
   81   if (is_null(validPL)) {
 
   82     RCP<ParameterList> pl = Teuchos::parameterList();
 
   83     pl->sublist(TimeStepNonlinearSolver_name);
 
   84     pl->sublist(Stratimikos_name);
 
   85     pl->sublist(DiagonalTransientModel_name);
 
   86     pl->sublist(RythmosStepper_name);
 
   87     pl->sublist(RythmosIntegrator_name);
 
   88     pl->sublist(FdCalc_name);
 
   98 int main(
int argc, 
char *argv[])
 
  102   typedef double Scalar;
 
  104   using Teuchos::describe;
 
  107   using Teuchos::rcp_implicit_cast;
 
  108   using Teuchos::rcp_dynamic_cast;
 
  110   using Teuchos::ParameterList;
 
  111   using Teuchos::CommandLineProcessor;
 
  112   typedef Teuchos::ParameterList::PrintOptions PLPrintOptions;
 
  113   typedef Thyra::ModelEvaluatorBase MEB;
 
  115   using Thyra::productVectorBase;
 
  117   bool result, success = 
true;
 
  119   Teuchos::GlobalMPISession mpiSession(&argc,&argv);
 
  121   RCP<Epetra_Comm> epetra_comm;
 
  123   epetra_comm = rcp( 
new Epetra_MpiComm(MPI_COMM_WORLD) );
 
  125   epetra_comm = rcp( 
new Epetra_SerialComm );
 
  128   RCP<Teuchos::FancyOStream>
 
  129     out = Teuchos::VerboseObjectBase::getDefaultOStream();
 
  137     CommandLineProcessor clp;
 
  138     clp.throwExceptions(
false);
 
  139     clp.addOutputSetupOptions(
true);
 
  141     std::string paramsFileName = 
"";
 
  142     clp.setOption( 
"params-file", ¶msFileName,
 
  143       "File name for XML parameters" );
 
  145     std::string extraParamsString = 
"";
 
  146     clp.setOption( 
"extra-params", &extraParamsString,
 
  147       "Extra XML parameters" );
 
  149     std::string extraParamsFile = 
"";
 
  150     clp.setOption( 
"extra-params-file", &extraParamsFile, 
"File containing extra parameters in XML format.");
 
  152     double maxStateError = 1e-6;
 
  153     clp.setOption( 
"max-state-error", &maxStateError,
 
  154       "The maximum allowed error in the integrated state in relation to the exact state solution" );
 
  156     double finalTime = 1e-3;
 
  157     clp.setOption( 
"final-time", &finalTime,
 
  158       "Final integration time (initial time is 0.0)" );
 
  160     int numTimeSteps = 10;
 
  161     clp.setOption( 
"num-time-steps", &numTimeSteps,
 
  162       "Number of (fixed) time steps.  If <= 0.0, then variable time steps are taken" );
 
  165     clp.setOption( 
"use-BDF", 
"use-BE", &useBDF,
 
  166       "Use BDF or Backward Euler (BE)" );
 
  169     clp.setOption( 
"use-IRK", 
"use-other", &useIRK,
 
  170       "Use IRK or something" );
 
  172     bool doFwdSensSolve = 
false;
 
  173     clp.setOption( 
"fwd-sens-solve", 
"state-solve", &doFwdSensSolve,
 
  174       "Do the forward sensitivity solve or just the state solve" );
 
  176     bool doFwdSensErrorControl = 
false;
 
  177     clp.setOption( 
"fwd-sens-err-cntrl", 
"no-fwd-sens-err-cntrl", &doFwdSensErrorControl,
 
  178       "Do error control on the forward sensitivity solve or not" );
 
  180     double maxRestateError = 0.0;
 
  181     clp.setOption( 
"max-restate-error", &maxRestateError,
 
  182       "The maximum allowed error between the state integrated by itself verses integrated along with DxDp" );
 
  184     double maxSensError = 1e-4;
 
  185     clp.setOption( 
"max-sens-error", &maxSensError,
 
  186       "The maximum allowed error in the integrated sensitivity in relation to" 
  187       " the finite-difference sensitivity" );
 
  189     Teuchos::EVerbosityLevel verbLevel = Teuchos::VERB_DEFAULT;
 
  190     setVerbosityLevelOption( 
"verb-level", &verbLevel,
 
  191       "Top-level verbosity level.  By default, this gets deincremented as you go deeper into numerical objects.",
 
  194     bool testExactSensitivity = 
false;
 
  195     clp.setOption( 
"test-exact-sens", 
"no-test-exact-sens", &testExactSensitivity,
 
  196       "Test the exact sensitivity with finite differences or not." );
 
  198     bool dumpFinalSolutions = 
false;
 
  200       "dump-final-solutions", 
"no-dump-final-solutions", &dumpFinalSolutions,
 
  201       "Determine if the final solutions are dumpped or not." );
 
  203     CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
 
  204     if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) 
return parse_return;
 
  206     if ( Teuchos::VERB_DEFAULT == verbLevel )
 
  207       verbLevel = Teuchos::VERB_LOW;
 
  209     const Teuchos::EVerbosityLevel
 
  210       solnVerbLevel = ( dumpFinalSolutions ? Teuchos::VERB_EXTREME : verbLevel );
 
  218       paramList = Teuchos::parameterList();
 
  219     if (paramsFileName.length())
 
  220       updateParametersFromXmlFile( paramsFileName, paramList.ptr() );
 
  221     if(extraParamsFile.length())
 
  222       Teuchos::updateParametersFromXmlFile( 
"./"+extraParamsFile, paramList.ptr() );
 
  223     if (extraParamsString.length())
 
  224       updateParametersFromXmlString( extraParamsString, paramList.ptr() );
 
  226     if (testExactSensitivity) {
 
  227       paramList->sublist(DiagonalTransientModel_name).set(
"Exact Solution as Response",
true);
 
  230     paramList->validateParameters(*getValidParameters(),0); 
 
  239     Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder;
 
  240     linearSolverBuilder.setParameterList(sublist(paramList,Stratimikos_name));
 
  241     RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
 
  242       W_factory = createLinearSolveStrategy(linearSolverBuilder);
 
  248     RCP<EpetraExt::DiagonalTransientModel>
 
  249       epetraStateModel = EpetraExt::diagonalTransientModel(
 
  251         sublist(paramList,DiagonalTransientModel_name)
 
  254     *out <<
"\nepetraStateModel valid options:\n";
 
  255     epetraStateModel->getValidParameters()->print(
 
  256       *out, PLPrintOptions().indent(2).showTypes(
true).showDoc(
true)
 
  263     RCP<Thyra::ModelEvaluator<double> >
 
  264       stateModel = epetraModelEvaluator(epetraStateModel,W_factory);
 
  266     *out << 
"\nParameter names = " << *stateModel->get_p_names(0) << 
"\n";
 
  272     RCP<Rythmos::TimeStepNonlinearSolver<double> >
 
  273       nonlinearSolver = Rythmos::timeStepNonlinearSolver<double>();
 
  275       nonlinearSolverPL = sublist(paramList,TimeStepNonlinearSolver_name);
 
  276     nonlinearSolverPL->get(
"Default Tol",1e-3*maxStateError); 
 
  277     nonlinearSolver->setParameterList(nonlinearSolverPL);
 
  279     RCP<Rythmos::StepperBase<Scalar> > stateStepper;
 
  284           stateModel, nonlinearSolver
 
  290       RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
 
  291         irk_W_factory = createLinearSolveStrategy(linearSolverBuilder);
 
  292       RCP<Rythmos::RKButcherTableauBase<double> > irkbt = Rythmos::createRKBT<double>(
"Backward Euler");
 
  293       stateStepper = Rythmos::implicitRKStepper<double>(
 
  294         stateModel, nonlinearSolver, irk_W_factory, irkbt
 
  300           stateModel, nonlinearSolver
 
  305     *out <<
"\nstateStepper:\n" << describe(*stateStepper,verbLevel);
 
  306     *out <<
"\nstateStepper valid options:\n";
 
  307     stateStepper->getValidParameters()->print(
 
  308       *out, PLPrintOptions().indent(2).showTypes(
true).showDoc(
true)
 
  311     stateStepper->setParameterList(sublist(paramList,RythmosStepper_name));
 
  317     Thyra::DirectionalFiniteDiffCalculator<Scalar> fdCalc;
 
  318     fdCalc.setParameterList(sublist(paramList,FdCalc_name));
 
  319     fdCalc.setOStream(out);
 
  320     fdCalc.setVerbLevel(verbLevel);
 
  326     const MEB::InArgs<Scalar>
 
  327       state_ic = stateModel->getNominalValues();
 
  328     *out << 
"\nstate_ic:\n" << describe(state_ic,verbLevel);
 
  330     RCP<Rythmos::IntegratorBase<Scalar> > integrator;
 
  333         integratorPL = sublist(paramList,RythmosIntegrator_name);
 
  334       integratorPL->set( 
"Take Variable Steps", as<bool>(numTimeSteps < 0) );
 
  335       integratorPL->set( 
"Fixed dt", as<double>((finalTime - state_ic.get_t())/numTimeSteps) );
 
  336       RCP<Rythmos::IntegratorBase<Scalar> >
 
  338           Rythmos::simpleIntegrationControlStrategy<Scalar>(integratorPL)
 
  343     RCP<Rythmos::StepperAsModelEvaluator<Scalar> >
 
  344       stateIntegratorAsModel = Rythmos::stepperAsModelEvaluator(
 
  345         stateStepper, integrator, state_ic
 
  347     stateIntegratorAsModel->setVerbLevel(verbLevel);
 
  349     *out << 
"\nUse the StepperAsModelEvaluator to integrate state x(p,finalTime) ... \n";
 
  351     RCP<Thyra::VectorBase<Scalar> > x_final;
 
  355       Teuchos::OSTab tab(out);
 
  357       x_final = createMember(stateIntegratorAsModel->get_g_space(0));
 
  360         *stateIntegratorAsModel,
 
  361         0, *state_ic.get_p(0),
 
  367         << 
"\nx_final = x(p,finalTime) evaluated using stateIntegratorAsModel:\n" 
  368         << describe(*x_final,solnVerbLevel);
 
  376     RCP<const Thyra::VectorBase<Scalar> >
 
  377       exact_x_final = create_Vector(
 
  378         epetraStateModel->getExactSolution(finalTime),
 
  379         stateModel->get_x_space()
 
  382     result = Thyra::testRelNormDiffErr(
 
  383       "exact_x_final", *exact_x_final, 
"x_final", *x_final,
 
  384       "maxStateError", maxStateError, 
"warningTol", 1.0, 
 
  387     if (!result) success = 
false;
 
  393     if (doFwdSensSolve) {
 
  399       RCP<Rythmos::ForwardSensitivityStepper<Scalar> > stateAndSensStepper =
 
  400         Rythmos::forwardSensitivityStepper<Scalar>();
 
  401       if (doFwdSensErrorControl) {
 
  402         stateAndSensStepper->initializeDecoupledSteppers(
 
  403           stateModel, 0, stateModel->getNominalValues(),
 
  404           stateStepper, nonlinearSolver,
 
  405           integrator->cloneIntegrator(), finalTime
 
  409         stateAndSensStepper->initializeSyncedSteppers(
 
  410           stateModel, 0, stateModel->getNominalValues(),
 
  411           stateStepper, nonlinearSolver
 
  422       RCP<Thyra::VectorBase<Scalar> > s_bar_init
 
  423         = createMember(stateAndSensStepper->getFwdSensModel()->get_x_space());
 
  424       assign( s_bar_init.ptr(), 0.0 );
 
  425       RCP<Thyra::VectorBase<Scalar> > s_bar_dot_init
 
  426         = createMember(stateAndSensStepper->getFwdSensModel()->get_x_space());
 
  427       assign( s_bar_dot_init.ptr(), 0.0 );
 
  432       RCP<const Rythmos::StateAndForwardSensitivityModelEvaluator<Scalar> >
 
  433         stateAndSensModel = stateAndSensStepper->getStateAndFwdSensModel();
 
  436         state_and_sens_ic = stateAndSensStepper->getModel()->createInArgs();
 
  439       state_and_sens_ic.setArgs(state_ic);
 
  441       state_and_sens_ic.set_x(
 
  442         stateAndSensModel->create_x_bar_vec(state_ic.get_x(),s_bar_init)
 
  445       state_and_sens_ic.set_x_dot(
 
  446         stateAndSensModel->create_x_bar_vec(state_ic.get_x_dot(),s_bar_dot_init)
 
  449       *out << 
"\nstate_and_sens_ic:\n" << describe(state_and_sens_ic,verbLevel);
 
  451       stateAndSensStepper->setInitialCondition(state_and_sens_ic);
 
  457       RCP<Rythmos::StepperAsModelEvaluator<Scalar> >
 
  458         stateAndSensIntegratorAsModel = Rythmos::stepperAsModelEvaluator(
 
  460           integrator, state_and_sens_ic
 
  462       stateAndSensIntegratorAsModel->setVerbLevel(verbLevel);
 
  464       *out << 
"\nUse the StepperAsModelEvaluator to integrate state + sens x_bar(p,finalTime) ... \n";
 
  466       RCP<Thyra::VectorBase<Scalar> > x_bar_final;
 
  470         Teuchos::OSTab tab(out);
 
  472         x_bar_final = createMember(stateAndSensIntegratorAsModel->get_g_space(0));
 
  475           *stateAndSensIntegratorAsModel,
 
  476           0, *state_ic.get_p(0),
 
  482           << 
"\nx_bar_final = x_bar(p,finalTime) evaluated using stateAndSensIntegratorAsModel:\n" 
  483           << describe(*x_bar_final,solnVerbLevel);
 
  491       *out << 
"\nChecking that x(p,finalTime) computed as part of x_bar above is the same ...\n";
 
  495         Teuchos::OSTab tab(out);
 
  497         RCP<const Thyra::VectorBase<Scalar> >
 
  498           x_in_x_bar_final = productVectorBase<Scalar>(x_bar_final)->getVectorBlock(0);
 
  500         result = Thyra::testRelNormDiffErr<Scalar>(
 
  502           "x_in_x_bar_final", *x_in_x_bar_final,
 
  503           "maxRestateError", maxRestateError,
 
  507         if (!result) success = 
false;
 
  515       *out << 
"\nApproximating DxDp(p,t) using directional finite differences of integrator for x(p,t) ...\n";
 
  517       RCP<Thyra::MultiVectorBase<Scalar> > DxDp_fd_final;
 
  521         Teuchos::OSTab tab(out);
 
  525           fdBasePoint = stateIntegratorAsModel->createInArgs();
 
  527         fdBasePoint.set_t(finalTime);
 
  528         fdBasePoint.set_p(0,stateModel->getNominalValues().get_p(0));
 
  530         DxDp_fd_final = createMembers(
 
  531           stateIntegratorAsModel->get_g_space(0),
 
  532           stateIntegratorAsModel->get_p_space(0)->dim()
 
  535         typedef Thyra::DirectionalFiniteDiffCalculatorTypes::SelectedDerivatives
 
  538         MEB::OutArgs<Scalar> fdOutArgs =
 
  539           fdCalc.createOutArgs(
 
  540             *stateIntegratorAsModel,
 
  541             SelectedDerivatives().supports(MEB::OUT_ARG_DgDp,0,0)
 
  543         fdOutArgs.set_DgDp(0,0,DxDp_fd_final);
 
  547         stateStepper->setVerbLevel(Teuchos::VERB_NONE);
 
  548         stateIntegratorAsModel->setVerbLevel(Teuchos::VERB_NONE);
 
  550         fdCalc.calcDerivatives(
 
  551           *stateIntegratorAsModel, fdBasePoint,
 
  552           stateIntegratorAsModel->createOutArgs(), 
 
  557           << 
"\nFinite difference DxDp_fd_final = DxDp(p,finalTime): " 
  558           << describe(*DxDp_fd_final,solnVerbLevel);
 
  566       *out << 
"\nChecking that integrated DxDp(p,finalTime) and finite-diff DxDp(p,finalTime) are similar ...\n";
 
  570         Teuchos::OSTab tab(out);
 
  572         RCP<const Thyra::VectorBase<Scalar> >
 
  573           DxDp_vec_final = Thyra::productVectorBase<Scalar>(x_bar_final)->getVectorBlock(1);
 
  575         RCP<const Thyra::VectorBase<Scalar> >
 
  576           DxDp_fd_vec_final = Thyra::multiVectorProductVector(
 
  577             rcp_dynamic_cast<
const Thyra::DefaultMultiVectorProductVectorSpace<Scalar> >(
 
  578               DxDp_vec_final->range()
 
  583         result = Thyra::testRelNormDiffErr(
 
  584           "DxDp_vec_final", *DxDp_vec_final,
 
  585           "DxDp_fd_vec_final", *DxDp_fd_vec_final,
 
  586           "maxSensError", maxSensError,
 
  590         if (!result) success = 
false;
 
  597   TEUCHOS_STANDARD_CATCH_STATEMENTS(
true,*out,success);
 
  600     *out << 
"\nEnd Result: TEST PASSED" << endl;
 
  602     *out << 
"\nEnd Result: TEST FAILED" << endl;
 
  604   return ( success ? 0 : 1 );
 
Simple concrete stepper subclass implementing an implicit backward Euler method. 
Base class for defining stepper functionality. 
RCP< DefaultIntegrator< Scalar > > defaultIntegrator()