Discontinuous Galerkin Library
#include "dg/algorithm.h"
|
Semi-implicit multistep ODE integrator \( \begin{align} v^{n+1} = \sum_{q=0}^{s-1} a_q v^{n-q} + \Delta t\left[\left(\sum_{q=0}^{s-1}b_q \hat E(t^{n}-q\Delta t, v^{n-q}) + \sum_{q=1}^{s} c_q \hat I( t^n - q\Delta t, v^{n-q})\right) + c_0\hat I(t^{n}+\Delta t, v^{n+1})\right] \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 | |
ImExMultistep ()=default | |
No memory allocation. More... | |
ImExMultistep (ConvertsToMultistepTableau< value_type > tableau, const ContainerType ©able) | |
Reserve memory for integration and construct Solver. 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 ExplicitRHS , class ImplicitRHS , class Solver > | |
void | init (const std::tuple< ExplicitRHS, ImplicitRHS, Solver > &ode, value_type t0, const ContainerType &u0, value_type dt) |
Initialize timestepper. Call before using the step function. More... | |
template<class ExplicitRHS , class ImplicitRHS , class Solver > | |
void | step (const std::tuple< ExplicitRHS, ImplicitRHS, Solver > &ode, value_type &t, ContainerType &u) |
Advance one timestep. More... | |
Semi-implicit multistep ODE integrator \( \begin{align} v^{n+1} = \sum_{q=0}^{s-1} a_q v^{n-q} + \Delta t\left[\left(\sum_{q=0}^{s-1}b_q \hat E(t^{n}-q\Delta t, v^{n-q}) + \sum_{q=1}^{s} c_q \hat I( t^n - q\Delta t, v^{n-q})\right) + c_0\hat I(t^{n}+\Delta t, v^{n+1})\right] \end{align} \).
which discretizes
\[ \frac{\partial v}{\partial t} = \hat E(t,v) + \hat I(t,v) \]
where \( \hat E \) contains the explicit and \( \hat I \) the implicit part of the equations. As an example, the coefficients for the 3-step, 3rd order "Karniadakis" scheme are
\[ a_0 = \frac{18}{11}\ a_1 = -\frac{9}{11}\ a_2 = \frac{2}{11} \\ b_0 = \frac{18}{11}\ b_1 = -\frac{18}{11}\ b_2 = \frac{6}{11} \\ c_0 = \frac{6}{11}\quad c_1 = c_2 = c_3 = 0 \\ \]
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 | 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)
|
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
|
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
|
The necessary Inversion in the implicit part is provided by the Implicit
class.
The following code example demonstrates how to implement the method of manufactured solutions on a 2d partial differential equation with the dg library:
In the main function:
blas1::axpby
routines to integrate one step. ContainerType | Any class for which a specialization of TensorTraits exists and which fulfills the requirements of the there defined data and execution policies derived from AnyVectorTag and AnyPolicyTag . Among others
ContainerTypes in the argument list, then TensorTraits must exist for all of them |
using dg::ImExMultistep< ContainerType >::container_type = ContainerType |
the type of the vector class in use
using dg::ImExMultistep< ContainerType >::value_type = get_value_type<ContainerType> |
the value type of the time variable (float or double)
|
default |
No memory allocation.
|
inline |
Reserve memory for integration and construct Solver.
tableau | Tableau, name or identifier that ConvertsToMultistepTableau |
copyable | vector 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) |
|
inline |
Perfect forward parameters to one of the constructors.
Params | deduced by the compiler |
ps | parameters forwarded to constructors |
|
inline |
Return an object of same size as the object used for construction.
void dg::ImExMultistep< ContainerType >::init | ( | const std::tuple< ExplicitRHS, 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.
ExplicitRHS | The 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 . |
ImplicitRHS | The implicit (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' = I(t, y) translates to I(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 . |
Solver | A 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 . |
ode | the <explicit rhs, implicit rhs, solver for the rhs> functor. Typically std::tie(explicit_rhs, implicit_rhs, solver) |
t0 | The intital time corresponding to u0 |
u0 | The initial value of the integration |
dt | The timestep saved for later use |
explicit_part
at
(t0,u0). This is useful if explicit_part
holds state, which is then updated to that timestep and/or if implicit_rhs
changes the state of explicit_rhs
void dg::ImExMultistep< ContainerType >::step | ( | const std::tuple< ExplicitRHS, ImplicitRHS, Solver > & | ode, |
value_type & | t, | ||
ContainerType & | u | ||
) |
Advance one timestep.
ExplicitRHS | The 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 . |
ImplicitRHS | The implicit (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' = I(t, y) translates to I(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 . |
Solver | A 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 . |
ode | the <explicit rhs, implicit rhs, solver for the rhs> functor. Typically std::tie(explicit_rhs, implicit_rhs, solver) |
t | (write-only), contains timestep corresponding to u on return |
u | (write-only), contains next step of time-integration on return |
solve
, we call explicit_rhs
at the new (t,u) which is the last call before return. This is useful if explicit_rhs
holds state, which is then updated to the new timestep and/or if solver
changes the state of explicit_rhs
implicit_rhs
functor is called is during the initialization phase (the first few steps after the call to the init function)