Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_UnitTest_OperatorSplit.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 
12 
14 
15 #include "Tempus_StepperForwardEuler.hpp"
16 #include "Tempus_StepperBackwardEuler.hpp"
17 
18 #include "Tempus_StepperOperatorSplit.hpp"
25 
26 #include "../TestModels/VanDerPol_IMEX_ExplicitModel.hpp"
27 #include "../TestModels/VanDerPol_IMEX_ImplicitModel.hpp"
28 
29 namespace Tempus_Unit_Test {
30 
31 using Teuchos::RCP;
32 using Teuchos::rcp;
33 using Teuchos::rcp_const_cast;
34 using Teuchos::rcp_dynamic_cast;
36 using Teuchos::sublist;
37 
39 
40 
41 // ************************************************************
42 // ************************************************************
43 TEUCHOS_UNIT_TEST(OperatorSplit, Default_Construction)
44 {
49 
50  // Default construction.
51  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
52  auto subStepper1 = Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
53  auto subStepper2 = Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
54  stepper->addStepper(subStepper1);
55  stepper->addStepper(subStepper2);
56  stepper->initialize();
57  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
58 
59  // Default values for construction.
63  bool useFSAL = stepper->getUseFSAL();
64  std::string ICConsistency = stepper->getICConsistency();
65  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
66  int order = 1;
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  stepper->setOrder(order); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
76  stepper->setOrderMin(order); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
77  stepper->setOrderMax(order); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
78 
79 
80  // Full argument list construction.
81  std::vector<RCP<const Thyra::ModelEvaluator<double> > > models;
82  models.push_back(explicitModel);
83  models.push_back(implicitModel);
84 
85  std::vector<Teuchos::RCP<Tempus::Stepper<double> > > subStepperList;
86  subStepperList.push_back(subStepper1);
87  subStepperList.push_back(subStepper2);
88 
90  models, subStepperList, useFSAL, ICConsistency, ICConsistencyCheck,order, order, order,modifier));
91 
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(OperatorSplit, StepperFactory_Construction)
102 {
103  // Read params from .xml file
104  auto pList = Teuchos::getParametersFromXmlFile(
105  "../test/OperatorSplit/Tempus_OperatorSplit_VanDerPol.xml");
106  auto tempusPL = sublist(pList, "Tempus", true);
107  auto stepperPL = sublist(tempusPL, "Demo Stepper", true);
108 
109  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
110  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
111  std::vector<RCP<const Thyra::ModelEvaluator<double> > > models;
112  models.push_back(explicitModel);
113  models.push_back(implicitModel);
114 
115 
117 
118  // Test using ParameterList.
119  // Passing in model.
120  auto stepper = sf->createStepper(stepperPL, models);
121  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
122 
123 }
124 
125 // ************************************************************
126 // ************************************************************
127 class StepperOperatorSplitModifierTest
128  : virtual public Tempus::StepperOperatorSplitModifierBase<double>
129 {
130 public:
131 
133  StepperOperatorSplitModifierTest()
134  : testBEGIN_STEP(false), testEND_STEP(false),
135  testCurrentValue(-0.99), testWorkingValue(-0.99),
136  testDt(-1.5), testName("")
137  {}
138 
140  virtual ~StepperOperatorSplitModifierTest(){}
141 
143  virtual void modify(
147  {
148  switch(actLoc) {
150  {
151  testBEGIN_STEP = true;
152  auto x = sh->getCurrentState()->getX();
153  testCurrentValue = get_ele(*(x), 0);
154  break;
155  }
157  {
158  testBEFORE_STEPPER = true;
159  testDt = sh->getWorkingState()->getTimeStep()/10.0;
160  sh->getWorkingState()->setTimeStep(testDt);
161  break;
162  }
164  {
165  testAFTER_STEPPER = true;
166  testName = "OperatorSplit - Modifier";
167  stepper->setStepperName(testName);
168  break;
169  }
171  {
172  testEND_STEP = true;
173  auto x = sh->getWorkingState()->getX();
174  testWorkingValue = get_ele(*(x), 0);
175  break;
176  }
177  default:
178  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
179  "Error - unknown action location.\n");
180  }
181  }
182 
183  bool testBEGIN_STEP;
184  bool testBEFORE_STEPPER;
185  bool testAFTER_STEPPER;
186  bool testEND_STEP;
187  double testCurrentValue;
188  double testWorkingValue;
189  double testDt;
190  std::string testName;
191 };
192 
193 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Modifier)
194 {
199  // Default construction.
200  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
201  auto subStepper1 = Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
202  auto subStepper2 = Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
203  auto modifier = rcp(new StepperOperatorSplitModifierTest());
204  stepper->setAppAction(modifier);
205  stepper->addStepper(subStepper1);
206  stepper->addStepper(subStepper2);
207  stepper->initialize();
208 
209  // Setup initial condition SolutionState --------------------
210  auto inArgsIC = stepper->getModel()->getNominalValues();
211  auto icX = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
212  auto icXDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
213  auto icState = Tempus::createSolutionStateX(icX, icXDot);
214  icState->setTime (0.0);
215  icState->setIndex (1);
216  icState->setTimeStep(-15.0);
217  icState->setOrder (stepper->getOrder());
218  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
219 
220  // Create a SolutionHistory.
221  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
222  solutionHistory->setName("Forward States");
223  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
224  solutionHistory->setStorageLimit(2);
225  solutionHistory->addState(icState);
226 
227  // Take one time step.
228  stepper->setInitialConditions(solutionHistory);
229  solutionHistory->initWorkingState();
230  solutionHistory->getWorkingState()->setTimeStep(-15.0);
231  stepper->takeStep(solutionHistory);
232 
233  // Testing that each ACTION_LOCATION has been called.
234  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
235  TEST_COMPARE(modifier->testBEFORE_STEPPER, ==, true);
236  TEST_COMPARE(modifier->testAFTER_STEPPER, ==, true);
237  TEST_COMPARE(modifier->testEND_STEP, ==, true);
238 
239  // Testing that values can be set through the Modifier.
240  auto x = solutionHistory->getCurrentState()->getX();
241  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
242  x = solutionHistory->getWorkingState()->getX();
243  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
244  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
245  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-14);
246 
247  TEST_COMPARE(modifier->testName, ==, "OperatorSplit - Modifier");
248 }
249 
250 // ************************************************************
251 // ************************************************************
252 class StepperOperatorSplitObserverTest
253  : virtual public Tempus::StepperOperatorSplitObserverBase<double>
254 {
255 public:
256 
258  StepperOperatorSplitObserverTest()
259  : testBEGIN_STEP(false), testBEFORE_STEPPER(false),
260  testAFTER_STEPPER(false), testEND_STEP(false),
261  testCurrentValue(-0.99), testWorkingValue(-0.99),
262  testDt(-1.5), testName("Operator Split")
263  {}
264 
266  virtual ~StepperOperatorSplitObserverTest(){}
267 
269  virtual void observe(
273  {
274  switch(actLoc) {
276  {
277  testBEGIN_STEP = true;
278  auto x = sh->getCurrentState()->getX();
279  testCurrentValue = get_ele(*(x), 0);
280  break;
281  }
283  {
284  testBEFORE_STEPPER = true;
285  testDt = sh->getWorkingState()->getTimeStep();
286  break;
287  }
289  {
290  testAFTER_STEPPER = true;
291  testName = stepper->getStepperType();
292  break;
293  }
295  {
296  testEND_STEP = true;
297  auto x = sh->getWorkingState()->getX();
298  testWorkingValue = get_ele(*(x), 0);
299  break;
300  }
301  default:
302  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
303  "Error - unknown action location.\n");
304  }
305  }
306 
307  bool testBEGIN_STEP;
308  bool testBEFORE_STEPPER;
309  bool testAFTER_STEPPER;
310  bool testEND_STEP;
311  double testCurrentValue;
312  double testWorkingValue;
313  double testDt;
314  std::string testName;
315 };
316 
317 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Observer)
318 {
323  // Default construction.
324  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
325  auto subStepper1 = Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
326  auto subStepper2 = Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
327  auto observer = rcp(new StepperOperatorSplitObserverTest());
328  stepper->setAppAction(observer);
329  stepper->addStepper(subStepper1);
330  stepper->addStepper(subStepper2);
331  stepper->initialize();
332 
333  // Setup initial condition SolutionState --------------------
334  auto inArgsIC = stepper->getModel()->getNominalValues();
335  auto icX = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
336  auto icXDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
337  auto icState = Tempus::createSolutionStateX(icX, icXDot);
338  icState->setTime (0.0);
339  icState->setIndex (1);
340  icState->setTimeStep(-1.5);
341  icState->setOrder (stepper->getOrder());
342  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
343 
344  // Create a SolutionHistory.
345  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
346  solutionHistory->setName("Forward States");
347  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
348  solutionHistory->setStorageLimit(2);
349  solutionHistory->addState(icState);
350 
351  // Take one time step.
352  stepper->setInitialConditions(solutionHistory);
353  solutionHistory->initWorkingState();
354  solutionHistory->getWorkingState()->setTimeStep(-1.5);
355  stepper->takeStep(solutionHistory);
356 
357  // Testing that each ACTION_LOCATION has been called.
358  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
359  TEST_COMPARE(observer->testBEFORE_STEPPER, ==, true);
360  TEST_COMPARE(observer->testAFTER_STEPPER, ==, true);
361  TEST_COMPARE(observer->testEND_STEP, ==, true);
362 
363  // Testing that values can be observed through the observer.
364  auto x = solutionHistory->getCurrentState()->getX();
365  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
366  x = solutionHistory->getWorkingState()->getX();
367  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
368  TEST_FLOATING_EQUALITY(observer->testDt, -1.5, 1.0e-14);
369 
370  TEST_COMPARE(observer->testName, ==, "Operator Split");
371 }
372 
373 // ************************************************************
374 // ************************************************************
375 class StepperOperatorSplitModifierXTest
376  : virtual public Tempus::StepperOperatorSplitModifierXBase<double>
377 {
378 public:
379 
381  StepperOperatorSplitModifierXTest()
382  : testX_BEGIN_STEP(false), testX_BEFORE_STEPPER(false),
383  testX_AFTER_STEPPER(false), testXDOT_END_STEP(false),
384  testX(-0.99), testXDot(-0.99),
385  testDt(-1.5), testTime(-1.5)
386  {}
387 
389  virtual ~StepperOperatorSplitModifierXTest(){}
390 
392  virtual void modify(
394  const double time, const double dt,
396  {
397  switch(modType) {
399  {
400  testX_BEGIN_STEP = true;
401  testX = get_ele(*(x), 0);
402  break;
403  }
405  {
406  testX_BEFORE_STEPPER = true;
407  testDt = dt;
408  break;
409  }
411  {
412  testX_AFTER_STEPPER = true;
413  testTime = time;
414  break;
415  }
417  {
418  testXDOT_END_STEP = true;
419  testXDot = get_ele(*(x), 0);
420  break;
421  }
422  default:
423  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
424  "Error - unknown action location.\n");
425  }
426  }
427 
428  bool testX_BEGIN_STEP;
429  bool testX_BEFORE_STEPPER;
430  bool testX_AFTER_STEPPER;
431  bool testXDOT_END_STEP;
432  double testX;
433  double testXDot;
434  double testDt;
435  double testTime;
436 };
437 
438 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_ModifierX)
439 {
444  // Default construction.
445  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
446  auto subStepper1 = Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
447  auto subStepper2 = Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
448  auto modifierX = rcp(new StepperOperatorSplitModifierXTest());
449  stepper->setAppAction(modifierX);
450  stepper->addStepper(subStepper1);
451  stepper->addStepper(subStepper2);
452  stepper->initialize();
453 
454  // Setup initial condition SolutionState --------------------
455  auto inArgsIC = stepper->getModel()->getNominalValues();
456  auto icX = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
457  auto icXDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
458  auto icState = Tempus::createSolutionStateX(icX, icXDot);
459  icState->setTime (0.0);
460  icState->setIndex (1);
461  icState->setTimeStep(-1.5);
462  icState->setOrder (stepper->getOrder());
463  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
464 
465  // Create a SolutionHistory.
466  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
467  solutionHistory->setName("Forward States");
468  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
469  solutionHistory->setStorageLimit(2);
470  solutionHistory->addState(icState);
471 
472  // Take one time step.
473  stepper->setInitialConditions(solutionHistory);
474  solutionHistory->initWorkingState();
475  solutionHistory->getWorkingState()->setTimeStep(-1.5);
476  stepper->takeStep(solutionHistory);
477 
478  // Testing that each ACTION_LOCATION has been called.
479  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
480  TEST_COMPARE(modifierX->testX_BEFORE_STEPPER, ==, true);
481  TEST_COMPARE(modifierX->testX_AFTER_STEPPER, ==, true);
482  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
483 
484  // Testing that values can be set through the Modifier.
485  auto x = solutionHistory->getCurrentState()->getX();
486  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-14);
487  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
488  auto xDot = solutionHistory->getWorkingState()->getXDot();
489  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
490 
491  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-14);
492  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
493  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-14);
494 
495  auto time = solutionHistory->getWorkingState()->getTime();
496  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-14);
497 }
498 
499 } // namespace Tempus_Unit_Test
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.
Explicit Runge-Kutta time stepper.
MODIFIER_TYPE
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)
OperatorSplit stepper loops through the Stepper list.
Teuchos::RCP< StepperForwardEuler< Scalar > > createStepperForwardEuler(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
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.
Teuchos::RCP< StepperBackwardEuler< Scalar > > createStepperBackwardEuler(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)