Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_UnitTest_TimeStepControlStrategyIntegralController.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 "Tempus_TimeStepControl.hpp"
14 
15 #include "../TestModels/DahlquistTestModel.hpp"
16 
17 namespace Tempus_Unit_Test {
18 
20 using Teuchos::RCP;
21 using Teuchos::rcp;
22 using Teuchos::rcp_const_cast;
23 using Teuchos::rcp_dynamic_cast;
24 using Teuchos::sublist;
25 
26 // ************************************************************
27 // ************************************************************
28 TEUCHOS_UNIT_TEST(TimeStepControlStrategyIntegralController,
29  Default_Construction)
30 {
31  auto tscs =
33  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
34 
35  // Test the get functions (i.e., defaults).
36  TEUCHOS_TEST_FOR_EXCEPT(tscs->getStepType() != "Variable");
37  TEUCHOS_TEST_FOR_EXCEPT(tscs->getController() != "PID");
38  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKI() != 0.58);
39  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKP() != 0.21);
40  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKD() != 0.10);
41  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactor() != 0.90);
42  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactorAfterReject() != 0.90);
43  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMax() != 5.0);
44  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMin() != 0.5);
45 
46  // Test the set functions.
47  tscs->setController("I");
48  tscs->initialize();
49  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
50  tscs->setKI(0.6);
51  tscs->initialize();
52  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
53  tscs->setKP(0.0);
54  tscs->initialize();
55  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
56  tscs->setKD(0.0);
57  tscs->initialize();
58  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
59  tscs->setSafetyFactor(0.8);
60  tscs->initialize();
61  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
62  tscs->setSafetyFactorAfterReject(0.8);
63  tscs->initialize();
64  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
65  tscs->setFacMax(4.0);
66  tscs->initialize();
67  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
68  tscs->setFacMin(0.4);
69  tscs->initialize();
70  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
71 
72  TEUCHOS_TEST_FOR_EXCEPT(tscs->getStepType() != "Variable");
73  TEUCHOS_TEST_FOR_EXCEPT(tscs->getController() != "I");
74  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKI() != 0.6);
75  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKP() != 0.0);
76  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKD() != 0.0);
77  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactor() != 0.8);
78  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactorAfterReject() != 0.8);
79  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMax() != 4.0);
80  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMin() != 0.4);
81 }
82 
83 // ************************************************************
84 // ************************************************************
85 TEUCHOS_UNIT_TEST(TimeStepControlStrategyIntegralController, Full_Construction)
86 {
88  "I", 0.6, 0.0, 0.0, 0.8, 0.8, 4.0, 0.4));
89  TEUCHOS_TEST_FOR_EXCEPT(!tscs->isInitialized());
90 
91  TEUCHOS_TEST_FOR_EXCEPT(tscs->getStepType() != "Variable");
92  TEUCHOS_TEST_FOR_EXCEPT(tscs->getController() != "I");
93  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKI() != 0.6);
94  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKP() != 0.0);
95  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKD() != 0.0);
96  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactor() != 0.8);
97  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactorAfterReject() != 0.8);
98  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMax() != 4.0);
99  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMin() != 0.4);
100 }
101 
102 // ************************************************************
103 // ************************************************************
104 TEUCHOS_UNIT_TEST(TimeStepControlStrategyIntegralController,
105  Create_Construction)
106 {
107  auto pl = Tempus::getTimeStepControlStrategyIntegralControllerPL<double>();
108 
109  pl->set<std::string>("Controller Type", "I");
110  pl->set<double>("KI", 0.6);
111  pl->set<double>("KP", 0.0);
112  pl->set<double>("KD", 0.0);
113  pl->set<double>("Safety Factor", 0.8);
114  pl->set<double>("Safety Factor After Step Rejection", 0.8);
115  pl->set<double>("Maximum Safety Factor", 4.0);
116  pl->set<double>("Minimum Safety Factor", 0.4);
117 
118  auto tscs =
119  Tempus::createTimeStepControlStrategyIntegralController<double>(pl);
120 
121  TEUCHOS_TEST_FOR_EXCEPT(tscs->getStepType() != "Variable");
122  TEUCHOS_TEST_FOR_EXCEPT(tscs->getController() != "I");
123  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKI() != 0.6);
124  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKP() != 0.0);
125  TEUCHOS_TEST_FOR_EXCEPT(tscs->getKD() != 0.0);
126  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactor() != 0.8);
127  TEUCHOS_TEST_FOR_EXCEPT(tscs->getSafetyFactorAfterReject() != 0.8);
128  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMax() != 4.0);
129  TEUCHOS_TEST_FOR_EXCEPT(tscs->getFacMin() != 0.4);
130 }
131 
132 // ************************************************************
133 // ************************************************************
134 TEUCHOS_UNIT_TEST(TimeStepControlStrategyIntegralController, setNextTimeStep)
135 {
136  double KI = 0.5;
137  double KP = 0.25;
138  double KD = 0.15;
139  double safetyFactor = 0.9;
140  double safetyFactorAfterReject = 0.9;
141  double facMax = 5.0;
142  double facMin = 0.5;
143 
145  "PID", KI, KP, KD, safetyFactor, safetyFactorAfterReject, facMax,
146  facMin));
147 
148  // Setup the TimeStepControl --------------------------------
149  auto tsc = rcp(new Tempus::TimeStepControl<double>());
150  tsc->setTimeStepControlStrategy(tscs);
151  tsc->setInitTime(0.0);
152  tsc->setFinalTime(10.0);
153  tsc->setMinTimeStep(0.01);
154  tsc->setInitTimeStep(1.0);
155  tsc->setMaxTimeStep(10.0);
156  tsc->setFinalIndex(100);
157  tsc->initialize();
158  TEUCHOS_TEST_FOR_EXCEPT(!tsc->isInitialized());
160 
161  // Setup the SolutionHistory --------------------------------
162  auto model = rcp(new Tempus_Test::DahlquistTestModel<double>());
163  auto inArgsIC = model->getNominalValues();
164  auto icSolution =
165  rcp_const_cast<Thyra::VectorBase<double> >(inArgsIC.get_x());
166  auto icState = Tempus::createSolutionStateX<double>(icSolution);
167  auto solutionHistory = rcp(new Tempus::SolutionHistory<double>());
168 
169  double order = 2.0;
170  solutionHistory->addState(icState);
171  solutionHistory->getCurrentState()->setTimeStep(1.0);
172  solutionHistory->getCurrentState()->setTime(0.0);
173  solutionHistory->getCurrentState()->setIndex(0);
174  solutionHistory->getCurrentState()->setOrder(order);
175 
176  // Mock Integrator
177 
178  // -- First Time Step
179  solutionHistory->initWorkingState();
180  auto currentState = solutionHistory->getCurrentState();
181  auto workingState = solutionHistory->getWorkingState();
182 
183  TEST_FLOATING_EQUALITY(workingState->getErrorRel(), 0.0, 1.0e-14);
184  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm1(), 0.0, 1.0e-14);
185  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm2(), 0.0, 1.0e-14);
186 
187  tsc->setNextTimeStep(solutionHistory, status);
188 
189  // First time step should cause no change to dt because
190  // internal relative errors = 1.
191  TEST_FLOATING_EQUALITY(workingState->getTimeStep(), 1.0, 1.0e-14);
192 
193  // Mock takeStep
194  double errN = 0.1;
195  workingState->setErrorRel(errN);
196  workingState->setSolutionStatus(Tempus::Status::PASSED);
197 
198  // -- Second Time Step
199  solutionHistory->initWorkingState();
200  currentState = solutionHistory->getCurrentState();
201  workingState = solutionHistory->getWorkingState();
202  double dt = workingState->getTimeStep();
203 
204  TEST_FLOATING_EQUALITY(workingState->getErrorRel(), 0.1, 1.0e-14);
205  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm1(), 0.0, 1.0e-14);
206  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm2(), 0.0, 1.0e-14);
207 
208  tsc->setNextTimeStep(solutionHistory, status);
209 
210  double p = order - 1.0;
211  double dtNew = dt * safetyFactor * std::pow(errN, -KI / p);
212  TEST_FLOATING_EQUALITY(workingState->getTimeStep(), dtNew, 1.0e-14);
213 
214  // Mock takeStep
215  errN = 0.2;
216  double errNm1 = 0.1;
217  workingState->setErrorRel(errN);
218  workingState->setSolutionStatus(Tempus::Status::PASSED);
219 
220  // -- Third Time Step
221  solutionHistory->initWorkingState();
222  currentState = solutionHistory->getCurrentState();
223  workingState = solutionHistory->getWorkingState();
224  dt = workingState->getTimeStep();
225 
226  TEST_FLOATING_EQUALITY(workingState->getErrorRel(), 0.2, 1.0e-14);
227  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm1(), 0.1, 1.0e-14);
228  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm2(), 0.0, 1.0e-14);
229 
230  tsc->setNextTimeStep(solutionHistory, status);
231 
232  dtNew =
233  dt * safetyFactor * std::pow(errN, -KI / p) * std::pow(errNm1, KP / p);
234  TEST_FLOATING_EQUALITY(workingState->getTimeStep(), dtNew, 1.0e-14);
235 
236  // Mock takeStep
237  errN = 0.3;
238  errNm1 = 0.2;
239  double errNm2 = 0.1;
240  workingState->setErrorRel(errN);
241  workingState->setSolutionStatus(Tempus::Status::PASSED);
242 
243  // -- Fourth Time Step
244  solutionHistory->initWorkingState();
245  currentState = solutionHistory->getCurrentState();
246  workingState = solutionHistory->getWorkingState();
247  dt = workingState->getTimeStep();
248 
249  TEST_FLOATING_EQUALITY(workingState->getErrorRel(), 0.3, 1.0e-14);
250  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm1(), 0.2, 1.0e-14);
251  TEST_FLOATING_EQUALITY(workingState->getErrorRelNm2(), 0.1, 1.0e-14);
252 
253  tsc->setNextTimeStep(solutionHistory, status);
254 
255  dtNew = dt * safetyFactor * std::pow(errN, -KI / p) *
256  std::pow(errNm1, KP / p) * std::pow(errNm2, -KD / p);
257  TEST_FLOATING_EQUALITY(workingState->getTimeStep(), dtNew, 1.0e-14);
258 }
259 
260 // ************************************************************
261 // ************************************************************
262 TEUCHOS_UNIT_TEST(TimeStepControlStrategyIntegralController, getValidParameters)
263 {
264  auto tscs =
266 
267  auto pl = tscs->getValidParameters();
268 
269  TEST_COMPARE(pl->get<std::string>("Strategy Type"), ==,
270  "Integral Controller");
271  TEST_COMPARE(pl->get<std::string>("Controller Type"), ==, "PID");
272  TEST_FLOATING_EQUALITY(pl->get<double>("KI"), 0.58, 1.0e-14);
273  TEST_FLOATING_EQUALITY(pl->get<double>("KP"), 0.21, 1.0e-14);
274  TEST_FLOATING_EQUALITY(pl->get<double>("KD"), 0.10, 1.0e-14);
275  TEST_FLOATING_EQUALITY(pl->get<double>("Safety Factor"), 0.9, 1.0e-14);
276  TEST_FLOATING_EQUALITY(pl->get<double>("Safety Factor After Step Rejection"),
277  0.9, 1.0e-14);
278  TEST_FLOATING_EQUALITY(pl->get<double>("Maximum Safety Factor"), 5.0,
279  1.0e-14);
280  TEST_FLOATING_EQUALITY(pl->get<double>("Minimum Safety Factor"), 0.5,
281  1.0e-14);
282 
283  { // Ensure that parameters are "used", excluding sublists.
284  std::ostringstream unusedParameters;
285  pl->unused(unusedParameters);
286  TEST_COMPARE(unusedParameters.str(), ==, "");
287  }
288 }
289 
290 } // namespace Tempus_Unit_Test
The classic Dahlquist Test Problem.
#define TEST_COMPARE(v1, comp, v2)
#define TEST_FLOATING_EQUALITY(v1, v2, tol)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Status
Status for the Integrator, the Stepper and the SolutionState.
TEUCHOS_UNIT_TEST(BackwardEuler, Default_Construction)
TimeStepControl manages the time step size. There several mechanisms that effect the time step size a...
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)