OGS
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 \( \partial x/\partial t \).

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

\[ F(\dot x, x, t) \stackrel{!}{=} 0. \]

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

\[ F(\hat x, x_C, t_C) \stackrel{!}{=} 0. \]

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.

\[ M(x,t)\cdot \dot x + K(x,t) \cdot x - b(x,t) =: r(\dot x, x, t) \stackrel{!}{=} 0. \]

After time discretization this formula becomes:

\[ M(x_C,t_C)\cdot \hat x + K(x_C,t_C) \cdot x_C - b(x_C,t_C) =: r(\hat x, x_C, t_C) \stackrel{!}{=} 0. \]

The meaning of indices for \( x \) and \( t \) is as follows:

  • \( C \) – "Current": The values of \( x \) and \( t \) at which the discretized ODE is being assembled.
  • \( N \) – "New": The values of \( x \) and \( t \) at the new timestep that is being calculated right now by the ODE solver.
  • \( O \) – "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.
  • \( n \) – Numerical index indicating the timestep.

\( \hat x \) is the discrete approximation of \( \dot x := \partial x/\partial t\). It is assumed that \( \hat x \) can be written in the following form:

\[ \hat x = \alpha \cdot x_N - x_O, \]

where \( \alpha := \partial \hat x / \partial x_N \) is a scalar.

For different time discretization schemes \( x_C \), \( t_C \), \( x_N \), \( x_O \) and \( \alpha \) take different values. Those for the time implemented schemes are given in the table below.

Scheme | \( x_C \) | \( t_C \) | \( \alpha \) | \( x_N \) | \( x_O \) -----------— | ------------— | ------------— | ------------------— | ------------— | -------------------— Backward Euler | \( x_{n+1} \) | \( t_{n+1} \) | \( 1/\Delta t \) | \( x_{n+1} \) | \( x_n / \Delta t \)

Definition at line 107 of file TimeDiscretization.h.

#include <TimeDiscretization.h>

Inheritance diagram for NumLib::TimeDiscretization:
[legend]

Public Member Functions

 TimeDiscretization ()=default
 
virtual void setInitialState (const double t0)=0
 Sets the initial condition. More...
 
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 const &x_old, GlobalVector &xdot) const
 
virtual void getWeightedOldX (GlobalVector &y, GlobalVector const &x_old) const =0
 Returns \( x_O \). More...
 
virtual ~TimeDiscretization ()=default
 

Constructor & Destructor Documentation

◆ TimeDiscretization()

NumLib::TimeDiscretization::TimeDiscretization ( )
default

◆ ~TimeDiscretization()

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

Member Function Documentation

◆ getCurrentTime()

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

Returns \( t_C \), i.e., the time at which the equation will be assembled.

Implemented in NumLib::BackwardEuler.

◆ getCurrentTimeIncrement()

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

Returns \( \Delta t_C \), i.e., the time at which the equation will be assembled.

Implemented in NumLib::BackwardEuler.

Referenced by getXdot().

◆ getWeightedOldX()

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

Returns \( x_O \).

Implemented in NumLib::BackwardEuler.

Referenced by getXdot().

◆ getXdot()

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

Returns \( \hat x \), i.e. the discretized approximation of \( \dot x \).

Definition at line 51 of file TimeDiscretization.cpp.

54 {
55  namespace LinAlg = MathLib::LinAlg;
56 
57  double const dt = getCurrentTimeIncrement();
58 
59  // xdot = 1/dt * x_at_new_timestep - x_old
60  getWeightedOldX(xdot, x_old);
61  LinAlg::axpby(xdot, 1. / dt, -1.0, x_at_new_timestep);
62 }
virtual double getCurrentTimeIncrement() const =0
virtual void getWeightedOldX(GlobalVector &y, GlobalVector const &x_old) const =0
Returns .
void axpby(PETScVector &y, PetscScalar const a, PetscScalar const b, PETScVector const &x)
Definition: LinAlg.cpp:64

References MathLib::LinAlg::axpby(), getCurrentTimeIncrement(), and getWeightedOldX().

◆ 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!

Implemented in NumLib::BackwardEuler.

◆ setInitialState()

virtual void NumLib::TimeDiscretization::setInitialState ( const double  t0)
pure virtual

Sets the initial condition.

Implemented in NumLib::BackwardEuler.


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