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: 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
12#include "Teuchos_XMLParameterListHelpers.hpp"
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
30namespace Tempus_Unit_Test {
31
32using Teuchos::ParameterList;
33using Teuchos::RCP;
34using Teuchos::rcp;
35using Teuchos::rcp_const_cast;
36using Teuchos::rcp_dynamic_cast;
37using Teuchos::sublist;
38
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 =
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
111 stepper = rcp(new Tempus::StepperOperatorSplit<double>(
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// ************************************************************
123TEUCHOS_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
139 auto sf = Teuchos::rcp(new Tempus::StepperFactory<double>());
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// ************************************************************
149class 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(
168 Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
169 Teuchos::RCP<Tempus::StepperOperatorSplit<double> > stepper,
171 double>::ACTION_LOCATION actLoc)
172 {
173 switch (actLoc) {
174 case StepperOperatorSplitAppAction<double>::BEGIN_STEP: {
175 testBEGIN_STEP = true;
176 auto x = sh->getCurrentState()->getX();
177 testCurrentValue = get_ele(*(x), 0);
178 break;
179 }
180 case StepperOperatorSplitAppAction<double>::BEFORE_STEPPER: {
181 testBEFORE_STEPPER = true;
182 testDt = sh->getWorkingState()->getTimeStep() / 10.0;
183 sh->getWorkingState()->setTimeStep(testDt);
184 break;
185 }
186 case StepperOperatorSplitAppAction<double>::AFTER_STEPPER: {
187 testAFTER_STEPPER = true;
188 testName = "OperatorSplit - Modifier";
189 stepper->setStepperName(testName);
190 break;
191 }
192 case StepperOperatorSplitAppAction<double>::END_STEP: {
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
214TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Modifier)
215{
216 RCP<const Thyra::ModelEvaluator<double> > explicitModel =
218 RCP<const Thyra::ModelEvaluator<double> > implicitModel =
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// ************************************************************
276class 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(
297 Teuchos::RCP<const Tempus::SolutionHistory<double> > sh,
298 Teuchos::RCP<const Tempus::StepperOperatorSplit<double> > stepper,
300 double>::ACTION_LOCATION actLoc)
301 {
302 switch (actLoc) {
303 case StepperOperatorSplitAppAction<double>::BEGIN_STEP: {
304 testBEGIN_STEP = true;
305 auto x = sh->getCurrentState()->getX();
306 testCurrentValue = get_ele(*(x), 0);
307 break;
308 }
309 case StepperOperatorSplitAppAction<double>::BEFORE_STEPPER: {
310 testBEFORE_STEPPER = true;
311 testDt = sh->getWorkingState()->getTimeStep();
312 break;
313 }
314 case StepperOperatorSplitAppAction<double>::AFTER_STEPPER: {
315 testAFTER_STEPPER = true;
316 testName = stepper->getStepperType();
317 break;
318 }
319 case StepperOperatorSplitAppAction<double>::END_STEP: {
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
341TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_Observer)
342{
343 RCP<const Thyra::ModelEvaluator<double> > explicitModel =
345 RCP<const Thyra::ModelEvaluator<double> > implicitModel =
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// ************************************************************
402class 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
422 virtual void modify(Teuchos::RCP<Thyra::VectorBase<double> > x,
423 const double time, const double dt,
425 double>::MODIFIER_TYPE modType)
426 {
427 switch (modType) {
428 case StepperOperatorSplitModifierXBase<double>::X_BEGIN_STEP: {
429 testX_BEGIN_STEP = true;
430 testX = get_ele(*(x), 0);
431 break;
432 }
433 case StepperOperatorSplitModifierXBase<double>::X_BEFORE_STEPPER: {
434 testX_BEFORE_STEPPER = true;
435 testDt = dt;
436 break;
437 }
438 case StepperOperatorSplitModifierXBase<double>::X_AFTER_STEPPER: {
439 testX_AFTER_STEPPER = true;
440 testTime = time;
441 break;
442 }
443 case StepperOperatorSplitModifierXBase<double>::XDOT_END_STEP: {
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
464TEUCHOS_UNIT_TEST(OperatorSplit, AppAction_ModifierX)
465{
466 RCP<const Thyra::ModelEvaluator<double> > explicitModel =
468 RCP<const Thyra::ModelEvaluator<double> > implicitModel =
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
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Explicit Runge-Kutta time stepper.
StepperOperatorSplitAppAction class for StepperOperatorSplit.
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.