Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
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
11#include "Teuchos_XMLParameterListHelpers.hpp"
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
29namespace Tempus_Unit_Test {
30
31using Teuchos::RCP;
32using Teuchos::rcp;
33using Teuchos::rcp_const_cast;
34using Teuchos::rcp_dynamic_cast;
35using Teuchos::ParameterList;
36using Teuchos::sublist;
37
39
40
41// ************************************************************
42// ************************************************************
43TEUCHOS_UNIT_TEST(OperatorSplit, Default_Construction)
44{
45 RCP<const Thyra::ModelEvaluator<double> > explicitModel =
47 RCP<const Thyra::ModelEvaluator<double> > implicitModel =
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// ************************************************************
101TEUCHOS_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
116 auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
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// ************************************************************
127class StepperOperatorSplitModifierTest
128 : virtual public Tempus::StepperOperatorSplitModifierBase<double>
129{
130public:
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(
144 Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
145 Teuchos::RCP<Tempus::StepperOperatorSplit<double> > stepper,
147 {
148 switch(actLoc) {
149 case StepperOperatorSplitAppAction<double>::BEGIN_STEP:
150 {
151 testBEGIN_STEP = true;
152 auto x = sh->getCurrentState()->getX();
153 testCurrentValue = get_ele(*(x), 0);
154 break;
155 }
156 case StepperOperatorSplitAppAction<double>::BEFORE_STEPPER:
157 {
158 testBEFORE_STEPPER = true;
159 testDt = sh->getWorkingState()->getTimeStep()/10.0;
160 sh->getWorkingState()->setTimeStep(testDt);
161 break;
162 }
163 case StepperOperatorSplitAppAction<double>::AFTER_STEPPER:
164 {
165 testAFTER_STEPPER = true;
166 testName = "OperatorSplit - Modifier";
167 stepper->setStepperName(testName);
168 break;
169 }
170 case StepperOperatorSplitAppAction<double>::END_STEP:
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
193TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Modifier)
194{
195 RCP<const Thyra::ModelEvaluator<double> > explicitModel =
197 RCP<const Thyra::ModelEvaluator<double> > implicitModel =
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// ************************************************************
252class StepperOperatorSplitObserverTest
253 : virtual public Tempus::StepperOperatorSplitObserverBase<double>
254{
255public:
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(
270 Teuchos::RCP<const Tempus::SolutionHistory<double> > sh,
271 Teuchos::RCP<const Tempus::StepperOperatorSplit<double> > stepper,
273 {
274 switch(actLoc) {
275 case StepperOperatorSplitAppAction<double>::BEGIN_STEP:
276 {
277 testBEGIN_STEP = true;
278 auto x = sh->getCurrentState()->getX();
279 testCurrentValue = get_ele(*(x), 0);
280 break;
281 }
282 case StepperOperatorSplitAppAction<double>::BEFORE_STEPPER:
283 {
284 testBEFORE_STEPPER = true;
285 testDt = sh->getWorkingState()->getTimeStep();
286 break;
287 }
288 case StepperOperatorSplitAppAction<double>::AFTER_STEPPER:
289 {
290 testAFTER_STEPPER = true;
291 testName = stepper->getStepperType();
292 break;
293 }
294 case StepperOperatorSplitAppAction<double>::END_STEP:
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
317TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Observer)
318{
319 RCP<const Thyra::ModelEvaluator<double> > explicitModel =
321 RCP<const Thyra::ModelEvaluator<double> > implicitModel =
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// ************************************************************
375class StepperOperatorSplitModifierXTest
376 : virtual public Tempus::StepperOperatorSplitModifierXBase<double>
377{
378public:
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(
393 Teuchos::RCP<Thyra::VectorBase<double> > x,
394 const double time, const double dt,
396 {
397 switch(modType) {
398 case StepperOperatorSplitModifierXBase<double>::X_BEGIN_STEP:
399 {
400 testX_BEGIN_STEP = true;
401 testX = get_ele(*(x), 0);
402 break;
403 }
404 case StepperOperatorSplitModifierXBase<double>::X_BEFORE_STEPPER:
405 {
406 testX_BEFORE_STEPPER = true;
407 testDt = dt;
408 break;
409 }
410 case StepperOperatorSplitModifierXBase<double>::X_AFTER_STEPPER:
411 {
412 testX_AFTER_STEPPER = true;
413 testTime = time;
414 break;
415 }
416 case StepperOperatorSplitModifierXBase<double>::XDOT_END_STEP:
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
438TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_ModifierX)
439{
440 RCP<const Thyra::ModelEvaluator<double> > explicitModel =
442 RCP<const Thyra::ModelEvaluator<double> > implicitModel =
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_Test
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Explicit Runge-Kutta time stepper.
MODIFIER_TYPE
Indicates the location of application action (see algorithm).
virtual void modify(Teuchos::RCP< Thyra::VectorBase< double > >, const double, const double, const MODIFIER_TYPE modType)=0
Modify solution based on the MODIFIER_TYPE.
OperatorSplit stepper loops through the Stepper list.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
@ STORAGE_TYPE_STATIC
Keep a fix number of states.
Teuchos::RCP< StepperBackwardEuler< Scalar > > createStepperBackwardEuler(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.
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.
Teuchos::RCP< StepperForwardEuler< Scalar > > createStepperForwardEuler(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model, Teuchos::RCP< Teuchos::ParameterList > pl)
Nonmember constructor - ModelEvaluator and ParameterList.