Discontinuous Galerkin Library
#include "dg/algorithm.h"
dg::ImplicitMultistep< ContainerType > Struct Template Reference

Implicit multistep ODE integrator \( \begin{align} v^{n+1} &= \sum_{i=0}^{s-1} a_i v^{n-i} + \Delta t \sum_{i=1}^{s} c_i\hat I(t^{n+1-i}, v^{n+1-i}) + \Delta t c_{0} \hat I (t + \Delta t, v^{n+1}) \\ \end{align} \). More...

Public Types

using value_type = get_value_type< ContainerType >
 the value type of the time variable (float or double) More...
 
using container_type = ContainerType
 

Public Member Functions

 ImplicitMultistep ()=default
 No memory allocation. More...
 
 ImplicitMultistep (ConvertsToMultistepTableau< value_type > tableau, const ContainerType &copyable)
 Reserve memory for integration. More...
 
template<class ... Params>
void construct (Params &&...ps)
 Perfect forward parameters to one of the constructors. More...
 
const ContainerType & copyable () const
 Return an object of same size as the object used for construction. More...
 
template<class ImplicitRHS , class Solver >
void init (const std::tuple< ImplicitRHS, Solver > &ode, value_type t0, const ContainerType &u0, value_type dt)
 Initialize timestepper. Call before using the step function. More...
 
template<class ImplicitRHS , class Solver >
void step (const std::tuple< ImplicitRHS, Solver > &ode, value_type &t, container_type &u)
 Advance one timestep. More...
 

Detailed Description

template<class ContainerType>
struct dg::ImplicitMultistep< ContainerType >

Implicit multistep ODE integrator \( \begin{align} v^{n+1} &= \sum_{i=0}^{s-1} a_i v^{n-i} + \Delta t \sum_{i=1}^{s} c_i\hat I(t^{n+1-i}, v^{n+1-i}) + \Delta t c_{0} \hat I (t + \Delta t, v^{n+1}) \\ \end{align} \).

which discretizes

\[ \frac{\partial v}{\partial t} = \hat I(t,v) \]

where \( \hat I \) represents the right hand side of the equations. You can use your own coefficients defined as a dg::MultistepTableau or use one of the predefined coefficients in

We follow the naming convention as NAME-S-Q

  • NAME is the author or name of the method
  • S is the number of steps in the method
  • Q is the global order of the method
Name Identifier Description
BDF-X-X dg::BDF_X_X The coefficients for backward differences can be found at https://en.wikipedia.org/wiki/Backward_differentiation_formula
Note
Possible values for X: 1, 2, 3, 4, 5, 6
A BDF scheme is simply constructed by discretizing the time derivative with a n-th order backward difference formula and evaluating the right hand side at the new timestep.
Methods with s>6 are not zero-stable so they cannot be used

and (any imex tableau can be used in an implicit scheme, disregarding the explicit coefficients)

We follow the naming convention as NAME-S-Q

  • NAME is the author or name of the method
  • S is the number of steps in the method
  • Q is the global order of the method
Name Identifier Description
ImEx-Euler-1-1 dg::IMEX_EULER_1_1 Explicit Euler combined with Implicit Euler
Euler dg::IMEX_EULER_1_1 For convenience
ImEx-Koto-2-2 dg::IMEX_KOTO_2_2 Koto T. Front. Math. China 2009, 4(1): 113-129 A stabilized 2nd order scheme with a large region of stability
ImEx-Adams-X-X dg::IMEX_ADAMS_X_X Hundsdorfer and Ruuth, Journal of Computational Physics 225 (2007)
Note
Possible values for X: 2 (C=0.44), 3 (C=0.16)
ImEx-BDF-X-X dg::IMEX_BDF_X_X The family of schems described in Hundsdorfer and Ruuth, Journal of Computational Physics 225 (2007)
The implicit part is a normal BDF scheme https://en.wikipedia.org/wiki/Backward_differentiation_formula while the explicit part equals the Minimal Projecting method by Alfeld, P., Math. Comput. 33.148 1195-1212 (1979) or extrapolated BDF in Hundsdorfer, W., Ruuth, S. J., & Spiteri, R. J. (2003). Monotonicity-preserving linear multistep methods. SIAM Journal on Numerical Analysis, 41(2), 605-623
Note
Possible values for X: 1 (C=1.00), 2 (C=0.63), 3 (C=0.39), 4 (C=0.22), 5 (C=0.09), 6
Note that X=3 is identical to the "Karniadakis" scheme
Karniadakis dg::IMEX_BDF_3_3 The ImEx-BDF-3-3 scheme is identical to the widely used "Karniadakis" scheme Karniadakis, et al. J. Comput. Phys. 97 (1991)
ImEx-TVB-X-X dg::IMEX_TVB_X_X The family of schems described in < Hundsdorfer and Ruuth, Journal of Computational Physics 225 (2007)
The explicit part is a TVB scheme while the implicit part is optimized to maximize damping of high wavelength
Note
Possible values for X: 3 (C=0.54), 4 (C=0.46), 5 (C=0.38)
Note
the CFL coefficient C is given relative to the forward Euler method: \( \Delta t < C \Delta t_{FE}\).
Attention
The coefficient C is the one that ensures the TVD property of the scheme and is not directly related to the stability region of the scheme

The necessary Inversion in the implicit part must be provided by the Implicit class.

