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: 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 
18 
19 #include "Tempus_StepperForwardEuler.hpp"
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;
41 using Teuchos::sublist;
42 using Teuchos::getParametersFromXmlFile;
43 
45 
46 // Comment out any of the following tests to exclude from build/run.
47 
48 
49 // ************************************************************
50 // ************************************************************
51 TEUCHOS_UNIT_TEST(ForwardEuler, Default_Construction)
52 {
53  auto model = rcp(new Tempus_Test::SinCosModel<double>());
54 
55  // Default construction.
59  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
60  stepper->setModel(model);
61  stepper->initialize();
62  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
63  // Default values for construction.
64  bool useFSAL = stepper->getUseFSAL();
65  std::string ICConsistency = stepper->getICConsistency();
66  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
67 
68  // Test the set functions.
69  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
70  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
71  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
72  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
73  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
74  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
75 
77  model, useFSAL, ICConsistency, ICConsistencyCheck,modifier));
78  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
79 
80  // Test stepper properties.
81  TEUCHOS_ASSERT(stepper->getOrder() == 1);
82 }
83 
84 
85 // ************************************************************
86 // ************************************************************
87 TEUCHOS_UNIT_TEST(ForwardEuler, StepperFactory_Construction)
88 {
89  auto model = rcp(new Tempus_Test::SinCosModel<double>());
90  testFactoryConstruction("Forward Euler", model);
91 }
92 
93 
94 // ************************************************************
95 // ************************************************************
96 class StepperForwardEulerModifierTest
97  : virtual public Tempus::StepperForwardEulerModifierBase<double>
98 {
99 public:
100 
102  StepperForwardEulerModifierTest()
103  : testBEGIN_STEP(false), testBEFORE_EXPLICIT_EVAL(false),
104  testEND_STEP(false), testCurrentValue(-0.99), testWorkingValue(-0.99),
105  testDt(-1.5), testName("")
106  {}
107 
109  virtual ~StepperForwardEulerModifierTest(){}
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_EXPLICIT_EVAL = true;
128  testDt = sh->getWorkingState()->getTimeStep()/10.0;
129  sh->getWorkingState()->setTimeStep(testDt);
130  testName = "Forward Euler - Modifier";
131  stepper->setStepperName(testName);
132  break;
133  }
135  {
136  testEND_STEP = true;
137  auto x = sh->getWorkingState()->getX();
138  testWorkingValue = get_ele(*(x), 0);
139  break;
140  }
141  default:
142  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
143  "Error - unknown action location.\n");
144  }
145  }
146  bool testBEGIN_STEP;
147  bool testBEFORE_EXPLICIT_EVAL;
148  bool testEND_STEP;
149  double testCurrentValue;
150  double testWorkingValue;
151  double testDt;
152  std::string testName;
153 };
154 
155 TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Modifier)
156 {
157  auto model = rcp(new Tempus_Test::SinCosModel<double>());
158 
159  // Setup Stepper for field solve ----------------------------
160  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
161  stepper->setModel(model);
162  auto modifier = rcp(new StepperForwardEulerModifierTest());
163  stepper->setAppAction(modifier);
164  stepper->initialize();
165 
166  // Setup initial condition SolutionState --------------------
167  auto inArgsIC = model->getNominalValues();
168  auto icSolution =
169  rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
170  auto icState = Tempus::createSolutionStateX(icSolution);
171  icState->setTime (0.0);
172  icState->setIndex (0);
173  icState->setTimeStep(0.0);
174  icState->setOrder (stepper->getOrder());
175  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
176 
177  // Setup SolutionHistory ------------------------------------
178  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
179  solutionHistory->setName("Forward States");
180  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
181  solutionHistory->setStorageLimit(2);
182  solutionHistory->addState(icState);
183 
184  // Take one time step.
185  stepper->setInitialConditions(solutionHistory);
186  solutionHistory->initWorkingState();
187  double dt = 0.1;
188  solutionHistory->getWorkingState()->setTimeStep(dt);
189  stepper->takeStep(solutionHistory);
190 
191  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
192  TEST_COMPARE(modifier->testBEFORE_EXPLICIT_EVAL, ==, true);
193  TEST_COMPARE(modifier->testEND_STEP, ==, true);
194 
195  auto x = solutionHistory->getCurrentState()->getX();
196  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
197  x = solutionHistory->getWorkingState()->getX();
198  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
199  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
200  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-14);
201 
202  TEST_COMPARE(modifier->testName, ==, "Forward Euler - Modifier");
203 }
204 
205 
206 // ************************************************************
207 // ************************************************************
208 class StepperForwardEulerObserverTest
209  : virtual public Tempus::StepperForwardEulerObserverBase<double>
210 {
211 public:
212 
214  StepperForwardEulerObserverTest()
215  : testBEGIN_STEP(false), testBEFORE_EXPLICIT_EVAL(false),
216  testEND_STEP(false), testCurrentValue(-0.99),
217  testWorkingValue(-0.99),testDt(-1.5), testName("")
218  {}
219 
221  virtual ~StepperForwardEulerObserverTest(){}
222 
224  virtual void observe(
228  {
229  switch(actLoc) {
231  {
232  testBEGIN_STEP = true;
233  auto x = sh->getCurrentState()->getX();
234  testCurrentValue = get_ele(*(x), 0);
235  break;
236  }
238  {
239  testBEFORE_EXPLICIT_EVAL = true;
240  testDt = sh->getWorkingState()->getTimeStep();
241  testName = stepper->getStepperName();
242  break;
243  }
245  {
246  testEND_STEP = true;
247  auto x = sh->getWorkingState()->getX();
248  testWorkingValue = get_ele(*(x), 0);
249  break;
250  }
251  default:
252  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
253  "Error - unknown action location.\n");
254  }
255  }
256 
257  bool testBEGIN_STEP;
258  bool testBEFORE_EXPLICIT_EVAL;
259  bool testEND_STEP;
260  double testCurrentValue;
261  double testWorkingValue;
262  double testDt;
263  std::string testName;
264 };
265 
266 TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Observer)
267 {
268  auto model = rcp(new Tempus_Test::SinCosModel<double>());
269 
270  // Setup Stepper for field solve ----------------------------
271  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
272  stepper->setModel(model);
273  auto observer = rcp(new StepperForwardEulerObserverTest());
274  stepper->setAppAction(observer);
275  stepper->initialize();
276 
277  // Setup initial condition SolutionState --------------------
278  auto inArgsIC = model->getNominalValues();
279  auto icSolution =
280  rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
281  auto icState = Tempus::createSolutionStateX(icSolution);
282  icState->setTime (0.0);
283  icState->setIndex (0);
284  icState->setTimeStep(0.0);
285  icState->setOrder (stepper->getOrder());
286  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
287 
288  // Setup SolutionHistory ------------------------------------
289  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
290  solutionHistory->setName("Forward States");
291  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
292  solutionHistory->setStorageLimit(2);
293  solutionHistory->addState(icState);
294 
295  // Take one time step.
296  stepper->setInitialConditions(solutionHistory);
297  solutionHistory->initWorkingState();
298  double dt = 0.1;
299  solutionHistory->getWorkingState()->setTimeStep(dt);
300  stepper->takeStep(solutionHistory);
301 
302  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
303  TEST_COMPARE(observer->testBEFORE_EXPLICIT_EVAL, ==, true);
304  TEST_COMPARE(observer->testEND_STEP, ==, true);
305 
306  auto x = solutionHistory->getCurrentState()->getX();
307  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
308  x = solutionHistory->getWorkingState()->getX();
309  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
310  TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-14);
311 
312  TEST_COMPARE(observer->testName, ==, "Forward Euler");
313 }
314 
315 
316 // ************************************************************
317 // ************************************************************
318 class StepperForwardEulerModifierXTest
319  : virtual public Tempus::StepperForwardEulerModifierXBase<double>
320 {
321 public:
322 
324  StepperForwardEulerModifierXTest()
325  : testX_BEGIN_STEP(false), testX_BEFORE_EXPLICIT_EVAL(false),
326  testXDOT_END_STEP(false), testX(-0.99),
327  testXDot(-0.99), testDt(-1.5), testTime(-1.5)
328  {}
329 
331  virtual ~StepperForwardEulerModifierXTest(){}
332 
334  virtual void modify(
336  const double time, const double dt,
338  {
339  switch(modType) {
341  {
342  testX_BEGIN_STEP = true;
343  testX = get_ele(*(x), 0);
344  break;
345  }
347  {
348  testX_BEFORE_EXPLICIT_EVAL = true;
349  testDt = dt;
350  testTime = time;
351  break;
352  }
354  {
355  testXDOT_END_STEP = true;
356  testXDot = get_ele(*(x), 0);
357  break;
358  }
359  default:
360  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
361  "Error - unknown action location.\n");
362  }
363  }
364  bool testX_BEGIN_STEP;
365  bool testX_BEFORE_EXPLICIT_EVAL;
366  bool testXDOT_END_STEP;
367  double testX;
368  double testXDot;
369  double testDt;
370  double testTime;
371 };
372 
373 TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_ModifierX)
374 {
375  auto model = rcp(new Tempus_Test::SinCosModel<double>());
376 
377  // Setup Stepper for field solve ----------------------------
378  auto stepper = rcp(new Tempus::StepperForwardEuler<double>());
379  stepper->setModel(model);
380  auto modifierX = rcp(new StepperForwardEulerModifierXTest());
381  stepper->setAppAction(modifierX);
382  stepper->initialize();
383 
384  // Setup initial condition SolutionState --------------------
385  auto inArgsIC = model->getNominalValues();
386  auto icSolution =
387  rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
388  auto icState = Tempus::createSolutionStateX(icSolution);
389  icState->setTime (0.0);
390  icState->setIndex (0);
391  icState->setTimeStep(0.0);
392  icState->setOrder (stepper->getOrder());
393  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
394 
395  // Setup SolutionHistory ------------------------------------
396  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
397  solutionHistory->setName("Forward States");
398  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
399  solutionHistory->setStorageLimit(2);
400  solutionHistory->addState(icState);
401 
402  // Take one time step.
403  stepper->setInitialConditions(solutionHistory);
404  solutionHistory->initWorkingState();
405  double dt = 0.1;
406  solutionHistory->getWorkingState()->setTimeStep(dt);
407  stepper->takeStep(solutionHistory);
408 
409  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
410  TEST_COMPARE(modifierX->testX_BEFORE_EXPLICIT_EVAL, ==, true);
411  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
412 
413  auto x = solutionHistory->getCurrentState()->getX();
414  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-14);
415  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
416  auto xDot = solutionHistory->getWorkingState()->getXDot();
417  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
418 
419  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-14);
420  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
421  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-14);
422 
423  auto time = solutionHistory->getWorkingState()->getTime();
424  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-14);
425  }
426 
427 } // namespace Tempus_Test
428 
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.
#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...
ACTION_LOCATION
Indicates the location of application action (see algorithm).
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...
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)