Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros 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 
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 
27 
28 #include "../TestModels/VanDerPol_IMEX_ExplicitModel.hpp"
29 #include "../TestModels/VanDerPol_IMEX_ImplicitModel.hpp"
30 #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp"
31 
32 #include <fstream>
33 #include <vector>
34 
35 namespace Tempus_Unit_Test {
36 
37 using Teuchos::RCP;
38 using Teuchos::rcp;
39 using Teuchos::rcp_const_cast;
40 using Teuchos::rcp_dynamic_cast;
41 using Teuchos::ParameterList;
42 using Teuchos::sublist;
43 using Teuchos::getParametersFromXmlFile;
44 
47 
48 
49 // ************************************************************
50 // ************************************************************
51 TEUCHOS_UNIT_TEST(OperatorSplit, Default_Construction)
52 {
53  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
54  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
55 
56  // Default construction.
57  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
58  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
59  auto subStepper1 =
60  sf->createStepperForwardEuler(explicitModel, Teuchos::null);
61  auto subStepper2 =
62  sf->createStepperBackwardEuler(implicitModel, Teuchos::null);
63  stepper->addStepper(subStepper1);
64  stepper->addStepper(subStepper2);
65  stepper->initialize();
66  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
67 
68  // Default values for construction.
69 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
71 #endif
72  auto modifier = rcp(new Tempus::StepperOperatorSplitModifierDefault<double>());
73  auto modifierX = rcp(new Tempus::StepperOperatorSplitModifierXDefault<double>());
74  auto observer = rcp(new Tempus::StepperOperatorSplitObserverDefault<double>());
75  bool useFSAL = stepper->getUseFSALDefault();
76  std::string ICConsistency = stepper->getICConsistencyDefault();
77  bool ICConsistencyCheck = stepper->getICConsistencyCheckDefault();
78  int order = 1;
79 
80  // Test the set functions.
81 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
82  stepper->setObserver(obs); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
83 #endif
84  stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
85  stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
86  stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
87  stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
88  stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
89  stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
90  stepper->setOrder(order); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
91  stepper->setOrderMin(order); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
92  stepper->setOrderMax(order); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
93 
94 
95  // Full argument list construction.
96  std::vector<RCP<const Thyra::ModelEvaluator<double> > > models;
97  models.push_back(explicitModel);
98  models.push_back(implicitModel);
99 
100  std::vector<Teuchos::RCP<Tempus::Stepper<double> > > subStepperList;
101  subStepperList.push_back(subStepper1);
102  subStepperList.push_back(subStepper2);
103 
104 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
105  stepper = rcp(new Tempus::StepperOperatorSplit<double>(
106  models, subStepperList, obs, useFSAL, ICConsistency, ICConsistencyCheck,
107  order, order, order));
108 #endif
109  stepper = rcp(new Tempus::StepperOperatorSplit<double>(
110  models, subStepperList, useFSAL, ICConsistency, ICConsistencyCheck,order, order, order,modifier));
111 
112  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
113 
114  // Test stepper properties.
115  TEUCHOS_ASSERT(stepper->getOrder() == 1);
116 }
117 
118 
119 // ************************************************************
120 // ************************************************************
121 TEUCHOS_UNIT_TEST(OperatorSplit, StepperFactory_Construction)
122 {
123  // Read params from .xml file
124  auto pList = getParametersFromXmlFile(
125  "../test/OperatorSplit/Tempus_OperatorSplit_VanDerPol.xml");
126  auto tempusPL = sublist(pList, "Tempus", true);
127  auto stepperPL = sublist(tempusPL, "Demo Stepper", true);
128 
129  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
130  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
131  std::vector<RCP<const Thyra::ModelEvaluator<double> > > models;
132  models.push_back(explicitModel);
133  models.push_back(implicitModel);
134 
135 
136  auto sf = Teuchos::rcp(new StepperFactory<double>());
137 
138  // Test using ParameterList.
139  // Passing in model.
140  auto stepper = sf->createMultiSteppers(stepperPL, models);
141  TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
142 
143 }
144 
145 // ************************************************************
146 // ************************************************************
148  : virtual public Tempus::StepperOperatorSplitModifierBase<double>
149 {
150 public:
151 
152  /// Constructor
154  : testBEGIN_STEP(false), testEND_STEP(false),
155  testCurrentValue(-0.99), testWorkingValue(-0.99),
156  testDt(-1.5), testType("")
157  {}
158 
159  /// Destructor
161 
162  /// Modify OperatorSplit Stepper at action location.
163  virtual void modify(
164  Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
165  Teuchos::RCP<Tempus::StepperOperatorSplit<double> > stepper,
167  {
168  switch(actLoc) {
170  {
171  testBEGIN_STEP = true;
172  auto x = sh->getCurrentState()->getX();
173  testCurrentValue = get_ele(*(x), 0);
174  break;
175  }
177  {
178  testBEFORE_STEPPER = true;
179  testDt = sh->getWorkingState()->getTimeStep()/10.0;
180  sh->getWorkingState()->setTimeStep(testDt);
181  break;
182  }
184  {
185  testAFTER_STEPPER = true;
186  testType = "OperatorSplit - Modifier";
187  stepper->setStepperType(testType);
188  break;
189  }
191  {
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 
209  double testDt;
210  std::string testType;
211 };
212 
213 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Modifier)
214 {
215  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
216  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
217  // Default construction.
218  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
219  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
220  auto subStepper1 =
221  sf->createStepperForwardEuler(explicitModel, Teuchos::null);
222  auto subStepper2 =
223  sf->createStepperBackwardEuler(implicitModel, Teuchos::null);
224  auto modifier = rcp(new StepperOperatorSplitModifierTest());
225  stepper->setAppAction(modifier);
226  stepper->addStepper(subStepper1);
227  stepper->addStepper(subStepper2);
228  stepper->initialize();
229 
230  // Setup initial condition SolutionState --------------------
231  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
232  stepper->getModel()->getNominalValues();
233  auto icX = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
234  auto icXDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
235  auto icState = Tempus::createSolutionStateX(icX, icXDot);
236  icState->setTime (0.0);
237  icState->setIndex (1);
238  icState->setTimeStep(-15.0);
239  icState->setOrder (stepper->getOrder());
240  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
241 
242  // Create a SolutionHistory.
243  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
244  solutionHistory->setName("Forward States");
245  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
246  solutionHistory->setStorageLimit(2);
247  solutionHistory->addState(icState);
248 
249  // Take one time step.
250  stepper->setInitialConditions(solutionHistory);
251  solutionHistory->initWorkingState();
252  solutionHistory->getWorkingState()->setTimeStep(-15.0);
253  stepper->takeStep(solutionHistory);
254 
255  // Testing that each ACTION_LOCATION has been called.
256  TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
257  TEST_COMPARE(modifier->testBEFORE_STEPPER, ==, true);
258  TEST_COMPARE(modifier->testAFTER_STEPPER, ==, true);
259  TEST_COMPARE(modifier->testEND_STEP, ==, true);
260 
261  // Testing that values can be set through the Modifier.
262  auto x = solutionHistory->getCurrentState()->getX();
263  TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
264  x = solutionHistory->getWorkingState()->getX();
265  TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
266  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
267  TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-15);
268 
269  TEST_COMPARE(modifier->testType, ==, "OperatorSplit - Modifier");
270 }
271 
272 // ************************************************************
273 // ************************************************************
275  : virtual public Tempus::StepperOperatorSplitObserverBase<double>
276 {
277 public:
278 
279  /// Constructor
281  : testBEGIN_STEP(false), testBEFORE_STEPPER(false),
282  testAFTER_STEPPER(false), testEND_STEP(false),
283  testCurrentValue(-0.99), testWorkingValue(-0.99),
284  testDt(-1.5), testType("Operator Split")
285  {}
286 
287  /// Destructor
289 
290  /// Observe OperatorSplit Stepper at action location.
291  virtual void observe(
292  Teuchos::RCP<const Tempus::SolutionHistory<double> > sh,
293  Teuchos::RCP<const Tempus::StepperOperatorSplit<double> > stepper,
295  {
296  switch(actLoc) {
298  {
299  testBEGIN_STEP = true;
300  auto x = sh->getCurrentState()->getX();
301  testCurrentValue = get_ele(*(x), 0);
302  break;
303  }
305  {
306  testBEFORE_STEPPER = true;
307  testDt = sh->getWorkingState()->getTimeStep();
308  break;
309  }
311  {
312  testAFTER_STEPPER = true;
313  testType = stepper->getStepperType();
314  break;
315  }
317  {
318  testEND_STEP = true;
319  auto x = sh->getWorkingState()->getX();
320  testWorkingValue = get_ele(*(x), 0);
321  break;
322  }
323  default:
324  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
325  "Error - unknown action location.\n");
326  }
327  }
328 
335  double testDt;
336  std::string testType;
337 };
338 
339 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Observer)
340 {
341  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
342  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
343  // Default construction.
344  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
345  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
346  auto subStepper1 =
347  sf->createStepperForwardEuler(explicitModel, Teuchos::null);
348  auto subStepper2 =
349  sf->createStepperBackwardEuler(implicitModel, Teuchos::null);
350  auto observer = rcp(new StepperOperatorSplitObserverTest());
351  stepper->setAppAction(observer);
352  stepper->addStepper(subStepper1);
353  stepper->addStepper(subStepper2);
354  stepper->initialize();
355 
356  // Setup initial condition SolutionState --------------------
357  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
358  stepper->getModel()->getNominalValues();
359  auto icX = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
360  auto icXDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
361  auto icState = Tempus::createSolutionStateX(icX, icXDot);
362  icState->setTime (0.0);
363  icState->setIndex (1);
364  icState->setTimeStep(-1.5);
365  icState->setOrder (stepper->getOrder());
366  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
367 
368  // Create a SolutionHistory.
369  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
370  solutionHistory->setName("Forward States");
371  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
372  solutionHistory->setStorageLimit(2);
373  solutionHistory->addState(icState);
374 
375  // Take one time step.
376  stepper->setInitialConditions(solutionHistory);
377  solutionHistory->initWorkingState();
378  solutionHistory->getWorkingState()->setTimeStep(-1.5);
379  stepper->takeStep(solutionHistory);
380 
381  // Testing that each ACTION_LOCATION has been called.
382  TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
383  TEST_COMPARE(observer->testBEFORE_STEPPER, ==, true);
384  TEST_COMPARE(observer->testAFTER_STEPPER, ==, true);
385  TEST_COMPARE(observer->testEND_STEP, ==, true);
386 
387  // Testing that values can be observed through the observer.
388  auto x = solutionHistory->getCurrentState()->getX();
389  TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-15);
390  x = solutionHistory->getWorkingState()->getX();
391  TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-15);
392  TEST_FLOATING_EQUALITY(observer->testDt, -1.5, 1.0e-15);
393 
394  TEST_COMPARE(observer->testType, ==, "Operator Split");
395 }
396 
397 // ************************************************************
398 // ************************************************************
400  : virtual public Tempus::StepperOperatorSplitModifierXBase<double>
401 {
402 public:
403 
404  /// Constructor
406  : testX_BEGIN_STEP(false), testX_BEFORE_STEPPER(false),
407  testX_AFTER_STEPPER(false), testXDOT_END_STEP(false),
408  testX(-0.99), testXDot(-0.99),
409  testDt(-1.5), testTime(-1.5)
410  {}
411 
412  /// Destructor
414 
415  /// Modify OperatorSplit Stepper at action location.
416  virtual void modify(
417  Teuchos::RCP<Thyra::VectorBase<double> > x,
418  const double time, const double dt,
420  {
421  switch(modType) {
423  {
424  testX_BEGIN_STEP = true;
425  testX = get_ele(*(x), 0);
426  break;
427  }
429  {
430  testX_BEFORE_STEPPER = true;
431  testDt = dt;
432  break;
433  }
435  {
436  testX_AFTER_STEPPER = true;
437  testTime = time;
438  break;
439  }
441  {
442  testXDOT_END_STEP = true;
443  testXDot = get_ele(*(x), 0);
444  break;
445  }
446  default:
447  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
448  "Error - unknown action location.\n");
449  }
450  }
451 
456  double testX;
457  double testXDot;
458  double testDt;
459  double testTime;
460 };
461 
462 TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_ModifierX)
463 {
464  auto explicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ExplicitModel<double>());
465  auto implicitModel = rcp(new Tempus_Test::VanDerPol_IMEX_ImplicitModel<double>());
466  // Default construction.
467  auto stepper = rcp(new Tempus::StepperOperatorSplit<double>());
468  auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
469  auto subStepper1 =
470  sf->createStepperForwardEuler(explicitModel, Teuchos::null);
471  auto subStepper2 =
472  sf->createStepperBackwardEuler(implicitModel, Teuchos::null);
473  auto modifierX = rcp(new StepperOperatorSplitModifierXTest());
474  stepper->setAppAction(modifierX);
475  stepper->addStepper(subStepper1);
476  stepper->addStepper(subStepper2);
477  stepper->initialize();
478 
479  // Setup initial condition SolutionState --------------------
480  Thyra::ModelEvaluatorBase::InArgs<double> inArgsIC =
481  stepper->getModel()->getNominalValues();
482  auto icX = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x());
483  auto icXDot = rcp_const_cast<Thyra::VectorBase<double> > (inArgsIC.get_x_dot());
484  auto icState = Tempus::createSolutionStateX(icX, icXDot);
485  icState->setTime (0.0);
486  icState->setIndex (1);
487  icState->setTimeStep(-1.5);
488  icState->setOrder (stepper->getOrder());
489  icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing.
490 
491  // Create a SolutionHistory.
492  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
493  solutionHistory->setName("Forward States");
494  solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC);
495  solutionHistory->setStorageLimit(2);
496  solutionHistory->addState(icState);
497 
498  // Take one time step.
499  stepper->setInitialConditions(solutionHistory);
500  solutionHistory->initWorkingState();
501  solutionHistory->getWorkingState()->setTimeStep(-1.5);
502  stepper->takeStep(solutionHistory);
503 
504  // Testing that each ACTION_LOCATION has been called.
505  TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
506  TEST_COMPARE(modifierX->testX_BEFORE_STEPPER, ==, true);
507  TEST_COMPARE(modifierX->testX_AFTER_STEPPER, ==, true);
508  TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
509 
510  // Testing that values can be set through the Modifier.
511  auto x = solutionHistory->getCurrentState()->getX();
512  TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-15);
513  // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
514  auto xDot = stepper->getStepperXDot(solutionHistory->getWorkingState());
515  TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-15);
516  auto Dt = solutionHistory->getWorkingState()->getTimeStep();
517  TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-15);
518 
519  auto time = solutionHistory->getWorkingState()->getTime();
520  TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-15);
521 }
522 
523 } // namespace Tempus_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).
OperatorSplit stepper loops through the Stepper list.
StepperOperatorSplitObserver class for StepperOperatorSplit.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
virtual void modify(Teuchos::RCP< Tempus::SolutionHistory< double > > sh, Teuchos::RCP< Tempus::StepperOperatorSplit< double > > stepper, const typename Tempus::StepperOperatorSplitAppAction< double >::ACTION_LOCATION actLoc)
Modify OperatorSplit Stepper at action location.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual void observe(Teuchos::RCP< const Tempus::SolutionHistory< double > > sh, Teuchos::RCP< const Tempus::StepperOperatorSplit< double > > stepper, const typename Tempus::StepperOperatorSplitAppAction< double >::ACTION_LOCATION actLoc)
Observe OperatorSplit Stepper at action location.
Keep a fix number of states.
virtual void modify(Teuchos::RCP< Thyra::VectorBase< double > > x, const double time, const double dt, const typename Tempus::StepperOperatorSplitModifierXBase< double >::MODIFIER_TYPE modType)
Modify OperatorSplit Stepper at action location.