Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_UnitTest_BackwardEuler.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 
10 
11 #include "Tempus_StepperForwardEuler.hpp"
12 #include "Tempus_StepperBackwardEuler.hpp"
13 
20 
21 
22 namespace Tempus_Unit_Test {
23 
24 using Teuchos::RCP;
25 using Teuchos::rcp;
26 using Teuchos::rcp_const_cast;
27 using Teuchos::rcp_dynamic_cast;
29 using Teuchos::sublist;
30 
31 
32 // ************************************************************
33 // ************************************************************
34 TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
35 {
36  auto model = rcp(new Tempus_Test::SinCosModel<double>());
37 
38  // Default construction.
39  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
40  stepper->setModel(model);
41  stepper->initialize();
42  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
43 
44 
45  // Default values for construction.
49  auto solver = rcp(new Thyra::NOXNonlinearSolver());
50  solver->setParameterList(Tempus::defaultSolverParameters());
51 
52  auto predictorStepper = rcp(new Tempus::StepperForwardEuler<double>());
53  predictorStepper->setModel(model); // Can use the same model since both steppers are implicit ODEs.
54  predictorStepper->initialize();
55 
56  auto defaultStepper = rcp(new Tempus::StepperBackwardEuler<double>());
57  bool useFSAL = defaultStepper->getUseFSAL();
58  std::string ICConsistency = defaultStepper->getICConsistency();
59  bool ICConsistencyCheck = defaultStepper->getICConsistencyCheck();
60  bool zeroInitialGuess = defaultStepper->getZeroInitialGuess();
61 
62  // Test the set functions.
63  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
64  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
65  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
66  stepper->setSolver(solver); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
67  stepper->setPredictor(predictorStepper); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
68  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
69  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
70  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
71  stepper->setZeroInitialGuess(zeroInitialGuess); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
72 
73  // Full argument list construction.
75  model, solver, predictorStepper, useFSAL,
76  ICConsistency, ICConsistencyCheck, zeroInitialGuess, modifier));
77  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
78 
79  // Test stepper properties.
80  TEUCHOS_ASSERT(stepper->getOrder() == 1);
81 }
82 
83 
84 // ************************************************************
85 // ************************************************************
86 TEUCHOS_UNIT_TEST(BackwardEuler, StepperFactory_Construction)
87 {
88  auto model = rcp(new Tempus_Test::SinCosModel<double>());
89  testFactoryConstruction("Backward Euler", model);
90 }
91 
92 
93 // ************************************************************
94 // ************************************************************
95 class StepperBackwardEulerModifierTest
96  : virtual public Tempus::StepperBackwardEulerModifierBase<double>
97 {
98 public:
99 
101  StepperBackwardEulerModifierTest()
102  : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
103  testAFTER_SOLVE(false), testEND_STEP(false),
104  testCurrentValue(-0.99), testWorkingValue(-0.99),
105  testDt(-1.5), testName("")
106  {}
107 
109  virtual ~StepperBackwardEulerModifierTest(){}
110 
112  virtual void modify(
116  {
117  switch(actLoc) {
119  {
120  testBEGIN_STEP = true;
121  auto x = sh->getCurrentState()->getX();
122  testCurrentValue = get_ele(*(x), 0);
123  break;
124  }
126  {
127  testBEFORE_SOLVE = true;
128  testDt = sh->getWorkingState()->getTimeStep()/10.0;
129  sh->getWorkingState()->setTimeStep(testDt);
130  break;
131  }
133  {
134  testAFTER_SOLVE = true;
135  testName = "Backward Euler - Modifier";
136  stepper->setStepperName(testName);
137  break;
138  }
140  {
141  testEND_STEP = true;
142  auto x = sh->getWorkingState()->getX();
143  testWorkingValue = get_ele(*(x), 0);
144  break;
145  }
146  default:
147  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
148  "Error - unknown action location.\n");
149  }
150  }
151 
152  bool testBEGIN_STEP;
153  bool testBEFORE_SOLVE;
154  bool testAFTER_SOLVE;
155  bool testEND_STEP;
156  double testCurrentValue;
157  double testWorkingValue;
158  double testDt;
159  std::string testName;
160 };
161 
162 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Modifier)
163 {
165  model = rcp(new Tempus_Test::SinCosModel<double>());
166 
167  // Setup Stepper for field solve ----------------------------
168  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
169  stepper->setModel(model);
170  auto modifier = rcp(new StepperBackwardEulerModifierTest());
171  stepper->setAppAction(modifier);
172  stepper->initialize();
173 
174  // Create a SolutionHistory.
175  auto solutionHistory = Tempus::createSolutionHistoryME(model);
176 
177  // Take one time step.
178  stepper->setInitialConditions(solutionHistory);
179  solutionHistory->initWorkingState();
180  double dt = 0.1;
181  solutionHistory->getWorkingState()->setTimeStep(dt);
182  stepper->takeStep(solutionHistory);
183 
184  // Testing that each ACTION_LOCATION has been called.
185  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
186  TEST_COMPARE(modifier->testBEFORE_SOLVE, ==, true);
187  TEST_COMPARE(modifier->testAFTER_SOLVE, ==, true);
188  TEST_COMPARE(modifier->testEND_STEP, ==, true);
189 
190  // Testing that values can be set through the Modifier.
191  auto x = solutionHistory->getCurrentState()->getX();
192  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
193  x = solutionHistory->getWorkingState()->getX();
194  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
195  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
196  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-14);
197 
198  TEST_COMPARE(modifier->testName, ==, "Backward Euler - Modifier");
199 
200 }
201 
202 
203 // ************************************************************
204 // ************************************************************
205 class StepperBackwardEulerObserverTest
206  : virtual public Tempus::StepperBackwardEulerObserverBase<double>
207 {
208 public:
209 
211  StepperBackwardEulerObserverTest()
212  : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
213  testAFTER_SOLVE(false), testEND_STEP(false),
214  testCurrentValue(-0.99), testWorkingValue(-0.99),
215  testDt(-1.5), testName("")
216  {}
217 
219  virtual ~StepperBackwardEulerObserverTest(){}
220 
222  virtual void observe(
226  {
227  switch(actLoc) {
229  {
230  testBEGIN_STEP = true;
231  auto x = sh->getCurrentState()->getX();
232  testCurrentValue = get_ele(*(x), 0);
233  break;
234  }
236  {
237  testBEFORE_SOLVE = true;
238  testDt = sh->getWorkingState()->getTimeStep();
239  break;
240  }
242  {
243  testAFTER_SOLVE = true;
244  testName = stepper->getStepperType();
245  break;
246  }
248  {
249  testEND_STEP = true;
250  auto x = sh->getWorkingState()->getX();
251  testWorkingValue = get_ele(*(x), 0);
252  break;
253  }
254  default:
255  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
256  "Error - unknown action location.\n");
257  }
258  }
259 
260  bool testBEGIN_STEP;
261  bool testBEFORE_SOLVE;
262  bool testAFTER_SOLVE;
263  bool testEND_STEP;
264  double testCurrentValue;
265  double testWorkingValue;
266  double testDt;
267  std::string testName;
268 };
269 
270 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Observer)
271 {
273  model = rcp(new Tempus_Test::SinCosModel<double>());
274 
275  // Setup Stepper for field solve ----------------------------
276  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
277  stepper->setModel(model);
278  auto observer = rcp(new StepperBackwardEulerObserverTest());
279  stepper->setAppAction(observer);
280  stepper->initialize();
281 
282  // Setup a SolutionHistory.
283  auto solutionHistory = Tempus::createSolutionHistoryME(model);
284 
285  // Take one time step.
286  stepper->setInitialConditions(solutionHistory);
287  solutionHistory->initWorkingState();
288  double dt = 0.1;
289  solutionHistory->getWorkingState()->setTimeStep(dt);
290  stepper->takeStep(solutionHistory);
291 
292  // Testing that each ACTION_LOCATION has been called.
293  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
294  TEST_COMPARE(observer->testBEFORE_SOLVE, ==, true);
295  TEST_COMPARE(observer->testAFTER_SOLVE, ==, true);
296  TEST_COMPARE(observer->testEND_STEP, ==, true);
297 
298  // Testing that values can be observed through the observer.
299  auto x = solutionHistory->getCurrentState()->getX();
300  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
301  x = solutionHistory->getWorkingState()->getX();
302  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
303  TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-14);
304 
305  TEST_COMPARE(observer->testName, ==, "Backward Euler");
306 }
307 
308 
309 // ************************************************************
310 // ************************************************************
311 class StepperBackwardEulerModifierXTest
312  : virtual public Tempus::StepperBackwardEulerModifierXBase<double>
313 {
314 public:
315 
317  StepperBackwardEulerModifierXTest()
318  : testX_BEGIN_STEP(false), testX_BEFORE_SOLVE(false),
319  testX_AFTER_SOLVE(false), testXDOT_END_STEP(false),
320  testX(-0.99), testXDot(-0.99),
321  testDt(-1.5), testTime(-1.5)
322  {}
323 
325  virtual ~StepperBackwardEulerModifierXTest(){}
326 
328  virtual void modify(
330  const double time, const double dt,
332  {
333  switch(modType) {
335  {
336  testX_BEGIN_STEP = true;
337  testX = get_ele(*(x), 0);
338  break;
339  }
341  {
342  testX_BEFORE_SOLVE = true;
343  testDt = dt;
344  break;
345  }
347  {
348  testX_AFTER_SOLVE = true;
349  testTime = time;
350  break;
351  }
353  {
354  testXDOT_END_STEP = true;
355  testXDot = get_ele(*(x), 0);
356  break;
357  }
358  default:
359  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
360  "Error - unknown action location.\n");
361  }
362  }
363 
364  bool testX_BEGIN_STEP;
365  bool testX_BEFORE_SOLVE;
366  bool testX_AFTER_SOLVE;
367  bool testXDOT_END_STEP;
368  double testX;
369  double testXDot;
370  double testDt;
371  double testTime;
372 };
373 
374 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_ModifierX)
375 {
377  model = rcp(new Tempus_Test::SinCosModel<double>());
378 
379  // Setup Stepper for field solve ----------------------------
380  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
381  stepper->setModel(model);
382  auto modifierX = rcp(new StepperBackwardEulerModifierXTest());
383  stepper->setAppAction(modifierX);
384  stepper->initialize();
385 
386  // Setup a SolutionHistory.
387  auto solutionHistory = Tempus::createSolutionHistoryME(model);
388 
389  // Take one time step.
390  stepper->setInitialConditions(solutionHistory);
391  solutionHistory->initWorkingState();
392  double dt = 0.1;
393  solutionHistory->getWorkingState()->setTimeStep(dt);
394  stepper->takeStep(solutionHistory);
395 
396  // Testing that each ACTION_LOCATION has been called.
397  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
398  TEST_COMPARE(modifierX->testX_BEFORE_SOLVE, ==, true);
399  TEST_COMPARE(modifierX->testX_AFTER_SOLVE, ==, true);
400  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
401 
402  // Testing that values can be set through the Modifier.
403  auto x = solutionHistory->getCurrentState()->getX();
404  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-14);
405  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
406  auto xDot = solutionHistory->getWorkingState()->getXDot();
407  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
408 
409  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-14);
410  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
411  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-14);
412 
413  auto time = solutionHistory->getWorkingState()->getTime();
414  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-14);
415 }
416 
417 
418 } // namespace Tempus_Unit_Test
void testFactoryConstruction(std::string stepperType, const Teuchos::RCP< const Thyra::ModelEvaluator< double > > &model)
Unit test utility for Stepper construction through StepperFactory.
MODIFIER_TYPE
Indicates the location of application action (see algorithm).
ACTION_LOCATION
Indicates the location of application action (see algorithm).
#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::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.
virtual void modify(Teuchos::RCP< Thyra::VectorBase< double > >, const double, const double, const MODIFIER_TYPE modType)=0
Modify solution based on the MODIFIER_TYPE.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)