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