Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_UnitTest_ForwardEuler.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 
12 
13 #include "Tempus_StepperForwardEuler.hpp"
20 
21 namespace Tempus_Unit_Test {
22 
24 using Teuchos::RCP;
25 using Teuchos::rcp;
26 using Teuchos::rcp_const_cast;
27 using Teuchos::rcp_dynamic_cast;
28 using Teuchos::sublist;
29 
31 
32 // ************************************************************
33 // ************************************************************
34 TEUCHOS_UNIT_TEST(ForwardEuler, Default_Construction)
35 {
36  auto model = rcp(new Tempus_Test::SinCosModel<double>());
37 
38  // Default construction.
40  auto modifierX =
43  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
44  stepper->setModel(model);
45  stepper->initialize();
46  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
47  // Default values for construction.
48  bool useFSAL = stepper->getUseFSAL();
49  std::string ICConsistency = stepper->getICConsistency();
50  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
51 
52  // Test the set functions.
53  stepper->setAppAction(modifier);
54  stepper->initialize();
55  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
56  stepper->setAppAction(modifierX);
57  stepper->initialize();
58  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
59  stepper->setAppAction(observer);
60  stepper->initialize();
61  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
62  stepper->setUseFSAL(useFSAL);
63  stepper->initialize();
64  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
65  stepper->setICConsistency(ICConsistency);
66  stepper->initialize();
67  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
68  stepper->setICConsistencyCheck(ICConsistencyCheck);
69  stepper->initialize();
70  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
71 
73  model, useFSAL, ICConsistency, ICConsistencyCheck, modifier));
74  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
75 
76  // Test stepper properties.
77  TEUCHOS_ASSERT(stepper->getOrder() == 1);
78 }
79 
80 // ************************************************************
81 // ************************************************************
82 TEUCHOS_UNIT_TEST(ForwardEuler, StepperFactory_Construction)
83 {
84  auto model = rcp(new Tempus_Test::SinCosModel<double>());
85  testFactoryConstruction("Forward Euler", model);
86 }
87 
88 // ************************************************************
89 // ************************************************************
90 class StepperForwardEulerModifierTest
91  : virtual public Tempus::StepperForwardEulerModifierBase<double> {
92  public:
94  StepperForwardEulerModifierTest()
95  : testBEGIN_STEP(false),
96  testBEFORE_EXPLICIT_EVAL(false),
97  testEND_STEP(false),
98  testCurrentValue(-0.99),
99  testWorkingValue(-0.99),
100  testDt(-1.5),
101  testName("")
102  {
103  }
104 
106  virtual ~StepperForwardEulerModifierTest() {}
107 
109  virtual void modify(
113  double>::ACTION_LOCATION actLoc)
114  {
115  switch (actLoc) {
117  testBEGIN_STEP = true;
118  auto x = sh->getCurrentState()->getX();
119  testCurrentValue = get_ele(*(x), 0);
120  break;
121  }
123  testBEFORE_EXPLICIT_EVAL = true;
124  testDt = sh->getWorkingState()->getTimeStep() / 10.0;
125  sh->getWorkingState()->setTimeStep(testDt);
126  testName = "Forward Euler - Modifier";
127  stepper->setStepperName(testName);
128  break;
129  }
131  testEND_STEP = true;
132  auto x = sh->getWorkingState()->getX();
133  testWorkingValue = get_ele(*(x), 0);
134  break;
135  }
136  default:
137  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
138  "Error - unknown action location.\n");
139  }
140  }
141  bool testBEGIN_STEP;
142  bool testBEFORE_EXPLICIT_EVAL;
143  bool testEND_STEP;
144  double testCurrentValue;
145  double testWorkingValue;
146  double testDt;
147  std::string testName;
148 };
149 
150 TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Modifier)
151 {
152  auto model = rcp(new Tempus_Test::SinCosModel<double>());
153 
154  // Setup Stepper for field solve ----------------------------
155  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
156  stepper->setModel(model);
157  auto modifier = rcp(new StepperForwardEulerModifierTest());
158  stepper->setAppAction(modifier);
159  stepper->initialize();
160 
161  // Setup initial condition SolutionState --------------------
162  auto inArgsIC = model->getNominalValues();
163  auto icSolution =
164  rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
165  auto icState = Tempus::createSolutionStateX(icSolution);
166  icState->setTime(0.0);
167  icState->setIndex(0);
168  icState->setTimeStep(0.0);
169  icState->setOrder(stepper->getOrder());
170  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
171 
172  // Setup SolutionHistory ------------------------------------
173  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
174  solutionHistory->setName("Forward States");
175  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
176  solutionHistory->setStorageLimit(2);
177  solutionHistory->addState(icState);
178 
179  // Take one time step.
180  stepper->setInitialConditions(solutionHistory);
181  solutionHistory->initWorkingState();
182  double dt = 0.1;
183  solutionHistory->getWorkingState()->setTimeStep(dt);
184  stepper->takeStep(solutionHistory);
185 
186  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
187  TEST_COMPARE(modifier->testBEFORE_EXPLICIT_EVAL, ==, true);
188  TEST_COMPARE(modifier->testEND_STEP, ==, true);
189 
190  auto x = solutionHistory->getCurrentState()->getX();
191  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
192  x = solutionHistory->getWorkingState()->getX();
193  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
194  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
195  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-14);
196 
197  TEST_COMPARE(modifier->testName, ==, "Forward Euler - Modifier");
198 }
199 
200 // ************************************************************
201 // ************************************************************
202 class StepperForwardEulerObserverTest
203  : virtual public Tempus::StepperForwardEulerObserverBase<double> {
204  public:
206  StepperForwardEulerObserverTest()
207  : testBEGIN_STEP(false),
208  testBEFORE_EXPLICIT_EVAL(false),
209  testEND_STEP(false),
210  testCurrentValue(-0.99),
211  testWorkingValue(-0.99),
212  testDt(-1.5),
213  testName("")
214  {
215  }
216 
218  virtual ~StepperForwardEulerObserverTest() {}
219 
221  virtual void observe(
225  double>::ACTION_LOCATION actLoc)
226  {
227  switch (actLoc) {
229  testBEGIN_STEP = true;
230  auto x = sh->getCurrentState()->getX();
231  testCurrentValue = get_ele(*(x), 0);
232  break;
233  }
235  testBEFORE_EXPLICIT_EVAL = true;
236  testDt = sh->getWorkingState()->getTimeStep();
237  testName = stepper->getStepperName();
238  break;
239  }
241  testEND_STEP = true;
242  auto x = sh->getWorkingState()->getX();
243  testWorkingValue = get_ele(*(x), 0);
244  break;
245  }
246  default:
247  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
248  "Error - unknown action location.\n");
249  }
250  }
251 
252  bool testBEGIN_STEP;
253  bool testBEFORE_EXPLICIT_EVAL;
254  bool testEND_STEP;
255  double testCurrentValue;
256  double testWorkingValue;
257  double testDt;
258  std::string testName;
259 };
260 
261 TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Observer)
262 {
263  auto model = rcp(new Tempus_Test::SinCosModel<double>());
264 
265  // Setup Stepper for field solve ----------------------------
266  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
267  stepper->setModel(model);
268  auto observer = rcp(new StepperForwardEulerObserverTest());
269  stepper->setAppAction(observer);
270  stepper->initialize();
271 
272  // Setup initial condition SolutionState --------------------
273  auto inArgsIC = model->getNominalValues();
274  auto icSolution =
275  rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
276  auto icState = Tempus::createSolutionStateX(icSolution);
277  icState->setTime(0.0);
278  icState->setIndex(0);
279  icState->setTimeStep(0.0);
280  icState->setOrder(stepper->getOrder());
281  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
282 
283  // Setup SolutionHistory ------------------------------------
284  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
285  solutionHistory->setName("Forward States");
286  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
287  solutionHistory->setStorageLimit(2);
288  solutionHistory->addState(icState);
289 
290  // Take one time step.
291  stepper->setInitialConditions(solutionHistory);
292  solutionHistory->initWorkingState();
293  double dt = 0.1;
294  solutionHistory->getWorkingState()->setTimeStep(dt);
295  stepper->takeStep(solutionHistory);
296 
297  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
298  TEST_COMPARE(observer->testBEFORE_EXPLICIT_EVAL, ==, true);
299  TEST_COMPARE(observer->testEND_STEP, ==, true);
300 
301  auto x = solutionHistory->getCurrentState()->getX();
302  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
303  x = solutionHistory->getWorkingState()->getX();
304  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
305  TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-14);
306 
307  TEST_COMPARE(observer->testName, ==, "Forward Euler");
308 }
309 
310 // ************************************************************
311 // ************************************************************
312 class StepperForwardEulerModifierXTest
313  : virtual public Tempus::StepperForwardEulerModifierXBase<double> {
314  public:
316  StepperForwardEulerModifierXTest()
317  : testX_BEGIN_STEP(false),
318  testX_BEFORE_EXPLICIT_EVAL(false),
319  testXDOT_END_STEP(false),
320  testX(-0.99),
321  testXDot(-0.99),
322  testDt(-1.5),
323  testTime(-1.5)
324  {
325  }
326 
328  virtual ~StepperForwardEulerModifierXTest() {}
329 
332  const double time, const double dt,
334  double>::MODIFIER_TYPE modType)
335  {
336  switch (modType) {
338  testX_BEGIN_STEP = true;
339  testX = get_ele(*(x), 0);
340  break;
341  }
343  testX_BEFORE_EXPLICIT_EVAL = true;
344  testDt = dt;
345  testTime = time;
346  break;
347  }
349  testXDOT_END_STEP = true;
350  testXDot = get_ele(*(x), 0);
351  break;
352  }
353  default:
354  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
355  "Error - unknown action location.\n");
356  }
357  }
358  bool testX_BEGIN_STEP;
359  bool testX_BEFORE_EXPLICIT_EVAL;
360  bool testXDOT_END_STEP;
361  double testX;
362  double testXDot;
363  double testDt;
364  double testTime;
365 };
366 
367 TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_ModifierX)
368 {
369  auto model = rcp(new Tempus_Test::SinCosModel<double>());
370 
371  // Setup Stepper for field solve ----------------------------
372  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
373  stepper->setModel(model);
374  auto modifierX = rcp(new StepperForwardEulerModifierXTest());
375  stepper->setAppAction(modifierX);
376  stepper->initialize();
377 
378  // Setup initial condition SolutionState --------------------
379  auto inArgsIC = model->getNominalValues();
380  auto icSolution =
381  rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
382  auto icState = Tempus::createSolutionStateX(icSolution);
383  icState->setTime(0.0);
384  icState->setIndex(0);
385  icState->setTimeStep(0.0);
386  icState->setOrder(stepper->getOrder());
387  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
388 
389  // Setup SolutionHistory ------------------------------------
390  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
391  solutionHistory->setName("Forward States");
392  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
393  solutionHistory->setStorageLimit(2);
394  solutionHistory->addState(icState);
395 
396  // Take one time step.
397  stepper->setInitialConditions(solutionHistory);
398  solutionHistory->initWorkingState();
399  double dt = 0.1;
400  solutionHistory->getWorkingState()->setTimeStep(dt);
401  stepper->takeStep(solutionHistory);
402 
403  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
404  TEST_COMPARE(modifierX->testX_BEFORE_EXPLICIT_EVAL, ==, true);
405  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
406 
407  auto x = solutionHistory->getCurrentState()->getX();
408  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-14);
409  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
410  auto xDot = solutionHistory->getWorkingState()->getXDot();
411  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
412 
413  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0), 1.0e-14);
414  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
415  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-14);
416 
417  auto time = solutionHistory->getWorkingState()->getTime();
418  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-14);
419 }
420 
421 } // namespace Tempus_Unit_Test
Teuchos::RCP< SolutionState< Scalar > > createSolutionStateX(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdot=Teuchos::null, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &xdotdot=Teuchos::null)
Nonmember constructor from non-const solution vectors, x.
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.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define TEST_COMPARE(v1, comp, v2)
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
Sine-Cosine model problem from Rythmos. This is a canonical Sine-Cosine differential equation with a...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Application Action for StepperForwardEuler.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Keep a fix number of states.
virtual void modify(Teuchos::RCP< Thyra::VectorBase< double > >, const double, const double, const MODIFIER_TYPE modType)=0
Modify solution based on the MODIFIER_TYPE.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)