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()