Loading web-font TeX/Main/Regular
OGS
NumLib::IterationNumberBasedTimeStepping Class Referencefinal

Detailed Description

Iteration number based adaptive time stepping.

This algorithm estimates a time step size depending on the number of iterations (e.g. of iterative linear solvers, nonlinear methods, partitioned coupling) needed in the last time step (see Hoffmann (2010) for Newton-Raphson case). The new time step \Delta t_{n+1} size is calculated as

\Delta t_{n+1} = \alpha \Delta t_n

with the previous time step size \Delta t_{n} and a multiplier coefficient \alpha depending on the iteration number. Note that a time step size is always bounded by the minimum and maximum allowed value.

\Delta t_{\min} \le \Delta t \le \Delta t_{\max}

For example, users can setup the following time stepping strategy based on the iteration number of the Newton-Raphson method in the last time step.

Num. of Newton steps0-23-67-89<
Time step size multiplier1.61.0.50.25 (repeat time step)
Upper and lower bound 1. \le \Delta t \le 10.

A time step size is increased for the small iteration number, and decreased for the large iteration number. If the iteration number exceeds a user-defined threshold (e.g. 9), a time step is repeated with a smaller time step size.

Reference

  • Hoffmann J (2010) Reactive Transport and Mineral Dissolution/Precipitation in Porous Media:Efficient Solution Algorithms, Benchmark Computations and Existence of Global Solutions. PhD thesis. pp82. Friedrich-Alexander-Universität Erlangen-Nürnberg.

Definition at line 67 of file IterationNumberBasedTimeStepping.h.

#include <IterationNumberBasedTimeStepping.h>

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

Public Member Functions

 IterationNumberBasedTimeStepping (double const t_initial, double const t_end, double const min_dt, double const max_dt, double const initial_dt, MultiplyerInterpolationType const multiplier_interpolation_type, std::vector< int > &&iter_times_vector, std::vector< double > &&multiplier_vector, std::vector< double > const &fixed_times_for_output)
 
 ~IterationNumberBasedTimeStepping () override=default
 
double next (double solution_error, int number_iterations, NumLib::TimeStep &ts_previous, NumLib::TimeStep &ts_current) override
 
bool isSolutionErrorComputationNeeded () const override
 
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 getNextTimeStepSize (NumLib::TimeStep const &ts_previous, NumLib::TimeStep const &ts_current) const
 Calculate the next time step size.
 

Private Attributes

const std::vector< int > _iter_times_vector
 
const std::vector< double > _multiplier_vector
 This vector stores the multiplier coefficients.
 
const double _min_dt
 The minimum allowed time step size.
 
const double _max_dt
 The maximum allowed time step size.
 
const double _initial_dt
 Initial time step size.
 
const MultiplyerInterpolationType _multiplier_interpolation_type
 Interpolation type for the multiplier.
 
const int _max_iter
 The maximum allowed iteration number to accept current time step.
 
int _iter_times = 0
 The number of nonlinear iterations.
 
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

◆ IterationNumberBasedTimeStepping()

NumLib::IterationNumberBasedTimeStepping::IterationNumberBasedTimeStepping ( double const t_initial,
double const t_end,
double const min_dt,
double const max_dt,
double const initial_dt,
MultiplyerInterpolationType const multiplier_interpolation_type,
std::vector< int > && iter_times_vector,
std::vector< double > && multiplier_vector,
std::vector< double > const & fixed_times_for_output )
Parameters
t_initialstart time
t_endend time
min_dtthe minimum allowed time step size
max_dtthe maximum allowed time step size
initial_dtinitial time step size
iter_times_vectora vector of iteration numbers ( i_1, i_2, ..., i_n) which defines intervals as [i_1,i_2), [i_2,i_3), ..., [i_n,\infty). If an iteration number is larger than i_n, current time step is repeated with the new time step size.
multiplier_vectora vector of multiplier coefficients ( a_1, a_2, ..., a_n) corresponding to the intervals given by iter_times_vector. A time step size is calculated by \Delta t_{n+1} = a * \Delta t_{n}
fixed_times_for_outputa vector of fixed time points for output

Definition at line 27 of file IterationNumberBasedTimeStepping.cpp.

