Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_UnitTest_BackwardEuler.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 "Tempus_StepperForwardEuler.hpp"
12#include "Tempus_StepperBackwardEuler.hpp"
13
20
21
23
24using Teuchos::RCP;
25using Teuchos::rcp;
26using Teuchos::rcp_const_cast;
27using Teuchos::rcp_dynamic_cast;
28using Teuchos::ParameterList;
29using Teuchos::sublist;
30
31
32// ************************************************************
33// ************************************************************
34TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
35{
36 auto model = rcp(new Tempus_Test::SinCosModel<double>());
37
38 // Default construction.
39 auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
40 stepper->setModel(model);
41 stepper->initialize();
42 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
43
44
45 // Default values for construction.
49 auto solver = rcp(new Thyra::NOXNonlinearSolver());
50 solver->setParameterList(Tempus::defaultSolverParameters());
51
52 auto predictorStepper = rcp(new Tempus::StepperForwardEuler<double>());
53 predictorStepper->setModel(model); // Can use the same model since both steppers are implicit ODEs.
54 predictorStepper->initialize();
55
56 auto defaultStepper = rcp(new Tempus::StepperBackwardEuler<double>());
57 bool useFSAL = defaultStepper->getUseFSAL();
58 std::string ICConsistency = defaultStepper->getICConsistency();
59 bool ICConsistencyCheck = defaultStepper->getICConsistencyCheck();
60 bool zeroInitialGuess = defaultStepper->getZeroInitialGuess();
61
62 // Test the set functions.
63 stepper->setAppAction(modifier); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
64 stepper->setAppAction(modifierX); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
65 stepper->setAppAction(observer); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
66 stepper->setSolver(solver); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
67 stepper->setPredictor(predictorStepper); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
68 stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
69 stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
70 stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
71 stepper->setZeroInitialGuess(zeroInitialGuess); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
72
73 // Full argument list construction.
75 model, solver, predictorStepper, useFSAL,
76 ICConsistency, ICConsistencyCheck, zeroInitialGuess, modifier));
77 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
78
79 // Test stepper properties.
80 TEUCHOS_ASSERT(stepper->getOrder() == 1);
81}
82
83
84// ************************************************************
85// ************************************************************
86TEUCHOS_UNIT_TEST(BackwardEuler, StepperFactory_Construction)
87{
88 auto model = rcp(new Tempus_Test::SinCosModel<double>());
89 testFactoryConstruction("Backward Euler", model);
90}
91
92
93// ************************************************************
94// ************************************************************
95class StepperBackwardEulerModifierTest
96 : virtual public Tempus::StepperBackwardEulerModifierBase<double>
97{
98public:
99
101 StepperBackwardEulerModifierTest()
102 : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
103 testAFTER_SOLVE(false), testEND_STEP(false),
104 testCurrentValue(-0.99), testWorkingValue(-0.99),
105 testDt(-1.5), testName("")
106 {}
107
109 virtual ~StepperBackwardEulerModifierTest(){}
110
112 virtual void modify(
113 Teuchos::RCP<Tempus::SolutionHistory<double> > sh,
114 Teuchos::RCP<Tempus::StepperBackwardEuler<double> > stepper,
116 {
117 switch(actLoc) {
118 case StepperBackwardEulerAppAction<double>::BEGIN_STEP:
119 {
120 testBEGIN_STEP = true;
121 auto x = sh->getCurrentState()->getX();
122 testCurrentValue = get_ele(*(x), 0);
123 break;
124 }
125 case StepperBackwardEulerAppAction<double>::BEFORE_SOLVE:
126 {
127 testBEFORE_SOLVE = true;
128 testDt = sh->getWorkingState()->getTimeStep()/10.0;
129 sh->getWorkingState()->setTimeStep(testDt);
130 break;
131 }
132 case StepperBackwardEulerAppAction<double>::AFTER_SOLVE:
133 {
134 testAFTER_SOLVE = true;
135 testName = "Backward Euler - Modifier";
136 stepper->setStepperName(testName);
137 break;
138 }
139 case StepperBackwardEulerAppAction<double>::END_STEP:
140 {
141 testEND_STEP = true;
142 auto x = sh->getWorkingState()->getX();
143 testWorkingValue = get_ele(*(x), 0);
144 break;
145 }
146 default:
147 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
148 "Error - unknown action location.\n");
149 }
150 }
151
152 bool testBEGIN_STEP;
153 bool testBEFORE_SOLVE;
154 bool testAFTER_SOLVE;
155 bool testEND_STEP;
156 double testCurrentValue;
157 double testWorkingValue;
158 double testDt;
159 std::string testName;
160};
161
162TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Modifier)
163{
164 Teuchos::RCP<const Thyra::ModelEvaluator<double> >
165 model = rcp(new Tempus_Test::SinCosModel<double>());
166
167 // Setup Stepper for field solve ----------------------------
168 auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
169 stepper->setModel(model);
170 auto modifier = rcp(new StepperBackwardEulerModifierTest());
171 stepper->setAppAction(modifier);
172 stepper->initialize();
173
174 // Create a SolutionHistory.
175 auto solutionHistory = Tempus::createSolutionHistoryME(model);
176
177 // Take one time step.
178 stepper->setInitialConditions(solutionHistory);
179 solutionHistory->initWorkingState();
180 double dt = 0.1;
181 solutionHistory->getWorkingState()->setTimeStep(dt);
182 stepper->takeStep(solutionHistory);
183
184 // Testing that each ACTION_LOCATION has been called.
185 TEST_COMPARE(modifier->testBEGIN_STEP, ==, true);
186 TEST_COMPARE(modifier->testBEFORE_SOLVE, ==, true);
187 TEST_COMPARE(modifier->testAFTER_SOLVE, ==, true);
188 TEST_COMPARE(modifier->testEND_STEP, ==, true);
189
190 // Testing that values can be set through the Modifier.
191 auto x = solutionHistory->getCurrentState()->getX();
192 TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
193 x = solutionHistory->getWorkingState()->getX();
194 TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
195 auto Dt = solutionHistory->getWorkingState()->getTimeStep();
196 TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-14);
197
198 TEST_COMPARE(modifier->testName, ==, "Backward Euler - Modifier");
199
200}
201
202
203// ************************************************************
204// ************************************************************
205class StepperBackwardEulerObserverTest
206 : virtual public Tempus::StepperBackwardEulerObserverBase<double>
207{
208public:
209
211 StepperBackwardEulerObserverTest()
212 : testBEGIN_STEP(false), testBEFORE_SOLVE(false),
213 testAFTER_SOLVE(false), testEND_STEP(false),
214 testCurrentValue(-0.99), testWorkingValue(-0.99),
215 testDt(-1.5), testName("")
216 {}
217
219 virtual ~StepperBackwardEulerObserverTest(){}
220
222 virtual void observe(
223 Teuchos::RCP<const Tempus::SolutionHistory<double> > sh,
224 Teuchos::RCP<const Tempus::StepperBackwardEuler<double> > stepper,
226 {
227 switch(actLoc) {
228 case StepperBackwardEulerAppAction<double>::BEGIN_STEP:
229 {
230 testBEGIN_STEP = true;
231 auto x = sh->getCurrentState()->getX();
232 testCurrentValue = get_ele(*(x), 0);
233 break;
234 }
235 case StepperBackwardEulerAppAction<double>::BEFORE_SOLVE:
236 {
237 testBEFORE_SOLVE = true;
238 testDt = sh->getWorkingState()->getTimeStep();
239 break;
240 }
241 case StepperBackwardEulerAppAction<double>::AFTER_SOLVE:
242 {
243 testAFTER_SOLVE = true;
244 testName = stepper->getStepperType();
245 break;
246 }
247 case StepperBackwardEulerAppAction<double>::END_STEP:
248 {
249 testEND_STEP = true;
250 auto x = sh->getWorkingState()->getX();
251 testWorkingValue = get_ele(*(x), 0);
252 break;
253 }
254 default:
255 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
256 "Error - unknown action location.\n");
257 }
258 }
259
260 bool testBEGIN_STEP;
261 bool testBEFORE_SOLVE;
262 bool testAFTER_SOLVE;
263 bool testEND_STEP;
264 double testCurrentValue;
265 double testWorkingValue;
266 double testDt;
267 std::string testName;
268};
269
270TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_Observer)
271{
272 Teuchos::RCP<const Thyra::ModelEvaluator<double> >
273 model = rcp(new Tempus_Test::SinCosModel<double>());
274
275 // Setup Stepper for field solve ----------------------------
276 auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
277 stepper->setModel(model);
278 auto observer = rcp(new StepperBackwardEulerObserverTest());
279 stepper->setAppAction(observer);
280 stepper->initialize();
281
282 // Setup a SolutionHistory.
283 auto solutionHistory = Tempus::createSolutionHistoryME(model);
284
285 // Take one time step.
286 stepper->setInitialConditions(solutionHistory);
287 solutionHistory->initWorkingState();
288 double dt = 0.1;
289 solutionHistory->getWorkingState()->setTimeStep(dt);
290 stepper->takeStep(solutionHistory);
291
292 // Testing that each ACTION_LOCATION has been called.
293 TEST_COMPARE(observer->testBEGIN_STEP, ==, true);
294 TEST_COMPARE(observer->testBEFORE_SOLVE, ==, true);
295 TEST_COMPARE(observer->testAFTER_SOLVE, ==, true);
296 TEST_COMPARE(observer->testEND_STEP, ==, true);
297
298 // Testing that values can be observed through the observer.
299 auto x = solutionHistory->getCurrentState()->getX();
300 TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-14);
301 x = solutionHistory->getWorkingState()->getX();
302 TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-14);
303 TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-14);
304
305 TEST_COMPARE(observer->testName, ==, "Backward Euler");
306}
307
308
309// ************************************************************
310// ************************************************************
311class StepperBackwardEulerModifierXTest
312 : virtual public Tempus::StepperBackwardEulerModifierXBase<double>
313{
314public:
315
317 StepperBackwardEulerModifierXTest()
318 : testX_BEGIN_STEP(false), testX_BEFORE_SOLVE(false),
319 testX_AFTER_SOLVE(false), testXDOT_END_STEP(false),
320 testX(-0.99), testXDot(-0.99),
321 testDt(-1.5), testTime(-1.5)
322 {}
323
325 virtual ~StepperBackwardEulerModifierXTest(){}
326
328 virtual void modify(
329 Teuchos::RCP<Thyra::VectorBase<double> > x,
330 const double time, const double dt,
332 {
333 switch(modType) {
334 case StepperBackwardEulerModifierXBase<double>::X_BEGIN_STEP:
335 {
336 testX_BEGIN_STEP = true;
337 testX = get_ele(*(x), 0);
338 break;
339 }
340 case StepperBackwardEulerModifierXBase<double>::X_BEFORE_SOLVE:
341 {
342 testX_BEFORE_SOLVE = true;
343 testDt = dt;
344 break;
345 }
346 case StepperBackwardEulerModifierXBase<double>::X_AFTER_SOLVE:
347 {
348 testX_AFTER_SOLVE = true;
349 testTime = time;
350 break;
351 }
352 case StepperBackwardEulerModifierXBase<double>::XDOT_END_STEP:
353 {
354 testXDOT_END_STEP = true;
355 testXDot = get_ele(*(x), 0);
356 break;
357 }
358 default:
359 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
360 "Error - unknown action location.\n");
361 }
362 }
363
364 bool testX_BEGIN_STEP;
365 bool testX_BEFORE_SOLVE;
366 bool testX_AFTER_SOLVE;
367 bool testXDOT_END_STEP;
368 double testX;
369 double testXDot;
370 double testDt;
371 double testTime;
372};
373
374TEUCHOS_UNIT_TEST(BackwardEuler, AppAction_ModifierX)
375{
376 Teuchos::RCP<const Thyra::ModelEvaluator<double> >
377 model = rcp(new Tempus_Test::SinCosModel<double>());
378
379 // Setup Stepper for field solve ----------------------------
380 auto stepper = rcp(new Tempus::StepperBackwardEuler<double>());
381 stepper->setModel(model);
382 auto modifierX = rcp(new StepperBackwardEulerModifierXTest());
383 stepper->setAppAction(modifierX);
384 stepper->initialize();
385
386 // Setup a SolutionHistory.
387 auto solutionHistory = Tempus::createSolutionHistoryME(model);
388
389 // Take one time step.
390 stepper->setInitialConditions(solutionHistory);
391 solutionHistory->initWorkingState();
392 double dt = 0.1;
393 solutionHistory->getWorkingState()->setTimeStep(dt);
394 stepper->takeStep(solutionHistory);
395
396 // Testing that each ACTION_LOCATION has been called.
397 TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true);
398 TEST_COMPARE(modifierX->testX_BEFORE_SOLVE, ==, true);
399 TEST_COMPARE(modifierX->testX_AFTER_SOLVE, ==, true);
400 TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true);
401
402 // Testing that values can be set through the Modifier.
403 auto x = solutionHistory->getCurrentState()->getX();
404 TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-14);
405 // Temporary memory for xDot is not guarranteed to exist outside the Stepper.
406 auto xDot = solutionHistory->getWorkingState()->getXDot();
407 if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
408
409 TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-14);
410 auto Dt = solutionHistory->getWorkingState()->getTimeStep();
411 TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-14);
412
413 auto time = solutionHistory->getWorkingState()->getTime();
414 TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-14);
415}
416
417
418} // namespace Tempus_Test
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
ACTION_LOCATION
Indicates the location of application action (see algorithm).
MODIFIER_TYPE
Indicates the location of application action (see algorithm).
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
void testFactoryConstruction(std::string stepperType, const Teuchos::RCP< const Thyra::ModelEvaluator< double > > &model)
Unit test utility for Stepper construction through StepperFactory.
Teuchos::RCP< SolutionHistory< Scalar > > createSolutionHistoryME(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Nonmember contructor from a Thyra ModelEvaluator.
Teuchos::RCP< Teuchos::ParameterList > defaultSolverParameters()
Returns the default solver ParameterList for implicit Steppers.