Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros 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 
9 #include "Teuchos_UnitTestHarness.hpp"
10 #include "Teuchos_XMLParameterListHelpers.hpp"
11 #include "Teuchos_TimeMonitor.hpp"
12 #include "Teuchos_DefaultComm.hpp"
13 
14 #include "Thyra_VectorStdOps.hpp"
15 
17 #include "Tempus_SolutionHistory.hpp"
25 
26 #include "../TestModels/SinCosModel.hpp"
27 #include "../TestModels/VanDerPolModel.hpp"
28 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
29 
30 #include <fstream>
31 #include <vector>
32 
33 namespace Tempus_Unit_Test {
34 
35 using Teuchos::RCP;
36 using Teuchos::rcp;
37 using Teuchos::rcp_const_cast;
38 using Teuchos::rcp_dynamic_cast;
39 using Teuchos::ParameterList;
40 using Teuchos::sublist;
41 using Teuchos::getParametersFromXmlFile;
42 
44 
45 
46 // ************************************************************
47 // ************************************************************
48 TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
49 {
50  auto model = rcp(new Tempus_Test::SinCosModel<double>());
51 
52  // Default construction.
53  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
54  stepper->setModel(model);
55  stepper->initialize();
56  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
57 
58 
59  // Default values for construction.
60  auto modifier = rcp(new Tempus::StepperBackwardEulerModifierDefault<double>());
61  auto modifierX = rcp(new Tempus::StepperBackwardEulerModifierXDefault<double>());
62  auto observer = rcp(new Tempus::StepperBackwardEulerObserverDefault<double>());
63  auto solver = rcp(new Thyra::NOXNonlinearSolver());
64  solver->setParameterList(Tempus::defaultSolverParameters());
65 
66  auto predictorStepper = rcp(new Tempus::StepperForwardEuler<double>());
67  predictorStepper->setModel(model); // Can use the same model since both steppers are implicit ODEs.
68  predictorStepper->initialize();
69 
70  auto defaultStepper = rcp(new Tempus::StepperBackwardEuler<double>());
71  bool useFSAL = defaultStepper->getUseFSALDefault();
72  std::string ICConsistency = defaultStepper->getICConsistencyDefault();
73  bool ICConsistencyCheck = defaultStepper->getICConsistencyCheckDefault();
74  bool zeroInitialGuess = defaultStepper->getZeroInitialGuess();
75 
76  // Test the set functions.
77 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
79  stepper->setObserver(obs); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
80 #endif
81  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
82  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
83  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
84  stepper->setSolver(solver); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
85  stepper->setPredictor(predictorStepper); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
86  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
87  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
88  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
89  stepper->setZeroInitialGuess(zeroInitialGuess); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
90 
91 
92 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
93  // Full argument list construction.
94  stepper = rcp(new Tempus::StepperBackwardEuler<double>(
95  model, obs, solver, predictorStepper, useFSAL,
96  ICConsistency, ICConsistencyCheck, zeroInitialGuess));
97  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
98 #endif
99 
100  // Full argument list construction.
101  stepper = rcp(new Tempus::StepperBackwardEuler<double>(
102  model, solver, predictorStepper, useFSAL,
103  ICConsistency, ICConsistencyCheck, zeroInitialGuess, modifier));
104  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
105 
106  // Test stepper properties.
107  TEUCHOS_ASSERT(stepper->getOrder() == 1);
108 }
109 
110 
111 // ************************************************************
112 // ************************************************************
113 TEUCHOS_UNIT_TEST(BackwardEuler, StepperFactory_Construction)
114 {
115  auto model = rcp(new Tempus_Test::SinCosModel<double>());
116  testFactoryConstruction("Backward Euler", model);
117 }
118 
119 
120 // ************************************************************
121 // ************************************************************
123  : virtual public Tempus::StepperBackwardEulerModifierBase<double>
124 {
125 public:
126 
127  /// Constructor
129  : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
130  testAFTER_SOLVE(false), testEND_STEP(false),
131  testCurrentValue(-0.99), testWorkingValue(-0.99),
132  testDt(-1.5), testType("")
133  {}
134 
135  /// Destructor
137 
138  /// Modify BackwardEuler Stepper at action location.
139  virtual void modify(
140  Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
141  Teuchos::RCP<Tempus::StepperBackwardEuler<double> > stepper,
143  {
144  switch(actLoc) {
146  {
147  testBEGIN_STEP = true;
148  auto x = sh->getCurrentState()->getX();
149  testCurrentValue = get_ele(*(x), 0);
150  break;
151  }
153  {
154  testBEFORE_SOLVE = true;
155  testDt = sh->getWorkingState()->getTimeStep()/10.0;
156  sh->getWorkingState()->setTimeStep(testDt);
157  break;
158  }
160  {
161  testAFTER_SOLVE = true;
162  testType = "Backward Euler - Modifier";
163  stepper->setStepperType(testType);
164  break;
165  }
167  {
168  testEND_STEP = true;
169  auto x = sh->getWorkingState()->getX();
170  testWorkingValue = get_ele(*(x), 0);
171  break;
172  }
173  default:
174  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
175  "Error - unknown action location.\n");
176  }
177  }
178 
185  double testDt;
186  std::string testType;
187 };
188 
189 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Modifier)
190 {
191  Teuchos::RCP<const Thyra::ModelEvaluator<double> >
192  model = rcp(new Tempus_Test::SinCosModel<double>());
193 
194  // Setup Stepper for field solve ----------------------------
195  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
196  stepper->setModel(model);
197  auto modifier = rcp(new StepperBackwardEulerModifierTest());
198  stepper->setAppAction(modifier);
199  stepper->initialize();
200 
201  // Create a SolutionHistory.
202  auto solutionHistory = Tempus::createSolutionHistoryME(model);
203 
204  // Take one time step.
205  stepper->setInitialConditions(solutionHistory);
206  solutionHistory->initWorkingState();
207  double dt = 0.1;
208  solutionHistory->getWorkingState()->setTimeStep(dt);
209  stepper->takeStep(solutionHistory);
210 
211  // Testing that each ACTION_LOCATION has been called.
212  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
213  TEST_COMPARE(modifier->testBEFORE_SOLVE, ==, true);
214  TEST_COMPARE(modifier->testAFTER_SOLVE, ==, true);
215  TEST_COMPARE(modifier->testEND_STEP, ==, true);
216 
217  // Testing that values can be set through the Modifier.
218  auto x = solutionHistory->getCurrentState()->getX();
219  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
220  x = solutionHistory->getWorkingState()->getX();
221  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
222  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
223  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-15);
224 
225  TEST_COMPARE(modifier->testType, ==, "Backward Euler - Modifier");
226 
227 }
228 
229 
230 // ************************************************************
231 // ************************************************************
233  : virtual public Tempus::StepperBackwardEulerObserverBase<double>
234 {
235 public:
236 
237  /// Constructor
239  : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
240  testAFTER_SOLVE(false), testEND_STEP(false),
241  testCurrentValue(-0.99), testWorkingValue(-0.99),
242  testDt(-1.5), testType("")
243  {}
244 
245  /// Destructor
247 
248  /// Observe BackwardEuler Stepper at action location.
249  virtual void observe(
250  Teuchos::RCP<const Tempus::SolutionHistory<double> > sh,
251  Teuchos::RCP<const Tempus::StepperBackwardEuler<double> > stepper,
253  {
254  switch(actLoc) {
256  {
257  testBEGIN_STEP = true;
258  auto x = sh->getCurrentState()->getX();
259  testCurrentValue = get_ele(*(x), 0);
260  break;
261  }
263  {
264  testBEFORE_SOLVE = true;
265  testDt = sh->getWorkingState()->getTimeStep();
266  break;
267  }
269  {
270  testAFTER_SOLVE = true;
271  testType = stepper->getStepperType();
272  break;
273  }
275  {
276  testEND_STEP = true;
277  auto x = sh->getWorkingState()->getX();
278  testWorkingValue = get_ele(*(x), 0);
279  break;
280  }
281  default:
282  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
283  "Error - unknown action location.\n");
284  }
285  }
286 
293  double testDt;
294  std::string testType;
295 };
296 
297 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Observer)
298 {
299  Teuchos::RCP<const Thyra::ModelEvaluator<double> >
300  model = rcp(new Tempus_Test::SinCosModel<double>());
301 
302  // Setup Stepper for field solve ----------------------------
303  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
304  stepper->setModel(model);
305  auto observer = rcp(new StepperBackwardEulerObserverTest());
306  stepper->setAppAction(observer);
307  stepper->initialize();
308 
309  // Setup a SolutionHistory.
310  auto solutionHistory = Tempus::createSolutionHistoryME(model);
311 
312  // Take one time step.
313  stepper->setInitialConditions(solutionHistory);
314  solutionHistory->initWorkingState();
315  double dt = 0.1;
316  solutionHistory->getWorkingState()->setTimeStep(dt);
317  stepper->takeStep(solutionHistory);
318 
319  // Testing that each ACTION_LOCATION has been called.
320  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
321  TEST_COMPARE(observer->testBEFORE_SOLVE, ==, true);
322  TEST_COMPARE(observer->testAFTER_SOLVE, ==, true);
323  TEST_COMPARE(observer->testEND_STEP, ==, true);
324 
325  // Testing that values can be observed through the observer.
326  auto x = solutionHistory->getCurrentState()->getX();
327  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
328  x = solutionHistory->getWorkingState()->getX();
329  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
330  TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-15);
331 
332  TEST_COMPARE(observer->testType, ==, "Backward Euler");
333 }
334 
335 
336 // ************************************************************
337 // ************************************************************
339  : virtual public Tempus::StepperBackwardEulerModifierXBase<double>
340 {
341 public:
342 
343  /// Constructor
345  : testX_BEGIN_STEP(false), testX_BEFORE_SOLVE(false),
346  testX_AFTER_SOLVE(false), testXDOT_END_STEP(false),
347  testX(-0.99), testXDot(-0.99),
348  testDt(-1.5), testTime(-1.5)
349  {}
350 
351  /// Destructor
353 
354  /// Modify BackwardEuler Stepper at action location.
355  virtual void modify(
356  Teuchos::RCP<Thyra::VectorBase<double> > x,
357  const double time, const double dt,
359  {
360  switch(modType) {
362  {
363  testX_BEGIN_STEP = true;
364  testX = get_ele(*(x), 0);
365  break;
366  }
368  {
369  testX_BEFORE_SOLVE = true;
370  testDt = dt;
371  break;
372  }
374  {
375  testX_AFTER_SOLVE = true;
376  testTime = time;
377  break;
378  }
380  {
381  testXDOT_END_STEP = true;
382  testXDot = get_ele(*(x), 0);
383  break;
384  }
385  default:
386  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
387  "Error - unknown action location.\n");
388  }
389  }
390 
395  double testX;
396  double testXDot;
397  double testDt;
398  double testTime;
399 };
400 
401 TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_ModifierX)
402 {
403  Teuchos::RCP<const Thyra::ModelEvaluator<double> >
404  model = rcp(new Tempus_Test::SinCosModel<double>());
405 
406  // Setup Stepper for field solve ----------------------------
407  auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
408  stepper->setModel(model);
409  auto modifierX = rcp(new StepperBackwardEulerModifierXTest());
410  stepper->setAppAction(modifierX);
411  stepper->initialize();
412 
413  // Setup a SolutionHistory.
414  auto solutionHistory = Tempus::createSolutionHistoryME(model);
415 
416  // Take one time step.
417  stepper->setInitialConditions(solutionHistory);
418  solutionHistory->initWorkingState();
419  double dt = 0.1;
420  solutionHistory->getWorkingState()->setTimeStep(dt);
421  stepper->takeStep(solutionHistory);
422 
423  // Testing that each ACTION_LOCATION has been called.
424  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
425  TEST_COMPARE(modifierX->testX_BEFORE_SOLVE, ==, true);
426  TEST_COMPARE(modifierX->testX_AFTER_SOLVE, ==, true);
427  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
428 
429  // Testing that values can be set through the Modifier.
430  auto x = solutionHistory->getCurrentState()->getX();
431  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-15);
432  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
433  auto xDot = stepper->getStepperXDot(solutionHistory->getWorkingState());
434  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-15);
435  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
436  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-15);
437 
438  auto time = solutionHistory->getWorkingState()->getTime();
439  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-15);
440 }
441 
442 
443 } // namespace Tempus_Test
StepperBackwardEulerObserver class for StepperBackwardEuler.
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).
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.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.
virtual void observe(Teuchos::RCP< const Tempus::SolutionHistory< double > > sh, Teuchos::RCP< const Tempus::StepperBackwardEuler< double > > stepper, const typename Tempus::StepperBackwardEulerAppAction< double >::ACTION_LOCATION actLoc)
Observe BackwardEuler Stepper at action location.
virtual void modify(Teuchos::RCP< Thyra::VectorBase< double > > x, const double time, const double dt, const typename Tempus::StepperBackwardEulerModifierXBase< double >::MODIFIER_TYPE modType)
Modify BackwardEuler Stepper at action location.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual void modify(Teuchos::RCP< Tempus::SolutionHistory< double > > sh, Teuchos::RCP< Tempus::StepperBackwardEuler< double > > stepper, const typename Tempus::StepperBackwardEulerAppAction< double >::ACTION_LOCATION actLoc)
Modify BackwardEuler Stepper at action location.