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, std::vector< double > const &fixed_times_for_output)
 
 ~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.
 
- 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
 
virtual void resetCurrentTimeStep (const double, TimeStep &, TimeStep &)
 reset the current step size from the previous time
 

Private Member Functions

double getNextTimeStepSize (NumLib::TimeStep const &ts_previous, NumLib::TimeStep const &ts_current) const
 Calculate the next time step size.
 
double findMultiplier (int const number_iterations, NumLib::TimeStep const &ts_current) const
 Find a multiplier for the given number of iterations.
 

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 int _max_iter
 The maximum allowed iteration number to accept current time step.
 
int _iter_times = 0
 The number of nonlinear iterations.
 
bool _previous_time_step_accepted = true
 
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,
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 25 of file IterationNumberBasedTimeStepping.cpp.

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

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

172{
173 return NumLib::canReduceTimestepSize(timestep_previous, timestep_current,
174 _min_dt);
175}
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 100 of file IterationNumberBasedTimeStepping.cpp.

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

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 121 of file IterationNumberBasedTimeStepping.cpp.

124{
125 double dt = 0.0;
126
127 // In first time step and first non-linear iteration take the initial dt.
128 if (ts_previous.timeStepNumber() == 0 && _iter_times == 0)
129 {
130 dt = _initial_dt;
131 }
132 else
133 {
134 // Attention: for the first time step and second iteration the
135 // ts_prev.dt is 0 and 0*multiplier is the next dt, which will be
136 // clamped to the minimum dt.
137 dt = ts_previous.dt() * findMultiplier(_iter_times, ts_current);
138 }
139
140 if (_fixed_times_for_output.empty())
141 {
142 return std::clamp(dt, _min_dt, _max_dt);
143 }
144
145 // find first fixed timestep for output larger than the current time, i.e.,
146 // current time < fixed output time
147 auto fixed_output_time_it = std::find_if(
149 [&ts_current](auto const fixed_output_time)
150 { return ts_current.current()() < fixed_output_time; });
151
152 if (fixed_output_time_it != _fixed_times_for_output.end())
153 {
154 // check if the fixed output time is in the interval
155 // (current time, current time + dt)
156 if (*fixed_output_time_it < ts_current.current()() + dt)
157 {
158 // check if the potential adjusted time step is larger than zero
159 if (std::abs(*fixed_output_time_it - ts_current.current()()) >
160 std::numeric_limits<double>::epsilon() * ts_current.current()())
161 {
162 return *fixed_output_time_it - ts_current.current()();
163 }
164 }
165 }
166 return std::clamp(dt, _min_dt, _max_dt);
167}
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.

References _fixed_times_for_output, _initial_dt, _iter_times, _max_dt, _min_dt, NumLib::TimeStep::current(), NumLib::TimeStep::dt(), findMultiplier(), 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 102 of file IterationNumberBasedTimeStepping.h.

102{ 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_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
A step acceptance flag and the computed step size.

Implements NumLib::TimeStepAlgorithm.

Definition at line 57 of file IterationNumberBasedTimeStepping.cpp.

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

References _iter_times, _previous_time_step_accepted, NumLib::TimeStep::dt(), getNextTimeStepSize(), NumLib::TimeStep::isAccepted(), NumLib::TimeStep::previous(), 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 134 of file IterationNumberBasedTimeStepping.h.

Referenced by getNextTimeStepSize().

◆ _initial_dt

const double NumLib::IterationNumberBasedTimeStepping::_initial_dt
private

Initial time step size.

Definition at line 127 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 119 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 125 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 123 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 121 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 133 of file IterationNumberBasedTimeStepping.h.

Referenced by next().


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