OGS 6.2.1-499-g3b941532c.dirty.20191012113459
NumLib::TimeDiscretization Class Referenceabstract

Detailed Description

Interface of time discretization schemes for first-order ODEs.

The purpose of TimeDiscretization instances is to store the solution history of an ODE, i. e., to keep the solution at as many timestamps as is required by the respective time discretization scheme. Furthermore, TimeDiscretization instances compute the discretized approximation of the time derivative .

Note
The method documentation of this class uses quantities introduced in the following section.
Todo:
Currently this interface does not yet support adaptive timestepping. While implementing that will lead to no changes for single-step methods, for multi-step methods this interface will have to be extended.

Discretizing first-order ODEs

A first-order (implicit) ODE has the general form

In order to solve it numerically a certain time discretization scheme, such as the forward or backward Euler methods, is used. The discretized ODE is then given by

This interface has been designed with first-order implicit quasi-linear ODEs in mind. They can be expressed as follows and are given here only to serve as an example.

After time discretization this formula becomes:

The meaning of indices for and is as follows:

• – "Current": The values of and at which the discretized ODE is being assembled.
• – "New": The values of and at the new timestep that is being calculated right now by the ODE solver.
• – "Old": The results from the preceding time step (or a linear combination of results of the preceding time steps in the case of multistep methods) weighted by a scalar factor.
• – Numerical index indicating the timestep.

is the discrete approximation of . It is assumed that can be written in the following form:

where is a scalar.

For different time discretization schemes , , , and take different values. Those for the time implemented schemes are given in the table below.

Scheme
Forward Euler
Backward Euler
Crank-Nicolson
BDF(2)

The other backward differentiation formulas of orders 1 to 6 are also implemented, but only BDF(2) has bee given here for brevity.

Definition at line 114 of file TimeDiscretization.h.

#include <TimeDiscretization.h>

Inheritance diagram for NumLib::TimeDiscretization:

Public Member Functions

TimeDiscretization ()=default

virtual void setInitialState (const double t0, GlobalVector const &x0)=0
Sets the initial condition. More...

virtual double getRelativeChangeFromPreviousTimestep (GlobalVector const &x, MathLib::VecNormType norm_type)=0

virtual void pushState (const double t, GlobalVector const &x, InternalMatrixStorage const &strg)=0

virtual void popState (GlobalVector &x)=0

virtual void nextTimestep (const double t, const double delta_t)=0

virtual double getCurrentTime () const =0

virtual double getCurrentTimeIncrement () const =0

void getXdot (GlobalVector const &x_at_new_timestep, GlobalVector &xdot) const

virtual double getNewXWeight () const =0
Returns . More...

virtual void getWeightedOldX (GlobalVector &y) const =0
Returns . More...

virtual ~TimeDiscretization ()=default

Extended Interface

These methods are provided primarily to make certain concrete time discretizations with special demands, such as the forward Euler or Crank-Nicolson schemes, possible.

virtual bool isLinearTimeDisc () const

virtual double getDxDx () const

virtual GlobalVector const & getCurrentX (GlobalVector const &x_at_new_timestep) const

Protected Member Functions

double computeRelativeChangeFromPreviousTimestep (GlobalVector const &x, GlobalVector const &x_old, MathLib::VecNormType norm_type)

Protected Attributes

std::unique_ptr< GlobalVector > _dx
Used to store . More...

◆ TimeDiscretization()

 NumLib::TimeDiscretization::TimeDiscretization ( )
default

◆ ~TimeDiscretization()

 virtual NumLib::TimeDiscretization::~TimeDiscretization ( )
virtualdefault

◆ computeRelativeChangeFromPreviousTimestep()

 double NumLib::TimeDiscretization::computeRelativeChangeFromPreviousTimestep ( GlobalVector const & x, GlobalVector const & x_old, MathLib::VecNormType norm_type )
protected

Compute and return the relative change of solutions between two successive time steps by .

Parameters
 x The current solution x_old The previous solution norm_type The norm type of global vector
Returns
.
Warning
the value of x_old is changed to x - x_old after this computation.

Definition at line 18 of file TimeDiscretization.cpp.

22 {
23  if (norm_type == MathLib::VecNormType::INVALID)
24  {
25  OGS_FATAL("An invalid norm type has been passed");
26  }
27
28  if (!_dx)
29  {
31  }
32
33  auto& dx = *_dx;
34  MathLib::LinAlg::copy(x, dx); // copy x to dx.
35
36  // dx = x - x_old --> x - dx --> dx
37  MathLib::LinAlg::axpy(dx, -1.0, x_old);
38  const double norm_dx = MathLib::LinAlg::norm(dx, norm_type);
39
40  const double norm_x = MathLib::LinAlg::norm(x, norm_type);
41  if (norm_x > std::numeric_limits<double>::epsilon())
42  {
43  return norm_dx / norm_x;
44  }
45
46  // Both of norm_x and norm_dx are close to zero
47  if (norm_dx < std::numeric_limits<double>::epsilon())
48  {
49  return 1.0;
50  }
51
52  // Only norm_x is close to zero
53  return norm_dx / std::numeric_limits<double>::epsilon();
54 }
double norm(MatrixOrVector const &x, MathLib::VecNormType type)
Definition: LinAlg.h:88
std::unique_ptr< GlobalVector > _dx
Used to store .
#define OGS_FATAL(fmt,...)
Definition: Error.h:64
void axpy(MatrixOrVector &y, double const a, MatrixOrVector const &x)
Computes .
Definition: LinAlg.h:58
void copy(MatrixOrVector const &x, MatrixOrVector &y)
Copies x to y.
Definition: LinAlg.h:37

