OGS
NumLib::EvolutionaryPIDcontroller Class Referencefinal

Detailed Description

This class gives an adaptive algorithm whose time step control is evolutionary PID controller. With an definition of relative solution change \(e_n=\frac{\|u^{n+1}-u^n\|}{\|u^{n+1}\|}\), the algorithm gives a time step size estimation as

\[ h_{n+1} = \left(\frac{e_{n-1}}{e_n}\right)^{k_P} \left(\frac{TOL}{e_n}\right)^{k_I} \left(\frac{e^2_{n-1}}{e_n e_{n-2}}\right)^{k_D} \]

where \(k_P=0.075\), \(k_I=0.175\), \(k_D=0.01\) are empirical PID parameters.

In the computation, \( e_n\) is calculated firstly. If \(e_n>TOL\), the current time step is rejected and repeated with a new time step size of \(h=\frac{TOL}{e_n} h_n\).

Limits of the time step size are given as

\[ h_{\mbox{min}} \leq h_{n+1} \leq h_{\mbox{max}}, l \leq \frac{h_{n+1}}{h_n} \leq L \]

Similar algorithm can be found in [1] .

Definition at line 51 of file EvolutionaryPIDcontroller.h.

#include <EvolutionaryPIDcontroller.h>

Inheritance diagram for NumLib::EvolutionaryPIDcontroller:
[legend]
Collaboration diagram for NumLib::EvolutionaryPIDcontroller:
[legend]

Public Member Functions

 EvolutionaryPIDcontroller (const double t0, const double t_end, const double h0, const double h_min, const double h_max, const double rel_h_min, const double rel_h_max, const double tol)
 
std::tuple< bool, double > next (double solution_error, int number_iterations) override
 
bool accepted () const override
 return if current time step is accepted or not More...
 
void setAcceptedOrNot (const bool accepted) override
 
bool isSolutionErrorComputationNeeded () const override
 
virtual bool canReduceTimestepSize () const override
 Query the timestepper if further time step size reduction is possible. More...
 
- Public Member Functions inherited from NumLib::TimeStepAlgorithm
 TimeStepAlgorithm (const double t0, const double t_end)
 
 TimeStepAlgorithm (const double t0, const double t_end, const double dt)
 
 TimeStepAlgorithm (const double t0, const double t_end, const std::vector< double > &all_step_sizes)
 
virtual ~TimeStepAlgorithm ()=default
 
double begin () const
 return the beginning of time steps More...
 
double end () const
 return the end of time steps More...
 
const TimeStep getTimeStep () const
 return current time step More...
 
void resetCurrentTimeStep (const double dt)
 reset the current step size from the previous time More...
 
const std::vector< double > & getTimeStepSizeHistory () const
 return a history of time step sizes More...
 

Private Member Functions

double limitStepSize (const double h_new, const bool previous_step_accepted) const
 

Private Attributes

const double _kP = 0.075
 Parameter. More...
 
const double _kI = 0.175
 Parameter. More...
 
const double _kD = 0.01
 Parameter. More...
 
const double _h0
 initial time step size. More...
 
const double _h_min
 minimum step size. More...
 
const double _h_max
 maximum step size. More...
 
const double _rel_h_min
 \(l\) in \( h_{\mbox{min}} \leq h_{n+1} \leq h_{\mbox{max}},\) More...
 
const double _rel_h_max
 \(L\) in \( h_{\mbox{min}} \leq h_{n+1} \leq h_{\mbox{max}},\) More...
 
const double _tol
 
double _e_n_minus1
 \(e_{n-1}\). More...
 
double _e_n_minus2
 \(e_{n-2}\). More...
 
bool _is_accepted
 

Additional Inherited Members

- Protected Attributes inherited from NumLib::TimeStepAlgorithm
const double _t_initial
 initial time More...
 
const double _t_end
 end time More...
 
TimeStep _ts_prev
 previous time step information More...
 
TimeStep _ts_current
 current time step information More...
 
std::vector< double > _dt_vector
 a vector of time step sizes More...
 

Constructor & Destructor Documentation

◆ EvolutionaryPIDcontroller()

NumLib::EvolutionaryPIDcontroller::EvolutionaryPIDcontroller ( const double  t0,
const double  t_end,
const double  h0,
const double  h_min,
const double  h_max,
const double  rel_h_min,
const double  rel_h_max,
const double  tol 
)
inline

Definition at line 54 of file EvolutionaryPIDcontroller.h.

58  : TimeStepAlgorithm(t0, t_end),
59  _h0(h0),
60  _h_min(h_min),
61  _h_max(h_max),
62  _rel_h_min(rel_h_min),
63  _rel_h_max(rel_h_max),
64  _tol(tol),
65  _e_n_minus1(0.),
66  _e_n_minus2(0.),
67  _is_accepted(true)
68  {
69  }
const double _h_max
maximum step size.
const double _h_min
minimum step size.
const double _h0
initial time step size.
TimeStepAlgorithm(const double t0, const double t_end)

