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) override
 
bool accepted () const override
 return if current time step is accepted or not More...
 
void setAcceptedOrNot (bool accepted) override
 
bool isSolutionErrorComputationNeeded () const override
 
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 getNextTimeStepSize () const
 Calculate the next time step size. More...
 
double findMultiplier (int number_iterations) 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
 
bool _accepted = true
 True, if the current time step is accepted. More...
 

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

◆ 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_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}\)

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

Member Function Documentation

◆ accepted()

bool NumLib::IterationNumberBasedTimeStepping::accepted ( ) const
overridevirtual

return if current time step is accepted or not

Implements NumLib::TimeStepAlgorithm.

Definition at line 139 of file IterationNumberBasedTimeStepping.cpp.

140 {
141  return _accepted;
142 }
bool _accepted
True, if the current time step is accepted.

References _accepted.

Referenced by next(), and setAcceptedOrNot().

◆ canReduceTimestepSize()

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

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

Reimplemented from NumLib::TimeStepAlgorithm.

Definition at line 144 of file IterationNumberBasedTimeStepping.cpp.

145 {
146  // If current and previous dt are both at minimum dt, then cannot reduce
147  // further.
148  return !(_ts_current.dt() == _min_dt && _ts_prev.dt() == _min_dt);
149 }
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 _min_dt, NumLib::TimeStepAlgorithm::_ts_current, NumLib::TimeStepAlgorithm::_ts_prev, and NumLib::TimeStep::dt().

◆ findMultiplier()

double NumLib::IterationNumberBasedTimeStepping::findMultiplier ( int  number_iterations) 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 (!_accepted && (multiplier >= 1.0))
111  {
112  return *std::min_element(_multiplier_vector.begin(),
113  _multiplier_vector.end());
114  }
115 
116  return multiplier;
117 }

References _accepted, _iter_times_vector, and _multiplier_vector.

Referenced by getNextTimeStepSize().

◆ getNextTimeStepSize()

double NumLib::IterationNumberBasedTimeStepping::getNextTimeStepSize ( ) const
private

Calculate the next time step size.

Definition at line 119 of file IterationNumberBasedTimeStepping.cpp.

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

References _initial_dt, _iter_times, _max_dt, _min_dt, NumLib::TimeStepAlgorithm::_ts_prev, NumLib::TimeStep::dt(), findMultiplier(), and NumLib::TimeStep::steps().

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

101 { return true; }

◆ next()

std::tuple< bool, double > NumLib::IterationNumberBasedTimeStepping::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 55 of file IterationNumberBasedTimeStepping.cpp.

57 {
58  _iter_times = number_iterations;
59 
61  {
63  }
64 
65  // confirm current time and move to the next if accepted
66  if (accepted())
67  {
69  return std::make_tuple(true, getNextTimeStepSize());
70  }
71  else
72  {
73  double dt = getNextTimeStepSize();
74  // In case it is the first time be rejected, re-computed dt again with
75  // current dt
76  if (std::abs(dt - _ts_current.dt()) <
77  std::numeric_limits<double>::epsilon())
78  {
79  // time step was rejected, keep dt for the next dt computation.
80  _ts_prev = // essentially equal to _ts_prev.dt = _ts_current.dt.
81  TimeStep{_ts_prev.previous(), _ts_prev.previous() + dt,
82  _ts_prev.steps()};
83  dt = getNextTimeStepSize();
84  }
85 
86  // time step was rejected, keep dt for the next dt computation.
87  _ts_prev = // essentially equal to _ts_prev.dt = _ts_current.dt.
88  TimeStep{_ts_prev.previous(), _ts_prev.previous() + dt,
89  _ts_prev.steps()};
90 
92 
93  return std::make_tuple(false, dt);
94  }
95  return {};
96 }
double getNextTimeStepSize() const
Calculate the next time step size.
bool accepted() const override
return if current time step is accepted or not
double previous() const
return previous time step
Definition: TimeStep.h:107

References _iter_times, _previous_time_step_accepted, NumLib::TimeStepAlgorithm::_ts_current, NumLib::TimeStepAlgorithm::_ts_prev, accepted(), NumLib::TimeStep::dt(), getNextTimeStepSize(), NumLib::TimeStep::previous(), and NumLib::TimeStep::steps().

◆ setAcceptedOrNot()

void NumLib::IterationNumberBasedTimeStepping::setAcceptedOrNot ( 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 99 of file IterationNumberBasedTimeStepping.h.

99 { _accepted = accepted; };

References _accepted, and accepted().

Member Data Documentation

◆ _accepted

bool NumLib::IterationNumberBasedTimeStepping::_accepted = true
private

True, if the current time step is accepted.

Definition at line 130 of file IterationNumberBasedTimeStepping.h.

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

◆ _initial_dt

const double NumLib::IterationNumberBasedTimeStepping::_initial_dt
private

Initial time step size.

Definition at line 122 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize().

◆ _iter_times

int NumLib::IterationNumberBasedTimeStepping::_iter_times = 0
private

The number of nonlinear iterations.

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

◆ _min_dt

const double NumLib::IterationNumberBasedTimeStepping::_min_dt
private

The minimum allowed time step size.

Definition at line 118 of file IterationNumberBasedTimeStepping.h.

Referenced by canReduceTimestepSize(), and getNextTimeStepSize().

◆ _multiplier_vector

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

This vector stores the multiplier coefficients.

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

Referenced by next().


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