Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_TimeStepControlStrategyIntegralController.hpp
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
10#ifndef Tempus_TimeStepControlStrategy_IntegralController_hpp
11#define Tempus_TimeStepControlStrategy_IntegralController_hpp
12
13#include "Tempus_config.hpp"
16#include "Tempus_SolutionState.hpp"
17#include "Tempus_SolutionHistory.hpp"
19
20namespace Tempus {
21
58template <class Scalar>
60 : virtual public TimeStepControlStrategy<Scalar> {
61 public:
64 : controller_("PID"),
65 KI_(0.58),
66 KP_(0.21),
67 KD_(0.10),
68 safetyFactor_(0.90),
70 facMax_(5.0),
71 facMin_(0.5)
72 {
74
75 this->setStrategyType("Integral Controller");
76 this->setStepType("Variable");
77 this->setName("Integral Controller");
78 this->initialize();
79 }
80
83 std::string controller, Scalar KI, Scalar KP, Scalar KD,
84 Scalar safetyFactor, Scalar safetyFactorAfterReject, Scalar facMax,
85 Scalar facMin, std::string name = "Integral Controller")
86 : controller_(controller),
87 KI_(KI),
88 KP_(KP),
89 KD_(KD),
90 safetyFactor_(safetyFactor),
91 safetyFactorAfterReject_(safetyFactorAfterReject),
92 facMax_(facMax),
93 facMin_(facMin)
94 {
96
97 this->setStrategyType("Integral Controller");
98 this->setStepType("Variable");
99 this->setName(name);
100 this->initialize();
101 }
102
105
107 virtual void setNextTimeStep(
108 const TimeStepControl<Scalar> &tsc,
109 Teuchos::RCP<SolutionHistory<Scalar> > solutionHistory,
110 Status & /* integratorStatus */) override
111 {
112 using Teuchos::RCP;
113
114 this->checkInitialized();
115
116 // Take first step with initial time step provided
119 return;
120 }
121
122 RCP<SolutionState<Scalar> > workingState =
123 solutionHistory->getWorkingState();
124 Scalar beta = 1.0;
125
126 // assumes the embedded solution is the low order solution
127 int order = workingState->getOrder() - 1;
128 Scalar dt = workingState->getTimeStep();
129
130 // Get the relative errors.
131 Scalar errN = workingState->getErrorRel();
132 Scalar errNm1 = workingState->getErrorRelNm1();
133 Scalar errNm2 = workingState->getErrorRelNm2();
134
135 if (errN < numericalTol<Scalar>()) errN = 1.0;
136 if (errNm1 < numericalTol<Scalar>()) errNm1 = 1.0;
137 if (errNm2 < numericalTol<Scalar>()) errNm2 = 1.0;
138
139 Scalar k1 = Teuchos::as<Scalar>(-KI_ / order);
140 Scalar k2 = Teuchos::as<Scalar>(KP_ / order);
141 Scalar k3 = Teuchos::as<Scalar>(-KD_ / order);
142
143 k1 = std::pow(errN, k1);
144 k2 = std::pow(errNm1, k2);
145 k3 = std::pow(errNm2, k3);
146
147 if (controller_ == "I")
148 beta = safetyFactor_ * k1;
149 else if (controller_ == "PI")
150 beta = safetyFactor_ * k1 * k2;
151 else // (controller_ == "PID")
152 beta = safetyFactor_ * k1 * k2 * k3;
153
154 beta = std::max(facMin_, beta);
155 beta = std::min(facMax_, beta);
156
157 // new (optimal) suggested time step
158 dt = beta * dt;
159
160 if (workingState->getSolutionStatus() == Status::PASSED ||
161 workingState->getSolutionStatus() == Status::WORKING) {
162 if (lastStepRejected_) {
163 dt = std::min(dt, workingState->getTimeStep());
164 }
165 else {
167 }
168 lastStepRejected_ = false;
169 }
170 else {
172 lastStepRejected_ = true;
173 }
174
175 // update dt
176 workingState->setTimeStep(dt);
177 workingState->setTime(solutionHistory->getCurrentState()->getTime() + dt);
178 }
179
181
182 std::string description() const override
183 {
184 return "Tempus::TimeStepControlStrategyIntegralController";
185 }
186
187 void describe(Teuchos::FancyOStream &out,
188 const Teuchos::EVerbosityLevel verbLevel) const override
189 {
190 auto l_out = Teuchos::fancyOStream(out.getOStream());
191 Teuchos::OSTab ostab(*l_out, 2, this->description());
192 l_out->setOutputToRootOnly(0);
193
194 *l_out << "\n--- " << this->description() << " ---" << std::endl;
195
196 if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_MEDIUM)) {
197 *l_out << " Strategy Type = "
198 << this->getStrategyType() << std::endl
199 << " Step Type = " << this->getStepType()
200 << std::endl
201 << " Controller Type = " << getController()
202 << std::endl
203 << " KI = " << getKI()
204 << std::endl
205 << " KP = " << getKP()
206 << std::endl
207 << " KD = " << getKD()
208 << std::endl
209 << " Safety Factor = " << getSafetyFactor()
210 << std::endl
211 << " Safety Factor After Step Rejection = "
212 << getSafetyFactorAfterReject() << std::endl
213 << " Maximum Safety Factor (INPUT) = " << facMaxINPUT_
214 << std::endl
215 << " Maximum Safety Factor = " << getFacMax()
216 << std::endl
217 << " Minimum Safety Factor = " << getFacMin()
218 << std::endl;
219 *l_out << std::string(this->description().length() + 8, '-') << std::endl;
220 }
221 }
223
225 virtual Teuchos::RCP<const Teuchos::ParameterList> getValidParameters()
226 const override
227 {
228 Teuchos::RCP<Teuchos::ParameterList> pl =
229 Teuchos::parameterList("Time Step Control Strategy");
230
231 pl->set<std::string>("Strategy Type", this->getStrategyType(),
232 "Integral Controller");
233 pl->set<std::string>("Controller Type", getController(),
234 "Proportional-Integral-Derivative");
235 pl->set<Scalar>("KI", getKI(), "Integral gain");
236 pl->set<Scalar>("KP", getKP(), "Proportional gain");
237 pl->set<Scalar>("KD", getKD(), "Derivative gain");
238 pl->set<Scalar>("Safety Factor", getSafetyFactor(), "Safety Factor");
239 pl->set<Scalar>("Safety Factor After Step Rejection",
241 "Safety Factor Following Step Rejection");
242 pl->set<Scalar>("Maximum Safety Factor", getFacMax(),
243 "Maximum Safety Factor");
244 pl->set<Scalar>("Minimum Safety Factor", getFacMin(),
245 "Minimum Safety Factor");
246 return pl;
247 }
248
249 virtual void initialize() const override
250 {
251 TEUCHOS_TEST_FOR_EXCEPTION(safetyFactor_ <= 0.0, std::out_of_range,
252 "Error - Invalid value of Safety Factory= "
253 << safetyFactor_ << "! \n"
254 << "Safety Factor must be > 0.0.\n");
255
256 TEUCHOS_TEST_FOR_EXCEPTION(
257 facMax_ <= 0.0, std::out_of_range,
258 "Error - Invalid value of Maximum Safety Factory= "
259 << facMax_ << "! \n"
260 << "Maximum Safety Factor must be > 0.0.\n");
261
262 TEUCHOS_TEST_FOR_EXCEPTION(
263 facMax_ <= 0.0, std::out_of_range,
264 "Error - Invalid value of Minimum Safety Factory= "
265 << facMin_ << "! \n"
266 << "Minimum Safety Factor must be > 0.0.\n");
267
268 TEUCHOS_TEST_FOR_EXCEPTION(((controller_ != "I") && (controller_ != "PI") &&
269 (controller_ != "PID")),
270 std::invalid_argument,
271 "Error - Invalid choice of Controller Type = "
272 << controller_ << "! \n"
273 << "Valid Choice are ['I', 'PI', 'PID'].\n");
274
275 this->isInitialized_ = true; // Only place where this is set to true!
276 }
277
278 virtual std::string getController() const { return controller_; }
279 virtual Scalar getKI() const { return KI_; }
280 virtual Scalar getKP() const { return KP_; }
281 virtual Scalar getKD() const { return KD_; }
282 virtual Scalar getSafetyFactor() const { return safetyFactor_; }
283 virtual Scalar getSafetyFactorAfterReject() const
284 {
286 }
287 virtual Scalar getFacMax() const { return facMax_; }
288 virtual Scalar getFacMin() const { return facMin_; }
289
290 virtual void setController(std::string c)
291 {
292 controller_ = c;
293 this->isInitialized_ = false;
294 }
295 virtual void setKI(Scalar k)
296 {
297 KI_ = k;
298 this->isInitialized_ = false;
299 }
300 virtual void setKP(Scalar k)
301 {
302 KP_ = k;
303 this->isInitialized_ = false;
304 }
305 virtual void setKD(Scalar k)
306 {
307 KD_ = k;
308 this->isInitialized_ = false;
309 }
310 virtual void setSafetyFactor(Scalar f)
311 {
312 safetyFactor_ = f;
313 this->isInitialized_ = false;
314 }
315 virtual void setSafetyFactorAfterReject(Scalar f)
316 {
318 this->isInitialized_ = false;
319 }
320 virtual void setFacMax(Scalar f)
321 {
322 facMax_ = f;
323 facMaxINPUT_ = f;
324 this->isInitialized_ = false;
325 }
326 virtual void setFacMin(Scalar f)
327 {
328 facMin_ = f;
329 this->isInitialized_ = false;
330 }
331
332 private:
333 std::string controller_;
334 Scalar KI_;
335 Scalar KP_;
336 Scalar KD_;
340 Scalar facMax_;
341 Scalar facMin_;
343 bool lastStepRejected_ = false;
344};
345
346// Nonmember constructor.
347template <class Scalar>
348Teuchos::RCP<TimeStepControlStrategyIntegralController<Scalar> >
350 const Teuchos::RCP<Teuchos::ParameterList> pList,
351 std::string name = "Integral Controller")
352{
353 using Teuchos::rcp;
355 if (pList == Teuchos::null || pList->numParams() == 0) return tscs;
356
357 TEUCHOS_TEST_FOR_EXCEPTION(
358 pList->get<std::string>("Strategy Type") != "Integral Controller",
359 std::logic_error,
360 "Error - Strategy Type != 'Integral Controller'. (='" +
361 pList->get<std::string>("Strategy Type") + "')\n");
362
363 pList->validateParametersAndSetDefaults(*tscs->getValidParameters());
364
365 tscs->setController(pList->get<std::string>("Controller Type"));
366 tscs->setKI(pList->get<Scalar>("KI"));
367 tscs->setKP(pList->get<Scalar>("KP"));
368 tscs->setKD(pList->get<Scalar>("KD"));
369 tscs->setSafetyFactor(pList->get<Scalar>("Safety Factor"));
370 tscs->setSafetyFactorAfterReject(
371 pList->get<Scalar>("Safety Factor After Step Rejection"));
372 tscs->setFacMax(pList->get<Scalar>("Maximum Safety Factor"));
373 tscs->setFacMin(pList->get<Scalar>("Minimum Safety Factor"));
374
375 tscs->setName(name);
376 tscs->initialize();
377
378 return tscs;
379}
380
382template <class Scalar>
383Teuchos::RCP<Teuchos::ParameterList>
385{
387 return Teuchos::rcp_const_cast<Teuchos::ParameterList>(
388 t->getValidParameters());
389}
390
391} // namespace Tempus
392#endif // Tempus_TimeStepControlStrategy_IntegralController_hpp
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
TimeStepControl manages the time step size. There several mechanisms that effect the time step size a...
TimeStepControlStrategy class for TimeStepControl.
bool isInitialized_
Bool if strategy is initialized.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const override
virtual Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const override
Return ParameterList with current values.
TimeStepControlStrategyIntegralController(std::string controller, Scalar KI, Scalar KP, Scalar KD, Scalar safetyFactor, Scalar safetyFactorAfterReject, Scalar facMax, Scalar facMin, std::string name="Integral Controller")
Full Constructor.
virtual void setNextTimeStep(const TimeStepControl< Scalar > &tsc, Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory, Status &) override
Set the time step size.
Status
Status for the Integrator, the Stepper and the SolutionState.
Teuchos::RCP< Teuchos::ParameterList > getTimeStepControlStrategyIntegralControllerPL()
Nonmember function to return ParameterList with default values.
Teuchos::RCP< TimeStepControlStrategyIntegralController< Scalar > > createTimeStepControlStrategyIntegralController(const Teuchos::RCP< Teuchos::ParameterList > pList, std::string name="Integral Controller")