Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_UnitTest_ForwardEuler.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 
19 
26 
27 #include "../TestModels/SinCosModel.hpp"
28 #include "../TestModels/VanDerPolModel.hpp"
29 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
30 
31 #include <fstream>
32 #include <vector>
33 
34 namespace Tempus_Unit_Test {
35 
36 using Teuchos::RCP;
37 using Teuchos::rcp;
38 using Teuchos::rcp_const_cast;
39 using Teuchos::rcp_dynamic_cast;
40 using Teuchos::ParameterList;
41 using Teuchos::sublist;
42 using Teuchos::getParametersFromXmlFile;
43 
46 
47 // Comment out any of the following tests to exclude from build/run.
48 
49 
50 // ************************************************************
51 // ************************************************************
52 TEUCHOS_UNIT_TEST(ForwardEuler, Default_Construction)
53 {
54  auto model = rcp(new Tempus_Test::SinCosModel<double>());
55 
56  // Default construction.
57  auto modifier = rcp(new Tempus::StepperForwardEulerModifierDefault<double>());
58  auto modifierX = rcp(new Tempus::StepperForwardEulerModifierXDefault<double>());
59  auto observer = rcp(new Tempus::StepperForwardEulerObserverDefault<double>());
60  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
61  stepper->setModel(model);
62  stepper->initialize();
63  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
64  // Default values for construction.
65  bool useFSAL = stepper->getUseFSALDefault();
66  std::string ICConsistency = stepper->getICConsistencyDefault();
67  bool ICConsistencyCheck = stepper->getICConsistencyCheckDefault();
68 
69  // Test the set functions.
70 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
71  auto obs = rcp(new Tempus::StepperForwardEulerObserver<double>());
72  stepper->setObserver(obs); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
73 #endif
74  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
75  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
76  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
77  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
78  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
79  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
80 
81 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
82  // Full argument list construction.
83  stepper = rcp(new Tempus::StepperForwardEuler<double>(
84  model, obs, useFSAL, ICConsistency, ICConsistencyCheck));
85  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
86 #endif
87  stepper = rcp(new Tempus::StepperForwardEuler<double>(
88  model, useFSAL, ICConsistency, ICConsistencyCheck,modifier));
89  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
90 
91  // Test stepper properties.
92  TEUCHOS_ASSERT(stepper->getOrder() == 1);
93 }
94 
95 
96 // ************************************************************
97 // ************************************************************
98 TEUCHOS_UNIT_TEST(ForwardEuler, StepperFactory_Construction)
99 {
100  auto model = rcp(new Tempus_Test::SinCosModel<double>());
101  testFactoryConstruction("Forward Euler", model);
102 }
103 
104 
105 // ************************************************************
106 // ************************************************************
108  : virtual public Tempus::StepperForwardEulerModifierBase<double>
109 {
110 public:
111 
112  /// Constructor
114  : testBEGIN_STEP(false), testBEFORE_EXPLICIT_EVAL(false),
115  testEND_STEP(false), testCurrentValue(-0.99), testWorkingValue(-0.99),
116  testDt(-1.5), testType("")
117  {}
118 
119  /// Destructor
121 
122  /// Observe ForwardEuler Stepper at end of takeStep.
123  virtual void modify(
124  Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
125  Teuchos::RCP<Tempus::StepperForwardEuler<double> > stepper,
127  {
128  switch(actLoc) {
130  {
131  testBEGIN_STEP = true;
132  auto x = sh->getCurrentState()->getX();
133  testCurrentValue = get_ele(*(x), 0);
134  break;
135  }
137  {
139  testDt = sh->getWorkingState()->getTimeStep()/10.0;
140  sh->getWorkingState()->setTimeStep(testDt);
141  testType = "Forward Euler - Modifier";
142  stepper->setStepperType(testType);
143  break;
144  }
146  {
147  testEND_STEP = true;
148  auto x = sh->getWorkingState()->getX();
149  testWorkingValue = get_ele(*(x), 0);
150  break;
151  }
152  default:
153  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
154  "Error - unknown action location.\n");
155  }
156  }
162  double testDt;
163  std::string testType;
164 };
165 
166 TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Modifier)
167 {
168  auto model = rcp(new Tempus_Test::SinCosModel<double>());
169 
170  // Setup Stepper for field solve ----------------------------
171  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
172  stepper->setModel(model);
173  auto modifier = rcp(new StepperForwardEulerModifierTest());
174  stepper->setAppAction(modifier);
175  stepper->initialize();
176 
177  // Setup initial condition SolutionState --------------------
178  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
179  stepper->getModel()->getNominalValues();
180  auto icSolution =
181  rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
182  auto icState = Tempus::createSolutionStateX(icSolution);
183  icState->setTime (0.0);
184  icState->setIndex (0);
185  icState->setTimeStep(0.0);
186  icState->setOrder (stepper->getOrder());
187  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
188 
189  // Setup SolutionHistory ------------------------------------
190  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
191  solutionHistory->setName("Forward States");
192  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
193  solutionHistory->setStorageLimit(2);
194  solutionHistory->addState(icState);
195 
196  // Take one time step.
197  stepper->setInitialConditions(solutionHistory);
198  solutionHistory->initWorkingState();
199  double dt = 0.1;
200  solutionHistory->getWorkingState()->setTimeStep(dt);
201  stepper->takeStep(solutionHistory);
202 
203  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
204  TEST_COMPARE(modifier->testBEFORE_EXPLICIT_EVAL, ==, true);
205  TEST_COMPARE(modifier->testEND_STEP, ==, true);
206 
207  auto x = solutionHistory->getCurrentState()->getX();
208  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
209  x = solutionHistory->getWorkingState()->getX();
210  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
211  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
212  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-15);
213 
214  TEST_COMPARE(modifier->testType, ==, "Forward Euler - Modifier");
215 }
216 
217  // ************************************************************
218  // ************************************************************
220  : virtual public Tempus::StepperForwardEulerObserverBase<double>
221 {
222 public:
223 
224  /// Constructor
226  : testBEGIN_STEP(false), testBEFORE_EXPLICIT_EVAL(false),
227  testEND_STEP(false), testCurrentValue(-0.99),
228  testWorkingValue(-0.99),testDt(-1.5), testType("")
229  {}
230 
231  /// Destructor
233 
234  /// Observe ForwardEuler Stepper at end of takeStep.
235  virtual void observe(
236  Teuchos::RCP<const Tempus::SolutionHistory<double> > sh,
237  Teuchos::RCP<const Tempus::StepperForwardEuler<double> > stepper,
239  {
240  switch(actLoc) {
242  {
243  testBEGIN_STEP = true;
244  auto x = sh->getCurrentState()->getX();
245  testCurrentValue = get_ele(*(x), 0);
246  break;
247  }
249  {
251  testDt = sh->getWorkingState()->getTimeStep();
252  testType = stepper->getStepperType();
253  break;
254  }
256  {
257  testEND_STEP = true;
258  auto x = sh->getWorkingState()->getX();
259  testWorkingValue = get_ele(*(x), 0);
260  break;
261  }
262  default:
263  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
264  "Error - unknown action location.\n");
265  }
266  }
267 
273  double testDt;
274  std::string testType;
275 };
276 
277  TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Observer)
278  {
279  auto model = rcp(new Tempus_Test::SinCosModel<double>());
280 
281  // Setup Stepper for field solve ----------------------------
282  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
283  stepper->setModel(model);
284  auto observer = rcp(new StepperForwardEulerObserverTest());
285  stepper->setAppAction(observer);
286  stepper->initialize();
287 
288  // Setup initial condition SolutionState --------------------
289  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
290  stepper->getModel()->getNominalValues();
291  auto icSolution =
292  rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
293  auto icState = Tempus::createSolutionStateX(icSolution);
294  icState->setTime (0.0);
295  icState->setIndex (0);
296  icState->setTimeStep(0.0);
297  icState->setOrder (stepper->getOrder());
298  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
299 
300  // Setup SolutionHistory ------------------------------------
301  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
302  solutionHistory->setName("Forward States");
303  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
304  solutionHistory->setStorageLimit(2);
305  solutionHistory->addState(icState);
306 
307  // Take one time step.
308  stepper->setInitialConditions(solutionHistory);
309  solutionHistory->initWorkingState();
310  double dt = 0.1;
311  solutionHistory->getWorkingState()->setTimeStep(dt);
312  stepper->takeStep(solutionHistory);
313 
314  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
315  TEST_COMPARE(observer->testBEFORE_EXPLICIT_EVAL, ==, true);
316  TEST_COMPARE(observer->testEND_STEP, ==, true);
317 
318  auto x = solutionHistory->getCurrentState()->getX();
319  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
320  x = solutionHistory->getWorkingState()->getX();
321  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
322  TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-15);
323 
324  TEST_COMPARE(observer->testType, ==, "Forward Euler");
325 }
326 
327  // ************************************************************
328  // ************************************************************
330  : virtual public Tempus::StepperForwardEulerModifierXBase<double>
331 {
332 public:
333 
334  /// Constructor
337  testXDOT_END_STEP(false), testX(-0.99),
338  testXDot(-0.99), testDt(-1.5), testTime(-1.5)
339  {}
340 
341  /// Destructor
343 
344  /// Observe BackwardEuler Stepper at end of takeStep.
345  virtual void modify(
346  Teuchos::RCP<Thyra::VectorBase<double> > x,
347  const double time, const double dt,
349  {
350  switch(modType) {
352  {
353  testX_BEGIN_STEP = true;
354  testX = get_ele(*(x), 0);
355  break;
356  }
358  {
360  testDt = dt;
361  testTime = time;
362  break;
363  }
365  {
366  testXDOT_END_STEP = true;
367  testXDot = get_ele(*(x), 0);
368  break;
369  }
370  default:
371  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
372  "Error - unknown action location.\n");
373  }
374  }
378  double testX;
379  double testXDot;
380  double testDt;
381  double testTime;
382 };
383 
384  TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_ModifierX)
385  {
386  auto model = rcp(new Tempus_Test::SinCosModel<double>());
387 
388  // Setup Stepper for field solve ----------------------------
389  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
390  stepper->setModel(model);
391  auto modifierX = rcp(new StepperForwardEulerModifierXTest());
392  stepper->setAppAction(modifierX);
393  stepper->initialize();
394 
395  // Setup initial condition SolutionState --------------------
396  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
397  stepper->getModel()->getNominalValues();
398  auto icSolution =
399  rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
400  auto icState = Tempus::createSolutionStateX(icSolution);
401  icState->setTime (0.0);
402  icState->setIndex (0);
403  icState->setTimeStep(0.0);
404  icState->setOrder (stepper->getOrder());
405  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
406 
407  // Setup SolutionHistory ------------------------------------
408  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
409  solutionHistory->setName("Forward States");
410  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
411  solutionHistory->setStorageLimit(2);
412  solutionHistory->addState(icState);
413 
414  // Take one time step.
415  stepper->setInitialConditions(solutionHistory);
416  solutionHistory->initWorkingState();
417  double dt = 0.1;
418  solutionHistory->getWorkingState()->setTimeStep(dt);
419  stepper->takeStep(solutionHistory);
420 
421  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
422  TEST_COMPARE(modifierX->testX_BEFORE_EXPLICIT_EVAL, ==, true);
423  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
424 
425  auto x = solutionHistory->getCurrentState()->getX();
426  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-15);
427  // Temperary memory for xDot is not guarranteed to exist outside the Stepper.
428  auto xDot = stepper->getStepperXDot(solutionHistory->getWorkingState());
429  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-15);
430  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
431  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-15);
432 
433  auto time = solutionHistory->getWorkingState()->getTime();
434  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-15);
435  }
436 
437 } // namespace Tempus_Test
438 
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.
MODIFIER_TYPE
Indicates the location of application action (see algorithm).
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.
Sine-Cosine model problem from Rythmos. This is a canonical Sine-Cosine differential equation with a...
ACTION_LOCATION
Indicates the location of application action (see algorithm).
StepperForwardEulerObserver class for StepperForwardEuler.
virtual void observe(Teuchos::RCP< const Tempus::SolutionHistory< double > > sh, Teuchos::RCP< const Tempus::StepperForwardEuler< double > > stepper, const typename Tempus::StepperForwardEulerAppAction< double >::ACTION_LOCATION actLoc)
Observe ForwardEuler Stepper at end of takeStep.
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 > > x, const double time, const double dt, const typename Tempus::StepperForwardEulerModifierXBase< double >::MODIFIER_TYPE modType)
Observe BackwardEuler Stepper at end of takeStep.
virtual void modify(Teuchos::RCP< Tempus::SolutionHistory< double > > sh, Teuchos::RCP< Tempus::StepperForwardEuler< double > > stepper, const typename Tempus::StepperForwardEulerAppAction< double >::ACTION_LOCATION actLoc)
Observe ForwardEuler Stepper at end of takeStep.