34 : TimeStepAlgorithm(t_initial, t_end),
35 _iter_times_vector(std::move(iter_times_vector)),
36 _multiplier_vector(std::move(multiplier_vector)),
37 _min_dt(min_dt),
38 _max_dt(max_dt),
39 _initial_dt(initial_dt),
40 _multiplier_interpolation_type(multiplier_interpolation_type),
42 _fixed_times_for_output(fixed_times_for_output)
43{
44 if (_iter_times_vector.empty())
45 {
46 OGS_FATAL("Vector of iteration numbers must not be empty.");
47 }
48 if (_iter_times_vector.size() != _multiplier_vector.size())
49 {
51 "Vector of iteration numbers must be of the same size as the "
52 "vector of multipliers.");
53 }
54 if (!std::is_sorted(std::begin(_iter_times_vector),
55 std::end(_iter_times_vector)))
56 {
57 OGS_FATAL("Vector of iteration numbers must be sorted.");
58 }
59}
#define OGS_FATAL(...)
Definition Error.h:26
const MultiplyerInterpolationType _multiplier_interpolation_type
Interpolation type for the multiplier.
const double _max_dt
The maximum allowed time step size.
const std::vector< double > _multiplier_vector
This vector stores the multiplier coefficients.
const double _min_dt
The minimum allowed time step size.
const int _max_iter
The maximum allowed iteration number to accept current time step.
TimeStepAlgorithm(const double t0, const double t_end)

References _iter_times_vector, _multiplier_vector, and OGS_FATAL.

◆ ~IterationNumberBasedTimeStepping()

NumLib::IterationNumberBasedTimeStepping::~IterationNumberBasedTimeStepping ( )
overridedefault

Member Function Documentation

◆ canReduceTimestepSize()

bool NumLib::IterationNumberBasedTimeStepping::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 193 of file IterationNumberBasedTimeStepping.cpp.

196{
197 return NumLib::canReduceTimestepSize(timestep_previous, timestep_current,
198 _min_dt);
199}
bool canReduceTimestepSize(TimeStep const &timestep_previous, TimeStep const &timestep_current, double const min_dt)

References _min_dt, and NumLib::canReduceTimestepSize().

◆ getNextTimeStepSize()

double NumLib::IterationNumberBasedTimeStepping::getNextTimeStepSize ( NumLib::TimeStep const & ts_previous,
NumLib::TimeStep const & ts_current ) const
private

Calculate the next time step size.

Definition at line 139 of file IterationNumberBasedTimeStepping.cpp.

