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_StepperNewmarkImplicitAForm.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;
50 #define TEST_BALL_PARABOLIC
51 #define TEST_SINCOS_EXPLICIT
52 #define TEST_HARMONIC_OSCILLATOR_DAMPED_EXPLICIT
53 #define TEST_HARMONIC_OSCILLATOR_DAMPED_CTOR
54 #define TEST_HARMONIC_OSCILLATOR_DAMPED
57 #ifdef TEST_BALL_PARABOLIC
62 double tolerance = 1.0e-14;
64 RCP<ParameterList> pList =
65 getParametersFromXmlFile(
"Tempus_NewmarkExplicitAForm_BallParabolic.xml");
68 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
69 RCP<HarmonicOscillatorModel<double> > model =
73 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
74 RCP<ParameterList> stepperPL = sublist(pl,
"Default Stepper",
true);
75 stepperPL->remove(
"Zero Initial Guess");
77 RCP<Tempus::IntegratorBasic<double> > integrator =
78 Tempus::integratorBasic<double>(pl, model);
81 bool integratorStatus = integrator->advanceTime();
82 TEST_ASSERT(integratorStatus)
85 double time = integrator->getTime();
86 double timeFinal =pl->sublist(
"Default Integrator")
87 .sublist(
"Time Step Control").get<
double>(
"Final Time");
88 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
91 RCP<Thyra::VectorBase<double> > x = integrator->getX();
92 RCP<const Thyra::VectorBase<double> > x_exact =
93 model->getExactSolution(time).get_x();
96 std::ofstream ftmp(
"Tempus_NewmarkExplicitAForm_BallParabolic.dat");
99 integrator->getSolutionHistory();
102 RCP<const Thyra::VectorBase<double> > x_exact_plot;
104 RCP<const SolutionState<double> > solutionState = (*solutionHistory)[i];
105 double time = solutionState->getTime();
106 RCP<const Thyra::VectorBase<double> > x_plot = solutionState->getX();
107 x_exact_plot = model->getExactSolution(time).get_x();
109 << get_ele(*(x_plot), 0) <<
" "
110 << get_ele(*(x_exact_plot), 0) << std::endl;
111 if (abs(get_ele(*(x_plot),0) - get_ele(*(x_exact_plot), 0)) > err)
112 err = abs(get_ele(*(x_plot),0) - get_ele(*(x_exact_plot), 0));
115 std::cout <<
"Max error = " << err <<
"\n \n";
119 TEUCHOS_TEST_FOR_EXCEPTION(!passed, std::logic_error,
120 "\n Test failed! Max error = " << err <<
" > tolerance = " << tolerance <<
"\n!");
125 #ifdef TEST_SINCOS_EXPLICIT
129 RCP<Tempus::IntegratorBasic<double> > integrator;
130 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
131 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
132 std::vector<double> StepSize;
133 std::vector<double> xErrorNorm;
134 std::vector<double> xDotErrorNorm;
135 const int nTimeStepSizes = 9;
139 RCP<ParameterList> pList =
140 getParametersFromXmlFile(
"Tempus_NewmarkExplicitAForm_SinCos.xml");
143 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
144 RCP<HarmonicOscillatorModel<double> > model =
149 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
150 RCP<ParameterList> stepperPL = sublist(pl,
"Default Stepper",
true);
151 stepperPL->remove(
"Zero Initial Guess");
155 double dt =pl->sublist(
"Default Integrator")
156 .sublist(
"Time Step Control").get<
double>(
"Initial Time Step");
159 for (
int n=0; n<nTimeStepSizes; n++) {
163 std::cout <<
"\n \n time step #" << n <<
" (out of "
164 << nTimeStepSizes-1 <<
"), dt = " << dt <<
"\n";
165 pl->sublist(
"Default Integrator")
166 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
167 integrator = Tempus::integratorBasic<double>(pl, model);
170 bool integratorStatus = integrator->advanceTime();
171 TEST_ASSERT(integratorStatus)
174 time = integrator->getTime();
175 double timeFinal =pl->sublist(
"Default Integrator")
176 .sublist(
"Time Step Control").get<
double>(
"Final Time");
177 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
182 integrator->getSolutionHistory();
185 RCP<Tempus::SolutionHistory<double> > solnHistExact =
188 double time = (*solutionHistory)[i]->getTime();
189 RCP<Tempus::SolutionState<double> > state =
191 model->getExactSolution(time).get_x(),
192 model->getExactSolution(time).get_x_dot()));
194 solnHistExact->addState(state);
196 writeSolution(
"Tempus_NewmarkExplicitAForm_SinCos-Ref.dat",solnHistExact);
200 StepSize.push_back(dt);
201 auto solution = Thyra::createMember(model->get_x_space());
202 Thyra::copy(*(integrator->getX()),solution.ptr());
203 solutions.push_back(solution);
204 auto solutionDot = Thyra::createMember(model->get_x_space());
205 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
206 solutionsDot.push_back(solutionDot);
207 if (n == nTimeStepSizes-1) {
208 StepSize.push_back(0.0);
209 auto solution = Thyra::createMember(model->get_x_space());
210 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
211 solutions.push_back(solution);
212 auto solutionDot = Thyra::createMember(model->get_x_space());
213 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
215 solutionsDot.push_back(solutionDot);
221 double xDotSlope = 0.0;
222 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
223 double order = stepper->getOrder();
226 solutions, xErrorNorm, xSlope,
227 solutionsDot, xDotErrorNorm, xDotSlope);
229 TEST_FLOATING_EQUALITY( xSlope, order, 0.02 );
230 TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.0157928, 1.0e-4 );
231 TEST_FLOATING_EQUALITY( xDotSlope, order, 0.02 );
232 TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.233045, 1.0e-4 );
234 Teuchos::TimeMonitor::summarize();
238 #ifdef TEST_HARMONIC_OSCILLATOR_DAMPED_EXPLICIT
242 RCP<Tempus::IntegratorBasic<double> > integrator;
243 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
244 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
245 std::vector<double> StepSize;
246 std::vector<double> xErrorNorm;
247 std::vector<double> xDotErrorNorm;
248 const int nTimeStepSizes = 9;
252 RCP<ParameterList> pList =
253 getParametersFromXmlFile(
"Tempus_NewmarkExplicitAForm_HarmonicOscillator_Damped.xml");
256 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
257 RCP<HarmonicOscillatorModel<double> > model =
262 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
263 RCP<ParameterList> stepperPL = sublist(pl,
"Default Stepper",
true);
264 stepperPL->remove(
"Zero Initial Guess");
268 double dt =pl->sublist(
"Default Integrator")
269 .sublist(
"Time Step Control").get<
double>(
"Initial Time Step");
272 for (
int n=0; n<nTimeStepSizes; n++) {
276 std::cout <<
"\n \n time step #" << n <<
" (out of "
277 << nTimeStepSizes-1 <<
"), dt = " << dt <<
"\n";
278 pl->sublist(
"Default Integrator")
279 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
280 integrator = Tempus::integratorBasic<double>(pl, model);
283 bool integratorStatus = integrator->advanceTime();
284 TEST_ASSERT(integratorStatus)
287 time = integrator->getTime();
288 double timeFinal =pl->sublist(
"Default Integrator")
289 .sublist(
"Time Step Control").get<
double>(
"Final Time");
290 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
295 integrator->getSolutionHistory();
298 RCP<Tempus::SolutionHistory<double> > solnHistExact =
301 double time = (*solutionHistory)[i]->getTime();
302 RCP<Tempus::SolutionState<double> > state =
304 model->getExactSolution(time).get_x(),
305 model->getExactSolution(time).get_x_dot()));
307 solnHistExact->addState(state);
309 writeSolution(
"Tempus_NewmarkExplicitAForm_HarmonicOscillator_Damped-Ref.dat", solnHistExact);
313 StepSize.push_back(dt);
314 auto solution = Thyra::createMember(model->get_x_space());
315 Thyra::copy(*(integrator->getX()),solution.ptr());
316 solutions.push_back(solution);
317 auto solutionDot = Thyra::createMember(model->get_x_space());
318 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
319 solutionsDot.push_back(solutionDot);
320 if (n == nTimeStepSizes-1) {
321 StepSize.push_back(0.0);
322 auto solution = Thyra::createMember(model->get_x_space());
323 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
324 solutions.push_back(solution);
325 auto solutionDot = Thyra::createMember(model->get_x_space());
326 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
328 solutionsDot.push_back(solutionDot);
334 double xDotSlope = 0.0;
335 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
336 double order = stepper->getOrder();
337 writeOrderError(
"Tempus_NewmarkExplicitAForm_HarmonicOscillator_Damped-Error.dat",
339 solutions, xErrorNorm, xSlope,
340 solutionsDot, xDotErrorNorm, xDotSlope);
342 TEST_FLOATING_EQUALITY( xSlope, order, 0.01 );
343 TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.617129, 1.0e-4 );
344 TEST_FLOATING_EQUALITY( xDotSlope, order, 0.01 );
345 TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.270671, 1.0e-4 );
347 Teuchos::TimeMonitor::summarize();
352 #ifdef TEST_HARMONIC_OSCILLATOR_DAMPED_CTOR
360 RCP<ParameterList> pList = getParametersFromXmlFile(
361 "Tempus_NewmarkImplicitAForm_HarmonicOscillator_Damped_SecondOrder.xml");
362 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
365 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
366 RCP<HarmonicOscillatorModel<double> > model =
370 RCP<Tempus::StepperNewmarkImplicitAForm<double> > stepper =
374 RCP<Tempus::TimeStepControl<double> > timeStepControl =
376 ParameterList tscPL = pl->sublist(
"Default Integrator")
377 .sublist(
"Time Step Control");
378 timeStepControl->setStepType (tscPL.get<std::string>(
"Integrator Step Type"));
379 timeStepControl->setInitIndex(tscPL.get<
int> (
"Initial Time Index"));
380 timeStepControl->setInitTime (tscPL.get<
double>(
"Initial Time"));
381 timeStepControl->setFinalTime(tscPL.get<
double>(
"Final Time"));
382 timeStepControl->setInitTimeStep(dt);
383 timeStepControl->initialize();
386 using Teuchos::rcp_const_cast;
387 Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
388 stepper->getModel()->getNominalValues();
389 RCP<Thyra::VectorBase<double> > icX =
390 rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
391 RCP<Thyra::VectorBase<double> > icXDot =
392 rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
393 RCP<Thyra::VectorBase<double> > icXDotDot =
394 rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot_dot());
395 RCP<Tempus::SolutionState<double> > icState =
397 icState->setTime (timeStepControl->getInitTime());
398 icState->setIndex (timeStepControl->getInitIndex());
399 icState->setTimeStep(0.0);
400 icState->setOrder (stepper->getOrder());
412 RCP<Tempus::IntegratorBasic<double> > integrator =
413 Tempus::integratorBasic<double>();
414 integrator->setStepperWStepper(stepper);
415 integrator->setTimeStepControl(timeStepControl);
418 integrator->initialize();
422 bool integratorStatus = integrator->advanceTime();
423 TEST_ASSERT(integratorStatus)
427 double time = integrator->getTime();
428 double timeFinal =pl->sublist(
"Default Integrator")
429 .sublist(
"Time Step Control").get<
double>(
"Final Time");
430 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
433 RCP<Thyra::VectorBase<double> > x = integrator->getX();
434 RCP<const Thyra::VectorBase<double> > x_exact =
435 model->getExactSolution(time).get_x();
438 RCP<Thyra::VectorBase<double> > xdiff = x->clone_v();
439 Thyra::V_StVpStV(xdiff.ptr(), 1.0, *x_exact, -1.0, *(x));
442 std::cout <<
" Stepper = " << stepper->description() << std::endl;
443 std::cout <<
" =========================" << std::endl;
444 std::cout <<
" Exact solution : " << get_ele(*(x_exact), 0) << std::endl;
445 std::cout <<
" Computed solution: " << get_ele(*(x ), 0) << std::endl;
446 std::cout <<
" Difference : " << get_ele(*(xdiff ), 0) << std::endl;
447 std::cout <<
" =========================" << std::endl;
448 TEST_FLOATING_EQUALITY(get_ele(*(x), 0), -0.222222, 1.0e-4 );
453 #ifdef TEST_HARMONIC_OSCILLATOR_DAMPED
457 RCP<Tempus::IntegratorBasic<double> > integrator;
458 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
459 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
460 std::vector<double> StepSize;
461 std::vector<double> xErrorNorm;
462 std::vector<double> xDotErrorNorm;
463 const int nTimeStepSizes = 10;
467 RCP<ParameterList> pList =
468 getParametersFromXmlFile(
"Tempus_NewmarkImplicitAForm_HarmonicOscillator_Damped_SecondOrder.xml");
471 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
472 RCP<HarmonicOscillatorModel<double> > model =
477 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
481 double dt =pl->sublist(
"Default Integrator")
482 .sublist(
"Time Step Control").get<
double>(
"Initial Time Step");
485 for (
int n=0; n<nTimeStepSizes; n++) {
489 std::cout <<
"\n \n time step #" << n <<
" (out of "
490 << nTimeStepSizes-1 <<
"), dt = " << dt <<
"\n";
491 pl->sublist(
"Default Integrator")
492 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
493 integrator = Tempus::integratorBasic<double>(pl, model);
496 bool integratorStatus = integrator->advanceTime();
497 TEST_ASSERT(integratorStatus)
500 time = integrator->getTime();
501 double timeFinal =pl->sublist(
"Default Integrator")
502 .sublist(
"Time Step Control").get<
double>(
"Final Time");
503 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
508 integrator->getSolutionHistory();
511 RCP<Tempus::SolutionHistory<double> > solnHistExact =
514 double time = (*solutionHistory)[i]->getTime();
515 RCP<Tempus::SolutionState<double> > state =
517 model->getExactSolution(time).get_x(),
518 model->getExactSolution(time).get_x_dot()));
520 solnHistExact->addState(state);
522 writeSolution(
"Tempus_NewmarkImplicitAForm_HarmonicOscillator_Damped_SecondOrder-Ref.dat", solnHistExact);
526 StepSize.push_back(dt);
527 auto solution = Thyra::createMember(model->get_x_space());
528 Thyra::copy(*(integrator->getX()),solution.ptr());
529 solutions.push_back(solution);
530 auto solutionDot = Thyra::createMember(model->get_x_space());
531 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
532 solutionsDot.push_back(solutionDot);
533 if (n == nTimeStepSizes-1) {
534 StepSize.push_back(0.0);
535 auto solution = Thyra::createMember(model->get_x_space());
536 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
537 solutions.push_back(solution);
538 auto solutionDot = Thyra::createMember(model->get_x_space());
539 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
541 solutionsDot.push_back(solutionDot);
547 double xDotSlope = 0.0;
548 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
549 double order = stepper->getOrder();
550 writeOrderError(
"Tempus_NewmarkImplicitAForm_HarmonicOscillator_Damped_SecondOrder_SinCos-Error.dat",
552 solutions, xErrorNorm, xSlope,
553 solutionsDot, xDotErrorNorm, xDotSlope);
555 TEST_FLOATING_EQUALITY( xSlope, order, 0.01 );
556 TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.0484483, 1.0e-4 );
557 TEST_FLOATING_EQUALITY( xDotSlope, order, 0.01 );
558 TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.0484483, 1.0e-4 );
560 Teuchos::TimeMonitor::summarize();
566 RCP<Tempus::IntegratorBasic<double> > integrator;
567 std::vector<RCP<Thyra::VectorBase<double>>> solutions;
568 std::vector<RCP<Thyra::VectorBase<double>>> solutionsDot;
569 std::vector<double> StepSize;
570 std::vector<double> xErrorNorm;
571 std::vector<double> xDotErrorNorm;
572 const int nTimeStepSizes = 10;
576 RCP<ParameterList> pList =
577 getParametersFromXmlFile(
"Tempus_NewmarkImplicitAForm_HarmonicOscillator_Damped_FirstOrder.xml");
580 RCP<ParameterList> hom_pl = sublist(pList,
"HarmonicOscillatorModel",
true);
581 RCP<HarmonicOscillatorModel<double> > model =
586 RCP<ParameterList> pl = sublist(pList,
"Tempus",
true);
590 double dt =pl->sublist(
"Default Integrator")
591 .sublist(
"Time Step Control").get<
double>(
"Initial Time Step");
594 for (
int n=0; n<nTimeStepSizes; n++) {
598 std::cout <<
"\n \n time step #" << n <<
" (out of "
599 << nTimeStepSizes-1 <<
"), dt = " << dt <<
"\n";
600 pl->sublist(
"Default Integrator")
601 .sublist(
"Time Step Control").set(
"Initial Time Step", dt);
602 integrator = Tempus::integratorBasic<double>(pl, model);
605 bool integratorStatus = integrator->advanceTime();
606 TEST_ASSERT(integratorStatus)
609 time = integrator->getTime();
610 double timeFinal =pl->sublist(
"Default Integrator")
611 .sublist(
"Time Step Control").get<
double>(
"Final Time");
612 TEST_FLOATING_EQUALITY(time, timeFinal, 1.0e-14);
617 integrator->getSolutionHistory();
620 RCP<Tempus::SolutionHistory<double> > solnHistExact =
623 double time = (*solutionHistory)[i]->getTime();
624 RCP<Tempus::SolutionState<double> > state =
626 model->getExactSolution(time).get_x(),
627 model->getExactSolution(time).get_x_dot()));
629 solnHistExact->addState(state);
631 writeSolution(
"Tempus_NewmarkImplicitAForm_HarmonicOscillator_Damped_FirstOrder-Ref.dat", solnHistExact);
635 StepSize.push_back(dt);
636 auto solution = Thyra::createMember(model->get_x_space());
637 Thyra::copy(*(integrator->getX()),solution.ptr());
638 solutions.push_back(solution);
639 auto solutionDot = Thyra::createMember(model->get_x_space());
640 Thyra::copy(*(integrator->getXdot()),solutionDot.ptr());
641 solutionsDot.push_back(solutionDot);
642 if (n == nTimeStepSizes-1) {
643 StepSize.push_back(0.0);
644 auto solution = Thyra::createMember(model->get_x_space());
645 Thyra::copy(*(model->getExactSolution(time).get_x()),solution.ptr());
646 solutions.push_back(solution);
647 auto solutionDot = Thyra::createMember(model->get_x_space());
648 Thyra::copy(*(model->getExactSolution(time).get_x_dot()),
650 solutionsDot.push_back(solutionDot);
656 double xDotSlope = 0.0;
657 RCP<Tempus::Stepper<double> > stepper = integrator->getStepper();
658 double order = stepper->getOrder();
659 writeOrderError(
"Tempus_NewmarkImplicitAForm_HarmonicOscillator_Damped_FirstOrder-Error.dat",
661 solutions, xErrorNorm, xSlope,
662 solutionsDot, xDotErrorNorm, xDotSlope);
664 TEST_FLOATING_EQUALITY( xSlope, order, 0.02 );
665 TEST_FLOATING_EQUALITY( xErrorNorm[0], 0.0224726, 1.0e-4 );
666 TEST_FLOATING_EQUALITY( xDotSlope, order, 0.02 );
667 TEST_FLOATING_EQUALITY( xDotErrorNorm[0], 0.0122223, 1.0e-4 );
669 Teuchos::TimeMonitor::summarize();