Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_UnitTest_ERK.cpp
Go to the documentation of this file.
1//@HEADER
2// *****************************************************************************
3// Tempus: Time Integration and Sensitivity Analysis Package
4//
5// Copyright 2017 NTESS and the Tempus contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8//@HEADER
9
11
16
17#include "../TestModels/DahlquistTestModel.hpp"
18
19namespace Tempus_Unit_Test {
20
21using Teuchos::RCP;
22using Teuchos::rcp;
23using Teuchos::rcp_const_cast;
24using Teuchos::rcp_dynamic_cast;
25
118class StepperRKModifierBogackiShampineTest
119 : virtual public Tempus::StepperRKModifierBase<double> {
120 public:
122 StepperRKModifierBogackiShampineTest(Teuchos::FancyOStream &Out,
123 bool &Success)
124 : out(Out), success(Success)
125 {
126 }
127
129 virtual ~StepperRKModifierBogackiShampineTest() {}
130
132 virtual void modify(
133 Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
134 Teuchos::RCP<Tempus::StepperRKBase<double> > stepper,
136 {
137 const double relTol = 1.0e-14;
138 auto stageNumber = stepper->getStageNumber();
139 Teuchos::SerialDenseVector<int, double> c = stepper->getTableau()->c();
140
141 auto currentState = sh->getCurrentState();
142 auto workingState = sh->getWorkingState();
143 const double dt = workingState->getTimeStep();
144 double time = currentState->getTime();
145 if (stageNumber >= 0) time += c(stageNumber) * dt;
146
147 auto x = workingState->getX();
148 auto xDot = workingState->getXDot();
149 if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
150
151 if (actLoc == StepperRKAppAction<double>::BEGIN_STEP) {
152 {
153 auto DME = Teuchos::rcp_dynamic_cast<
155 stepper->getModel());
156 TEST_FLOATING_EQUALITY(DME->getLambda(), -1.0, relTol);
157 }
158 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
159
160 const double x_0 = get_ele(*(x), 0);
161 const double xDot_0 = get_ele(*(xDot), 0);
162 TEST_FLOATING_EQUALITY(x_0, 1.0, relTol); // Should be x_0
163 TEST_FLOATING_EQUALITY(xDot_0, -1.0, relTol); // Should be xDot_0
164 TEST_ASSERT(std::abs(time) < relTol);
165 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
166 TEST_COMPARE(stageNumber, ==, -1);
167 }
168 else if (actLoc == StepperRKAppAction<double>::BEGIN_STAGE ||
169 actLoc == StepperRKAppAction<double>::BEFORE_SOLVE ||
170 actLoc == StepperRKAppAction<double>::AFTER_SOLVE ||
171 actLoc == StepperRKAppAction<double>::BEFORE_EXPLICIT_EVAL ||
172 actLoc == StepperRKAppAction<double>::END_STAGE) {
173 const double X_i = get_ele(*(x), 0);
174 const double f_i = get_ele(*(xDot), 0);
175 if (stageNumber == 0) {
176 TEST_FLOATING_EQUALITY(X_i, 1.0, relTol); // Should be X_1
177 TEST_ASSERT(std::abs(time) < relTol);
178 if (actLoc == StepperRKAppAction<double>::END_STAGE ||
179 !stepper->getUseFSAL()) {
180 TEST_FLOATING_EQUALITY(f_i, -1.0, relTol); // Should be \bar{f}_1
181 }
182 else {
183 TEST_ASSERT(std::abs(f_i) < relTol); // Not set yet.
184 }
185 }
186 else if (stageNumber == 1) {
187 TEST_FLOATING_EQUALITY(X_i, 0.5, relTol); // Should be X_2
188 TEST_FLOATING_EQUALITY(time, 0.5, relTol);
189 if (actLoc == StepperRKAppAction<double>::END_STAGE) {
190 TEST_FLOATING_EQUALITY(f_i, -0.5, relTol); // Should be \bar{f}_2
191 }
192 else {
193 TEST_ASSERT(std::abs(f_i) < relTol); // Not set yet.
194 }
195 }
196 else if (stageNumber == 2) {
197 TEST_FLOATING_EQUALITY(X_i, 5.0 / 8.0, relTol); // Should be X_3
198 TEST_FLOATING_EQUALITY(time, 0.75, relTol);
199 if (actLoc == StepperRKAppAction<double>::END_STAGE) {
200 TEST_FLOATING_EQUALITY(f_i, -5.0 / 8.0,
201 relTol); // Should be \bar{f}_3
202 }
203 else {
204 TEST_ASSERT(std::abs(f_i) < relTol); // Not set yet.
205 }
206 }
207 else if (stageNumber == 3) {
208 TEST_FLOATING_EQUALITY(X_i, 1.0 / 3.0, relTol); // Should be X_4
209 TEST_FLOATING_EQUALITY(time, 1.0, relTol);
210 if (actLoc == StepperRKAppAction<double>::END_STAGE) {
211 TEST_FLOATING_EQUALITY(f_i, -1.0 / 3.0,
212 relTol); // Should be \bar{f}_4
213 }
214 else if (workingState->getNConsecutiveFailures() > 0) {
215 TEST_FLOATING_EQUALITY(f_i, -1.0, relTol); // From IC and FSAL swap.
216 }
217 else {
218 TEST_ASSERT(std::abs(f_i) < relTol); // Not set yet.
219 }
220 }
221 else {
222 TEUCHOS_TEST_FOR_EXCEPT(!(-1 < stageNumber && stageNumber < 4));
223 }
224 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
225 }
226 else if (actLoc == StepperRKAppAction<double>::END_STEP) {
227 const double x_1 = get_ele(*(x), 0);
228 time = workingState->getTime();
229 TEST_FLOATING_EQUALITY(x_1, 1.0 / 3.0, relTol); // Should be x_1
230 TEST_FLOATING_EQUALITY(time, 1.0, relTol);
231 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
232 TEST_COMPARE(stageNumber, ==, -1);
233
234 if (stepper->getUseEmbedded() == true) {
235 TEST_FLOATING_EQUALITY(workingState->getTolRel(), 1.0, relTol);
236 TEST_ASSERT(std::abs(workingState->getTolAbs()) < relTol);
237 // e = 0 from doxygen above.
238 TEST_ASSERT(std::abs(workingState->getErrorRel()) < relTol);
239 }
240 }
241 else {
242 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
243 "Error - unknown action location.\n");
244 }
245 }
246
247 private:
248 Teuchos::FancyOStream &out;
249 bool &success;
250};
251
252// ************************************************************
253// ************************************************************
254TEUCHOS_UNIT_TEST(ERK, Modifier)
255{
256 auto stepper = rcp(new Tempus::StepperERK_BogackiShampine32<double>());
257 Teuchos::RCP<const Thyra::ModelEvaluator<double> > model =
259 auto modifier = rcp(new StepperRKModifierBogackiShampineTest(out, success));
260
261 stepper->setModel(model);
262 stepper->setAppAction(modifier);
263 stepper->setICConsistency("Consistent");
264 stepper->setUseFSAL(false);
265 stepper->initialize();
266
267 // Create a SolutionHistory.
268 auto solutionHistory = Tempus::createSolutionHistoryME(model);
269
270 // Take one time step.
271 stepper->setInitialConditions(solutionHistory);
272 solutionHistory->initWorkingState();
273 double dt = 1.0;
274 solutionHistory->getWorkingState()->setTimeStep(dt);
275 solutionHistory->getWorkingState()->setTime(dt);
276 stepper->takeStep(solutionHistory); // Primary testing occurs in
277 // modifierX during takeStep().
278 // Test stepper properties.
279 TEUCHOS_ASSERT(stepper->getOrder() == 3);
280}
281
282// ************************************************************
283// ************************************************************
284TEUCHOS_UNIT_TEST(ERK, Modifier_FSAL)
285{
286 auto stepper = rcp(new Tempus::StepperERK_BogackiShampine32<double>());
287 Teuchos::RCP<const Thyra::ModelEvaluator<double> > model =
289 auto modifier = rcp(new StepperRKModifierBogackiShampineTest(out, success));
290
291 stepper->setModel(model);
292 stepper->setAppAction(modifier);
293 stepper->setICConsistency("Consistent");
294 stepper->setUseFSAL(true);
295 stepper->initialize();
296
297 // Create a SolutionHistory.
298 auto solutionHistory = Tempus::createSolutionHistoryME(model);
299
300 // Take one time step.
301 stepper->setInitialConditions(solutionHistory);
302 solutionHistory->initWorkingState();
303 double dt = 1.0;
304 solutionHistory->getWorkingState()->setTimeStep(dt);
305 solutionHistory->getWorkingState()->setTime(dt);
306 stepper->takeStep(solutionHistory); // Primary testing occurs in
307 // modifierX during takeStep().
308 // Test stepper properties.
309 TEUCHOS_ASSERT(stepper->getOrder() == 3);
310}
311
312// ************************************************************
313// ************************************************************
314TEUCHOS_UNIT_TEST(ERK, Modifier_FSAL_Failure)
315{
316 auto stepper = rcp(new Tempus::StepperERK_BogackiShampine32<double>());
317 Teuchos::RCP<const Thyra::ModelEvaluator<double> > model =
319 auto modifier = rcp(new StepperRKModifierBogackiShampineTest(out, success));
320
321 stepper->setModel(model);
322 stepper->setAppAction(modifier);
323 stepper->setICConsistency("Consistent");
324 stepper->setUseFSAL(true);
325 stepper->initialize();
326
327 // Create a SolutionHistory.
328 auto solutionHistory = Tempus::createSolutionHistoryME(model);
329
330 // Take one time step.
331 stepper->setInitialConditions(solutionHistory);
332 solutionHistory->initWorkingState();
333 double dt = 1.0;
334 solutionHistory->getWorkingState()->setTimeStep(dt);
335 solutionHistory->getWorkingState()->setTime(dt);
336 solutionHistory->getWorkingState()->setNConsecutiveFailures(1);
337 stepper->takeStep(solutionHistory); // Primary testing occurs in
338 // modifierX during takeStep().
339 // Test stepper properties.
340 TEUCHOS_ASSERT(stepper->getOrder() == 3);
341}
342
343// ************************************************************
344// ************************************************************
345TEUCHOS_UNIT_TEST(ERK, Modifier_Embedded)
346{
347 auto stepper = rcp(new Tempus::StepperERK_BogackiShampine32<double>());
348 Teuchos::RCP<const Thyra::ModelEvaluator<double> > model =
350 auto modifier = rcp(new StepperRKModifierBogackiShampineTest(out, success));
351
352 stepper->setModel(model);
353 stepper->setAppAction(modifier);
354 stepper->setICConsistency("Consistent");
355 stepper->setUseFSAL(false);
356 stepper->setUseEmbedded(true);
357 stepper->initialize();
358
359 // Create a SolutionHistory.
360 auto solutionHistory = Tempus::createSolutionHistoryME(model);
361
362 // Take one time step.
363 stepper->setInitialConditions(solutionHistory);
364 solutionHistory->initWorkingState();
365 double dt = 1.0;
366 solutionHistory->getWorkingState()->setTimeStep(dt);
367 solutionHistory->getWorkingState()->setTime(dt);
368 solutionHistory->getWorkingState()->setTolRel(1.0);
369 solutionHistory->getWorkingState()->setTolAbs(0.0);
370 stepper->takeStep(solutionHistory); // Primary testing occurs in
371 // modifierX during takeStep().
372 // Test stepper properties.
373 TEUCHOS_ASSERT(stepper->getOrder() == 3);
374}
375
383class StepperRKModifierXBogackiShampineTest
384 : virtual public Tempus::StepperRKModifierXBase<double> {
385 public:
387 StepperRKModifierXBogackiShampineTest(Teuchos::FancyOStream &Out,
388 bool &Success)
389 : out(Out), success(Success)
390 {
391 }
392
394 virtual ~StepperRKModifierXBogackiShampineTest() {}
395
397 virtual void modify(
398 Teuchos::RCP<Thyra::VectorBase<double> > x, const double time,
399 const double dt, const int stageNumber,
401 modType)
402 {
403 const double relTol = 1.0e-14;
404 if (modType == StepperRKModifierXBase<double>::X_BEGIN_STEP) {
405 const double x_0 = get_ele(*(x), 0); // Should be x_0
406 TEST_FLOATING_EQUALITY(x_0, 1.0, relTol);
407 TEST_FLOATING_EQUALITY(time, 0.0, relTol);
408 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
409 TEST_COMPARE(stageNumber, ==, -1);
410 }
411 else if (modType == StepperRKModifierXBase<double>::X_BEGIN_STAGE ||
412 modType == StepperRKModifierXBase<double>::X_BEFORE_SOLVE ||
413 modType == StepperRKModifierXBase<double>::X_AFTER_SOLVE ||
414 modType ==
415 StepperRKModifierXBase<double>::X_BEFORE_EXPLICIT_EVAL ||
416 modType == StepperRKModifierXBase<double>::X_END_STAGE) {
417 const double X_i = get_ele(*(x), 0);
418 if (stageNumber == 0) {
419 TEST_FLOATING_EQUALITY(X_i, 1.0, relTol); // Should be X_1
420 TEST_FLOATING_EQUALITY(time, 0.0, relTol);
421 }
422 else if (stageNumber == 1) {
423 TEST_FLOATING_EQUALITY(X_i, 0.5, relTol); // Should be X_2
424 TEST_FLOATING_EQUALITY(time, 0.5, relTol);
425 }
426 else if (stageNumber == 2) {
427 TEST_FLOATING_EQUALITY(X_i, 5.0 / 8.0, relTol); // Should be X_3
428 TEST_FLOATING_EQUALITY(time, 0.75, relTol);
429 }
430 else if (stageNumber == 3) {
431 TEST_FLOATING_EQUALITY(X_i, 1.0 / 3.0, relTol); // Should be X_4
432 TEST_FLOATING_EQUALITY(time, 1.0, relTol);
433 }
434 else {
435 TEUCHOS_TEST_FOR_EXCEPT(!(-1 < stageNumber && stageNumber < 4));
436 }
437 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
438 }
439 else if (modType == StepperRKModifierXBase<double>::X_END_STEP) {
440 const double x_1 = get_ele(*(x), 0);
441 TEST_FLOATING_EQUALITY(x_1, 1.0 / 3.0, relTol); // Should be x_1
442 TEST_FLOATING_EQUALITY(time, 1.0, relTol);
443 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
444 TEST_COMPARE(stageNumber, ==, -1);
445 }
446 else {
447 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
448 "Error - unknown action location.\n");
449 }
450 }
451
452 private:
453 Teuchos::FancyOStream &out;
454 bool &success;
455};
456
457// ************************************************************
458// ************************************************************
459TEUCHOS_UNIT_TEST(ERK, ModifierX)
460{
461 auto stepper = rcp(new Tempus::StepperERK_BogackiShampine32<double>());
462 Teuchos::RCP<const Thyra::ModelEvaluator<double> > model =
464 auto modifierX = rcp(new StepperRKModifierXBogackiShampineTest(out, success));
465
466 stepper->setModel(model);
467 stepper->setAppAction(modifierX);
468 stepper->setICConsistency("Consistent");
469 stepper->setUseFSAL(false);
470 stepper->initialize();
471
472 // Create a SolutionHistory.
473 auto solutionHistory = Tempus::createSolutionHistoryME(model);
474
475 // Take one time step.
476 stepper->setInitialConditions(solutionHistory);
477 solutionHistory->initWorkingState();
478 double dt = 1.0;
479 solutionHistory->getWorkingState()->setTimeStep(dt);
480 solutionHistory->getWorkingState()->setTime(dt);
481 stepper->takeStep(solutionHistory); // Primary testing occurs in
482 // modifierX during takeStep().
483 // Test stepper properties.
484 TEUCHOS_ASSERT(stepper->getOrder() == 3);
485}
486
487// ************************************************************
488// ************************************************************
489TEUCHOS_UNIT_TEST(ERK, ModifierX_FSAL)
490{
491 auto stepper = rcp(new Tempus::StepperERK_BogackiShampine32<double>());
492 Teuchos::RCP<const Thyra::ModelEvaluator<double> > model =
494 auto modifierX = rcp(new StepperRKModifierXBogackiShampineTest(out, success));
495
496 stepper->setModel(model);
497 stepper->setAppAction(modifierX);
498 stepper->setICConsistency("Consistent");
499 stepper->setUseFSAL(true);
500 stepper->initialize();
501
502 // Create a SolutionHistory.
503 auto solutionHistory = Tempus::createSolutionHistoryME(model);
504
505 // Take one time step.
506 stepper->setInitialConditions(solutionHistory);
507 solutionHistory->initWorkingState();
508 double dt = 1.0;
509 solutionHistory->getWorkingState()->setTimeStep(dt);
510 solutionHistory->getWorkingState()->setTime(dt);
511 stepper->takeStep(solutionHistory); // Primary testing occurs in
512 // modifierX during takeStep().
513 // Test stepper properties.
514 TEUCHOS_ASSERT(stepper->getOrder() == 3);
515}
516
517// ************************************************************
518// ************************************************************
519TEUCHOS_UNIT_TEST(ERK, ModifierX_FSAL_Failure)
520{
521 auto stepper = rcp(new Tempus::StepperERK_BogackiShampine32<double>());
522 Teuchos::RCP<const Thyra::ModelEvaluator<double> > model =
524 auto modifierX = rcp(new StepperRKModifierXBogackiShampineTest(out, success));
525
526 stepper->setModel(model);
527 stepper->setAppAction(modifierX);
528 stepper->setICConsistency("Consistent");
529 stepper->setUseFSAL(true);
530 stepper->initialize();
531
532 // Create a SolutionHistory.
533 auto solutionHistory = Tempus::createSolutionHistoryME(model);
534
535 // Take one time step.
536 stepper->setInitialConditions(solutionHistory);
537 solutionHistory->initWorkingState();
538 double dt = 1.0;
539 solutionHistory->getWorkingState()->setTimeStep(dt);
540 solutionHistory->getWorkingState()->setTime(dt);
541 solutionHistory->getWorkingState()->setNConsecutiveFailures(1);
542 stepper->takeStep(solutionHistory); // Primary testing occurs in
543 // modifierX during takeStep().
544 // Test stepper properties.
545 TEUCHOS_ASSERT(stepper->getOrder() == 3);
546}
547
548} // namespace Tempus_Unit_Test
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Explicit RK Bogacki-Shampine Butcher Tableau.
ACTION_LOCATION
Indicates the location of application action (see algorithm).
Base class for Runge-Kutta methods, ExplicitRK, DIRK and IMEX.
MODIFIER_TYPE
Indicates the location of application action (see algorithm).
virtual void modify(Teuchos::RCP< Thyra::VectorBase< double > >, const double, const double, const int, const MODIFIER_TYPE modType)=0
Modify solution based on the MODIFIER_TYPE.
The classic Dahlquist Test Problem.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.