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...
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.
TimeStepControlStrategy class for TimeStepControl.
bool isInitialized_
Bool if strategy is initialized.
TimeStepControl manages the time step size. There several mechanisms that effect the time step size a...
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")