142{
143 double dt = 0.0;
144
145 // In first time step and first non-linear iteration take the initial dt.
146 if (ts_previous.timeStepNumber() == 0 && _iter_times == 0)
147 {
148 dt = _initial_dt;
149 }
150 else
151 {
152 // Attention: for the first time step and second iteration the
153 // ts_prev.dt is 0 and 0*multiplier is the next dt, which will be
154 // clamped to the minimum dt.
155 dt = ts_previous.dt() *
156 findMultiplier(_iter_times, ts_current.isAccepted(),
159 }
160
161 if (_fixed_times_for_output.empty())
162 {
163 return std::clamp(dt, _min_dt, _max_dt);
164 }
165
166 // restrict dt to _max_dt before taking fixed times for output into account
167 dt = std::min(dt, _max_dt);
168
169 // find first fixed timestep for output larger than the current time, i.e.,
170 // current time < fixed output time
171 auto fixed_output_time_it = std::find_if(
173 [&ts_current](auto const fixed_output_time)
174 { return ts_current.current()() < fixed_output_time; });
175
176 if (fixed_output_time_it != _fixed_times_for_output.end())
177 {
178 // check if the fixed output time is in the interval
179 // (current time, current time + dt)
180 if (*fixed_output_time_it < ts_current.current()() + dt)
181 {
182 // check if the potential adjusted time step is larger than zero
183 if (std::abs(*fixed_output_time_it - ts_current.current()()) >
184 std::numeric_limits<double>::epsilon() * ts_current.current()())
185 {
186 return *fixed_output_time_it - ts_current.current()();
187 }
188 }
189 }
190 return std::clamp(dt, _min_dt, _max_dt);
191}
int _iter_times
The number of nonlinear iterations.
double findMultiplier(int const number_iterations, bool const current_time_step_is_accepted, std::vector< int > const &nonlinear_iteration_numbers, std::vector< double > const &multipliers, MultiplyerInterpolationType const multiplier_interpolation_type)
Find a multiplier for the given number of iterations.

References _fixed_times_for_output, _initial_dt, _iter_times, _iter_times_vector, _max_dt, _min_dt, _multiplier_interpolation_type, _multiplier_vector, NumLib::TimeStep::current(), NumLib::TimeStep::dt(), NumLib::findMultiplier(), NumLib::TimeStep::isAccepted(), and NumLib::TimeStep::timeStepNumber().

Referenced by next().

◆ isSolutionErrorComputationNeeded()

bool NumLib::IterationNumberBasedTimeStepping::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 104 of file IterationNumberBasedTimeStepping.h.

104{ return true; }

◆ next()

double NumLib::IterationNumberBasedTimeStepping::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 61 of file IterationNumberBasedTimeStepping.cpp.

65{
66 _iter_times = number_iterations;
67
68 if (ts_previous.isAccepted())
69 {
70 ts_previous = ts_current;
71 }
72
73 // confirm current time and move to the next if accepted
74 if (ts_current.isAccepted())
75 {
76 ts_previous.setAccepted(true);
77 return getNextTimeStepSize(ts_previous, ts_current);
78 }
79
80 double dt = getNextTimeStepSize(ts_previous, ts_current);
81 // In case it is the first time be rejected, re-computed dt again with
82 // current dt
83 if (std::abs(dt - ts_current.dt()) < std::numeric_limits<double>::epsilon())
84 {
85 // time step was rejected, keep dt for the next dt computation.
86 ts_previous = // essentially equal to _ts_prev.dt = _ts_current.dt.
87 TimeStep{ts_previous.previous(), ts_previous.previous() + dt,
88 ts_previous.timeStepNumber()};
89 dt = getNextTimeStepSize(ts_previous, ts_current);
90 }
91
92 // time step was rejected, keep dt for the next dt computation.
93 ts_previous = // essentially equal to ts_previous.dt = _ts_current.dt.
94 TimeStep{ts_previous.previous(), ts_previous.previous() + dt,
95 ts_previous.timeStepNumber()};
96 ts_current = TimeStep{ts_current.previous(), ts_current.previous() + dt,
97 ts_current.timeStepNumber()};
98
99 return dt;
100}
double getNextTimeStepSize(NumLib::TimeStep const &ts_previous, NumLib::TimeStep const &ts_current) const
Calculate the next time step size.
void setAccepted(bool const accepted)
Definition TimeStep.h:86
bool isAccepted() const
Definition TimeStep.h:87
Time previous() const
return previous time step
Definition TimeStep.h:78
double dt() const
time step size from _previous
Definition TimeStep.h:82
std::size_t timeStepNumber() const
the time step number
Definition TimeStep.h:84

References _iter_times, NumLib::TimeStep::dt(), getNextTimeStepSize(), NumLib::TimeStep::isAccepted(), NumLib::TimeStep::previous(), NumLib::TimeStep::setAccepted(), and NumLib::TimeStep::timeStepNumber().

Member Data Documentation

◆ _fixed_times_for_output

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

Definition at line 133 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize().

◆ _initial_dt

const double NumLib::IterationNumberBasedTimeStepping::_initial_dt
private

Initial time step size.

Definition at line 125 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize().

◆ _iter_times

int NumLib::IterationNumberBasedTimeStepping::_iter_times = 0
private

The number of nonlinear iterations.

Definition at line 131 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize(), and next().

◆ _iter_times_vector

const std::vector<int> NumLib::IterationNumberBasedTimeStepping::_iter_times_vector
private

This vector stores the number of iterations to which the respective multiplier coefficient will be applied.

Definition at line 117 of file IterationNumberBasedTimeStepping.h.

Referenced by IterationNumberBasedTimeStepping(), and getNextTimeStepSize().

◆ _max_dt

const double NumLib::IterationNumberBasedTimeStepping::_max_dt
private

The maximum allowed time step size.

Definition at line 123 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize().

◆ _max_iter

const int NumLib::IterationNumberBasedTimeStepping::_max_iter
private

The maximum allowed iteration number to accept current time step.

Definition at line 129 of file IterationNumberBasedTimeStepping.h.

◆ _min_dt

const double NumLib::IterationNumberBasedTimeStepping::_min_dt
private

The minimum allowed time step size.

Definition at line 121 of file IterationNumberBasedTimeStepping.h.

Referenced by canReduceTimestepSize(), and getNextTimeStepSize().

◆ _multiplier_interpolation_type

const MultiplyerInterpolationType NumLib::IterationNumberBasedTimeStepping::_multiplier_interpolation_type
private

Interpolation type for the multiplier.

Definition at line 127 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize().

◆ _multiplier_vector

const std::vector<double> NumLib::IterationNumberBasedTimeStepping::_multiplier_vector
private

This vector stores the multiplier coefficients.

Definition at line 119 of file IterationNumberBasedTimeStepping.h.

Referenced by IterationNumberBasedTimeStepping(), and getNextTimeStepSize().


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