9 #include "Teuchos_UnitTestHarness.hpp"
10 #include "Teuchos_XMLParameterListHelpers.hpp"
11 #include "Teuchos_TimeMonitor.hpp"
13 #include "Tempus_config.hpp"
14 #include "Tempus_IntegratorBasic.hpp"
15 #include "Tempus_StepperHHTAlpha.hpp"
17 #include "../TestModels/HarmonicOscillatorModel.hpp"
18 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
20 #include "Stratimikos_DefaultLinearSolverBuilder.hpp"
21 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
22 #include "Thyra_DetachedVectorView.hpp"
23 #include "Thyra_DetachedMultiVectorView.hpp"
26 #ifdef Tempus_ENABLE_MPI
27 #include "Epetra_MpiComm.h"
29 #include "Epetra_SerialComm.h"
40 using Teuchos::ParameterList;
41 using Teuchos::sublist;
42 using Teuchos::getParametersFromXmlFile;
49 #define TEST_BALL_PARABOLIC
50 #define TEST_CONSTRUCTING_FROM_DEFAULTS
51 #define TEST_SINCOS_SECONDORDER
52 #define TEST_SINCOS_FIRSTORDER
53 #define TEST_SINCOS_CD
56 #ifdef TEST_BALL_PARABOLIC
62 double tolerance = 1.0e-14;
64 RCP<ParameterList> pList =
65 getParametersFromXmlFile(
"Tempus_HHTAlpha_BallParabolic.xml");
68 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
69 RCP<HarmonicOscillatorModel<double> > model =
73 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
75 RCP<Tempus::IntegratorBasic<double> > integrator =
76 Tempus::integratorBasic<double>(pl, model);
79 bool integratorStatus = integrator->advanceTime();
80 TEST_ASSERT(integratorStatus)
83 double time = integrator->getTime();
84 double timeFinal =pl->sublist(
"Default Integrator")
85 .sublist(
"Time Step Control").get<
double>(
"Final Time");
86 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
89 RCP<Thyra::VectorBase<double> > x = integrator->getX();
90 RCP<const Thyra::VectorBase<double> > x_exact =
91 model->getExactSolution(time).get_x();
94 std::ofstream ftmp(
"Tempus_HHTAlpha_BallParabolic.dat");
97 integrator->getSolutionHistory();
100 RCP<const Thyra::VectorBase<double> > x_exact_plot;
102 RCP<const SolutionState<double> > solutionState = (*solutionHistory)[i];
103 double time = solutionState->getTime();
104 RCP<const Thyra::VectorBase<double> > x_plot = solutionState->getX();
105 x_exact_plot = model->getExactSolution(time).get_x();
107 << get_ele(*(x_plot), 0) <<
" "
108 << get_ele(*(x_exact_plot), 0) << std::endl;
109 if (abs(get_ele(*(x_plot),0) - get_ele(*(x_exact_plot), 0)) > err)
110 err = abs(get_ele(*(x_plot),0) - get_ele(*(x_exact_plot), 0));
113 std::cout <<
"Max error = " << err <<
"\n \n";
117 TEUCHOS_TEST_FOR_EXCEPTION(!passed, std::logic_error,
118 "\n Test failed! Max error = " << err <<
" > tolerance = " << tolerance <<
"\n!");
121 #endif // TEST_BALL_PARABOLIC
124 #ifdef TEST_CONSTRUCTING_FROM_DEFAULTS
132 RCP<ParameterList> pList =
133 getParametersFromXmlFile(
"Tempus_HHTAlpha_SinCos_SecondOrder.xml");
134 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
137 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
138 RCP<HarmonicOscillatorModel<double> > model =
142 RCP<Tempus::StepperHHTAlpha<double> > stepper =
146 RCP<Tempus::TimeStepControl<double> > timeStepControl =
148 ParameterList tscPL = pl->sublist(
"Default Integrator")
149 .sublist(
"Time Step Control");
150 timeStepControl->setStepType (tscPL.get<std::string>(
"Integrator Step Type"));
151 timeStepControl->setInitIndex(tscPL.get<
int> (
"Initial Time Index"));
152 timeStepControl->setInitTime (tscPL.get<
double>(
"Initial Time"));
153 timeStepControl->setFinalTime(tscPL.get<
double>(
"Final Time"));
154 timeStepControl->setInitTimeStep(dt);
155 timeStepControl->initialize();
158 using Teuchos::rcp_const_cast;
159 Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
160 stepper->getModel()->getNominalValues();
161 RCP<Thyra::VectorBase<double> > icX =
162 rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
163 RCP<Thyra::VectorBase<double> > icXDot =
164 rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
165 RCP<Thyra::VectorBase<double> > icXDotDot =
166 rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot_dot());
167 RCP<Tempus::SolutionState<double> > icState =
169 icState->setTime (timeStepControl->getInitTime());
170 icState->setIndex (timeStepControl->getInitIndex());
171 icState->setTimeStep(0.0);
172 icState->setOrder (stepper->getOrder());
184 RCP<Tempus::IntegratorBasic<double> > integrator =
185 Tempus::integratorBasic<double>();
186 integrator->setStepperWStepper(stepper);
187 integrator->setTimeStepControl(timeStepControl);
190 integrator->initialize();
194 bool integratorStatus = integrator->advanceTime();
195 TEST_ASSERT(integratorStatus)
199 double time = integrator->getTime();
200 double timeFinal =pl->sublist(
"Default Integrator")
201 .sublist(
"Time Step Control").get<
double>(
"Final Time");
202 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
205 RCP<Thyra::VectorBase<double> > x = integrator->getX();
206 RCP<const Thyra::VectorBase<double> > x_exact =
207 model->getExactSolution(time).get_x();
210 RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
211 Thyra::V_StVpStV(xdiff.ptr(), 1.0, *x_exact, -1.0, *(x));
214 std::cout <<
" Stepper = " << stepper->description() << std::endl;
215 std::cout <<
" =========================" << std::endl;
216 std::cout <<
" Exact solution : " << get_ele(*(x_exact), 0) << std::endl;
217 std::cout <<
" Computed solution: " << get_ele(*(x ), 0) << std::endl;
218 std::cout <<
" Difference : " << get_ele(*(xdiff ), 0) << std::endl;
219 std::cout <<
" =========================" << std::endl;
220 TEST_FLOATING_EQUALITY(get_ele(*(x), 0), 0.144918, 1.0e-4 );
222 #endif // TEST_CONSTRUCTING_FROM_DEFAULTS
225 #ifdef TEST_SINCOS_SECONDORDER
229 RCP<Tempus::IntegratorBasic<double> > integrator;
230 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
231 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
232 std::vector<double> StepSize;
233 std::vector<double> xErrorNorm;
234 std::vector<double> xDotErrorNorm;
235 const int nTimeStepSizes = 8;
239 RCP<ParameterList> pList =
240 getParametersFromXmlFile(
"Tempus_HHTAlpha_SinCos_SecondOrder.xml");
243 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
244 RCP<HarmonicOscillatorModel<double> > model =
248 double k = hom_pl->get<
double>(
"x coeff k");
249 double m = hom_pl->get<
double>(
"Mass coeff m");
252 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
256 double dt =pl->sublist(
"Default Integrator")
257 .sublist(
"Time Step Control").get<
double>(
"Initial Time Step");
260 for (
int n=0; n<nTimeStepSizes; n++) {
264 std::cout <<
"\n \n time step #" << n <<
" (out of "
265 << nTimeStepSizes-1 <<
"), dt = " << dt <<
"\n";
266 pl->sublist(
"Default Integrator")
267 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
268 integrator = Tempus::integratorBasic<double>(pl, model);
271 bool integratorStatus = integrator->advanceTime();
272 TEST_ASSERT(integratorStatus)
275 time = integrator->getTime();
276 double timeFinal =pl->sublist(
"Default Integrator")
277 .sublist(
"Time Step Control").get<
double>(
"Final Time");
278 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
281 RCP<Thyra::VectorBase<double> > x = integrator->getX();
282 RCP<const Thyra::VectorBase<double> > x_exact =
283 model->getExactSolution(time).get_x();
286 if (n == nTimeStepSizes-1) {
288 integrator->getSolutionHistory();
291 RCP<Tempus::SolutionHistory<double> > solnHistExact =
294 double time = (*solutionHistory)[i]->getTime();
295 RCP<Tempus::SolutionState<double> > state =
297 model->getExactSolution(time).get_x(),
298 model->getExactSolution(time).get_x_dot()));
300 solnHistExact->addState(state);
302 writeSolution(
"Tempus_HHTAlpha_SinCos_SecondOrder-Ref.dat", solnHistExact);
306 std::ofstream ftmp(
"Tempus_HHTAlpha_SinCos_SecondOrder-Energy.dat");
309 integrator->getSolutionHistory();
310 RCP<const Thyra::VectorBase<double> > x_exact_plot;
312 RCP<const SolutionState<double> > solutionState = (*solutionHistory)[i];
313 double time = solutionState->getTime();
314 RCP<const Thyra::VectorBase<double> > x_plot = solutionState->getX();
315 RCP<const Thyra::VectorBase<double> > x_dot_plot = solutionState->getXDot();
316 x_exact_plot = model->getExactSolution(time).get_x();
318 double ke = Thyra::dot(*x_dot_plot, *x_dot_plot);
321 double pe = Thyra::dot(*x_plot, *x_plot);
327 << get_ele(*(x_plot), 0) <<
" "
328 << get_ele(*(x_exact_plot), 0) <<
" "
329 << get_ele(*(x_dot_plot), 0) <<
" "
330 << ke <<
" " << pe <<
" " << te << std::endl;
337 StepSize.push_back(dt);
338 auto solution = Thyra::createMember(model->get_x_space());
339 Thyra::copy(*(integrator->getX()),solution.ptr());
340 solutions.push_back(solution);
341 auto solutionDot = Thyra::createMember(model->get_x_space());
342 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
343 solutionsDot.push_back(solutionDot);
344 if (n == nTimeStepSizes-1) {
345 StepSize.push_back(0.0);
346 auto solution = Thyra::createMember(model->get_x_space());
347 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
348 solutions.push_back(solution);
349 auto solutionDot = Thyra::createMember(model->get_x_space());
350 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
352 solutionsDot.push_back(solutionDot);
358 double xDotSlope = 0.0;
359 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
360 double order = stepper->getOrder();
363 solutions, xErrorNorm, xSlope,
364 solutionsDot, xDotErrorNorm, xDotSlope);
366 TEST_FLOATING_EQUALITY( xSlope, order, 0.02 );
367 TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.00644755, 1.0e-4 );
368 TEST_FLOATING_EQUALITY( xDotSlope, order, 0.01 );
369 TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.104392, 1.0e-4 );
371 #endif // TEST_SINCOS_SECONDORDER
374 #ifdef TEST_SINCOS_FIRSTORDER
379 RCP<Tempus::IntegratorBasic<double> > integrator;
380 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
381 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
382 std::vector<double> StepSize;
383 std::vector<double> xErrorNorm;
384 std::vector<double> xDotErrorNorm;
385 const int nTimeStepSizes = 8;
389 RCP<ParameterList> pList =
390 getParametersFromXmlFile(
"Tempus_HHTAlpha_SinCos_FirstOrder.xml");
393 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
394 RCP<HarmonicOscillatorModel<double> > model =
398 double k = hom_pl->get<
double>(
"x coeff k");
399 double m = hom_pl->get<
double>(
"Mass coeff m");
402 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
406 double dt =pl->sublist(
"Default Integrator")
407 .sublist(
"Time Step Control").get<
double>(
"Initial Time Step");
410 for (
int n=0; n<nTimeStepSizes; n++) {
414 std::cout <<
"\n \n time step #" << n <<
" (out of "
415 << nTimeStepSizes-1 <<
"), dt = " << dt <<
"\n";
416 pl->sublist(
"Default Integrator")
417 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
418 integrator = Tempus::integratorBasic<double>(pl, model);
421 bool integratorStatus = integrator->advanceTime();
422 TEST_ASSERT(integratorStatus)
425 time = integrator->getTime();
426 double timeFinal =pl->sublist(
"Default Integrator")
427 .sublist(
"Time Step Control").get<
double>(
"Final Time");
428 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
431 RCP<Thyra::VectorBase<double> > x = integrator->getX();
432 RCP<const Thyra::VectorBase<double> > x_exact =
433 model->getExactSolution(time).get_x();
436 if (n == nTimeStepSizes-1) {
438 integrator->getSolutionHistory();
441 RCP<Tempus::SolutionHistory<double> > solnHistExact =
444 double time = (*solutionHistory)[i]->getTime();
445 RCP<Tempus::SolutionState<double> > state =
447 model->getExactSolution(time).get_x(),
448 model->getExactSolution(time).get_x_dot()));
450 solnHistExact->addState(state);
452 writeSolution(
"Tempus_HHTAlpha_SinCos_FirstOrder-Ref.dat", solnHistExact);
456 std::ofstream ftmp(
"Tempus_HHTAlpha_SinCos_FirstOrder-Energy.dat");
459 integrator->getSolutionHistory();
460 RCP<const Thyra::VectorBase<double> > x_exact_plot;
462 RCP<const SolutionState<double> > solutionState = (*solutionHistory)[i];
463 double time = solutionState->getTime();
464 RCP<const Thyra::VectorBase<double> > x_plot = solutionState->getX();
465 RCP<const Thyra::VectorBase<double> > x_dot_plot = solutionState->getXDot();
466 x_exact_plot = model->getExactSolution(time).get_x();
468 double ke = Thyra::dot(*x_dot_plot, *x_dot_plot);
471 double pe = Thyra::dot(*x_plot, *x_plot);
477 << get_ele(*(x_plot), 0) <<
" "
478 << get_ele(*(x_exact_plot), 0) <<
" "
479 << get_ele(*(x_dot_plot), 0) <<
" "
480 << ke <<
" " << pe <<
" " << te << std::endl;
487 StepSize.push_back(dt);
488 auto solution = Thyra::createMember(model->get_x_space());
489 Thyra::copy(*(integrator->getX()),solution.ptr());
490 solutions.push_back(solution);
491 auto solutionDot = Thyra::createMember(model->get_x_space());
492 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
493 solutionsDot.push_back(solutionDot);
494 if (n == nTimeStepSizes-1) {
495 StepSize.push_back(0.0);
496 auto solution = Thyra::createMember(model->get_x_space());
497 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
498 solutions.push_back(solution);
499 auto solutionDot = Thyra::createMember(model->get_x_space());
500 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
502 solutionsDot.push_back(solutionDot);
508 double xDotSlope = 0.0;
509 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
510 double order = stepper->getOrder();
513 solutions, xErrorNorm, xSlope,
514 solutionsDot, xDotErrorNorm, xDotSlope);
516 TEST_FLOATING_EQUALITY( xSlope, order, 0.02 );
517 TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.048932, 1.0e-4 );
518 TEST_FLOATING_EQUALITY( xDotSlope, 1.18873, 0.01 );
519 TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.393504, 1.0e-4 );
522 #endif // TEST_SINCOS_FIRSTORDER
525 #ifdef TEST_SINCOS_CD
530 RCP<Tempus::IntegratorBasic<double> > integrator;
531 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
532 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
533 std::vector<double> StepSize;
534 std::vector<double> xErrorNorm;
535 std::vector<double> xDotErrorNorm;
536 const int nTimeStepSizes = 8;
540 RCP<ParameterList> pList =
541 getParametersFromXmlFile(
"Tempus_HHTAlpha_SinCos_ExplicitCD.xml");
544 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
545 RCP<HarmonicOscillatorModel<double> > model =
549 double k = hom_pl->get<
double>(
"x coeff k");
550 double m = hom_pl->get<
double>(
"Mass coeff m");
553 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
557 double dt =pl->sublist(
"Default Integrator")
558 .sublist(
"Time Step Control").get<
double>(
"Initial Time Step");
561 for (
int n=0; n<nTimeStepSizes; n++) {
565 std::cout <<
"\n \n time step #" << n <<
" (out of "
566 << nTimeStepSizes-1 <<
"), dt = " << dt <<
"\n";
567 pl->sublist(
"Default Integrator")
568 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
569 integrator = Tempus::integratorBasic<double>(pl, model);
572 bool integratorStatus = integrator->advanceTime();
573 TEST_ASSERT(integratorStatus)
576 time = integrator->getTime();
577 double timeFinal =pl->sublist(
"Default Integrator")
578 .sublist(
"Time Step Control").get<
double>(
"Final Time");
579 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
582 RCP<Thyra::VectorBase<double> > x = integrator->getX();
583 RCP<const Thyra::VectorBase<double> > x_exact =
584 model->getExactSolution(time).get_x();
587 if (n == nTimeStepSizes-1) {
589 integrator->getSolutionHistory();
592 RCP<Tempus::SolutionHistory<double> > solnHistExact =
595 double time = (*solutionHistory)[i]->getTime();
596 RCP<Tempus::SolutionState<double> > state =
598 model->getExactSolution(time).get_x(),
599 model->getExactSolution(time).get_x_dot()));
601 solnHistExact->addState(state);
603 writeSolution(
"Tempus_HHTAlpha_SinCos_ExplicitCD-Ref.dat", solnHistExact);
607 std::ofstream ftmp(
"Tempus_HHTAlpha_SinCos_ExplicitCD-Energy.dat");
610 integrator->getSolutionHistory();
611 RCP<const Thyra::VectorBase<double> > x_exact_plot;
613 RCP<const SolutionState<double> > solutionState = (*solutionHistory)[i];
614 double time = solutionState->getTime();
615 RCP<const Thyra::VectorBase<double> > x_plot = solutionState->getX();
616 RCP<const Thyra::VectorBase<double> > x_dot_plot = solutionState->getXDot();
617 x_exact_plot = model->getExactSolution(time).get_x();
619 double ke = Thyra::dot(*x_dot_plot, *x_dot_plot);
622 double pe = Thyra::dot(*x_plot, *x_plot);
628 << get_ele(*(x_plot), 0) <<
" "
629 << get_ele(*(x_exact_plot), 0) <<
" "
630 << get_ele(*(x_dot_plot), 0) <<
" "
631 << ke <<
" " << pe <<
" " << te << std::endl;
638 StepSize.push_back(dt);
639 auto solution = Thyra::createMember(model->get_x_space());
640 Thyra::copy(*(integrator->getX()),solution.ptr());
641 solutions.push_back(solution);
642 auto solutionDot = Thyra::createMember(model->get_x_space());
643 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
644 solutionsDot.push_back(solutionDot);
645 if (n == nTimeStepSizes-1) {
646 StepSize.push_back(0.0);
647 auto solution = Thyra::createMember(model->get_x_space());
648 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
649 solutions.push_back(solution);
650 auto solutionDot = Thyra::createMember(model->get_x_space());
651 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
653 solutionsDot.push_back(solutionDot);
659 double xDotSlope = 0.0;
660 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
661 double order = stepper->getOrder();
664 solutions, xErrorNorm, xSlope,
665 solutionsDot, xDotErrorNorm, xDotSlope);
667 TEST_FLOATING_EQUALITY( xSlope, order, 0.02 );
668 TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.00451069, 1.0e-4 );
669 TEST_FLOATING_EQUALITY( xDotSlope, order, 0.01 );
670 TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.0551522, 1.0e-4 );
672 #endif // TEST_SINCOS_CD