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: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
11 #include "Teuchos_TimeMonitor.hpp"
12 #include "Teuchos_DefaultComm.hpp"
13 
14 #include "Thyra_VectorStdOps.hpp"
15 
16 #include "Tempus_SolutionHistory.hpp"
17 #include "Tempus_StepperFactory.hpp"
20 
21 
22 #include "../TestModels/DahlquistTestModel.hpp"
23 #include "../TestModels/VanDerPol_IMEX_ExplicitModel.hpp"
24 #include "../TestModels/VanDerPol_IMEX_ImplicitModel.hpp"
25 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
26 
27 #include <fstream>
28 #include <vector>
29 
30 namespace Tempus_Unit_Test {
31 
32 using Teuchos::RCP;
33 using Teuchos::rcp;
34 using Teuchos::rcp_const_cast;
35 using Teuchos::rcp_dynamic_cast;
37 using Teuchos::sublist;
38 using Teuchos::getParametersFromXmlFile;
39 
42 
43 
44 // ************************************************************
45 // ************************************************************
46 TEUCHOS_UNIT_TEST(IMEX_RK, Default_Construction)
47 {
48  // Setup the IMEX Pair ModelEvaluator
49  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
50  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
52  explicitModel, implicitModel));
53 
54  // Default construction.
55  auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
56  stepper->setModel(model);
57  stepper->initialize();
58  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
59 
60  // Default values for construction.
61  auto modifier = rcp(new Tempus::StepperRKModifierDefault<double>());
62  auto modifierX = rcp(new Tempus::StepperRKModifierXDefault<double>());
63  auto observer = rcp(new Tempus::StepperRKObserverDefault<double>());
64  auto solver = rcp(new Thyra::NOXNonlinearSolver());
65  solver->setParameterList(Tempus::defaultSolverParameters());
66 
67  bool useFSAL = stepper->getUseFSAL();
68  std::string ICConsistency = stepper->getICConsistency();
69  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
70  bool zeroInitialGuess = stepper->getZeroInitialGuess();
71  std::string stepperType = "IMEX RK SSP2";
73  auto explicitTableau = stepperERK->getTableau();
75  auto implicitTableau = stepperSDIRK->getTableau();
76  int order = 2;
77 
78 
79  // Test the set functions.
80  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
81  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
82  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
83  stepper->setSolver(solver); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
84  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
85  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
86  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
87  stepper->setZeroInitialGuess(zeroInitialGuess); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
88 
89  stepper->setStepperName(stepperType); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
90  stepper->setExplicitTableau(explicitTableau); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
91  stepper->setImplicitTableau(implicitTableau); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
92  stepper->setOrder(order); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
93 
94  TEUCHOS_TEST_FOR_EXCEPT(explicitTableau != stepper->getTableau());
95  TEUCHOS_TEST_FOR_EXCEPT(explicitTableau != stepper->getExplicitTableau());
96  TEUCHOS_TEST_FOR_EXCEPT(implicitTableau != stepper->getImplicitTableau());
97 
98  // Full argument list construction.
99  stepper = rcp(new Tempus::StepperIMEX_RK<double>(
100  model, solver, useFSAL, ICConsistency, ICConsistencyCheck,
101  zeroInitialGuess, modifier, stepperType, explicitTableau,
102  implicitTableau, order));
103  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
104 
105  // Test stepper properties.
106  TEUCHOS_ASSERT(stepper->getOrder() == 2);
107 }
108 
109 
110 // ************************************************************
111 // ************************************************************
112 TEUCHOS_UNIT_TEST(IMEX_RK, StepperFactory_Construction)
113 {
114  // Setup the IMEX Pair ModelEvaluator
115  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
116  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
118  explicitModel, implicitModel));
119 
120  testFactoryConstruction("IMEX RK SSP2", model);
121 }
122 
123 
124 // ************************************************************
125 // ************************************************************
126 TEUCHOS_UNIT_TEST(IMEX_RK, StepperFactory_Construction_General_wo_Parameterlist)
127 {
128  // Setup the IMEX Pair ModelEvaluator
129  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
130  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
132  explicitModel, implicitModel));
133 
135 
136  auto stepper = sf->createStepper("General IMEX RK", model);
137  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
138 }
139 
140 
141 // ************************************************************
142 // ************************************************************
143 TEUCHOS_UNIT_TEST(IMEX_RK, StepperFactory_Construction_General_wo_Parameterlist_Model)
144 {
145  // Setup the IMEX Pair ModelEvaluator
146  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
147  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
149  explicitModel, implicitModel));
150 
152 
153  auto stepper = sf->createStepper("General IMEX RK");
154  stepper->setModel(model);
155  stepper->initialize();
156  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
157 }
158 
159 
160 // ************************************************************
161 // ************************************************************
162 TEUCHOS_UNIT_TEST(IMEX_RK, AppAction)
163 {
164  auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
165  // Setup the IMEX Pair ModelEvaluator
166  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
167  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
169  explicitModel, implicitModel));
170 
171  testRKAppAction(stepper, model, out, success);
172 }
173 
174 
175 
176 class StepperRKModifierIMEX_TrapezoidaTest
177  : virtual public Tempus::StepperRKModifierBase<double>
178 {
179  public:
180 
182  StepperRKModifierIMEX_TrapezoidaTest(Teuchos::FancyOStream &Out, bool &Success)
183  : out(Out), success(Success)
184  {}
185 
186  // FSAL
188  virtual ~StepperRKModifierIMEX_TrapezoidaTest(){}
189 
191  virtual void modify(
195  {
196  const double relTol = 1.0e-14;
197  auto stepper_imex = Teuchos::rcp_dynamic_cast<const Tempus::StepperIMEX_RK<double>>(stepper, true);
198  auto stageNumber = stepper->getStageNumber();
199  Teuchos::SerialDenseVector<int,double> c = stepper_imex->getTableau()->c();
200  Teuchos::SerialDenseVector<int,double> chat = stepper_imex->getImplicitTableau()->c();
201 
202  auto currentState = sh->getCurrentState();
203  auto workingState = sh->getWorkingState();
204  const double dt = workingState->getTimeStep();
205  double time = currentState->getTime();
206  double imp_time = time;
207  if (stageNumber >= 0) {
208  time += c(stageNumber)*dt;
209  imp_time += chat(stageNumber)*dt;
210  }
211 
212  auto x = workingState->getX();
213  auto xDot = workingState->getXDot();
214  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
215 
216  switch (actLoc) {
218  {
219  {
220 
221  auto imex_me = Teuchos::rcp_dynamic_cast<const Tempus::WrapperModelEvaluatorPairIMEX_Basic<double>>(stepper->getModel(), true);
222  auto explicitModel = Teuchos::rcp_dynamic_cast<const Tempus_Test::DahlquistTestModel<double> > (imex_me->getExplicitModel(), true);
223  auto implicitModel = Teuchos::rcp_dynamic_cast<const Tempus_Test::DahlquistTestModel<double> > (imex_me->getImplicitModel(), true);
224 
225  TEST_FLOATING_EQUALITY(explicitModel->getLambda(), 1.0, relTol);
226  TEST_FLOATING_EQUALITY(implicitModel->getLambda(), 2.0, relTol);
227  }
228  TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
229 
230  const double x_0 = get_ele(*(x), 0);
231  TEST_FLOATING_EQUALITY(x_0, 1.0, relTol);
232  TEST_ASSERT(std::abs(time) < relTol);
233  TEST_ASSERT(std::abs(imp_time) < relTol);
234  TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
235  TEST_COMPARE(stageNumber, ==, -1);
236  break;
237  }
240  {
241  const double X_i = get_ele(*(x), 0);
242  const double f_i = get_ele(*(xDot), 0);
243 
244  if (stageNumber == 0) {
245  TEST_FLOATING_EQUALITY(X_i , 1.0 , relTol); // 1
246  TEST_FLOATING_EQUALITY(f_i , 1.0 , relTol); // 1
247  TEST_FLOATING_EQUALITY(imp_time , 0.78867513459481275 , relTol); // 1
248  TEST_ASSERT(std::abs(time) < relTol);
249  } else if (stageNumber == 1) {
250  TEST_FLOATING_EQUALITY(X_i , -std::sqrt(3) , relTol); // -sqrt(3)
251  TEST_FLOATING_EQUALITY(f_i , 1.0 , relTol); // 1
252  TEST_FLOATING_EQUALITY(time , 1.0 , relTol);
253  TEST_FLOATING_EQUALITY(imp_time , 0.21132486540518725 , relTol); // 1
254  } else {
255  TEUCHOS_TEST_FOR_EXCEPT( !(-1 < stageNumber && stageNumber < 2));
256  }
257 
258  break;
259  }
263  {
264  const double X_i = get_ele(*(x), 0);
265  const double f_i = get_ele(*(xDot), 0);
266 
267  if (stageNumber == 0) {
268  // X_i = 1, f_1 = 0
269  TEST_FLOATING_EQUALITY(X_i, -std::sqrt(3), relTol); // -sqrt(3)
270  TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
271  TEST_FLOATING_EQUALITY(imp_time , 0.78867513459481275 , relTol); // 1
272  TEST_ASSERT(std::abs(time) < relTol);
273  } else if (stageNumber == 1) {
274  // X_i = , f_i =
275  TEST_FLOATING_EQUALITY(X_i, 3.0 - 3.0*std::sqrt(3.0), relTol); // -3sqrt(3) - 3
276  TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
277  TEST_FLOATING_EQUALITY(time, 1.0, relTol);
278  } else {
279  TEUCHOS_TEST_FOR_EXCEPT( !(-1 < stageNumber && stageNumber < 2));
280  }
281 
282  break;
283  }
285  {
286  const double x_1 = get_ele(*(x), 0);
287  time = workingState->getTime();
288  TEST_FLOATING_EQUALITY(x_1, -(6.0*std::sqrt(3) - 11.0/2.0), relTol); // -( 6sqrt(3) - 11/2)
289  TEST_FLOATING_EQUALITY(time, 1.0, relTol);
290  TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
291  TEST_COMPARE(stageNumber, ==, -1);
292 
293  }
294 
295  }
296 
297 
298  }
299 
300  private:
301 
302  Teuchos::FancyOStream & out;
303  bool & success;
304 };
305 
306 // ************************************************************
307 // ************************************************************
308 TEUCHOS_UNIT_TEST(IMEX_RK, IMEX_RK_Modifier)
309 {
310 
313 
315  explicitModel, implicitModel));
316 
317  auto modifier = rcp(new StepperRKModifierIMEX_TrapezoidaTest(out, success));
318 
319 
320  // Default construction.
321  auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
322  stepper->setModel(model);
323 
324  // Default values for construction.
325  auto solver = rcp(new Thyra::NOXNonlinearSolver());
326  solver->setParameterList(Tempus::defaultSolverParameters());
327 
328  bool useFSAL = stepper->getUseFSAL();
329  std::string ICConsistency = stepper->getICConsistency();
330  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
331  bool zeroInitialGuess = stepper->getZeroInitialGuess();
332  std::string stepperType = "IMEX RK SSP2";
333  auto stepperERK = Teuchos::rcp(new Tempus::StepperERK_Trapezoidal<double>());
334  auto explicitTableau = stepperERK->getTableau();
336  auto implicitTableau = stepperSDIRK->getTableau();
337  int order = 2;
338 
339  stepper->setStepperName(stepperType);
340  stepper->setExplicitTableau(explicitTableau);
341  stepper->setImplicitTableau(implicitTableau);
342  stepper->setOrder(order);
343  stepper->setSolver(solver);
344  stepper->setUseFSAL(useFSAL);
345  stepper->setICConsistency(ICConsistency);
346  stepper->setICConsistencyCheck(ICConsistencyCheck);
347  stepper->setZeroInitialGuess(zeroInitialGuess);
348 
349  stepper->setModel(model);
350  stepper->setAppAction(modifier);
351  stepper->setUseFSAL(false);
352  stepper->initialize();
353 
354  // Create a SolutionHistory.
355  auto solutionHistory = Tempus::createSolutionHistoryME(explicitModel);
356 
358  stepper->setInitialConditions(solutionHistory);
359  solutionHistory->initWorkingState();
360  double dt = 1.0;
361  solutionHistory->getWorkingState()->setTimeStep(dt);
362  solutionHistory->getWorkingState()->setTime(dt);
363  stepper->takeStep(solutionHistory);
364 
365  // Test stepper properties.
366  TEUCHOS_ASSERT(stepper->getOrder() == 2);
367 }
368 
369 
370 
371 } // namespace Tempus_Test
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.
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.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
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)