Member Function Documentation

◆ accepted()

bool NumLib::EvolutionaryPIDcontroller::accepted ( ) const
inlineoverridevirtual

return if current time step is accepted or not

Implements NumLib::TimeStepAlgorithm.

Definition at line 74 of file EvolutionaryPIDcontroller.h.

74 { return _is_accepted; }

References _is_accepted.

Referenced by setAcceptedOrNot().

◆ canReduceTimestepSize()

bool NumLib::EvolutionaryPIDcontroller::canReduceTimestepSize ( ) const
overridevirtual

Query the timestepper if further time step size reduction is possible.

Reimplemented from NumLib::TimeStepAlgorithm.

Definition at line 139 of file EvolutionaryPIDcontroller.cpp.

140 {
141  // If current and previous dt are both at minimum dt, then cannot reduce
142  // further.
143  return !(_ts_current.dt() == _h_min && _ts_prev.dt() == _h_min);
144 }
TimeStep _ts_current
current time step information
TimeStep _ts_prev
previous time step information
double dt() const
time step size from _previous
Definition: TimeStep.h:111

References _h_min, NumLib::TimeStepAlgorithm::_ts_current, NumLib::TimeStepAlgorithm::_ts_prev, and NumLib::TimeStep::dt().

◆ isSolutionErrorComputationNeeded()

bool NumLib::EvolutionaryPIDcontroller::isSolutionErrorComputationNeeded ( ) const
inlineoverridevirtual

Get a flag to indicate whether this algorithm needs to compute solution error. The default return value is false.

Reimplemented from NumLib::TimeStepAlgorithm.

Definition at line 81 of file EvolutionaryPIDcontroller.h.

81 { return true; }

◆ limitStepSize()

double NumLib::EvolutionaryPIDcontroller::limitStepSize ( const double  h_new,
const bool  previous_step_accepted 
) const
private

Forced the computed time step size in the given range (see the formulas in the documentation of the class) or use the half of the previous time step size under some other constrains.

Parameters
h_newThe computed time step size.
previous_step_acceptedAn indicator for whether the previous time step is rejected.
Returns
The new time step after apply the constrains.

Definition at line 103 of file EvolutionaryPIDcontroller.cpp.

105 {
106  const double h_n = _ts_current.dt();
107  // Forced the computed time step size in the given range
108  // (see the formulas in the documentation of the class)
109  const double h_in_range = std::max(_h_min, std::min(h_new, _h_max));
110  // Limit the step size change ratio.
111  double limited_h =
112  std::max(_rel_h_min * h_n, std::min(h_in_range, _rel_h_max * h_n));
113 
114  if (!previous_step_accepted)
115  {
116  // If the last time step was rejected and the new predicted time step
117  // size is identical to that of the previous rejected step, the new
118  // step size is then reduced by half.
119  if (std::abs(limited_h - _ts_current.dt()) <
120  std::numeric_limits<double>::min())
121  {
122  limited_h = std::max(_h_min, 0.5 * limited_h);
123  }
124 
125  // If the last time step was rejected and the new predicted time step
126  // size is larger than the step size of the rejected step, the new step
127  // size takes the half of the size of the rejected step. This could
128  // happen when a time step is rejected due to a diverged non-linear
129  // solver. In such case, this algorithm may give a large time step size
130  // by using the diverged solution.
131  if (limited_h > _ts_current.dt())
132  {
133  limited_h = std::max(_h_min, 0.5 * _ts_current.dt());
134  }
135  }
136  return limited_h;
137 }

References _h_max, _h_min, _rel_h_max, _rel_h_min, NumLib::TimeStepAlgorithm::_ts_current, and NumLib::TimeStep::dt().

Referenced by next().

◆ next()

std::tuple< bool, double > NumLib::EvolutionaryPIDcontroller::next ( double  solution_error,
int  number_iterations 
)
overridevirtual

Move to the next time step

Parameters
solution_errorSolution error \(e_n\) between two successive time steps.
number_iterationsNumber of non-linear iterations used.
Returns
A step acceptance flag and the computed step size.

Implements NumLib::TimeStepAlgorithm.

Definition at line 23 of file EvolutionaryPIDcontroller.cpp.