◆ getCurrentTime()

 virtual double NumLib::TimeDiscretization::getCurrentTime ( ) const
pure virtual

Returns , i.e., the time at which the equation will be assembled.

◆ getCurrentTimeIncrement()

 virtual double NumLib::TimeDiscretization::getCurrentTimeIncrement ( ) const
pure virtual

Returns , i.e., the time at which the equation will be assembled.

◆ getCurrentX()

 virtual GlobalVector const& NumLib::TimeDiscretization::getCurrentX ( GlobalVector const & x_at_new_timestep ) const
inlinevirtual

Returns , i.e., the state at which the equation will be assembled.

This method is overridden in the ForwardEuler scheme.

Reimplemented in NumLib::ForwardEuler.

Definition at line 217 of file TimeDiscretization.h.

218  {
219  return x_at_new_timestep;
220  }

◆ getDxDx()

 virtual double NumLib::TimeDiscretization::getDxDx ( ) const
inlinevirtual

Returns .

The ForwardEuler scheme overrides this.

Reimplemented in NumLib::ForwardEuler.

Definition at line 211 of file TimeDiscretization.h.

211 { return 1.0; }

◆ getNewXWeight()

 virtual double NumLib::TimeDiscretization::getNewXWeight ( ) const
pure virtual

Returns .

◆ getRelativeChangeFromPreviousTimestep()

 virtual double NumLib::TimeDiscretization::getRelativeChangeFromPreviousTimestep ( GlobalVector const & x, MathLib::VecNormType norm_type )
pure virtual

Get the relative change of solutions between two successive time steps by .

Parameters
 x The solution at the current timestep. norm_type The type of global vector norm.

◆ getWeightedOldX()

 virtual void NumLib::TimeDiscretization::getWeightedOldX ( GlobalVector & y ) const
pure virtual

Returns .

◆ getXdot()

 void NumLib::TimeDiscretization::getXdot ( GlobalVector const & x_at_new_timestep, GlobalVector & xdot ) const
inline

Returns , i.e. the discretized approximation of .

Definition at line 175 of file TimeDiscretization.h.

References MathLib::LinAlg::axpby().

176  {
177  namespace LinAlg = MathLib::LinAlg;
178
179  auto const dxdot_dx = getNewXWeight();
180
181  // xdot = dxdot_dx * x_at_new_timestep - x_old
182  getWeightedOldX(xdot);
183  LinAlg::axpby(xdot, dxdot_dx, -1.0, x_at_new_timestep);
184  }
virtual double getNewXWeight() const =0
Returns .
virtual void getWeightedOldX(GlobalVector &y) const =0
Returns .
void axpby(MatrixOrVector &y, double const a, double const b, MatrixOrVector const &x)
Computes .
Definition: LinAlg.h:65

◆ isLinearTimeDisc()

 virtual bool NumLib::TimeDiscretization::isLinearTimeDisc ( ) const
inlinevirtual

Tell whether this scheme inherently requires a nonlinear solver or not.

The ForwardEuler scheme is inherently linear in that sense, the others are not.

Reimplemented in NumLib::ForwardEuler.

Definition at line 206 of file TimeDiscretization.h.

206 { return false; }

 virtual bool NumLib::TimeDiscretization::needsPreload ( ) const
inlinevirtual

Indicate that this scheme needs some additional assembly before the first timestep will be solved.

The CrankNicolson scheme needs such preload.

Reimplemented in NumLib::CrankNicolson.

Definition at line 228 of file TimeDiscretization.h.

228 { return false; }

◆ nextTimestep()

 virtual void NumLib::TimeDiscretization::nextTimestep ( const double t, const double delta_t )
pure virtual

Indicate that the computation of a new timestep is being started now.

Warning
Currently changing timestep sizes are not supported. Thus, delta_t must not change throughout the entire time integration process! This is not checked by this code!

◆ popState()

 virtual void NumLib::TimeDiscretization::popState ( GlobalVector & x )
pure virtual

Restores the given vector x to its old value. Used only for repeating of the time step with new time step size when the current time step is rejected. The restored x is only used as an initial guess for linear solver in the first Picard nonlinear iteration.

Parameters
 x The solution at the current time step, which is going to be reset to its previous value.

◆ pushState()

 virtual void NumLib::TimeDiscretization::pushState ( const double t, GlobalVector const & x, InternalMatrixStorage const & strg )
pure virtual

Indicate that the current timestep is done and that you will proceed to the next one.

Warning
Do not use this method for setting the initial condition, rather use setInitialState()!
Parameters
 t The current timestep. x The solution at the current timestep. strg Trigger storing some internal state. Currently only used by the CrankNicolson scheme.

◆ setInitialState()

 virtual void NumLib::TimeDiscretization::setInitialState ( const double t0, GlobalVector const & x0 )
pure virtual

Sets the initial condition.

◆ _dx

 std::unique_ptr NumLib::TimeDiscretization::_dx
protected

Used to store .

Definition at line 232 of file TimeDiscretization.h.

Referenced by computeRelativeChangeFromPreviousTimestep().

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