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