9 #include "Teuchos_UnitTestHarness.hpp"
10 #include "Teuchos_XMLParameterListHelpers.hpp"
11 #include "Teuchos_TimeMonitor.hpp"
12 #include "Teuchos_DefaultComm.hpp"
14 #include "Thyra_VectorStdOps.hpp"
16 #include "Tempus_IntegratorBasic.hpp"
19 #include "../TestModels/SinCosModel.hpp"
20 #include "../TestModels/VanDerPolModel.hpp"
21 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
30 using Teuchos::rcp_const_cast;
31 using Teuchos::ParameterList;
32 using Teuchos::sublist;
33 using Teuchos::getParametersFromXmlFile;
44 std::vector<std::string> RKMethods;
45 RKMethods.push_back(
"General ERK");
46 RKMethods.push_back(
"RK Forward Euler");
47 RKMethods.push_back(
"RK Explicit 4 Stage");
48 RKMethods.push_back(
"RK Explicit 3/8 Rule");
49 RKMethods.push_back(
"RK Explicit 4 Stage 3rd order by Runge");
50 RKMethods.push_back(
"RK Explicit 5 Stage 3rd order by Kinnmark and Gray");
51 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order");
52 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order TVD");
53 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order by Heun");
54 RKMethods.push_back(
"RK Explicit Midpoint");
55 RKMethods.push_back(
"RK Explicit Trapezoidal");
56 RKMethods.push_back(
"Heuns Method");
57 RKMethods.push_back(
"Bogacki-Shampine 3(2) Pair");
58 RKMethods.push_back(
"Merson 4(5) Pair");
60 for(std::vector<std::string>::size_type m = 0; m != RKMethods.size(); m++) {
62 std::string RKMethod = RKMethods[m];
63 std::replace(RKMethod.begin(), RKMethod.end(),
' ',
'_');
64 std::replace(RKMethod.begin(), RKMethod.end(),
'/',
'.');
67 RCP<ParameterList> pList =
68 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
71 RCP<ParameterList> scm_pl = sublist(pList,
"SinCosModel",
true);
75 RCP<ParameterList> tempusPL = sublist(pList,
"Tempus",
true);
76 if (RKMethods[m] ==
"General ERK") {
77 tempusPL->sublist(
"Demo Integrator").set(
"Stepper Name",
"Demo Stepper 2");
79 tempusPL->sublist(
"Demo Stepper").set(
"Stepper Type", RKMethods[m]);
83 tempusPL->sublist(
"Demo Stepper")
84 .set(
"Initial Condition Consistency",
"None");
88 RCP<Tempus::IntegratorBasic<double> > integrator =
89 Tempus::integratorBasic<double>(tempusPL, model);
91 RCP<ParameterList> stepperPL = sublist(tempusPL,
"Demo Stepper",
true);
92 if (RKMethods[m] ==
"General ERK")
93 stepperPL = sublist(tempusPL,
"Demo Stepper 2",
true);
94 RCP<ParameterList> defaultPL =
95 Teuchos::rcp_const_cast<Teuchos::ParameterList>(
96 integrator->getStepper()->getValidParameters());
97 defaultPL->remove(
"Description");
99 bool pass = haveSameValues(*stepperPL, *defaultPL,
true);
101 std::cout << std::endl;
102 std::cout <<
"stepperPL -------------- \n" << *stepperPL << std::endl;
103 std::cout <<
"defaultPL -------------- \n" << *defaultPL << std::endl;
110 RCP<Tempus::IntegratorBasic<double> > integrator =
111 Tempus::integratorBasic<double>(model, RKMethods[m]);
113 RCP<ParameterList> stepperPL = sublist(tempusPL,
"Demo Stepper",
true);
114 if (RKMethods[m] ==
"General ERK")
115 stepperPL = sublist(tempusPL,
"Demo Stepper 2",
true);
116 RCP<ParameterList> defaultPL =
117 Teuchos::rcp_const_cast<Teuchos::ParameterList>(
118 integrator->getStepper()->getValidParameters());
119 defaultPL->remove(
"Description");
121 bool pass = haveSameValues(*stepperPL, *defaultPL,
true);
123 std::cout << std::endl;
124 std::cout <<
"stepperPL -------------- \n" << *stepperPL << std::endl;
125 std::cout <<
"defaultPL -------------- \n" << *defaultPL << std::endl;
140 RCP<ParameterList> pList =
141 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
142 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
145 RCP<ParameterList> scm_pl = sublist(pList,
"SinCosModel",
true);
150 RCP<Tempus::StepperFactory<double> > sf =
152 RCP<Tempus::Stepper<double> > stepper =
153 sf->createStepper(
"RK Explicit 4 Stage");
154 stepper->setModel(model);
155 stepper->initialize();
159 ParameterList tscPL = pl->sublist(
"Demo Integrator")
160 .sublist(
"Time Step Control");
161 timeStepControl->setStepType (tscPL.get<std::string>(
"Integrator Step Type"));
162 timeStepControl->setInitIndex(tscPL.get<
int> (
"Initial Time Index"));
163 timeStepControl->setInitTime (tscPL.get<
double>(
"Initial Time"));
164 timeStepControl->setFinalTime(tscPL.get<
double>(
"Final Time"));
165 timeStepControl->setInitTimeStep(dt);
166 timeStepControl->initialize();
169 Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
170 stepper->getModel()->getNominalValues();
171 auto icSolution = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
173 icState->setTime (timeStepControl->getInitTime());
174 icState->setIndex (timeStepControl->getInitIndex());
175 icState->setTimeStep(0.0);
176 icState->setOrder (stepper->getOrder());
181 solutionHistory->setName(
"Forward States");
183 solutionHistory->setStorageLimit(2);
184 solutionHistory->addState(icState);
187 RCP<Tempus::IntegratorBasic<double> > integrator =
188 Tempus::integratorBasic<double>();
189 integrator->setStepperWStepper(stepper);
190 integrator->setTimeStepControl(timeStepControl);
191 integrator->setSolutionHistory(solutionHistory);
193 integrator->initialize();
197 bool integratorStatus = integrator->advanceTime();
198 TEST_ASSERT(integratorStatus)
202 double time = integrator->getTime();
203 double timeFinal =pl->sublist(
"Demo Integrator")
204 .sublist(
"Time Step Control").get<
double>(
"Final Time");
205 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
208 RCP<Thyra::VectorBase<double> > x = integrator->getX();
209 RCP<const Thyra::VectorBase<double> > x_exact =
210 model->getExactSolution(time).get_x();
213 RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
214 Thyra::V_StVpStV(xdiff.ptr(), 1.0, *x_exact, -1.0, *(x));
217 std::cout <<
" Stepper = RK Explicit 4 Stage" << std::endl;
218 std::cout <<
" =========================" << std::endl;
219 std::cout <<
" Exact solution : " << get_ele(*(x_exact), 0) <<
" "
220 << get_ele(*(x_exact), 1) << std::endl;
221 std::cout <<
" Computed solution: " << get_ele(*(x ), 0) <<
" "
222 << get_ele(*(x ), 1) << std::endl;
223 std::cout <<
" Difference : " << get_ele(*(xdiff ), 0) <<
" "
224 << get_ele(*(xdiff ), 1) << std::endl;
225 std::cout <<
" =========================" << std::endl;
226 TEST_FLOATING_EQUALITY(get_ele(*(x), 0), 0.841470, 1.0e-4 );
227 TEST_FLOATING_EQUALITY(get_ele(*(x), 1), 0.540303, 1.0e-4 );
235 std::vector<std::string> RKMethods;
236 RKMethods.push_back(
"General ERK");
237 RKMethods.push_back(
"RK Forward Euler");
238 RKMethods.push_back(
"RK Explicit 4 Stage");
239 RKMethods.push_back(
"RK Explicit 3/8 Rule");
240 RKMethods.push_back(
"RK Explicit 4 Stage 3rd order by Runge");
241 RKMethods.push_back(
"RK Explicit 5 Stage 3rd order by Kinnmark and Gray");
242 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order");
243 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order TVD");
244 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order by Heun");
245 RKMethods.push_back(
"RK Explicit Midpoint");
246 RKMethods.push_back(
"RK Explicit Trapezoidal");
247 RKMethods.push_back(
"Heuns Method");
248 RKMethods.push_back(
"Bogacki-Shampine 3(2) Pair");
249 RKMethods.push_back(
"Merson 4(5) Pair");
250 RKMethods.push_back(
"General ERK Embedded");
251 RKMethods.push_back(
"SSPERK22");
252 RKMethods.push_back(
"SSPERK33");
253 RKMethods.push_back(
"SSPERK54");
254 RKMethods.push_back(
"RK2");
256 std::vector<double> RKMethodErrors;
257 RKMethodErrors.push_back(8.33251e-07);
258 RKMethodErrors.push_back(0.051123);
259 RKMethodErrors.push_back(8.33251e-07);
260 RKMethodErrors.push_back(8.33251e-07);
261 RKMethodErrors.push_back(4.16897e-05);
262 RKMethodErrors.push_back(8.32108e-06);
263 RKMethodErrors.push_back(4.16603e-05);
264 RKMethodErrors.push_back(4.16603e-05);
265 RKMethodErrors.push_back(4.16603e-05);
266 RKMethodErrors.push_back(0.00166645);
267 RKMethodErrors.push_back(0.00166645);
268 RKMethodErrors.push_back(0.00166645);
269 RKMethodErrors.push_back(4.16603e-05);
270 RKMethodErrors.push_back(1.39383e-07);
271 RKMethodErrors.push_back(4.16603e-05);
272 RKMethodErrors.push_back(0.00166645);
273 RKMethodErrors.push_back(4.16603e-05);
274 RKMethodErrors.push_back(3.85613e-07);
275 RKMethodErrors.push_back(0.00166644);
278 TEST_ASSERT(RKMethods.size() == RKMethodErrors.size() );
280 for(std::vector<std::string>::size_type m = 0; m != RKMethods.size(); m++) {
282 std::string RKMethod = RKMethods[m];
283 std::replace(RKMethod.begin(), RKMethod.end(),
' ',
'_');
284 std::replace(RKMethod.begin(), RKMethod.end(),
'/',
'.');
286 RCP<Tempus::IntegratorBasic<double> > integrator;
287 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
288 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
289 std::vector<double> StepSize;
290 std::vector<double> xErrorNorm;
291 std::vector<double> xDotErrorNorm;
293 const int nTimeStepSizes = 7;
296 for (
int n=0; n<nTimeStepSizes; n++) {
299 RCP<ParameterList> pList =
300 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
303 RCP<ParameterList> scm_pl = sublist(pList,
"SinCosModel",
true);
308 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
309 if (RKMethods[m] ==
"General ERK") {
310 pl->sublist(
"Demo Integrator").set(
"Stepper Name",
"Demo Stepper 2");
311 }
else if (RKMethods[m] ==
"General ERK Embedded"){
312 pl->sublist(
"Demo Integrator").set(
"Stepper Name",
"General ERK Embedded Stepper");
314 pl->sublist(
"Demo Stepper").set(
"Stepper Type", RKMethods[m]);
321 pl->sublist(
"Demo Integrator")
322 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
323 integrator = Tempus::integratorBasic<double>(pl, model);
329 RCP<Thyra::VectorBase<double> > x0 =
330 model->getNominalValues().get_x()->clone_v();
331 integrator->initializeSolutionHistory(0.0, x0);
334 bool integratorStatus = integrator->advanceTime();
335 TEST_ASSERT(integratorStatus)
338 time = integrator->getTime();
339 double timeFinal = pl->sublist(
"Demo Integrator")
340 .sublist(
"Time Step Control").get<
double>(
"Final Time");
341 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
344 RCP<Thyra::VectorBase<double> > x = integrator->getX();
345 RCP<const Thyra::VectorBase<double> > x_exact =
346 model->getExactSolution(time).get_x();
350 RCP<const SolutionHistory<double> > solutionHistory =
351 integrator->getSolutionHistory();
352 writeSolution(
"Tempus_"+RKMethod+
"_SinCos.dat", solutionHistory);
355 for (
int i=0; i<solutionHistory->getNumStates(); i++) {
356 double time_i = (*solutionHistory)[i]->getTime();
358 rcp_const_cast<Thyra::VectorBase<double> > (
359 model->getExactSolution(time_i).get_x()),
360 rcp_const_cast<Thyra::VectorBase<double> > (
361 model->getExactSolution(time_i).get_x_dot()));
362 state->setTime((*solutionHistory)[i]->getTime());
363 solnHistExact->addState(state);
365 writeSolution(
"Tempus_"+RKMethod+
"_SinCos-Ref.dat", solnHistExact);
369 StepSize.push_back(dt);
370 auto solution = Thyra::createMember(model->get_x_space());
371 Thyra::copy(*(integrator->getX()),solution.ptr());
372 solutions.push_back(solution);
373 auto solutionDot = Thyra::createMember(model->get_x_space());
374 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
375 solutionsDot.push_back(solutionDot);
376 if (n == nTimeStepSizes-1) {
377 StepSize.push_back(0.0);
378 auto solutionExact = Thyra::createMember(model->get_x_space());
379 Thyra::copy(*(model->getExactSolution(time).get_x()),solutionExact.ptr());
380 solutions.push_back(solutionExact);
381 auto solutionDotExact = Thyra::createMember(model->get_x_space());
382 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
383 solutionDotExact.ptr());
384 solutionsDot.push_back(solutionDotExact);
390 double xDotSlope = 0.0;
391 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
392 double order = stepper->getOrder();
395 solutions, xErrorNorm, xSlope,
396 solutionsDot, xDotErrorNorm, xDotSlope);
398 double order_tol = 0.01;
399 if (RKMethods[m] ==
"Merson 4(5) Pair") order_tol = 0.04;
400 if (RKMethods[m] ==
"SSPERK54") order_tol = 0.06;
402 TEST_FLOATING_EQUALITY( xSlope, order, order_tol );
403 TEST_FLOATING_EQUALITY( xErrorNorm[0], RKMethodErrors[m], 1.0e-4 );
418 std::vector<std::string> IntegratorList;
419 IntegratorList.push_back(
"Embedded_Integrator_PID");
420 IntegratorList.push_back(
"Demo_Integrator");
421 IntegratorList.push_back(
"Embedded_Integrator");
422 IntegratorList.push_back(
"General_Embedded_Integrator");
423 IntegratorList.push_back(
"Embedded_Integrator_PID_General");
427 const int refIstep = 45;
429 for(
auto integratorChoice : IntegratorList){
431 std::cout <<
"Using Integrator: " << integratorChoice <<
" !!!" << std::endl;
434 RCP<ParameterList> pList =
435 getParametersFromXmlFile(
"Tempus_ExplicitRK_VanDerPol.xml");
439 RCP<ParameterList> vdpm_pl = sublist(pList,
"VanDerPolModel",
true);
444 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
445 pl->set(
"Integrator Name", integratorChoice);
448 RCP<Tempus::IntegratorBasic<double> > integrator =
449 Tempus::integratorBasic<double>(pl, model);
451 const std::string RKMethod =
452 pl->sublist(integratorChoice).get<std::string>(
"Stepper Name");
455 bool integratorStatus = integrator->advanceTime();
456 TEST_ASSERT(integratorStatus);
459 double time = integrator->getTime();
460 double timeFinal = pl->sublist(integratorChoice)
461 .sublist(
"Time Step Control").get<
double>(
"Final Time");
462 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
466 RCP<Thyra::VectorBase<double> > x = integrator->getX();
467 RCP<Thyra::VectorBase<double> > xref = x->clone_v();
468 Thyra::set_ele(0, -1.5484458614405929, xref.ptr());
469 Thyra::set_ele(1, 1.0181127316101317, xref.ptr());
472 RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
473 Thyra::V_StVpStV(xdiff.ptr(), 1.0, *xref, -1.0, *(x));
474 const double L2norm = Thyra::norm_2(*xdiff);
477 if ((integratorChoice ==
"Embedded_Integrator_PID") or
478 (integratorChoice ==
"Embedded_Integrator_PID_General")) {
480 const double absTol = pl->sublist(integratorChoice).
481 sublist(
"Time Step Control").get<
double>(
"Maximum Absolute Error");
482 const double relTol = pl->sublist(integratorChoice).
483 sublist(
"Time Step Control").get<
double>(
"Maximum Relative Error");
486 TEST_COMPARE(std::log10(L2norm), <, std::log10(absTol));
487 TEST_COMPARE(std::log10(L2norm), <, std::log10(relTol));
492 const int iStep = integrator->getSolutionHistory()->
493 getCurrentState()->getIndex();
494 const int nFail = integrator->getSolutionHistory()->
495 getCurrentState()->getMetaData()->getNRunningFailures();
498 TEST_EQUALITY(iStep, refIstep);
499 std::cout <<
"Tolerance = " << absTol
500 <<
" L2norm = " << L2norm
501 <<
" iStep = " << iStep
502 <<
" nFail = " << nFail << std::endl;
506 std::ofstream ftmp(
"Tempus_"+integratorChoice+RKMethod+
"_VDP_Example.dat");
507 RCP<const SolutionHistory<double> > solutionHistory =
508 integrator->getSolutionHistory();
509 int nStates = solutionHistory->getNumStates();
511 for (
int i=0; i<nStates; i++) {
512 RCP<const SolutionState<double> > solutionState = (*solutionHistory)[i];
513 double time_i = solutionState->getTime();
514 RCP<const Thyra::VectorBase<double> > x_plot = solutionState->getX();
516 ftmp << time_i <<
" "
517 << Thyra::get_ele(*(x_plot), 0) <<
" "
518 << Thyra::get_ele(*(x_plot), 1) <<
" " << std::endl;
523 Teuchos::TimeMonitor::summarize();
534 RCP<ParameterList> pList =
535 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
536 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
539 RCP<ParameterList> scm_pl = sublist(pList,
"SinCosModel",
true);
544 RCP<Tempus::StepperFactory<double> > sf =
546 RCP<Tempus::Stepper<double> > stepper =
547 sf->createStepper(
"RK Explicit 4 Stage");
548 stepper->setModel(model);
549 stepper->initialize();
553 ParameterList tscPL = pl->sublist(
"Demo Integrator")
554 .sublist(
"Time Step Control");
555 timeStepControl->setStepType (tscPL.get<std::string>(
"Integrator Step Type"));
556 timeStepControl->setInitIndex(tscPL.get<
int> (
"Initial Time Index"));
557 timeStepControl->setInitTime (tscPL.get<
double>(
"Initial Time"));
558 timeStepControl->setFinalTime(tscPL.get<
double>(
"Final Time"));
559 timeStepControl->setInitTimeStep(dt);
560 timeStepControl->initialize();
563 Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
564 stepper->getModel()->getNominalValues();
565 auto icSolution = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
567 icState->setTime (timeStepControl->getInitTime());
568 icState->setIndex (timeStepControl->getInitIndex());
569 icState->setTimeStep(0.0);
570 icState->setOrder (stepper->getOrder());
575 solutionHistory->setName(
"Forward States");
577 solutionHistory->setStorageLimit(2);
578 solutionHistory->addState(icState);
581 RCP<Tempus::IntegratorBasic<double> > integrator =
582 Tempus::integratorBasic<double>();
583 integrator->setStepperWStepper(stepper);
584 integrator->setTimeStepControl(timeStepControl);
585 integrator->setSolutionHistory(solutionHistory);
587 integrator->initialize();
590 auto erk_stepper = Teuchos::rcp_dynamic_cast<Tempus::StepperExplicitRK<double> >(stepper,
true);
592 TEST_EQUALITY( -1 , erk_stepper->getStageNumber());
593 const std::vector<int> ref_stageNumber = { 1, 4, 8, 10, 11, -1, 5};
594 for(
auto stage_number : ref_stageNumber) {
596 erk_stepper->setStageNumber(stage_number);
598 TEST_EQUALITY( stage_number, erk_stepper->getStageNumber());
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Solution state for integrators and steppers. SolutionState contains the metadata for solutions and th...
TimeStepControl manages the time step size. There several mechanicisms that effect the time step size...
Sine-Cosine model problem from Rythmos. This is a canonical Sine-Cosine differential equation.
van der Pol model problem for nonlinear electrical circuit.
void writeSolution(const std::string filename, Teuchos::RCP< const Tempus::SolutionHistory< Scalar > > solutionHistory)
void writeOrderError(const std::string filename, Teuchos::RCP< Tempus::Stepper< Scalar > > stepper, std::vector< Scalar > &StepSize, std::vector< Teuchos::RCP< Thyra::VectorBase< Scalar >>> &solutions, std::vector< Scalar > &xErrorNorm, Scalar &xSlope, std::vector< Teuchos::RCP< Thyra::VectorBase< Scalar >>> &solutionsDot, std::vector< Scalar > &xDotErrorNorm, Scalar &xDotSlope, std::vector< Teuchos::RCP< Thyra::VectorBase< Scalar >>> &solutionsDotDot, std::vector< Scalar > &xDotDotErrorNorm, Scalar &xDotDotSlope)
TEUCHOS_UNIT_TEST(BackwardEuler, SinCos_ASA)
@ STORAGE_TYPE_STATIC
Keep a fix number of states.
Teuchos::RCP< SolutionState< Scalar > > createSolutionStateX(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdot=Teuchos::null, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdotdot=Teuchos::null)
Nonmember constructor from non-const solution vectors, x.