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 66 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, std::vector< int > &&iter_times_vector, std::vector< double > &&multiplier_vector)

~IterationNumberBasedTimeStepping () override=default

std::tuple< bool, 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. More...

Public Member Functions inherited from NumLib::TimeStepAlgorithm
TimeStepAlgorithm (const double t0, const double t_end)

virtual ~TimeStepAlgorithm ()=default

double begin () const
return the beginning of time steps More...

double end () const
return the end of time steps More...

virtual void resetCurrentTimeStep (const double, TimeStep &, TimeStep &)
reset the current step size from the previous time More...

## Private Member Functions

double getNextTimeStepSize (NumLib::TimeStep const &ts_previous, NumLib::TimeStep const &ts_current) const
Calculate the next time step size. More...

double findMultiplier (int const number_iterations, NumLib::TimeStep const &ts_current) const
Find a multiplier for the given number of iterations. More...

## Private Attributes

const std::vector< int > _iter_times_vector

const std::vector< double > _multiplier_vector
This vector stores the multiplier coefficients. More...

const double _min_dt
The minimum allowed time step size. More...

const double _max_dt
The maximum allowed time step size. More...

const double _initial_dt
Initial time step size. More...

const int _max_iter
The maximum allowed iteration number to accept current time step. More...

int _iter_times = 0
The number of nonlinear iterations. More...

bool _previous_time_step_accepted = true

## ◆ IterationNumberBasedTimeStepping()

 NumLib::IterationNumberBasedTimeStepping::IterationNumberBasedTimeStepping ( double const t_initial, double const t_end, double const min_dt, double const max_dt, double const initial_dt, std::vector< int > && iter_times_vector, std::vector< double > && multiplier_vector )
Parameters
 t_initial start time t_end end time min_dt the minimum allowed time step size max_dt the maximum allowed time step size initial_dt initial time step size iter_times_vector a 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_vector a 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}$$

Definition at line 25 of file IterationNumberBasedTimeStepping.cpp.

30  : TimeStepAlgorithm(t_initial, t_end),
31  _iter_times_vector(std::move(iter_times_vector)),
32  _multiplier_vector(std::move(multiplier_vector)),
33  _min_dt(min_dt),
34  _max_dt(max_dt),
35  _initial_dt(initial_dt),
36  _max_iter(_iter_times_vector.empty() ? 0 : _iter_times_vector.back())
37 {
38  if (_iter_times_vector.empty())
39  {
40  OGS_FATAL("Vector of iteration numbers must not be empty.");
41  }
42  if (_iter_times_vector.size() != _multiplier_vector.size())
43  {
44  OGS_FATAL(
45  "Vector of iteration numbers must be of the same size as the "
46  "vector of multipliers.");
47  }
48  if (!std::is_sorted(std::begin(_iter_times_vector),
49  std::end(_iter_times_vector)))
50  {
51  OGS_FATAL("Vector of iteration numbers must be sorted.");
52  }
53 }
#define OGS_FATAL(...)
Definition: Error.h:26
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

## ◆ 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 141 of file IterationNumberBasedTimeStepping.cpp.

144 {
145  return NumLib::canReduceTimestepSize(timestep_previous, timestep_current,
146  _min_dt);
147 }
bool canReduceTimestepSize(TimeStep const &timestep_previous, TimeStep const &timestep_current, double const min_dt)

References _min_dt, and NumLib::canReduceTimestepSize().

## ◆ findMultiplier()

 double NumLib::IterationNumberBasedTimeStepping::findMultiplier ( int const number_iterations, NumLib::TimeStep const & ts_current ) const
private

Find a multiplier for the given number of iterations.

Definition at line 98 of file IterationNumberBasedTimeStepping.cpp.

100 {
101  double multiplier = _multiplier_vector.front();
102  for (std::size_t i = 0; i < _iter_times_vector.size(); i++)
103  {
104  if (number_iterations >= _iter_times_vector[i])
105  {
106  multiplier = _multiplier_vector[i];
107  }
108  }
109
110  if (!ts_current.isAccepted() && (multiplier >= 1.0))
111  {
112  return *std::min_element(_multiplier_vector.begin(),
113  _multiplier_vector.end());
114  }
115
116  return multiplier;
117 }

References _iter_times_vector, _multiplier_vector, and NumLib::TimeStep::isAccepted().

Referenced by getNextTimeStepSize().

## ◆ 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 119 of file IterationNumberBasedTimeStepping.cpp.

122 {
123  double dt = 0.0;
124
125  // In first time step and first non-linear iteration take the initial dt.
126  if (ts_previous.timeStepNumber() == 0 && _iter_times == 0)
127  {
128  dt = _initial_dt;
129  }
130  else
131  {
132  // Attention: for the first time step and second iteration the
133  // ts_prev.dt is 0 and 0*multiplier is the next dt, which will be
134  // clamped to the minimum dt.
135  dt = ts_previous.dt() * findMultiplier(_iter_times, ts_current);
136  }
137
138  return std::clamp(dt, _min_dt, _max_dt);
139 }
double findMultiplier(int const number_iterations, NumLib::TimeStep const &ts_current) const
Find a multiplier for the given number of iterations.
int _iter_times
The number of nonlinear iterations.

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 99 of file IterationNumberBasedTimeStepping.h.

99 { return true; }

## ◆ next()

 std::tuple< bool, 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_error Solution error $$e_n$$ between two successive time steps. number_iterations Number of non-linear iterations used. ts_previous the previous time step used to compute the size of the next step ts_current the current time step used to compute the size of the next step
Returns
A step acceptance flag and the computed step size.

Implements NumLib::TimeStepAlgorithm.

Definition at line 55 of file IterationNumberBasedTimeStepping.cpp.

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

## ◆ _initial_dt

 const double NumLib::IterationNumberBasedTimeStepping::_initial_dt
private

Initial time step size.

Definition at line 124 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize().

## ◆ _iter_times

 int NumLib::IterationNumberBasedTimeStepping::_iter_times = 0
private

The number of nonlinear iterations.

Definition at line 128 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize(), and next().

## ◆ _iter_times_vector

 const std::vector 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 116 of file IterationNumberBasedTimeStepping.h.

Referenced by IterationNumberBasedTimeStepping(), and findMultiplier().

## ◆ _max_dt

 const double NumLib::IterationNumberBasedTimeStepping::_max_dt
private

The maximum allowed time step size.

Definition at line 122 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 126 of file IterationNumberBasedTimeStepping.h.

## ◆ _min_dt

 const double NumLib::IterationNumberBasedTimeStepping::_min_dt
private

The minimum allowed time step size.

Definition at line 120 of file IterationNumberBasedTimeStepping.h.

Referenced by canReduceTimestepSize(), and getNextTimeStepSize().

## ◆ _multiplier_vector

 const std::vector NumLib::IterationNumberBasedTimeStepping::_multiplier_vector
private

This vector stores the multiplier coefficients.

Definition at line 118 of file IterationNumberBasedTimeStepping.h.

Referenced by IterationNumberBasedTimeStepping(), and findMultiplier().

## ◆ _previous_time_step_accepted

 bool NumLib::IterationNumberBasedTimeStepping::_previous_time_step_accepted = true
private

Definition at line 130 of file IterationNumberBasedTimeStepping.h.

Referenced by next().

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