Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_TimeStepControlStrategyPID.hpp
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 
9 #ifndef Tempus_TimeStepControlStrategy_PID_hpp
10 #define Tempus_TimeStepControlStrategy_PID_hpp
11 
12 #include "Tempus_TimeStepControl.hpp"
14 #include "Tempus_SolutionState.hpp"
15 #include "Tempus_SolutionHistory.hpp"
16 #include "Tempus_StepperState.hpp"
17 
18 
19 namespace Tempus {
20 
21 /** \brief StepControlStrategy class for TimeStepControl
22  *
23  */
24 template<class Scalar>
26  : virtual public TimeStepControlStrategy<Scalar>
27 {
28 public:
29 
30  /// Constructor
31  TimeStepControlStrategyPID(Teuchos::RCP<Teuchos::ParameterList> pList = Teuchos::null){
32  this->setParameterList(pList);
33  }
34 
35  /// Destructor
37 
38  /** \brief Determine the time step size.*/
39  virtual void getNextTimeStep(const TimeStepControl<Scalar> tsc,
40  Teuchos::RCP<SolutionHistory<Scalar> > solutionHistory,
41  Status & integratorStatus) override
42  {
43 
44  // Take first step with initial time step provided
46  firstSuccessfulStep_ = true;
47  return;
48  }
49 
50  Teuchos::RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
51  const Scalar errorAbs = workingState->getErrorAbs();
52  volatile const int iStep = workingState->getIndex();
53  volatile const Scalar errorRel = workingState->getErrorRel();
54  int order = workingState->getOrder();
55  Scalar dt = workingState->getTimeStep();
56  //bool printDtChanges = tsc.getPrintDtChanges();
57 
58  Teuchos::RCP<Teuchos::FancyOStream> out = tsc.getOStream();
59  Teuchos::OSTab ostab(out,1,"getNextTimeStep");
60 
61  // For now, only time step is changed (not order)
62  /*
63  auto changeOrder = [] (int order_old, int order_new, std::string reason) {
64  std::stringstream message;
65  message << " (order = " << std::setw(2) << order_old
66  << ", new = " << std::setw(2) << order_new
67  << ") " << reason << std::endl;
68  return message.str();
69  };
70  */
71 
72  // update errors
73  errNm2_ = errNm1_;
74  errNm1_ = errN_;
75  errN_ = errorRel;
76 
77  Scalar k1 = Teuchos::as<Scalar>(-k1_ / order);
78  Scalar k2 = Teuchos::as<Scalar>(k2_ / order);
79  Scalar k3 = Teuchos::as<Scalar>(-k3_ / order);
80 
81  k1 = std::pow(errN_, k1);
82  k2 = std::pow(errNm1_, k2);
83  k3 = std::pow(errNm2_, k3);
84  Scalar beta = safetyFactor_*k1*k2*k3;
85  beta = std::max(facMin_, beta);
86  beta = std::min(facMax_, beta);
87 
88  // new (optimal) suggested time step
89  dt = beta * dt;
90 
91  if (workingState->getSolutionStatus() == Status::PASSED or
92  workingState->getSolutionStatus() == Status::WORKING) {
94  dt = std::min(dt, workingState->getTimestep());
95  } else {
96  facMax_ = tscsPL_->get<Scalar>("Maximum Safety Factor");
97  }
98  lastStepRejected_ = false;
99  } else {
100  facMax_ = 0.90;
101  lastStepRejected_ = true;
102  }
103 
104  // update dt
105  workingState->setTimeStep(dt);
106  }
107 
108  /// \name Overridden from Teuchos::ParameterListAcceptor
109  //@{
110  void setParameterList(const Teuchos::RCP<Teuchos::ParameterList> & pList){
111 
112  if (pList == Teuchos::null) {
113  // Create default parameters if null, otherwise keep current parameters.
114  if (tscsPL_ == Teuchos::null) {
115  tscsPL_ = Teuchos::parameterList("TimeStepControlStrategyPID");
116  *tscsPL_= *(this->getValidParameters());
117  }
118  } else {
119  tscsPL_ = pList;
120  }
121  tscsPL_->validateParametersAndSetDefaults(*this->getValidParameters());
122 
123  errN_ = Scalar(1.0);
124  errNm1_ = Scalar(1.0);
125  errNm2_ = Scalar(1.0);
126  k1_ = tscsPL_->get<Scalar>("K1");
127  k2_ = tscsPL_->get<Scalar>("K2");
128  k3_ = tscsPL_->get<Scalar>("K3");
129  safetyFactor_ = tscsPL_->get<Scalar>("Safety Factor");
130  facMax_ = tscsPL_->get<Scalar>("Maximum Safety Factor");
131  facMin_ = tscsPL_->get<Scalar>("Minimum Safety Factor");
132 
133  TEUCHOS_TEST_FOR_EXCEPTION(safetyFactor_ <= 0.0, std::out_of_range,
134  "Error - Invalid value of Safety Factory= " << safetyFactor_ << "! \n"
135  << "Safety Factor must be > 0.0.\n");
136 
137  TEUCHOS_TEST_FOR_EXCEPTION(facMax_ <= 0.0, std::out_of_range,
138  "Error - Invalid value of Maximum Safety Factory= " << facMax_ << "! \n"
139  << "Maximum Safety Factor must be > 0.0.\n");
140 
141  TEUCHOS_TEST_FOR_EXCEPTION(facMax_<= 0.0, std::out_of_range,
142  "Error - Invalid value of Minimum Safety Factory= " << facMin_ << "! \n"
143  << "Minimum Safety Factor must be > 0.0.\n");
144 
145  }
146 
147  Teuchos::RCP<const Teuchos::ParameterList> getValidParameters() const {
148  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
149 
150  pl->set<std::string>("Name","PID");
151  pl->set<Scalar>("K1" , 0.58, "");
152  pl->set<Scalar>("K2" , 0.21, "");
153  pl->set<Scalar>("K3" , 0.10, "");
154  pl->set<Scalar>("Safety Factor" , 0.90, "Safety Factor");
155  pl->set<Scalar>("Maximum Safety Factor" , 5.0, "Maximum Safety Factor");
156  pl->set<Scalar>("Minimum Safety Factor" , 0.5, "Minimum Safety Factor");
157  return pl;
158  }
159 
160  Teuchos::RCP<Teuchos::ParameterList> getNonconstParameterList() {
161  return tscsPL_;
162  }
163 
164  Teuchos::RCP<Teuchos::ParameterList> unsetParameterList() {
165  Teuchos::RCP<Teuchos::ParameterList> temp_plist = tscsPL_;
166  tscsPL_ = Teuchos::null;
167  return(temp_plist);
168  }
169  //@}
170 
171 private:
172  Teuchos::RCP<Teuchos::ParameterList> tscsPL_;
173  Scalar k1_;
174  Scalar k2_;
175  Scalar k3_;
176  Scalar errN_;
177  Scalar errNm1_;
178  Scalar errNm2_;
180  Scalar facMax_;
181  Scalar facMin_;
182  bool firstSuccessfulStep_ = false;
183  bool lastStepRejected_ = false;
184 
185 };
186 } // namespace Tempus
187 #endif // Tempus_TimeStepControlStrategy_PID_hpp
virtual void getNextTimeStep(const TimeStepControl< Scalar > tsc, Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory, Status &integratorStatus) override
Determine the time step size.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
TimeStepControlStrategyPID(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Constructor.
StepControlStrategy class for TimeStepControl.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Status
Status for the Integrator, the Stepper and the SolutionState.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pList)
TimeStepControl manages the time step size. There several mechanicisms that effect the time step size...
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Teuchos::RCP< Teuchos::ParameterList > tscsPL_
StepControlStrategy class for TimeStepControl.