12 #include "Teuchos_DefaultComm.hpp"
14 #include "Thyra_VectorStdOps.hpp"
16 #include "Tempus_IntegratorBasic.hpp"
17 #include "Tempus_StepperFactory.hpp"
18 #include "Tempus_StepperExplicitRK.hpp"
20 #include "../TestModels/SinCosModel.hpp"
21 #include "../TestModels/VanDerPolModel.hpp"
22 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
27 namespace Tempus_Test {
29 using Teuchos::getParametersFromXmlFile;
33 using Teuchos::rcp_const_cast;
34 using Teuchos::sublist;
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++) {
61 std::string RKMethod = RKMethods[m];
62 std::replace(RKMethod.begin(), RKMethod.end(),
' ',
'_');
63 std::replace(RKMethod.begin(), RKMethod.end(),
'/',
'.');
67 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
75 if (RKMethods[m] ==
"General ERK") {
76 tempusPL->
sublist(
"Demo Integrator")
77 .
set(
"Stepper Name",
"Demo Stepper 2");
80 tempusPL->
sublist(
"Demo Stepper").
set(
"Stepper Type", RKMethods[m]);
86 Tempus::createIntegratorBasic<double>(tempusPL, model,
false);
91 TEST_ASSERT(!integrator->getNonConstTimeStepControl()->isInitialized());
93 integrator->initialize();
95 TEST_ASSERT(integrator->getNonConstTimeStepControl()->isInitialized());
99 if (RKMethods[m] ==
"General ERK")
100 stepperPL = sublist(tempusPL,
"Demo Stepper 2",
true);
103 integrator->getStepper()->getValidParameters());
105 bool pass = haveSameValuesSorted(*stepperPL, *defaultPL,
true);
108 out <<
"stepperPL -------------- \n"
109 << *stepperPL << std::endl;
110 out <<
"defaultPL -------------- \n"
111 << *defaultPL << std::endl;
117 if (RKMethods[m] ==
"General ERK") {
118 tempusPL->
sublist(
"Demo Stepper 2")
119 .
set(
"Initial Condition Consistency",
"None");
121 if (RKMethods[m] ==
"RK Forward Euler" ||
122 RKMethods[m] ==
"Bogacki-Shampine 3(2) Pair") {
123 tempusPL->
sublist(
"Demo Stepper")
124 .
set(
"Initial Condition Consistency",
"Consistent");
125 tempusPL->
sublist(
"Demo Stepper").
set(
"Use FSAL",
true);
128 tempusPL->
sublist(
"Demo Stepper")
129 .
set(
"Initial Condition Consistency",
"None");
135 Tempus::createIntegratorBasic<double>(model, RKMethods[m]);
138 if (RKMethods[m] ==
"General ERK")
139 stepperPL = sublist(tempusPL,
"Demo Stepper 2",
true);
142 integrator->getStepper()->getValidParameters());
144 bool pass = haveSameValuesSorted(*stepperPL, *defaultPL,
true);
147 out <<
"stepperPL -------------- \n"
148 << *stepperPL << std::endl;
149 out <<
"defaultPL -------------- \n"
150 << *defaultPL << std::endl;
162 std::vector<std::string> options;
163 options.push_back(
"Default Parameters");
164 options.push_back(
"ICConsistency and Check");
166 for (
const auto& option : options) {
169 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
181 sf->createStepper(
"RK Explicit 4 Stage");
182 stepper->setModel(model);
183 if (option ==
"ICConsistency and Check") {
184 stepper->setICConsistency(
"Consistent");
185 stepper->setICConsistencyCheck(
true);
187 stepper->initialize();
193 timeStepControl->setInitIndex(tscPL.
get<
int>(
"Initial Time Index"));
194 timeStepControl->setInitTime(tscPL.
get<
double>(
"Initial Time"));
195 timeStepControl->setFinalTime(tscPL.
get<
double>(
"Final Time"));
196 timeStepControl->setInitTimeStep(dt);
197 timeStepControl->initialize();
200 auto inArgsIC = model->getNominalValues();
204 icState->setTime(timeStepControl->getInitTime());
205 icState->setIndex(timeStepControl->getInitIndex());
206 icState->setTimeStep(0.0);
207 icState->setOrder(stepper->getOrder());
212 solutionHistory->setName(
"Forward States");
214 solutionHistory->setStorageLimit(2);
215 solutionHistory->addState(icState);
219 Tempus::createIntegratorBasic<double>();
220 integrator->setStepper(stepper);
221 integrator->setTimeStepControl(timeStepControl);
222 integrator->setSolutionHistory(solutionHistory);
224 integrator->initialize();
227 bool integratorStatus = integrator->advanceTime();
231 double time = integrator->getTime();
232 double timeFinal = pl->
sublist(
"Demo Integrator")
234 .
get<
double>(
"Final Time");
240 model->getExactSolution(time).get_x();
244 Thyra::V_StVpStV(xdiff.
ptr(), 1.0, *x_exact, -1.0, *(x));
247 out <<
" Stepper = " << stepper->description() <<
"\n with "
248 << option << std::endl;
249 out <<
" =========================" << std::endl;
250 out <<
" Exact solution : " << get_ele(*(x_exact), 0) <<
" "
251 << get_ele(*(x_exact), 1) << std::endl;
252 out <<
" Computed solution: " << get_ele(*(x), 0) <<
" "
253 << get_ele(*(x), 1) << std::endl;
254 out <<
" Difference : " << get_ele(*(xdiff), 0) <<
" "
255 << get_ele(*(xdiff), 1) << std::endl;
256 out <<
" =========================" << std::endl;
257 TEST_FLOATING_EQUALITY(get_ele(*(x), 0), 0.841470, 1.0e-4);
258 TEST_FLOATING_EQUALITY(get_ele(*(x), 1), 0.540303, 1.0e-4);
267 std::vector<std::string> RKMethods;
268 RKMethods.push_back(
"RK Forward Euler");
269 RKMethods.push_back(
"Bogacki-Shampine 3(2) Pair");
271 for (std::vector<std::string>::size_type m = 0; m != RKMethods.size(); m++) {
277 auto stepper = sf->createStepper(RKMethods[m]);
278 stepper->setModel(model);
279 stepper->setUseFSAL(
false);
280 stepper->initialize();
284 timeStepControl->setInitTime(0.0);
285 timeStepControl->setFinalTime(1.0);
286 timeStepControl->setInitTimeStep(dt);
287 timeStepControl->initialize();
290 auto inArgsIC = model->getNominalValues();
294 icState->setTime(timeStepControl->getInitTime());
295 icState->setIndex(timeStepControl->getInitIndex());
296 icState->setTimeStep(0.0);
297 icState->setOrder(stepper->getOrder());
302 solutionHistory->setName(
"Forward States");
304 solutionHistory->setStorageLimit(2);
305 solutionHistory->addState(icState);
308 auto integrator = Tempus::createIntegratorBasic<double>();
309 integrator->setStepper(stepper);
310 integrator->setTimeStepControl(timeStepControl);
311 integrator->setSolutionHistory(solutionHistory);
312 integrator->initialize();
315 bool integratorStatus = integrator->advanceTime();
319 double time = integrator->getTime();
323 auto x = integrator->getX();
324 auto x_exact = model->getExactSolution(time).get_x();
328 Thyra::V_StVpStV(xdiff.
ptr(), 1.0, *x_exact, -1.0, *(x));
331 out <<
" Stepper = " << stepper->description() <<
"\n with "
332 <<
"useFSAL=false" << std::endl;
333 out <<
" =========================" << std::endl;
334 out <<
" Exact solution : " << get_ele(*(x_exact), 0) <<
" "
335 << get_ele(*(x_exact), 1) << std::endl;
336 out <<
" Computed solution: " << get_ele(*(x), 0) <<
" "
337 << get_ele(*(x), 1) << std::endl;
338 out <<
" Difference : " << get_ele(*(xdiff), 0) <<
" "
339 << get_ele(*(xdiff), 1) << std::endl;
340 out <<
" =========================" << std::endl;
341 if (RKMethods[m] ==
"RK Forward Euler") {
345 else if (RKMethods[m] ==
"Bogacki-Shampine 3(2) Pair") {
356 std::vector<std::string> RKMethods;
357 RKMethods.push_back(
"General ERK");
358 RKMethods.push_back(
"RK Forward Euler");
359 RKMethods.push_back(
"RK Explicit 4 Stage");
360 RKMethods.push_back(
"RK Explicit 3/8 Rule");
361 RKMethods.push_back(
"RK Explicit 4 Stage 3rd order by Runge");
362 RKMethods.push_back(
"RK Explicit 5 Stage 3rd order by Kinnmark and Gray");
363 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order");
364 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order TVD");
365 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order by Heun");
366 RKMethods.push_back(
"RK Explicit Midpoint");
367 RKMethods.push_back(
"RK Explicit Trapezoidal");
368 RKMethods.push_back(
"Heuns Method");
369 RKMethods.push_back(
"Bogacki-Shampine 3(2) Pair");
370 RKMethods.push_back(
"Merson 4(5) Pair");
371 RKMethods.push_back(
"General ERK Embedded");
372 RKMethods.push_back(
"SSPERK22");
373 RKMethods.push_back(
"SSPERK33");
374 RKMethods.push_back(
"SSPERK54");
375 RKMethods.push_back(
"RK2");
377 std::vector<double> RKMethodErrors;
378 RKMethodErrors.push_back(8.33251e-07);
379 RKMethodErrors.push_back(0.051123);
380 RKMethodErrors.push_back(8.33251e-07);
381 RKMethodErrors.push_back(8.33251e-07);
382 RKMethodErrors.push_back(4.16897e-05);
383 RKMethodErrors.push_back(8.32108e-06);
384 RKMethodErrors.push_back(4.16603e-05);
385 RKMethodErrors.push_back(4.16603e-05);
386 RKMethodErrors.push_back(4.16603e-05);
387 RKMethodErrors.push_back(0.00166645);
388 RKMethodErrors.push_back(0.00166645);
389 RKMethodErrors.push_back(0.00166645);
390 RKMethodErrors.push_back(4.16603e-05);
391 RKMethodErrors.push_back(1.39383e-07);
392 RKMethodErrors.push_back(4.16603e-05);
393 RKMethodErrors.push_back(0.00166645);
394 RKMethodErrors.push_back(4.16603e-05);
395 RKMethodErrors.push_back(3.85613e-07);
396 RKMethodErrors.push_back(0.00166644);
398 TEST_ASSERT(RKMethods.size() == RKMethodErrors.size());
400 for (std::vector<std::string>::size_type m = 0; m != RKMethods.size(); m++) {
401 std::string RKMethod = RKMethods[m];
402 std::replace(RKMethod.begin(), RKMethod.end(),
' ',
'_');
403 std::replace(RKMethod.begin(), RKMethod.end(),
'/',
'.');
406 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
407 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
408 std::vector<double> StepSize;
409 std::vector<double> xErrorNorm;
410 std::vector<double> xDotErrorNorm;
412 const int nTimeStepSizes = 7;
415 for (
int n = 0; n < nTimeStepSizes; n++) {
418 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
427 if (RKMethods[m] ==
"General ERK") {
428 pl->
sublist(
"Demo Integrator").
set(
"Stepper Name",
"Demo Stepper 2");
430 else if (RKMethods[m] ==
"General ERK Embedded") {
432 .
set(
"Stepper Name",
"General ERK Embedded Stepper");
435 pl->
sublist(
"Demo Stepper").
set(
"Stepper Type", RKMethods[m]);
443 .
set(
"Initial Time Step", dt);
444 integrator = Tempus::createIntegratorBasic<double>(pl, model);
452 model->getNominalValues().get_x()->clone_v();
453 integrator->initializeSolutionHistory(0.0, x0);
456 bool integratorStatus = integrator->advanceTime();
460 time = integrator->getTime();
461 double timeFinal = pl->sublist(
"Demo Integrator")
462 .sublist(
"Time Step Control")
463 .get<
double>(
"Final Time");
469 model->getExactSolution(time).get_x();
474 integrator->getSolutionHistory();
475 writeSolution(
"Tempus_" + RKMethod +
"_SinCos.dat", solutionHistory);
478 for (
int i = 0; i < solutionHistory->getNumStates(); i++) {
479 double time_i = (*solutionHistory)[i]->getTime();
482 model->getExactSolution(time_i).get_x()),
484 model->getExactSolution(time_i).get_x_dot()));
485 state->setTime((*solutionHistory)[i]->getTime());
486 solnHistExact->addState(state);
488 writeSolution(
"Tempus_" + RKMethod +
"_SinCos-Ref.dat", solnHistExact);
492 StepSize.push_back(dt);
493 auto solution = Thyra::createMember(model->get_x_space());
494 Thyra::copy(*(integrator->getX()), solution.ptr());
495 solutions.push_back(solution);
496 auto solutionDot = Thyra::createMember(model->get_x_space());
497 Thyra::copy(*(integrator->getXDot()), solutionDot.ptr());
498 solutionsDot.push_back(solutionDot);
499 if (n == nTimeStepSizes - 1) {
500 StepSize.push_back(0.0);
501 auto solutionExact = Thyra::createMember(model->get_x_space());
502 Thyra::copy(*(model->getExactSolution(time).get_x()),
503 solutionExact.ptr());
504 solutions.push_back(solutionExact);
505 auto solutionDotExact = Thyra::createMember(model->get_x_space());
506 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
507 solutionDotExact.ptr());
508 solutionsDot.push_back(solutionDotExact);
514 double xDotSlope = 0.0;
516 double order = stepper->getOrder();
518 StepSize, solutions, xErrorNorm, xSlope, solutionsDot,
519 xDotErrorNorm, xDotSlope, out);
521 double order_tol = 0.01;
522 if (RKMethods[m] ==
"Merson 4(5) Pair") order_tol = 0.04;
523 if (RKMethods[m] ==
"SSPERK54") order_tol = 0.06;
538 std::vector<std::string> IntegratorList;
539 IntegratorList.push_back(
"Embedded_Integrator_PID");
540 IntegratorList.push_back(
"Demo_Integrator");
541 IntegratorList.push_back(
"Embedded_Integrator");
542 IntegratorList.push_back(
"General_Embedded_Integrator");
543 IntegratorList.push_back(
"Embedded_Integrator_PID_General");
547 const int refIstep = 36;
549 for (
auto integratorChoice : IntegratorList) {
550 out <<
"Using Integrator: " << integratorChoice <<
" !!!" << std::endl;
554 getParametersFromXmlFile(
"Tempus_ExplicitRK_VanDerPol.xml");
562 pl->
set(
"Integrator Name", integratorChoice);
566 Tempus::createIntegratorBasic<double>(pl, model);
568 const std::string RKMethod =
569 pl->sublist(integratorChoice).
get<std::string>(
"Stepper Name");
572 bool integratorStatus = integrator->advanceTime();
576 double time = integrator->getTime();
577 double timeFinal = pl->sublist(integratorChoice)
578 .sublist(
"Time Step Control")
579 .
get<
double>(
"Final Time");
585 Thyra::set_ele(0, -1.5484458614405929, xref.
ptr());
586 Thyra::set_ele(1, 1.0181127316101317, xref.
ptr());
590 Thyra::V_StVpStV(xdiff.ptr(), 1.0, *xref, -1.0, *(x));
591 const double L2norm = Thyra::norm_2(*xdiff);
594 if ((integratorChoice ==
"Embedded_Integrator_PID") ||
595 (integratorChoice ==
"Embedded_Integrator_PID_General")) {
596 const double absTol = pl->sublist(integratorChoice)
597 .sublist(
"Time Step Control")
598 .get<
double>(
"Maximum Absolute Error");
599 const double relTol = pl->sublist(integratorChoice)
600 .sublist(
"Time Step Control")
601 .get<
double>(
"Maximum Relative Error");
604 TEST_COMPARE(std::log10(L2norm), <, std::log10(absTol));
605 TEST_COMPARE(std::log10(L2norm), <, std::log10(relTol));
611 integrator->getSolutionHistory()->getCurrentState()->getIndex();
612 const int nFail = integrator->getSolutionHistory()
615 ->getNRunningFailures();
619 out <<
"Tolerance = " << absTol <<
" L2norm = " << L2norm
620 <<
" iStep = " << iStep <<
" nFail = " << nFail << std::endl;
624 std::ofstream ftmp(
"Tempus_" + integratorChoice + RKMethod +
627 integrator->getSolutionHistory();
628 int nStates = solutionHistory->getNumStates();
630 for (
int i = 0; i < nStates; i++) {
632 double time_i = solutionState->getTime();
635 ftmp << time_i <<
" " << Thyra::get_ele(*(x_plot), 0) <<
" "
636 << Thyra::get_ele(*(x_plot), 1) <<
" " << std::endl;
652 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
664 sf->createStepper(
"RK Explicit 4 Stage");
665 stepper->setModel(model);
666 stepper->initialize();
672 timeStepControl->setInitIndex(tscPL.
get<
int>(
"Initial Time Index"));
673 timeStepControl->setInitTime(tscPL.
get<
double>(
"Initial Time"));
674 timeStepControl->setFinalTime(tscPL.
get<
double>(
"Final Time"));
675 timeStepControl->setInitTimeStep(dt);
676 timeStepControl->initialize();
679 auto inArgsIC = model->getNominalValues();
682 icState->setTime(timeStepControl->getInitTime());
683 icState->setIndex(timeStepControl->getInitIndex());
684 icState->setTimeStep(0.0);
685 icState->setOrder(stepper->getOrder());
690 solutionHistory->setName(
"Forward States");
692 solutionHistory->setStorageLimit(2);
693 solutionHistory->addState(icState);
697 Tempus::createIntegratorBasic<double>();
698 integrator->setStepper(stepper);
699 integrator->setTimeStepControl(timeStepControl);
700 integrator->setSolutionHistory(solutionHistory);
702 integrator->initialize();
710 const std::vector<int> ref_stageNumber = {1, 4, 8, 10, 11, -1, 5};
711 for (
auto stage_number : ref_stageNumber) {
713 erk_stepper->setStageNumber(stage_number);
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.
Explicit Runge-Kutta time stepper.
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEST_COMPARE(v1, comp, v2)
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::FancyOStream &out)
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
Sine-Cosine model problem from Rythmos. This is a canonical Sine-Cosine differential equation with a...
void writeSolution(const std::string filename, Teuchos::RCP< const Tempus::SolutionHistory< Scalar >> solutionHistory)
TEUCHOS_UNIT_TEST(BackwardEuler, SinCos_ASA)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
TimeStepControl manages the time step size. There several mechanisms that effect the time step size a...
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Keep a fix number of states.
van der Pol model problem for nonlinear electrical circuit.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
#define TEST_EQUALITY(v1, v2)
Solution state for integrators and steppers.