Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_UnitTest_IMEX_RK.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 
14 #include "../TestModels/DahlquistTestModel.hpp"
15 #include "../TestModels/VanDerPol_IMEX_ExplicitModel.hpp"
16 #include "../TestModels/VanDerPol_IMEX_ImplicitModel.hpp"
17 
18 namespace Tempus_Unit_Test {
19 
21 using Teuchos::RCP;
22 using Teuchos::rcp;
23 using Teuchos::rcp_const_cast;
24 using Teuchos::rcp_dynamic_cast;
25 using Teuchos::sublist;
26 
29 
30 // ************************************************************
31 // ************************************************************
32 TEUCHOS_UNIT_TEST(IMEX_RK, Default_Construction)
33 {
34  // Setup the IMEX Pair ModelEvaluator
35  auto explicitModel =
37  auto implicitModel =
40  explicitModel, implicitModel));
41 
42  // Default construction.
43  auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
44  stepper->setModel(model);
45  stepper->initialize();
46  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
47 
48  // Default values for construction.
49  auto modifier = rcp(new Tempus::StepperRKModifierDefault<double>());
50  auto modifierX = rcp(new Tempus::StepperRKModifierXDefault<double>());
51  auto observer = rcp(new Tempus::StepperRKObserverDefault<double>());
52  auto solver = rcp(new Thyra::NOXNonlinearSolver());
53  solver->setParameterList(Tempus::defaultSolverParameters());
54 
55  bool useFSAL = stepper->getUseFSAL();
56  std::string ICConsistency = stepper->getICConsistency();
57  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
58  bool zeroInitialGuess = stepper->getZeroInitialGuess();
59  std::string stepperType = "IMEX RK SSP2";
61  auto explicitTableau = stepperERK->getTableau();
62  auto stepperSDIRK =
64  auto implicitTableau = stepperSDIRK->getTableau();
65  int order = 2;
66 
67  // Test the set functions.
68  stepper->setAppAction(modifier);
69  stepper->initialize();
70  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
71  stepper->setAppAction(modifierX);
72  stepper->initialize();
73  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
74  stepper->setAppAction(observer);
75  stepper->initialize();
76  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
77  stepper->setSolver(solver);
78  stepper->initialize();
79  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
80  stepper->setUseFSAL(useFSAL);
81  stepper->initialize();
82  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
83  stepper->setICConsistency(ICConsistency);
84  stepper->initialize();
85  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
86  stepper->setICConsistencyCheck(ICConsistencyCheck);
87  stepper->initialize();
88  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
89  stepper->setZeroInitialGuess(zeroInitialGuess);
90  stepper->initialize();
91  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
92 
93  stepper->setStepperName(stepperType);
94  stepper->initialize();
95  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
96  stepper->setExplicitTableau(explicitTableau);
97  stepper->initialize();
98  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
99  stepper->setImplicitTableau(implicitTableau);
100  stepper->initialize();
101  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
102  stepper->setOrder(order);
103  stepper->initialize();
104  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
105 
106  TEUCHOS_TEST_FOR_EXCEPT(explicitTableau != stepper->getTableau());
107  TEUCHOS_TEST_FOR_EXCEPT(explicitTableau != stepper->getExplicitTableau());
108  TEUCHOS_TEST_FOR_EXCEPT(implicitTableau != stepper->getImplicitTableau());
109 
110  // Full argument list construction.
111  stepper = rcp(new Tempus::StepperIMEX_RK<double>(
112  model, solver, useFSAL, ICConsistency, ICConsistencyCheck,
113  zeroInitialGuess, modifier, stepperType, explicitTableau, implicitTableau,
114  order));
115  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
116 
117  // Test stepper properties.
118  TEUCHOS_ASSERT(stepper->getOrder() == 2);
119 }
120 
121 // ************************************************************
122 // ************************************************************
123 TEUCHOS_UNIT_TEST(IMEX_RK, StepperFactory_Construction)
124 {
125  // Setup the IMEX Pair ModelEvaluator
126  auto explicitModel =
128  auto implicitModel =
131  explicitModel, implicitModel));
132 
133  testFactoryConstruction("IMEX RK SSP2", model);
134 }
135 
136 // ************************************************************
137 // ************************************************************
138 TEUCHOS_UNIT_TEST(IMEX_RK, StepperFactory_Construction_General_wo_Parameterlist)
139 {
140  // Setup the IMEX Pair ModelEvaluator
141  auto explicitModel =
143  auto implicitModel =
146  explicitModel, implicitModel));
147 
149 
150  auto stepper = sf->createStepper("General IMEX RK", model);
151  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
152 }
153 
154 // ************************************************************
155 // ************************************************************
157  StepperFactory_Construction_General_wo_Parameterlist_Model)
158 {
159  // Setup the IMEX Pair ModelEvaluator
160  auto explicitModel =
162  auto implicitModel =
165  explicitModel, implicitModel));
166 
168 
169  auto stepper = sf->createStepper("General IMEX RK");
170  stepper->setModel(model);
171  stepper->initialize();
172  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
173 }
174 
175 // ************************************************************
176 // ************************************************************
177 TEUCHOS_UNIT_TEST(IMEX_RK, AppAction)
178 {
179  auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
180  // Setup the IMEX Pair ModelEvaluator
181  auto explicitModel =
183  auto implicitModel =
186  explicitModel, implicitModel));
187 
188  testRKAppAction(stepper, model, out, success);
189 }
190 
191 class StepperRKModifierIMEX_TrapezoidaTest
192  : virtual public Tempus::StepperRKModifierBase<double> {
193  public:
195  StepperRKModifierIMEX_TrapezoidaTest(Teuchos::FancyOStream &Out,
196  bool &Success)
197  : out(Out), success(Success)
198  {
199  }
200 
201  // FSAL
203  virtual ~StepperRKModifierIMEX_TrapezoidaTest() {}
204 
206  virtual void modify(
210  {
211  const double relTol = 1.0e-14;
212  auto stepper_imex =
213  Teuchos::rcp_dynamic_cast<const Tempus::StepperIMEX_RK<double>>(stepper,
214  true);
215  auto stageNumber = stepper->getStageNumber();
216  Teuchos::SerialDenseVector<int, double> c = stepper_imex->getTableau()->c();
218  stepper_imex->getImplicitTableau()->c();
219 
220  auto currentState = sh->getCurrentState();
221  auto workingState = sh->getWorkingState();
222  const double dt = workingState->getTimeStep();
223  double time = currentState->getTime();
224  double imp_time = time;
225  if (stageNumber >= 0) {
226  time += c(stageNumber) * dt;
227  imp_time += chat(stageNumber) * dt;
228  }
229 
230  auto x = workingState->getX();
231  auto xDot = workingState->getXDot();
232  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
233 
234  switch (actLoc) {
236  {
237  auto imex_me = Teuchos::rcp_dynamic_cast<
239  stepper->getModel(), true);
240  auto explicitModel = Teuchos::rcp_dynamic_cast<
242  imex_me->getExplicitModel(), true);
243  auto implicitModel = Teuchos::rcp_dynamic_cast<
245  imex_me->getImplicitModel(), true);
246 
247  TEST_FLOATING_EQUALITY(explicitModel->getLambda(), 1.0, relTol);
248  TEST_FLOATING_EQUALITY(implicitModel->getLambda(), 2.0, relTol);
249  }
250  TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
251 
252  const double x_0 = get_ele(*(x), 0);
253  TEST_FLOATING_EQUALITY(x_0, 1.0, relTol);
254  TEST_ASSERT(std::abs(time) < relTol);
255  TEST_ASSERT(std::abs(imp_time) < relTol);
256  TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
257  TEST_COMPARE(stageNumber, ==, -1);
258  break;
259  }
262  const double X_i = get_ele(*(x), 0);
263  const double f_i = get_ele(*(xDot), 0);
264 
265  if (stageNumber == 0) {
266  TEST_FLOATING_EQUALITY(X_i, 1.0, relTol); // 1
267  TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
268  TEST_FLOATING_EQUALITY(imp_time, 0.78867513459481275, relTol); // 1
269  TEST_ASSERT(std::abs(time) < relTol);
270  }
271  else if (stageNumber == 1) {
272  TEST_FLOATING_EQUALITY(X_i, -std::sqrt(3), relTol); // -sqrt(3)
273  TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
274  TEST_FLOATING_EQUALITY(time, 1.0, relTol);
275  TEST_FLOATING_EQUALITY(imp_time, 0.21132486540518725, relTol); // 1
276  }
277  else {
278  TEUCHOS_TEST_FOR_EXCEPT(!(-1 < stageNumber && stageNumber < 2));
279  }
280 
281  break;
282  }
286  const double X_i = get_ele(*(x), 0);
287  const double f_i = get_ele(*(xDot), 0);
288 
289  if (stageNumber == 0) {
290  // X_i = 1, f_1 = 0
291  TEST_FLOATING_EQUALITY(X_i, -std::sqrt(3), relTol); // -sqrt(3)
292  TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
293  TEST_FLOATING_EQUALITY(imp_time, 0.78867513459481275, relTol); // 1
294  TEST_ASSERT(std::abs(time) < relTol);
295  }
296  else if (stageNumber == 1) {
297  // X_i = , f_i =
298  TEST_FLOATING_EQUALITY(X_i, 3.0 - 3.0 * std::sqrt(3.0),
299  relTol); // -3sqrt(3) - 3
300  TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
301  TEST_FLOATING_EQUALITY(time, 1.0, relTol);
302  }
303  else {
304  TEUCHOS_TEST_FOR_EXCEPT(!(-1 < stageNumber && stageNumber < 2));
305  }
306 
307  break;
308  }
310  const double x_1 = get_ele(*(x), 0);
311  time = workingState->getTime();
312  TEST_FLOATING_EQUALITY(x_1, -(6.0 * std::sqrt(3) - 11.0 / 2.0),
313  relTol); // -( 6sqrt(3) - 11/2)
314  TEST_FLOATING_EQUALITY(time, 1.0, relTol);
315  TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
316  TEST_COMPARE(stageNumber, ==, -1);
317  }
318  }
319  }
320 
321  private:
323  bool &success;
324 };
325 
326 // ************************************************************
327 // ************************************************************
328 TEUCHOS_UNIT_TEST(IMEX_RK, IMEX_RK_Modifier)
329 {
334 
336  explicitModel, implicitModel));
337 
338  auto modifier = rcp(new StepperRKModifierIMEX_TrapezoidaTest(out, success));
339 
340  // Default construction.
341  auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
342  stepper->setModel(model);
343 
344  // Default values for construction.
345  auto solver = rcp(new Thyra::NOXNonlinearSolver());
346  solver->setParameterList(Tempus::defaultSolverParameters());
347 
348  bool useFSAL = stepper->getUseFSAL();
349  std::string ICConsistency = stepper->getICConsistency();
350  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
351  bool zeroInitialGuess = stepper->getZeroInitialGuess();
352  std::string stepperType = "IMEX RK SSP2";
353  auto stepperERK = Teuchos::rcp(new Tempus::StepperERK_Trapezoidal<double>());
354  auto explicitTableau = stepperERK->getTableau();
355  auto stepperSDIRK =
357  auto implicitTableau = stepperSDIRK->getTableau();
358  int order = 2;
359 
360  stepper->setStepperName(stepperType);
361  stepper->setExplicitTableau(explicitTableau);
362  stepper->setImplicitTableau(implicitTableau);
363  stepper->setOrder(order);
364  stepper->setSolver(solver);
365  stepper->setUseFSAL(useFSAL);
366  stepper->setICConsistency(ICConsistency);
367  stepper->setICConsistencyCheck(ICConsistencyCheck);
368  stepper->setZeroInitialGuess(zeroInitialGuess);
369 
370  stepper->setModel(model);
371  stepper->setAppAction(modifier);
372  stepper->setUseFSAL(false);
373  stepper->initialize();
374 
375  // Create a SolutionHistory.
376  auto solutionHistory = Tempus::createSolutionHistoryME(explicitModel);
377 
379  stepper->setInitialConditions(solutionHistory);
380  solutionHistory->initWorkingState();
381  double dt = 1.0;
382  solutionHistory->getWorkingState()->setTimeStep(dt);
383  solutionHistory->getWorkingState()->setTime(dt);
384  stepper->takeStep(solutionHistory);
385 
386  // Test stepper properties.
387  TEUCHOS_ASSERT(stepper->getOrder() == 2);
388 }
389 
390 } // namespace Tempus_Unit_Test
Explicit Runge-Kutta time stepper.
void testFactoryConstruction(std::string stepperType, const Teuchos::RCP< const Thyra::ModelEvaluator< double > > &model)
Unit test utility for Stepper construction through StepperFactory.
The classic Dahlquist Test Problem.
ModelEvaluator pair for implicit and explicit (IMEX) evaulations.
Implicit-Explicit Runge-Kutta (IMEX-RK) time stepper.
#define TEST_COMPARE(v1, comp, v2)
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
#define TEST_ASSERT(v1)
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
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.
void testRKAppAction(const Teuchos::RCP< Tempus::StepperRKBase< double >> &stepper, const Teuchos::RCP< const Thyra::ModelEvaluator< double >> &model, Teuchos::FancyOStream &out, bool &success)
Unit test utility for Stepper RK AppAction.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
virtual void modify(Teuchos::RCP< SolutionHistory< double > >, Teuchos::RCP< StepperRKBase< double > >, const typename StepperRKAppAction< double >::ACTION_LOCATION actLoc)=0
Modify RK Stepper.
virtual int getStageNumber() const
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
ACTION_LOCATION
Indicates the location of application action (see algorithm).
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)