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 
32 using Teuchos::RCP;
33 using Teuchos::rcp;
34 using Teuchos::rcp_const_cast;
35 using Teuchos::rcp_dynamic_cast;
36 using Teuchos::sublist;
37 
39 
40 // ************************************************************
41 // ************************************************************
42 TEUCHOS_UNIT_TEST(OperatorSplit, Default_Construction)
43 {
48 
49  // Default construction.
50  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
51  auto subStepper1 =
52  Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
53  auto subStepper2 =
54  Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
55  stepper->addStepper(subStepper1);
56  stepper->addStepper(subStepper2);
57  stepper->initialize();
58  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
59 
60  // Default values for construction.
61  auto modifier =
63  auto modifierX =
65  auto observer =
67  bool useFSAL = stepper->getUseFSAL();
68  std::string ICConsistency = stepper->getICConsistency();
69  bool ICConsistencyCheck = stepper->getICConsistencyCheck();
70  int order = 1;
71 
72  // Test the set functions.
73  stepper->setAppAction(modifier);
74  stepper->initialize();
75  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
76  stepper->setAppAction(modifierX);
77  stepper->initialize();
78  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
79  stepper->setAppAction(observer);
80  stepper->initialize();
81  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
82  stepper->setUseFSAL(useFSAL);
83  stepper->initialize();
84  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
85  stepper->setICConsistency(ICConsistency);
86  stepper->initialize();
87  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
88  stepper->setICConsistencyCheck(ICConsistencyCheck);
89  stepper->initialize();
90  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
91  stepper->setOrder(order);
92  stepper->initialize();
93  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
94  stepper->setOrderMin(order);
95  stepper->initialize();
96  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
97  stepper->setOrderMax(order);
98  stepper->initialize();
99  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
100 
101  // Full argument list construction.
102  std::vector<RCP<const Thyra::ModelEvaluator<double> > > models;
103  models.push_back(explicitModel);
104  models.push_back(implicitModel);
105 
106  std::vector<Teuchos::RCP<Tempus::Stepper<double> > > subStepperList;
107  subStepperList.push_back(subStepper1);
108  subStepperList.push_back(subStepper2);
109 
111  models, subStepperList, useFSAL, ICConsistency, ICConsistencyCheck, order,
112  order, order, modifier));
113 
114  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
115 
116  // Test stepper properties.
117  TEUCHOS_ASSERT(stepper->getOrder() == 1);
118 }
119 
120 // ************************************************************
121 // ************************************************************
122 TEUCHOS_UNIT_TEST(OperatorSplit, StepperFactory_Construction)
123 {
124  // Read params from .xml file
125  auto pList = Teuchos::getParametersFromXmlFile(
126  "../test/OperatorSplit/Tempus_OperatorSplit_VanDerPol.xml");
127  auto tempusPL = sublist(pList, "Tempus", true);
128  auto stepperPL = sublist(tempusPL, "Demo Stepper", true);
129 
130  auto explicitModel =
132  auto implicitModel =
134  std::vector<RCP<const Thyra::ModelEvaluator<double> > > models;
135  models.push_back(explicitModel);
136  models.push_back(implicitModel);
137 
139 
140  // Test using ParameterList.
141  // Passing in model.
142  auto stepper = sf->createStepper(stepperPL, models);
143  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
144 }
145 
146 // ************************************************************
147 // ************************************************************
148 class StepperOperatorSplitModifierTest
149  : virtual public Tempus::StepperOperatorSplitModifierBase<double> {
150  public:
152  StepperOperatorSplitModifierTest()
153  : testBEGIN_STEP(false),
154  testEND_STEP(false),
155  testCurrentValue(-0.99),
156  testWorkingValue(-0.99),
157  testDt(-1.5),
158  testName("")
159  {
160  }
161 
163  virtual ~StepperOperatorSplitModifierTest() {}
164 
166  virtual void modify(
170  double>::ACTION_LOCATION actLoc)
171  {
172  switch (actLoc) {
174  testBEGIN_STEP = true;
175  auto x = sh->getCurrentState()->getX();
176  testCurrentValue = get_ele(*(x), 0);
177  break;
178  }
180  testBEFORE_STEPPER = true;
181  testDt = sh->getWorkingState()->getTimeStep() / 10.0;
182  sh->getWorkingState()->setTimeStep(testDt);
183  break;
184  }
186  testAFTER_STEPPER = true;
187  testName = "OperatorSplit - Modifier";
188  stepper->setStepperName(testName);
189  break;
190  }
192  testEND_STEP = true;
193  auto x = sh->getWorkingState()->getX();
194  testWorkingValue = get_ele(*(x), 0);
195  break;
196  }
197  default:
198  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
199  "Error - unknown action location.\n");
200  }
201  }
202 
203  bool testBEGIN_STEP;
204  bool testBEFORE_STEPPER;
205  bool testAFTER_STEPPER;
206  bool testEND_STEP;
207  double testCurrentValue;
208  double testWorkingValue;
209  double testDt;
210  std::string testName;
211 };
212 
213 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Modifier)
214 {
219  // Default construction.
220  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
221  auto subStepper1 =
222  Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
223  auto subStepper2 =
224  Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
225  auto modifier = rcp(new StepperOperatorSplitModifierTest());
226  stepper->setAppAction(modifier);
227  stepper->addStepper(subStepper1);
228  stepper->addStepper(subStepper2);
229  stepper->initialize();
230 
231  // Setup initial condition SolutionState --------------------
232  auto inArgsIC = stepper->getModel()->getNominalValues();
233  auto icX = rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
234  auto icXDot =
235  rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x_dot());
236  auto icState = Tempus::createSolutionStateX(icX, icXDot);
237  icState->setTime(0.0);
238  icState->setIndex(1);
239  icState->setTimeStep(-15.0);
240  icState->setOrder(stepper->getOrder());
241  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
242 
243  // Create a SolutionHistory.
244  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
245  solutionHistory->setName("Forward States");
246  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
247  solutionHistory->setStorageLimit(2);
248  solutionHistory->addState(icState);
249 
250  // Take one time step.
251  stepper->setInitialConditions(solutionHistory);
252  solutionHistory->initWorkingState();
253  solutionHistory->getWorkingState()->setTimeStep(-15.0);
254  stepper->takeStep(solutionHistory);
255 
256  // Testing that each ACTION_LOCATION has been called.
257  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
258  TEST_COMPARE(modifier->testBEFORE_STEPPER, ==, true);
259  TEST_COMPARE(modifier->testAFTER_STEPPER, ==, true);
260  TEST_COMPARE(modifier->testEND_STEP, ==, true);
261 
262  // Testing that values can be set through the Modifier.
263  auto x = solutionHistory->getCurrentState()->getX();
264  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
265  x = solutionHistory->getWorkingState()->getX();
266  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
267  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
268  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-14);
269 
270  TEST_COMPARE(modifier->testName, ==, "OperatorSplit - Modifier");
271 }
272 
273 // ************************************************************
274 // ************************************************************
275 class StepperOperatorSplitObserverTest
276  : virtual public Tempus::StepperOperatorSplitObserverBase<double> {
277  public:
279  StepperOperatorSplitObserverTest()
280  : testBEGIN_STEP(false),
281  testBEFORE_STEPPER(false),
282  testAFTER_STEPPER(false),
283  testEND_STEP(false),
284  testCurrentValue(-0.99),
285  testWorkingValue(-0.99),
286  testDt(-1.5),
287  testName("Operator Split")
288  {
289  }
290 
292  virtual ~StepperOperatorSplitObserverTest() {}
293 
295  virtual void observe(
299  double>::ACTION_LOCATION actLoc)
300  {
301  switch (actLoc) {
303  testBEGIN_STEP = true;
304  auto x = sh->getCurrentState()->getX();
305  testCurrentValue = get_ele(*(x), 0);
306  break;
307  }
309  testBEFORE_STEPPER = true;
310  testDt = sh->getWorkingState()->getTimeStep();
311  break;
312  }
314  testAFTER_STEPPER = true;
315  testName = stepper->getStepperType();
316  break;
317  }
319  testEND_STEP = true;
320  auto x = sh->getWorkingState()->getX();
321  testWorkingValue = get_ele(*(x), 0);
322  break;
323  }
324  default:
325  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
326  "Error - unknown action location.\n");
327  }
328  }
329 
330  bool testBEGIN_STEP;
331  bool testBEFORE_STEPPER;
332  bool testAFTER_STEPPER;
333  bool testEND_STEP;
334  double testCurrentValue;
335  double testWorkingValue;
336  double testDt;
337  std::string testName;
338 };
339 
340 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Observer)
341 {
346  // Default construction.
347  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
348  auto subStepper1 =
349  Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
350  auto subStepper2 =
351  Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
352  auto observer = rcp(new StepperOperatorSplitObserverTest());
353  stepper->setAppAction(observer);
354  stepper->addStepper(subStepper1);
355  stepper->addStepper(subStepper2);
356  stepper->initialize();
357 
358  // Setup initial condition SolutionState --------------------
359  auto inArgsIC = stepper->getModel()->getNominalValues();
360  auto icX = rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
361  auto icXDot =
362  rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x_dot());
363  auto icState = Tempus::createSolutionStateX(icX, icXDot);
364  icState->setTime(0.0);
365  icState->setIndex(1);
366  icState->setTimeStep(-1.5);
367  icState->setOrder(stepper->getOrder());
368  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
369 
370  // Create a SolutionHistory.
371  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
372  solutionHistory->setName("Forward States");
373  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
374  solutionHistory->setStorageLimit(2);
375  solutionHistory->addState(icState);
376 
377  // Take one time step.
378  stepper->setInitialConditions(solutionHistory);
379  solutionHistory->initWorkingState();
380  solutionHistory->getWorkingState()->setTimeStep(-1.5);
381  stepper->takeStep(solutionHistory);
382 
383  // Testing that each ACTION_LOCATION has been called.
384  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
385  TEST_COMPARE(observer->testBEFORE_STEPPER, ==, true);
386  TEST_COMPARE(observer->testAFTER_STEPPER, ==, true);
387  TEST_COMPARE(observer->testEND_STEP, ==, true);
388 
389  // Testing that values can be observed through the observer.
390  auto x = solutionHistory->getCurrentState()->getX();
391  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
392  x = solutionHistory->getWorkingState()->getX();
393  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
394  TEST_FLOATING_EQUALITY(observer->testDt, -1.5, 1.0e-14);
395 
396  TEST_COMPARE(observer->testName, ==, "Operator Split");
397 }
398 
399 // ************************************************************
400 // ************************************************************
401 class StepperOperatorSplitModifierXTest
402  : virtual public Tempus::StepperOperatorSplitModifierXBase<double> {
403  public:
405  StepperOperatorSplitModifierXTest()
406  : testX_BEGIN_STEP(false),
407  testX_BEFORE_STEPPER(false),
408  testX_AFTER_STEPPER(false),
409  testXDOT_END_STEP(false),
410  testX(-0.99),
411  testXDot(-0.99),
412  testDt(-1.5),
413  testTime(-1.5)
414  {
415  }
416 
418  virtual ~StepperOperatorSplitModifierXTest() {}
419 
422  const double time, const double dt,
424  double>::MODIFIER_TYPE modType)
425  {
426  switch (modType) {
428  testX_BEGIN_STEP = true;
429  testX = get_ele(*(x), 0);
430  break;
431  }
433  testX_BEFORE_STEPPER = true;
434  testDt = dt;
435  break;
436  }
438  testX_AFTER_STEPPER = true;
439  testTime = time;
440  break;
441  }
443  testXDOT_END_STEP = true;
444  testXDot = get_ele(*(x), 0);
445  break;
446  }
447  default:
448  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
449  "Error - unknown action location.\n");
450  }
451  }
452 
453  bool testX_BEGIN_STEP;
454  bool testX_BEFORE_STEPPER;
455  bool testX_AFTER_STEPPER;
456  bool testXDOT_END_STEP;
457  double testX;
458  double testXDot;
459  double testDt;
460  double testTime;
461 };
462 
463 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_ModifierX)
464 {
469  // Default construction.
470  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
471  auto subStepper1 =
472  Tempus::createStepperForwardEuler(explicitModel, Teuchos::null);
473  auto subStepper2 =
474  Tempus::createStepperBackwardEuler(implicitModel, Teuchos::null);
475  auto modifierX = rcp(new StepperOperatorSplitModifierXTest());
476  stepper->setAppAction(modifierX);
477  stepper->addStepper(subStepper1);
478  stepper->addStepper(subStepper2);
479  stepper->initialize();
480 
481  // Setup initial condition SolutionState --------------------
482  auto inArgsIC = stepper->getModel()->getNominalValues();
483  auto icX = rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
484  auto icXDot =
485  rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x_dot());
486  auto icState = Tempus::createSolutionStateX(icX, icXDot);
487  icState->setTime(0.0);
488  icState->setIndex(1);
489  icState->setTimeStep(-1.5);
490  icState->setOrder(stepper->getOrder());
491  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
492 
493  // Create a SolutionHistory.
494  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
495  solutionHistory->setName("Forward States");
496  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
497  solutionHistory->setStorageLimit(2);
498  solutionHistory->addState(icState);
499 
500  // Take one time step.
501  stepper->setInitialConditions(solutionHistory);
502  solutionHistory->initWorkingState();
503  solutionHistory->getWorkingState()->setTimeStep(-1.5);
504  stepper->takeStep(solutionHistory);
505 
506  // Testing that each ACTION_LOCATION has been called.
507  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
508  TEST_COMPARE(modifierX->testX_BEFORE_STEPPER, ==, true);
509  TEST_COMPARE(modifierX->testX_AFTER_STEPPER, ==, true);
510  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
511 
512  // Testing that values can be set through the Modifier.
513  auto x = solutionHistory->getCurrentState()->getX();
514  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-14);
515  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
516  auto xDot = solutionHistory->getWorkingState()->getXDot();
517  if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
518 
519  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0), 1.0e-14);
520  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
521  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-14);
522 
523  auto time = solutionHistory->getWorkingState()->getTime();
524  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-14);
525 }
526 
527 } // 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.
#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.
StepperOperatorSplitAppAction class for StepperOperatorSplit.
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)