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"
17 #include "Tempus_StepperExplicitRK.hpp"
19 #include "../TestModels/SinCosModel.hpp"
20 #include "../TestModels/VanDerPolModel.hpp"
21 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
29 using Teuchos::ParameterList;
30 using Teuchos::sublist;
31 using Teuchos::getParametersFromXmlFile;
38 #define TEST_PARAMETERLIST
39 #define TEST_CONSTRUCTING_FROM_DEFAULTS
41 #define TEST_EMBEDDED_VANDERPOL
44 #ifdef TEST_PARAMETERLIST
49 std::vector<std::string> RKMethods;
50 RKMethods.push_back(
"Bogacki-Shampine 3(2) Pair");
51 RKMethods.push_back(
"Merson 4(5) Pair");
52 RKMethods.push_back(
"General ERK");
53 RKMethods.push_back(
"RK Forward Euler");
54 RKMethods.push_back(
"RK Explicit 4 Stage");
55 RKMethods.push_back(
"RK Explicit 3/8 Rule");
56 RKMethods.push_back(
"RK Explicit 4 Stage 3rd order by Runge");
57 RKMethods.push_back(
"RK Explicit 5 Stage 3rd order by Kinnmark and Gray");
58 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order");
59 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order TVD");
60 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order by Heun");
61 RKMethods.push_back(
"RK Explicit 2 Stage 2nd order by Runge");
62 RKMethods.push_back(
"RK Explicit Trapezoidal");
64 for(std::vector<std::string>::size_type m = 0; m != RKMethods.size(); m++) {
66 std::string RKMethod = RKMethods[m];
67 std::replace(RKMethod.begin(), RKMethod.end(),
' ',
'_');
68 std::replace(RKMethod.begin(), RKMethod.end(),
'/',
'.');
71 RCP<ParameterList> pList =
72 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
75 RCP<ParameterList> scm_pl = sublist(pList,
"SinCosModel",
true);
76 RCP<SinCosModel<double> > model =
80 RCP<ParameterList> tempusPL = sublist(pList,
"Tempus",
true);
81 if (RKMethods[m] ==
"General ERK") {
82 tempusPL->sublist(
"Demo Integrator").set(
"Stepper Name",
"Demo Stepper 2");
84 tempusPL->sublist(
"Demo Stepper").set(
"Stepper Type", RKMethods[m]);
89 RCP<Tempus::IntegratorBasic<double> > integrator =
90 Tempus::integratorBasic<double>(tempusPL, model);
92 RCP<ParameterList> stepperPL = sublist(tempusPL,
"Demo Stepper",
true);
93 if (RKMethods[m] ==
"General ERK")
94 stepperPL = sublist(tempusPL,
"Demo Stepper 2",
true);
95 RCP<ParameterList> defaultPL =
96 integrator->getStepper()->getDefaultParameters();
97 defaultPL->remove(
"Description");
99 TEST_ASSERT(haveSameValues(*stepperPL, *defaultPL,
true));
104 RCP<Tempus::IntegratorBasic<double> > integrator =
105 Tempus::integratorBasic<double>(model, RKMethods[m]);
107 RCP<ParameterList> stepperPL = sublist(tempusPL,
"Demo Stepper",
true);
108 if (RKMethods[m] ==
"General ERK")
109 stepperPL = sublist(tempusPL,
"Demo Stepper 2",
true);
110 RCP<ParameterList> defaultPL =
111 integrator->getStepper()->getDefaultParameters();
112 defaultPL->remove(
"Description");
114 TEST_ASSERT(haveSameValues(*stepperPL, *defaultPL,
true))
118 #endif // TEST_PARAMETERLIST
121 #ifdef TEST_CONSTRUCTING_FROM_DEFAULTS
129 RCP<ParameterList> pList =
130 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
131 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
134 RCP<ParameterList> scm_pl = sublist(pList,
"SinCosModel",
true);
136 RCP<SinCosModel<double> > model =
140 RCP<Tempus::StepperExplicitRK<double> > stepper =
144 RCP<Tempus::TimeStepControl<double> > timeStepControl =
146 ParameterList tscPL = pl->sublist(
"Demo Integrator")
147 .sublist(
"Time Step Control");
148 timeStepControl->setStepType (tscPL.get<std::string>(
"Integrator Step Type"));
149 timeStepControl->setInitIndex(tscPL.get<
int> (
"Initial Time Index"));
150 timeStepControl->setInitTime (tscPL.get<
double>(
"Initial Time"));
151 timeStepControl->setFinalTime(tscPL.get<
double>(
"Final Time"));
152 timeStepControl->setInitTimeStep(dt);
153 timeStepControl->initialize();
156 Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
157 stepper->getModel()->getNominalValues();
158 RCP<Thyra::VectorBase<double> > icSolution =
159 Teuchos::rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
160 RCP<Tempus::SolutionState<double> > icState =
162 icState->setTime (timeStepControl->getInitTime());
163 icState->setIndex (timeStepControl->getInitIndex());
164 icState->setTimeStep(0.0);
165 icState->setOrder (stepper->getOrder());
177 RCP<Tempus::IntegratorBasic<double> > integrator =
178 Tempus::integratorBasic<double>();
179 integrator->setStepperWStepper(stepper);
180 integrator->setTimeStepControl(timeStepControl);
183 integrator->initialize();
187 bool integratorStatus = integrator->advanceTime();
188 TEST_ASSERT(integratorStatus)
192 double time = integrator->getTime();
193 double timeFinal =pl->sublist(
"Demo Integrator")
194 .sublist(
"Time Step Control").get<
double>(
"Final Time");
195 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
198 RCP<Thyra::VectorBase<double> > x = integrator->getX();
199 RCP<const Thyra::VectorBase<double> > x_exact =
200 model->getExactSolution(time).get_x();
203 RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
204 Thyra::V_StVpStV(xdiff.ptr(), 1.0, *x_exact, -1.0, *(x));
207 std::cout <<
" Stepper = RK Explicit 4 Stage" << std::endl;
208 std::cout <<
" =========================" << std::endl;
209 std::cout <<
" Exact solution : " << get_ele(*(x_exact), 0) <<
" "
210 << get_ele(*(x_exact), 1) << std::endl;
211 std::cout <<
" Computed solution: " << get_ele(*(x ), 0) <<
" "
212 << get_ele(*(x ), 1) << std::endl;
213 std::cout <<
" Difference : " << get_ele(*(xdiff ), 0) <<
" "
214 << get_ele(*(xdiff ), 1) << std::endl;
215 std::cout <<
" =========================" << std::endl;
216 TEST_FLOATING_EQUALITY(get_ele(*(x), 0), 0.841470, 1.0e-4 );
217 TEST_FLOATING_EQUALITY(get_ele(*(x), 1), 0.540303, 1.0e-4 );
219 #endif // TEST_CONSTRUCTING_FROM_DEFAULTS
227 std::vector<std::string> RKMethods;
228 RKMethods.push_back(
"RK Forward Euler");
229 RKMethods.push_back(
"RK Explicit 4 Stage");
230 RKMethods.push_back(
"RK Explicit 3/8 Rule");
231 RKMethods.push_back(
"RK Explicit 4 Stage 3rd order by Runge");
232 RKMethods.push_back(
"RK Explicit 5 Stage 3rd order by Kinnmark and Gray");
233 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order");
234 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order TVD");
235 RKMethods.push_back(
"RK Explicit 3 Stage 3rd order by Heun");
236 RKMethods.push_back(
"RK Explicit 2 Stage 2nd order by Runge");
237 RKMethods.push_back(
"RK Explicit Trapezoidal");
238 RKMethods.push_back(
"Bogacki-Shampine 3(2) Pair");
239 RKMethods.push_back(
"General ERK");
240 RKMethods.push_back(
"General ERK Embedded");
242 std::vector<double> RKMethodErrors;
243 RKMethodErrors.push_back(0.051123);
244 RKMethodErrors.push_back(8.33251e-07);
245 RKMethodErrors.push_back(8.33251e-07);
246 RKMethodErrors.push_back(4.16897e-05);
247 RKMethodErrors.push_back(8.32108e-06);
248 RKMethodErrors.push_back(4.16603e-05);
249 RKMethodErrors.push_back(4.16603e-05);
250 RKMethodErrors.push_back(4.16603e-05);
251 RKMethodErrors.push_back(0.00166645);
252 RKMethodErrors.push_back(0.00166645);
253 RKMethodErrors.push_back(4.16603e-05);
254 RKMethodErrors.push_back(8.33251e-07);
255 RKMethodErrors.push_back(4.16603e-05);
258 for(std::vector<std::string>::size_type m = 0; m != RKMethods.size(); m++) {
260 std::string RKMethod = RKMethods[m];
261 std::replace(RKMethod.begin(), RKMethod.end(),
' ',
'_');
262 std::replace(RKMethod.begin(), RKMethod.end(),
'/',
'.');
264 RCP<Tempus::IntegratorBasic<double> > integrator;
265 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
266 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
267 std::vector<double> StepSize;
268 std::vector<double> xErrorNorm;
269 std::vector<double> xDotErrorNorm;
271 const int nTimeStepSizes = 7;
274 for (
int n=0; n<nTimeStepSizes; n++) {
277 RCP<ParameterList> pList =
278 getParametersFromXmlFile(
"Tempus_ExplicitRK_SinCos.xml");
281 RCP<ParameterList> scm_pl = sublist(pList,
"SinCosModel",
true);
283 RCP<SinCosModel<double> > model =
287 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
288 if (RKMethods[m] ==
"General ERK") {
289 pl->sublist(
"Demo Integrator").set(
"Stepper Name",
"Demo Stepper 2");
290 }
else if (RKMethods[m] ==
"General ERK Embedded"){
291 pl->sublist(
"Demo Integrator").set(
"Stepper Name",
"General ERK Embedded Stepper");
293 pl->sublist(
"Demo Stepper").set(
"Stepper Type", RKMethods[m]);
300 pl->sublist(
"Demo Integrator")
301 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
302 integrator = Tempus::integratorBasic<double>(pl, model);
308 RCP<Thyra::VectorBase<double> > x0 =
309 model->getNominalValues().get_x()->clone_v();
310 integrator->setInitialState(0.0, x0);
313 bool integratorStatus = integrator->advanceTime();
314 TEST_ASSERT(integratorStatus)
317 time = integrator->getTime();
318 double timeFinal = pl->sublist(
"Demo Integrator")
319 .sublist(
"Time Step Control").get<
double>(
"Final Time");
320 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
323 RCP<Thyra::VectorBase<double> > x = integrator->getX();
324 RCP<const Thyra::VectorBase<double> > x_exact =
325 model->getExactSolution(time).get_x();
330 integrator->getSolutionHistory();
333 RCP<Tempus::SolutionHistory<double> > solnHistExact =
336 double time = (*solutionHistory)[i]->getTime();
337 RCP<Tempus::SolutionState<double> > state =
339 model->getExactSolution(time).get_x(),
340 model->getExactSolution(time).get_x_dot()));
342 solnHistExact->addState(state);
344 writeSolution(
"Tempus_"+RKMethod+
"_SinCos-Ref.dat", solnHistExact);
348 StepSize.push_back(dt);
349 auto solution = Thyra::createMember(model->get_x_space());
350 Thyra::copy(*(integrator->getX()),solution.ptr());
351 solutions.push_back(solution);
352 auto solutionDot = Thyra::createMember(model->get_x_space());
353 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
354 solutionsDot.push_back(solutionDot);
355 if (n == nTimeStepSizes-1) {
356 StepSize.push_back(0.0);
357 auto solution = Thyra::createMember(model->get_x_space());
358 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
359 solutions.push_back(solution);
360 auto solutionDot = Thyra::createMember(model->get_x_space());
361 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
363 solutionsDot.push_back(solutionDot);
369 double xDotSlope = 0.0;
370 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
371 double order = stepper->getOrder();
374 solutions, xErrorNorm, xSlope,
375 solutionsDot, xDotErrorNorm, xDotSlope);
377 TEST_FLOATING_EQUALITY( xSlope, order, 0.01 );
378 TEST_FLOATING_EQUALITY( xErrorNorm[0], RKMethodErrors[m], 1.0e-4 );
386 #endif // TEST_SINCOS
389 #ifdef TEST_EMBEDDED_VANDERPOL
395 std::vector<std::string> IntegratorList;
396 IntegratorList.push_back(
"Embedded_Integrator_PID");
397 IntegratorList.push_back(
"Demo_Integrator");
398 IntegratorList.push_back(
"Embedded_Integrator");
399 IntegratorList.push_back(
"General_Embedded_Integrator");
400 IntegratorList.push_back(
"Embedded_Integrator_PID_General");
404 const int refIstep = 45;
406 for(
auto integratorChoice : IntegratorList){
408 std::cout <<
"Using Integrator: " << integratorChoice <<
" !!!" << std::endl;
411 RCP<ParameterList> pList =
412 getParametersFromXmlFile(
"Tempus_ExplicitRK_VanDerPol.xml");
416 RCP<ParameterList> vdpm_pl = sublist(pList,
"VanDerPolModel",
true);
417 RCP<VanDerPolModel<double> > model =
422 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
423 pl->set(
"Integrator Name", integratorChoice);
426 RCP<Tempus::IntegratorBasic<double> > integrator =
427 Tempus::integratorBasic<double>(pl, model);
429 const std::string RKMethod =
430 pl->sublist(integratorChoice).get<std::string>(
"Stepper Name");
433 bool integratorStatus = integrator->advanceTime();
434 TEST_ASSERT(integratorStatus);
437 double time = integrator->getTime();
438 double timeFinal = pl->sublist(integratorChoice)
439 .sublist(
"Time Step Control").get<
double>(
"Final Time");
440 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
444 RCP<Thyra::VectorBase<double> > x = integrator->getX();
445 RCP<Thyra::VectorBase<double> > xref = x->clone_v();
446 Thyra::set_ele(0, -1.5484458614405929, xref.ptr());
447 Thyra::set_ele(1, 1.0181127316101317, xref.ptr());
450 RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
451 Thyra::V_StVpStV(xdiff.ptr(), 1.0, *xref, -1.0, *(x));
452 const double L2norm = Thyra::norm_2(*xdiff);
455 if ((integratorChoice ==
"Embedded_Integrator_PID") or
456 (integratorChoice ==
"Embedded_Integrator_PID_General")) {
458 const double absTol = pl->sublist(integratorChoice).
459 sublist(
"Time Step Control").get<
double>(
"Maximum Absolute Error");
460 const double relTol = pl->sublist(integratorChoice).
461 sublist(
"Time Step Control").get<
double>(
"Maximum Relative Error");
464 TEST_COMPARE(std::log10(L2norm), <, std::log10(absTol));
465 TEST_COMPARE(std::log10(L2norm), <, std::log10(relTol));
470 const int iStep = integrator->getSolutionHistory()->
471 getCurrentState()->getIndex();
472 const int nFail = integrator->getSolutionHistory()->
473 getCurrentState()->getMetaData()->getNRunningFailures();
476 TEST_EQUALITY(iStep, refIstep);
477 std::cout <<
"Tolerance = " << absTol
478 <<
" L2norm = " << L2norm
479 <<
" iStep = " << iStep
480 <<
" nFail = " << nFail << std::endl;
484 std::ofstream ftmp(
"Tempus_"+integratorChoice+RKMethod+
"_VDP_Example.dat");
486 integrator->getSolutionHistory();
489 for (
int i=0; i<nStates; i++) {
490 RCP<const SolutionState<double> > solutionState = (*solutionHistory)[i];
491 double time = solutionState->getTime();
492 RCP<const Thyra::VectorBase<double> > x_plot = solutionState->getX();
495 << Thyra::get_ele(*(x_plot), 0) <<
" "
496 << Thyra::get_ele(*(x_plot), 1) <<
" " << std::endl;
501 Teuchos::TimeMonitor::summarize();
503 #endif // TEST_EMBEDDED_VANDERPOL