Note
In our experience the implicit treatment of diffusive or hyperdiffusive terms can significantly reduce the required number of time steps. This outweighs the increased computational cost of the additional inversions. However, each PDE is different and general statements like this one should be treated with care.
Uses only blas1::axpby routines to integrate one step.
The difference between a multistep and a single step method like RungeKutta is that the multistep only takes one right-hand-side evaluation per step. This is advantageous if the right hand side is expensive to evaluate. Even though Runge Kutta methods can have a larger absolute timestep, if the effective timestep per rhs evaluation is compared, multistep methods generally win.
a disadvantage of multistep is that timestep adaption is not easily done.

Member Typedef Documentation

◆ container_type

template<class ContainerType >
using dg::ImplicitMultistep< ContainerType >::container_type = ContainerType

the type of the vector class in use

◆ value_type

template<class ContainerType >
using dg::ImplicitMultistep< ContainerType >::value_type = get_value_type<ContainerType>

the value type of the time variable (float or double)

Constructor & Destructor Documentation

◆ ImplicitMultistep() [1/2]

template<class ContainerType >
dg::ImplicitMultistep< ContainerType >::ImplicitMultistep ( )
default

No memory allocation.

◆ ImplicitMultistep() [2/2]

template<class ContainerType >
dg::ImplicitMultistep< ContainerType >::ImplicitMultistep ( ConvertsToMultistepTableau< value_type tableau,
const ContainerType &  copyable 
)
inline

Reserve memory for integration.

Parameters
tableauTableau, name or identifier that ConvertsToMultistepTableau
copyablevector of the size that is later used in step ( it does not matter what values copyable contains, but its size is important; the step method can only be called with vectors of the same size)

Member Function Documentation

◆ construct()

template<class ContainerType >
template<class ... Params>
void dg::ImplicitMultistep< ContainerType >::construct ( Params &&...  ps)
inline

Perfect forward parameters to one of the constructors.

Template Parameters
Paramsdeduced by the compiler
Parameters
psparameters forwarded to constructors

◆ copyable()

template<class ContainerType >
const ContainerType & dg::ImplicitMultistep< ContainerType >::copyable ( ) const
inline

Return an object of same size as the object used for construction.

Returns
A copyable object; what it contains is undefined, its size is important

◆ init()

template<class ContainerType >
template<class ImplicitRHS , class Solver >
void dg::ImplicitMultistep< ContainerType >::init ( const std::tuple< ImplicitRHS, Solver > &  ode,
value_type  t0,
const ContainerType &  u0,
value_type  dt 
)

Initialize timestepper. Call before using the step function.

This routine has to be called before the first timestep is made.

Template Parameters
ExplicitRHSThe explicit (part of the) right hand side is a functor type with no return value (subroutine) of signature void operator()(value_type, const ContainerType&, ContainerType&) The first argument is the time, the second is the input vector, which the functor may not override, and the third is the output, i.e. y' = E(t, y) translates to E(t, y, y'). The two ContainerType arguments never alias each other in calls to the functor. The functor can throw to indicate failure. Exceptions should derive from std::exception.
SolverA functor type for the implicit right hand side. Must solve the equation \( y - \alpha I(y,t) = y^*\) for y for given alpha, t and ys. Alpha is always positive and non-zero. Signature void operator()( value_type alpha, value_type t, ContainerType& y, const ContainerType& ys); The functor can throw. Any Exception should derive from std::exception.
Parameters
odethe <right hand side, solver for the rhs> functors. Typically std::tie(implicit_rhs, solver)
Attention
solver is not actually called only implicit_rhs and only if the rhs actually needs to be stored (The dg::BDF_X_X tableaus in fact completely avoid calling implicit_rhs)
Parameters
t0The intital time corresponding to u0
u0The initial value of the integration
dtThe timestep saved for later use This might be interesting if the call to ex changes its state.

◆ step()

template<class ContainerType >
template<class ImplicitRHS , class Solver >
void dg::ImplicitMultistep< ContainerType >::step ( const std::tuple< ImplicitRHS, Solver > &  ode,
value_type t,
container_type u 
)

Advance one timestep.

Template Parameters
ExplicitRHSThe explicit (part of the) right hand side is a functor type with no return value (subroutine) of signature void operator()(value_type, const ContainerType&, ContainerType&) The first argument is the time, the second is the input vector, which the functor may not override, and the third is the output, i.e. y' = E(t, y) translates to E(t, y, y'). The two ContainerType arguments never alias each other in calls to the functor. The functor can throw to indicate failure. Exceptions should derive from std::exception.
SolverA functor type for the implicit right hand side. Must solve the equation \( y - \alpha I(y,t) = y^*\) for y for given alpha, t and ys. Alpha is always positive and non-zero. Signature void operator()( value_type alpha, value_type t, ContainerType& y, const ContainerType& ys); The functor can throw. Any Exception should derive from std::exception.
Parameters
odethe <right hand side, solver for the rhs> functors. Typically std::tie(implicit_rhs, solver)
Attention
the implicit_rhs functor is only called during the initialization phase (the first few steps after the call to the init function) but only if the rhs actually needs to be stored (The dg::BDF_X_X tableaus in fact completely avoid calling implicit_rhs)
Parameters
t(write-only), contains timestep corresponding to u on return
u(write-only), contains next step of time-integration on return This might be interesting if the call to ex changes its state.
Note
The first few steps after the call to the init function are performed with a DIRK method (of the same order) to initialize the multistepper

The documentation for this struct was generated from the following file: