Loading [MathJax]/jax/element/mml/optable/GeneralPunctuation.js
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 46 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::vector< double > const &fixed_times_for_output)
 
double next (double solution_error, int number_iterations, NumLib::TimeStep &timestep_previous, NumLib::TimeStep &timestep_current) override
 
bool isSolutionErrorComputationNeeded () const override
 
virtual bool canReduceTimestepSize (NumLib::TimeStep const &timestep_previous, NumLib::TimeStep const &timestep_current) const override
 Query the timestepper if further time step size reduction is possible.
 
- Public Member Functions inherited from NumLib::TimeStepAlgorithm
 TimeStepAlgorithm (const double t0, const double t_end)
 
virtual ~TimeStepAlgorithm ()=default
 
Time begin () const
 return the beginning of time steps
 
Time end () const
 return the end of time steps
 

Private Member Functions

double limitStepSize (const double h_new, const bool previous_step_accepted, NumLib::TimeStep const &timestep_current) const
 

Private Attributes

const double _kP = 0.075
 Parameter.
 
const double _kI = 0.175
 Parameter.
 
const double _kD = 0.01
 Parameter.
 
const double _h0
 initial time step size.
 
const double _h_min
 minimum step size.
 
const double _h_max
 maximum step size.
 
const double _rel_h_min
 l in h_{\mbox{min}} \leq h_{n+1} \leq h_{\mbox{max}},
 
const double _rel_h_max
 L in h_{\mbox{min}} \leq h_{n+1} \leq h_{\mbox{max}},
 
const double _tol
 
double _e_n_minus1
 e_{n-1}.
 
double _e_n_minus2
 e_{n-2}.
 
std::vector< double > const _fixed_times_for_output
 

Additional Inherited Members

- Protected Attributes inherited from NumLib::TimeStepAlgorithm
const Time _t_initial
 initial time
 
const Time _t_end
 end time
 

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,
std::vector< double > const & fixed_times_for_output )
inline

Definition at line 49 of file EvolutionaryPIDcontroller.h.

54 : TimeStepAlgorithm(t0, t_end),
55 _h0(h0),
56 _h_min(h_min),
57 _h_max(h_max),
58 _rel_h_min(rel_h_min),
59 _rel_h_max(rel_h_max),
60 _tol(tol),
61 _e_n_minus1(0.),
62 _e_n_minus2(0.),
63 _fixed_times_for_output(fixed_times_for_output)
64 {
65 }
const double _h_max
maximum step size.
std::vector< double > const _fixed_times_for_output
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

◆ canReduceTimestepSize()

bool NumLib::EvolutionaryPIDcontroller::canReduceTimestepSize ( NumLib::TimeStep const & ,
NumLib::TimeStep const &  ) const
overridevirtual

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

Reimplemented from NumLib::TimeStepAlgorithm.

Definition at line 168 of file EvolutionaryPIDcontroller.cpp.

171{
172 return NumLib::canReduceTimestepSize(timestep_previous, timestep_current,
173 _h_min);
174}
bool canReduceTimestepSize(TimeStep const &timestep_previous, TimeStep const &timestep_current, double const min_dt)

References _h_min, and NumLib::canReduceTimestepSize().

◆ 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 72 of file EvolutionaryPIDcontroller.h.

72{ return true; }

◆ limitStepSize()

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

Force 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.
timestep_currentthe current time step
Returns
The new time step after apply the constrains.

Definition at line 102 of file EvolutionaryPIDcontroller.cpp.

105{
106 const double h_n = timestep_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 - timestep_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 > timestep_current.dt())
132 {
133 limited_h = std::max(_h_min, 0.5 * timestep_current.dt());
134 }
135 }
136
137 if (_fixed_times_for_output.empty())
138 {
139 return limited_h;
140 }
141
142 // find first fixed output time larger than the current time, i.e.,
143 // current time < fixed output time
144 auto fixed_output_time_it = std::find_if(
146 [&timestep_current](auto const fixed_output_time)
147 { return timestep_current.current() < Time{fixed_output_time}; });
148
149 if (fixed_output_time_it != _fixed_times_for_output.end())
150 {
151 // check if the fixed output time is in the interval
152 // (current time, current time + limited_h)
153 if (Time{*fixed_output_time_it} <
154 timestep_current.current() + limited_h)
155 {
156 // check if the potential adjusted time step is larger than zero
157 if (std::abs(*fixed_output_time_it - timestep_current.current()()) >
158 std::numeric_limits<double>::epsilon() *
159 timestep_current.current()())
160 {
161 return *fixed_output_time_it - timestep_current.current()();
162 }
163 }
164 }
165 return limited_h;
166}

References _fixed_times_for_output, _h_max, _h_min, _rel_h_max, _rel_h_min, NumLib::TimeStep::current(), and NumLib::TimeStep::dt().

Referenced by next().

◆ next()

double NumLib::EvolutionaryPIDcontroller::next ( double solution_error,
int number_iterations,
NumLib::TimeStep & ts_previous,
NumLib::TimeStep & ts_current )
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.
ts_previousthe previous time step used to compute the size of the next step
ts_currentthe current time step used to compute the size of the next step
Returns
the computed step size.

Implements NumLib::TimeStepAlgorithm.

Definition at line 23 of file EvolutionaryPIDcontroller.cpp.

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

References _e_n_minus1, _e_n_minus2, _h0, _kD, _kI, _kP, _tol, NumLib::TimeStep::dt(), NumLib::TimeStep::isAccepted(), limitStepSize(), NumLib::TimeStep::setAccepted(), NumLib::TimeStep::timeStepNumber(), and WARN().

Member Data Documentation

◆ _e_n_minus1

double NumLib::EvolutionaryPIDcontroller::_e_n_minus1
private

e_{n-1}.

Definition at line 94 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _e_n_minus2

double NumLib::EvolutionaryPIDcontroller::_e_n_minus2
private

e_{n-2}.

Definition at line 95 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _fixed_times_for_output

std::vector<double> const NumLib::EvolutionaryPIDcontroller::_fixed_times_for_output
private

Definition at line 97 of file EvolutionaryPIDcontroller.h.

Referenced by limitStepSize().

◆ _h0

const double NumLib::EvolutionaryPIDcontroller::_h0
private

initial time step size.

Definition at line 83 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _h_max

const double NumLib::EvolutionaryPIDcontroller::_h_max
private

maximum step size.

Definition at line 85 of file EvolutionaryPIDcontroller.h.

Referenced by limitStepSize().

◆ _h_min

const double NumLib::EvolutionaryPIDcontroller::_h_min
private

minimum step size.

Definition at line 84 of file EvolutionaryPIDcontroller.h.

Referenced by canReduceTimestepSize(), and limitStepSize().

◆ _kD

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

Parameter.

See also
EvolutionaryPIDcontroller

Definition at line 81 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _kI

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

Parameter.

See also
EvolutionaryPIDcontroller

Definition at line 80 of file EvolutionaryPIDcontroller.h.

Referenced by next().

◆ _kP

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

Parameter.

See also
EvolutionaryPIDcontroller

Definition at line 79 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 90 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 88 of file EvolutionaryPIDcontroller.h.

Referenced by limitStepSize().

◆ _tol

const double NumLib::EvolutionaryPIDcontroller::_tol
private

Definition at line 92 of file EvolutionaryPIDcontroller.h.

Referenced by next().


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