Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
13 #include "Tempus_StepperRKBase.hpp"
16 
17 #include "../TestModels/DahlquistTestModel.hpp"
18 
19 namespace Tempus_Unit_Test {
20 
21 using Teuchos::RCP;
22 using Teuchos::rcp;
23 using Teuchos::rcp_const_cast;
24 using Teuchos::rcp_dynamic_cast;
25 
118 class 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(
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 
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 ||
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);
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);
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);
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);
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:
249  bool &success;
250 };
251 
252 // ************************************************************
253 // ************************************************************
254 TEUCHOS_UNIT_TEST(ERK, Modifier)
255 {
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 // ************************************************************
284 TEUCHOS_UNIT_TEST(ERK, Modifier_FSAL)
285 {
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 // ************************************************************
314 TEUCHOS_UNIT_TEST(ERK, Modifier_FSAL_Failure)
315 {
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 // ************************************************************
345 TEUCHOS_UNIT_TEST(ERK, Modifier_Embedded)
346 {
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 
383 class 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;
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 ||
414  modType ==
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:
454  bool &success;
455 };
456 
457 // ************************************************************
458 // ************************************************************
459 TEUCHOS_UNIT_TEST(ERK, ModifierX)
460 {
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 // ************************************************************
489 TEUCHOS_UNIT_TEST(ERK, ModifierX_FSAL)
490 {
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 // ************************************************************
519 TEUCHOS_UNIT_TEST(ERK, ModifierX_FSAL_Failure)
520 {
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
The classic Dahlquist Test Problem.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define TEST_COMPARE(v1, comp, v2)
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
#define TEST_ASSERT(v1)
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.
Base class for Runge-Kutta methods, ExplicitRK, DIRK and IMEX.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Explicit RK Bogacki-Shampine Butcher Tableau.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
MODIFIER_TYPE
Indicates the location of application action (see algorithm).
ACTION_LOCATION
Indicates the location of application action (see algorithm).
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
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.