Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_UnitTest_IMEX_RK.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
14#include "../TestModels/DahlquistTestModel.hpp"
15#include "../TestModels/VanDerPol_IMEX_ExplicitModel.hpp"
16#include "../TestModels/VanDerPol_IMEX_ImplicitModel.hpp"
17
18namespace Tempus_Unit_Test {
19
20using Teuchos::ParameterList;
21using Teuchos::RCP;
22using Teuchos::rcp;
23using Teuchos::rcp_const_cast;
24using Teuchos::rcp_dynamic_cast;
25using Teuchos::sublist;
26
29
30// ************************************************************
31// ************************************************************
32TEUCHOS_UNIT_TEST(IMEX_RK, Default_Construction)
33{
34 // Setup the IMEX Pair ModelEvaluator
35 auto explicitModel =
37 auto implicitModel =
40 explicitModel, implicitModel));
41
42 // Default construction.
43 auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
44 stepper->setModel(model);
45 stepper->initialize();
46 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
47
48 // Default values for construction.
49 auto modifier = rcp(new Tempus::StepperRKModifierDefault<double>());
50 auto modifierX = rcp(new Tempus::StepperRKModifierXDefault<double>());
51 auto observer = rcp(new Tempus::StepperRKObserverDefault<double>());
52 auto solver = rcp(new Thyra::NOXNonlinearSolver());
53 solver->setParameterList(Tempus::defaultSolverParameters());
54
55 bool useFSAL = stepper->getUseFSAL();
56 std::string ICConsistency = stepper->getICConsistency();
57 bool ICConsistencyCheck = stepper->getICConsistencyCheck();
58 bool zeroInitialGuess = stepper->getZeroInitialGuess();
59 std::string stepperType = "IMEX RK SSP2";
60 auto stepperERK = Teuchos::rcp(new Tempus::StepperERK_Trapezoidal<double>());
61 auto explicitTableau = stepperERK->getTableau();
62 auto stepperSDIRK =
64 auto implicitTableau = stepperSDIRK->getTableau();
65 int order = 2;
66
67 // Test the set functions.
68 stepper->setAppAction(modifier);
69 stepper->initialize();
70 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
71 stepper->setAppAction(modifierX);
72 stepper->initialize();
73 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
74 stepper->setAppAction(observer);
75 stepper->initialize();
76 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
77 stepper->setSolver(solver);
78 stepper->initialize();
79 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
80 stepper->setUseFSAL(useFSAL);
81 stepper->initialize();
82 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
83 stepper->setICConsistency(ICConsistency);
84 stepper->initialize();
85 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
86 stepper->setICConsistencyCheck(ICConsistencyCheck);
87 stepper->initialize();
88 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
89 stepper->setZeroInitialGuess(zeroInitialGuess);
90 stepper->initialize();
91 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
92
93 stepper->setStepperName(stepperType);
94 stepper->initialize();
95 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
96 stepper->setExplicitTableau(explicitTableau);
97 stepper->initialize();
98 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
99 stepper->setImplicitTableau(implicitTableau);
100 stepper->initialize();
101 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
102 stepper->setOrder(order);
103 stepper->initialize();
104 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
105
106 TEUCHOS_TEST_FOR_EXCEPT(explicitTableau != stepper->getTableau());
107 TEUCHOS_TEST_FOR_EXCEPT(explicitTableau != stepper->getExplicitTableau());
108 TEUCHOS_TEST_FOR_EXCEPT(implicitTableau != stepper->getImplicitTableau());
109
110 // Full argument list construction.
111 stepper = rcp(new Tempus::StepperIMEX_RK<double>(
112 model, solver, useFSAL, ICConsistency, ICConsistencyCheck,
113 zeroInitialGuess, modifier, stepperType, explicitTableau, implicitTableau,
114 order));
115 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
116
117 // Test stepper properties.
118 TEUCHOS_ASSERT(stepper->getOrder() == 2);
119}
120
121// ************************************************************
122// ************************************************************
123TEUCHOS_UNIT_TEST(IMEX_RK, StepperFactory_Construction)
124{
125 // Setup the IMEX Pair ModelEvaluator
126 auto explicitModel =
128 auto implicitModel =
131 explicitModel, implicitModel));
132
133 testFactoryConstruction("IMEX RK SSP2", model);
134}
135
136// ************************************************************
137// ************************************************************
138TEUCHOS_UNIT_TEST(IMEX_RK, StepperFactory_Construction_General_wo_Parameterlist)
139{
140 // Setup the IMEX Pair ModelEvaluator
141 auto explicitModel =
143 auto implicitModel =
146 explicitModel, implicitModel));
147
148 RCP<StepperFactory<double>> sf = Teuchos::rcp(new StepperFactory<double>());
149
150 auto stepper = sf->createStepper("General IMEX RK", model);
151 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
152}
153
154// ************************************************************
155// ************************************************************
157 StepperFactory_Construction_General_wo_Parameterlist_Model)
158{
159 // Setup the IMEX Pair ModelEvaluator
160 auto explicitModel =
162 auto implicitModel =
165 explicitModel, implicitModel));
166
167 RCP<StepperFactory<double>> sf = Teuchos::rcp(new StepperFactory<double>());
168
169 auto stepper = sf->createStepper("General IMEX RK");
170 stepper->setModel(model);
171 stepper->initialize();
172 TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized());
173}
174
175// ************************************************************
176// ************************************************************
177TEUCHOS_UNIT_TEST(IMEX_RK, AppAction)
178{
179 auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
180 // Setup the IMEX Pair ModelEvaluator
181 auto explicitModel =
183 auto implicitModel =
186 explicitModel, implicitModel));
187
188 testRKAppAction(stepper, model, out, success);
189}
190
191class StepperRKModifierIMEX_TrapezoidaTest
192 : virtual public Tempus::StepperRKModifierBase<double> {
193 public:
195 StepperRKModifierIMEX_TrapezoidaTest(Teuchos::FancyOStream &Out,
196 bool &Success)
197 : out(Out), success(Success)
198 {
199 }
200
201 // FSAL
203 virtual ~StepperRKModifierIMEX_TrapezoidaTest() {}
204
206 virtual void modify(
207 Teuchos::RCP<Tempus::SolutionHistory<double>> sh,
208 Teuchos::RCP<Tempus::StepperRKBase<double>> stepper,
210 {
211 const double relTol = 1.0e-14;
212 auto stepper_imex =
213 Teuchos::rcp_dynamic_cast<const Tempus::StepperIMEX_RK<double>>(stepper,
214 true);
215 auto stageNumber = stepper->getStageNumber();
216 Teuchos::SerialDenseVector<int, double> c = stepper_imex->getTableau()->c();
217 Teuchos::SerialDenseVector<int, double> chat =
218 stepper_imex->getImplicitTableau()->c();
219
220 auto currentState = sh->getCurrentState();
221 auto workingState = sh->getWorkingState();
222 const double dt = workingState->getTimeStep();
223 double time = currentState->getTime();
224 double imp_time = time;
225 if (stageNumber >= 0) {
226 time += c(stageNumber) * dt;
227 imp_time += chat(stageNumber) * dt;
228 }
229
230 auto x = workingState->getX();
231 auto xDot = workingState->getXDot();
232 if (xDot == Teuchos::null) xDot = stepper->getStepperXDot();
233
234 switch (actLoc) {
235 case StepperRKAppAction<double>::BEGIN_STEP: {
236 {
237 auto imex_me = Teuchos::rcp_dynamic_cast<
239 stepper->getModel(), true);
240 auto explicitModel = Teuchos::rcp_dynamic_cast<
242 imex_me->getExplicitModel(), true);
243 auto implicitModel = Teuchos::rcp_dynamic_cast<
245 imex_me->getImplicitModel(), true);
246
247 TEST_FLOATING_EQUALITY(explicitModel->getLambda(), 1.0, relTol);
248 TEST_FLOATING_EQUALITY(implicitModel->getLambda(), 2.0, relTol);
249 }
250 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
251
252 const double x_0 = get_ele(*(x), 0);
253 TEST_FLOATING_EQUALITY(x_0, 1.0, relTol);
254 TEST_ASSERT(std::abs(time) < relTol);
255 TEST_ASSERT(std::abs(imp_time) < relTol);
256 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
257 TEST_COMPARE(stageNumber, ==, -1);
258 break;
259 }
260 case StepperRKAppAction<double>::BEGIN_STAGE:
261 case StepperRKAppAction<double>::BEFORE_SOLVE: {
262 const double X_i = get_ele(*(x), 0);
263 const double f_i = get_ele(*(xDot), 0);
264
265 if (stageNumber == 0) {
266 TEST_FLOATING_EQUALITY(X_i, 1.0, relTol); // 1
267 TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
268 TEST_FLOATING_EQUALITY(imp_time, 0.78867513459481275, relTol); // 1
269 TEST_ASSERT(std::abs(time) < relTol);
270 }
271 else if (stageNumber == 1) {
272 TEST_FLOATING_EQUALITY(X_i, -std::sqrt(3), relTol); // -sqrt(3)
273 TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
274 TEST_FLOATING_EQUALITY(time, 1.0, relTol);
275 TEST_FLOATING_EQUALITY(imp_time, 0.21132486540518725, relTol); // 1
276 }
277 else {
278 TEUCHOS_TEST_FOR_EXCEPT(!(-1 < stageNumber && stageNumber < 2));
279 }
280
281 break;
282 }
283 case StepperRKAppAction<double>::AFTER_SOLVE:
284 case StepperRKAppAction<double>::BEFORE_EXPLICIT_EVAL:
285 case StepperRKAppAction<double>::END_STAGE: {
286 const double X_i = get_ele(*(x), 0);
287 const double f_i = get_ele(*(xDot), 0);
288
289 if (stageNumber == 0) {
290 // X_i = 1, f_1 = 0
291 TEST_FLOATING_EQUALITY(X_i, -std::sqrt(3), relTol); // -sqrt(3)
292 TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
293 TEST_FLOATING_EQUALITY(imp_time, 0.78867513459481275, relTol); // 1
294 TEST_ASSERT(std::abs(time) < relTol);
295 }
296 else if (stageNumber == 1) {
297 // X_i = , f_i =
298 TEST_FLOATING_EQUALITY(X_i, 3.0 - 3.0 * std::sqrt(3.0),
299 relTol); // -3sqrt(3) - 3
300 TEST_FLOATING_EQUALITY(f_i, 1.0, relTol); // 1
301 TEST_FLOATING_EQUALITY(time, 1.0, relTol);
302 }
303 else {
304 TEUCHOS_TEST_FOR_EXCEPT(!(-1 < stageNumber && stageNumber < 2));
305 }
306
307 break;
308 }
309 case StepperRKAppAction<double>::END_STEP: {
310 const double x_1 = get_ele(*(x), 0);
311 time = workingState->getTime();
312 TEST_FLOATING_EQUALITY(x_1, -(6.0 * std::sqrt(3) - 11.0 / 2.0),
313 relTol); // -( 6sqrt(3) - 11/2)
314 TEST_FLOATING_EQUALITY(time, 1.0, relTol);
315 TEST_FLOATING_EQUALITY(dt, 1.0, relTol);
316 TEST_COMPARE(stageNumber, ==, -1);
317 }
318 }
319 }
320
321 private:
322 Teuchos::FancyOStream &out;
323 bool &success;
324};
325
326// ************************************************************
327// ************************************************************
328TEUCHOS_UNIT_TEST(IMEX_RK, IMEX_RK_Modifier)
329{
330 Teuchos::RCP<const Thyra::ModelEvaluator<double>> explicitModel =
331 rcp(new Tempus_Test::DahlquistTestModel<double>(1.0, true));
332 Teuchos::RCP<const Thyra::ModelEvaluator<double>> implicitModel =
333 rcp(new Tempus_Test::DahlquistTestModel<double>(2.0, true));
334
336 explicitModel, implicitModel));
337
338 auto modifier = rcp(new StepperRKModifierIMEX_TrapezoidaTest(out, success));
339
340 // Default construction.
341 auto stepper = rcp(new Tempus::StepperIMEX_RK<double>());
342 stepper->setModel(model);
343
344 // Default values for construction.
345 auto solver = rcp(new Thyra::NOXNonlinearSolver());
346 solver->setParameterList(Tempus::defaultSolverParameters());
347
348 bool useFSAL = stepper->getUseFSAL();
349 std::string ICConsistency = stepper->getICConsistency();
350 bool ICConsistencyCheck = stepper->getICConsistencyCheck();
351 bool zeroInitialGuess = stepper->getZeroInitialGuess();
352 std::string stepperType = "IMEX RK SSP2";
353 auto stepperERK = Teuchos::rcp(new Tempus::StepperERK_Trapezoidal<double>());
354 auto explicitTableau = stepperERK->getTableau();
355 auto stepperSDIRK =
357 auto implicitTableau = stepperSDIRK->getTableau();
358 int order = 2;
359
360 stepper->setStepperName(stepperType);
361 stepper->setExplicitTableau(explicitTableau);
362 stepper->setImplicitTableau(implicitTableau);
363 stepper->setOrder(order);
364 stepper->setSolver(solver);
365 stepper->setUseFSAL(useFSAL);
366 stepper->setICConsistency(ICConsistency);
367 stepper->setICConsistencyCheck(ICConsistencyCheck);
368 stepper->setZeroInitialGuess(zeroInitialGuess);
369
370 stepper->setModel(model);
371 stepper->setAppAction(modifier);
372 stepper->setUseFSAL(false);
373 stepper->initialize();
374
375 // Create a SolutionHistory.
376 auto solutionHistory = Tempus::createSolutionHistoryME(explicitModel);
377
379 stepper->setInitialConditions(solutionHistory);
380 solutionHistory->initWorkingState();
381 double dt = 1.0;
382 solutionHistory->getWorkingState()->setTimeStep(dt);
383 solutionHistory->getWorkingState()->setTime(dt);
384 stepper->takeStep(solutionHistory);
385
386 // Test stepper properties.
387 TEUCHOS_ASSERT(stepper->getOrder() == 2);
388}
389
390} // namespace Tempus_Unit_Test
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Explicit Runge-Kutta time stepper.
Implicit-Explicit Runge-Kutta (IMEX-RK) time stepper.
ACTION_LOCATION
Indicates the location of application action (see algorithm).
Base class for Runge-Kutta methods, ExplicitRK, DIRK and IMEX.
ModelEvaluator pair for implicit and explicit (IMEX) evaulations.
The classic Dahlquist Test Problem.
void testRKAppAction(const Teuchos::RCP< Tempus::StepperRKBase< double > > &stepper, const Teuchos::RCP< const Thyra::ModelEvaluator< double > > &model, Teuchos::FancyOStream &out, bool &success)
Unit test utility for Stepper RK AppAction.
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.