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 
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_StepperForwardEuler.hpp"
18 #include "Tempus_StepperBackwardEuler.hpp"
19 
27 
28 #include "../TestModels/SinCosModel.hpp"
29 #include "../TestModels/VanDerPolModel.hpp"
30 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
31 
32 #include <fstream>
33 #include <vector>
34 
35 namespace Tempus_Unit_Test {
36 
37 using Teuchos::RCP;
38 using Teuchos::rcp;
39 using Teuchos::rcp_const_cast;
40 using Teuchos::rcp_dynamic_cast;
42 using Teuchos::sublist;
43 using Teuchos::getParametersFromXmlFile;
44 
45 
46 
47 // ************************************************************
48 // ************************************************************
49 TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
50 {
51  auto model = rcp(new Tempus_Test::SinCosModel<double>());
52 
53  // Default construction.
54  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
55  stepper->setModel(model);
56  stepper->initialize();
57  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
58 
59 
60  // Default values for construction.
64  auto solver = rcp(new Thyra::NOXNonlinearSolver());
65  solver->setParameterList(Tempus::defaultSolverParameters());
66 
67  auto predictorStepper = rcp(new Tempus::StepperForwardEuler<double>());
68  predictorStepper->setModel(model); // Can use the same model since both steppers are implicit ODEs.
69  predictorStepper->initialize();
70 
71  auto defaultStepper = rcp(new Tempus::StepperBackwardEuler<double>());
72  bool useFSAL = defaultStepper->getUseFSAL();
73  std::string ICConsistency = defaultStepper->getICConsistency();
74  bool ICConsistencyCheck = defaultStepper->getICConsistencyCheck();
75  bool zeroInitialGuess = defaultStepper->getZeroInitialGuess();
76 
77  // Test the set functions.
78  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
79  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
80  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
81  stepper->setSolver(solver); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
82  stepper->setPredictor(predictorStepper); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
83  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
84  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
85  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
86  stepper->setZeroInitialGuess(zeroInitialGuess); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
87 
88  // Full argument list construction.
90  model, solver, predictorStepper, useFSAL,
91  ICConsistency, ICConsistencyCheck, zeroInitialGuess, modifier));
92  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
93 
94  // Test stepper properties.
95  TEUCHOS_ASSERT(stepper->getOrder() == 1);
96 }
97 
98 
99 // ************************************************************
100 // ************************************************************
101 TEUCHOS_UNIT_TEST(BackwardEuler, StepperFactory_Construction)
102 {
103  auto model = rcp(new Tempus_Test::SinCosModel<double>());
104  testFactoryConstruction("Backward Euler", model);
105 }
106 
107 
108 // ************************************************************
109 // ************************************************************
110 class StepperBackwardEulerModifierTest
111  : virtual public Tempus::StepperBackwardEulerModifierBase<double>
112 {
113 public:
114 
116  StepperBackwardEulerModifierTest()
117  : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
118  testAFTER_SOLVE(false), testEND_STEP(false),
119  testCurrentValue(-0.99), testWorkingValue(-0.99),
120  testDt(-1.5), testName("")
121  {}
122 
124  virtual ~StepperBackwardEulerModifierTest(){}
125 
127  virtual void modify(
131  {
132  switch(actLoc) {
134  {
135  testBEGIN_STEP = true;
136  auto x = sh->getCurrentState()->getX();
137  testCurrentValue = get_ele(*(x), 0);
138  break;
139  }
141  {
142  testBEFORE_SOLVE = true;
143  testDt = sh->getWorkingState()->getTimeStep()/10.0;
144  sh->getWorkingState()->setTimeStep(testDt);
145  break;
146  }
148  {
149  testAFTER_SOLVE = true;
150  testName = "Backward Euler - Modifier";
151  stepper->setStepperName(testName);
152  break;
153  }
155  {
156  testEND_STEP = true;
157  auto x = sh->getWorkingState()->getX();
158  testWorkingValue = get_ele(*(x), 0);
159  break;
160  }
161  default:
162  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
163  "Error - unknown action location.\n");
164  }
165  }
166 
167  bool testBEGIN_STEP;
168  bool testBEFORE_SOLVE;
169  bool testAFTER_SOLVE;
170  bool testEND_STEP;
171  double testCurrentValue;
172  double testWorkingValue;
173  double testDt;
174  std::string testName;
175 };
176 
177 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Modifier)
178 {
180  model = rcp(new Tempus_Test::SinCosModel<double>());
181 
182  // Setup Stepper for field solve ----------------------------
183  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
184  stepper->setModel(model);
185  auto modifier = rcp(new StepperBackwardEulerModifierTest());
186  stepper->setAppAction(modifier);
187  stepper->initialize();
188 
189  // Create a SolutionHistory.
190  auto solutionHistory = Tempus::createSolutionHistoryME(model);
191 
192  // Take one time step.
193  stepper->setInitialConditions(solutionHistory);
194  solutionHistory->initWorkingState();
195  double dt = 0.1;
196  solutionHistory->getWorkingState()->setTimeStep(dt);
197  stepper->takeStep(solutionHistory);
198 
199  // Testing that each ACTION_LOCATION has been called.
200  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
201  TEST_COMPARE(modifier->testBEFORE_SOLVE, ==, true);
202  TEST_COMPARE(modifier->testAFTER_SOLVE, ==, true);
203  TEST_COMPARE(modifier->testEND_STEP, ==, true);
204 
205  // Testing that values can be set through the Modifier.
206  auto x = solutionHistory->getCurrentState()->getX();
207  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
208  x = solutionHistory->getWorkingState()->getX();
209  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
210  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
211  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-14);
212 
213  TEST_COMPARE(modifier->testName, ==, "Backward Euler - Modifier");
214 
215 }
216 
217 
218 // ************************************************************
219 // ************************************************************
220 class StepperBackwardEulerObserverTest
221  : virtual public Tempus::StepperBackwardEulerObserverBase<double>
222 {
223 public:
224 
226  StepperBackwardEulerObserverTest()
227  : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
228  testAFTER_SOLVE(false), testEND_STEP(false),
229  testCurrentValue(-0.99), testWorkingValue(-0.99),
230  testDt(-1.5), testName("")
231  {}
232 
234  virtual ~StepperBackwardEulerObserverTest(){}
235 
237  virtual void observe(
241  {
242  switch(actLoc) {
244  {
245  testBEGIN_STEP = true;
246  auto x = sh->getCurrentState()->getX();
247  testCurrentValue = get_ele(*(x), 0);
248  break;
249  }
251  {
252  testBEFORE_SOLVE = true;
253  testDt = sh->getWorkingState()->getTimeStep();
254  break;
255  }
257  {
258  testAFTER_SOLVE = true;
259  testName = stepper->getStepperType();
260  break;
261  }
263  {
264  testEND_STEP = true;
265  auto x = sh->getWorkingState()->getX();
266  testWorkingValue = get_ele(*(x), 0);
267  break;
268  }
269  default:
270  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
271  "Error - unknown action location.\n");
272  }
273  }
274 
275  bool testBEGIN_STEP;
276  bool testBEFORE_SOLVE;
277  bool testAFTER_SOLVE;
278  bool testEND_STEP;
279  double testCurrentValue;
280  double testWorkingValue;
281  double testDt;
282  std::string testName;
283 };
284 
285 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Observer)
286 {
288  model = rcp(new Tempus_Test::SinCosModel<double>());
289 
290  // Setup Stepper for field solve ----------------------------
291  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
292  stepper->setModel(model);
293  auto observer = rcp(new StepperBackwardEulerObserverTest());
294  stepper->setAppAction(observer);
295  stepper->initialize();
296 
297  // Setup a SolutionHistory.
298  auto solutionHistory = Tempus::createSolutionHistoryME(model);
299 
300  // Take one time step.
301  stepper->setInitialConditions(solutionHistory);
302  solutionHistory->initWorkingState();
303  double dt = 0.1;
304  solutionHistory->getWorkingState()->setTimeStep(dt);
305  stepper->takeStep(solutionHistory);
306 
307  // Testing that each ACTION_LOCATION has been called.
308  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
309  TEST_COMPARE(observer->testBEFORE_SOLVE, ==, true);
310  TEST_COMPARE(observer->testAFTER_SOLVE, ==, true);
311  TEST_COMPARE(observer->testEND_STEP, ==, true);
312 
313  // Testing that values can be observed through the observer.
314  auto x = solutionHistory->getCurrentState()->getX();
315  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
316  x = solutionHistory->getWorkingState()->getX();
317  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
318  TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-14);
319 
320  TEST_COMPARE(observer->testName, ==, "Backward Euler");
321 }
322 
323 
324 // ************************************************************
325 // ************************************************************
326 class StepperBackwardEulerModifierXTest
327  : virtual public Tempus::StepperBackwardEulerModifierXBase<double>
328 {
329 public:
330 
332  StepperBackwardEulerModifierXTest()
333  : testX_BEGIN_STEP(false), testX_BEFORE_SOLVE(false),
334  testX_AFTER_SOLVE(false), testXDOT_END_STEP(false),
335  testX(-0.99), testXDot(-0.99),
336  testDt(-1.5), testTime(-1.5)
337  {}
338 
340  virtual ~StepperBackwardEulerModifierXTest(){}
341 
343  virtual void modify(
345  const double time, const double dt,
347  {
348  switch(modType) {
350  {
351  testX_BEGIN_STEP = true;
352  testX = get_ele(*(x), 0);
353  break;
354  }
356  {
357  testX_BEFORE_SOLVE = true;
358  testDt = dt;
359  break;
360  }
362  {
363  testX_AFTER_SOLVE = true;
364  testTime = time;
365  break;
366  }
368  {
369  testXDOT_END_STEP = true;
370  testXDot = get_ele(*(x), 0);
371  break;
372  }
373  default:
374  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
375  "Error - unknown action location.\n");
376  }
377  }
378 
379  bool testX_BEGIN_STEP;
380  bool testX_BEFORE_SOLVE;
381  bool testX_AFTER_SOLVE;
382  bool testXDOT_END_STEP;
383  double testX;
384  double testXDot;
385  double testDt;
386  double testTime;
387 };
388 
389 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_ModifierX)
390 {
392  model = rcp(new Tempus_Test::SinCosModel<double>());
393 
394  // Setup Stepper for field solve ----------------------------
395  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
396  stepper->setModel(model);
397  auto modifierX = rcp(new StepperBackwardEulerModifierXTest());
398  stepper->setAppAction(modifierX);
399  stepper->initialize();
400 
401  // Setup a SolutionHistory.
402  auto solutionHistory = Tempus::createSolutionHistoryME(model);
403 
404  // Take one time step.
405  stepper->setInitialConditions(solutionHistory);
406  solutionHistory->initWorkingState();
407  double dt = 0.1;
408  solutionHistory->getWorkingState()->setTimeStep(dt);
409  stepper->takeStep(solutionHistory);
410 
411  // Testing that each ACTION_LOCATION has been called.
412  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
413  TEST_COMPARE(modifierX->testX_BEFORE_SOLVE, ==, true);
414  TEST_COMPARE(modifierX->testX_AFTER_SOLVE, ==, true);
415  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
416 
417  // Testing that values can be set through the Modifier.
418  auto x = solutionHistory->getCurrentState()->getX();
419  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-14);
420  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
421  auto xDot = solutionHistory->getWorkingState()->getXDot();
422  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
423 
424  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-14);
425  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
426  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-14);
427 
428  auto time = solutionHistory->getWorkingState()->getTime();
429  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-14);
430 }
431 
432 
433 } // namespace Tempus_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)