25 {
26  const bool is_previous_step_accepted = _is_accepted;
27 
28  const double e_n = solution_error;
29  const double zero_threshlod = std::numeric_limits<double>::epsilon();
30  // step rejected.
31  if (e_n > _tol)
32  {
33  _is_accepted = false;
34 
35  double h_new = (e_n > zero_threshlod) ? _ts_current.dt() * _tol / e_n
36  : 0.5 * _ts_current.dt();
37 
38  h_new = limitStepSize(h_new, is_previous_step_accepted);
39 
40  WARN(
41  "This step is rejected due to the relative change from the"
42  " solution of the previous\n"
43  "\t time step to the current solution exceeds the given tolerance"
44  " of {:g}.\n"
45  "\t This time step will be repeated with a new time step size of"
46  " {:g}\n"
47  "\t or the simulation will be halted.",
48  _tol, h_new);
49 
50  return std::make_tuple(false, h_new);
51  }
52 
53  // step accepted.
54  _is_accepted = true;
55 
56  if (_ts_current.steps() == 0)
57  {
58  _e_n_minus1 = e_n;
59 
60  return std::make_tuple(true, _h0);
61  }
62  else
63  {
64  const double h_n = _ts_current.dt();
65  double h_new = h_n;
66 
67  if (e_n > zero_threshlod)
68  {
69  if (_e_n_minus1 > zero_threshlod)
70  {
71  if (_e_n_minus2 > zero_threshlod)
72  {
73  h_new = std::pow(_e_n_minus1 / e_n, _kP) *
74  std::pow(_tol / e_n, _kI) *
75  std::pow(
77  _kD) *
78  h_n;
79  }
80  else
81  {
82  h_new = std::pow(_e_n_minus1 / e_n, _kP) *
83  std::pow(_tol / e_n, _kI) * h_n;
84  }
85  }
86  else
87  {
88  h_new = std::pow(_tol / e_n, _kI) * h_n;
89  }
90  }
91 
92  h_new = limitStepSize(h_new, is_previous_step_accepted);
93 
95  _e_n_minus1 = e_n;
96 
97  return std::make_tuple(true, h_new);
98  }
99 
100  return {};
101 }
void WARN(char const *fmt, Args const &... args)
Definition: Logging.h:37
double limitStepSize(const double h_new, const bool previous_step_accepted) const
std::size_t steps() const
the number of time _steps
Definition: TimeStep.h:113

References _e_n_minus1, _e_n_minus2, _h0, _is_accepted, _kD, _kI, _kP, _tol, NumLib::TimeStepAlgorithm::_ts_current, NumLib::TimeStep::dt(), limitStepSize(), NumLib::TimeStep::steps(), and WARN().

◆ setAcceptedOrNot()

void NumLib::EvolutionaryPIDcontroller::setAcceptedOrNot ( const bool  accepted)
inlineoverridevirtual

Set the status of the step.

Parameters
acceptedA boolean parameter is needed to indicated whether the step is accepted or not.

Reimplemented from NumLib::TimeStepAlgorithm.

Definition at line 76 of file EvolutionaryPIDcontroller.h.

77  {
79  }
bool accepted() const override
return if current time step is accepted or not

References _is_accepted, and accepted().

Member Data Documentation

◆ _e_n_minus1

double NumLib::EvolutionaryPIDcontroller::_e_n_minus1
private

\(e_{n-1}\).

Definition at line 101 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _e_n_minus2

double NumLib::EvolutionaryPIDcontroller::_e_n_minus2
private

\(e_{n-2}\).

Definition at line 102 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _h0

const double NumLib::EvolutionaryPIDcontroller::_h0
private

initial time step size.

Definition at line 90 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _h_max

const double NumLib::EvolutionaryPIDcontroller::_h_max
private

maximum step size.

Definition at line 92 of file EvolutionaryPIDcontroller.h.

Referenced by limitStepSize().

◆ _h_min

const double NumLib::EvolutionaryPIDcontroller::_h_min
private

minimum step size.

Definition at line 91 of file EvolutionaryPIDcontroller.h.

Referenced by canReduceTimestepSize(), and limitStepSize().

◆ _is_accepted

bool NumLib::EvolutionaryPIDcontroller::_is_accepted
private

Definition at line 104 of file EvolutionaryPIDcontroller.h.

Referenced by accepted(), next(), and setAcceptedOrNot().

◆ _kD

const double NumLib::EvolutionaryPIDcontroller::_kD = 0.01
private

Parameter.

See also
EvolutionaryPIDcontroller

Definition at line 88 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _kI

const double NumLib::EvolutionaryPIDcontroller::_kI = 0.175
private

Parameter.

See also
EvolutionaryPIDcontroller

Definition at line 87 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _kP

const double NumLib::EvolutionaryPIDcontroller::_kP = 0.075
private

Parameter.

See also
EvolutionaryPIDcontroller

Definition at line 86 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _rel_h_max

const double NumLib::EvolutionaryPIDcontroller::_rel_h_max
private

\(L\) in \( h_{\mbox{min}} \leq h_{n+1} \leq h_{\mbox{max}},\)

Definition at line 97 of file EvolutionaryPIDcontroller.h.

Referenced by limitStepSize().

◆ _rel_h_min

const double NumLib::EvolutionaryPIDcontroller::_rel_h_min
private

\(l\) in \( h_{\mbox{min}} \leq h_{n+1} \leq h_{\mbox{max}},\)

Definition at line 95 of file EvolutionaryPIDcontroller.h.

Referenced by limitStepSize().

◆ _tol

const double NumLib::EvolutionaryPIDcontroller::_tol
private

Definition at line 99 of file EvolutionaryPIDcontroller.h.

Referenced by next().


The documentation for this class was generated from the following files: