Integrators
GeometricIntegrators.jl provides a plethora of geometric and non-geometric integrators. Most integrators are specified by a tableau, that is a Butcher tableau for Runge-Kutta methods, a pair of tableaus for partitioned Runge-Kutta and VPRK methods, or generalizations thereof for SPARK methods. Other integrators, such as Galerkin variational integrators require the specification of a basis and a quadrature rule.
In many cases, the correct integrator is automatically selected based on the tableau and equation types by calling
Integrator(equation, tableau, Δt)
where Δt
is the time step.
As an example, consider an ODE like the harmonic oscillator, which is included as an example problem:
ode = TestProblems.HarmonicOscillatorProblem.harmonic_oscillator_ode()
Create an explicit Euler tableau:
tab = TableauExplicitEuler()
TableauERK{Float64}(:explicit_euler, 1, 1, Runge-Kutta Coefficients explicit_euler with 1 stages and order 1 a = [0.0] b = [1.0] c = [0.0])
And now create an Integrator with the general Integrator
constructor:
int = Integrator(ode, tab, 0.1)
We see that we obtained an IntegratorERK
, i.e., an explicit Runge-Kutta integrator. If instead we choose the implicit Euler tableau:
tab = TableauImplicitEuler()
TableauFIRK{Float64}(:implicit_euler, 1, 1, Runge-Kutta Coefficients implicit_euler with 1 stages and order 1 a = [1.0] b = [1.0] c = [1.0])
the general Integrator
constructor creates a different integrator:
int = Integrator(ode, tab, 0.1)
namely an IntegratorFIRK
, i.e., a fully implicit Runge-Kutta integrator.
This is possible because most integrators come with a dedicated tableau type, so that Integrator
can dispatch on that.
In some cases, in particular the VPRK integrators, the integrator has to be explicitly specified as there are different integrators that use the same tableau type and operate on the same equation type, here TableauVPRK
and IODE
. Consider again the harmonic oscillator:
iode = harmonic_oscillator_iode
Create a VPRK tableau that uses Gauss-Legendre Runge-Kutta coefficients with two stages:
tab = TableauVPGLRK(2)
If we just call the Integrator
constructor,
int = Integrator(iode, tab, 0.1)
we obtain a plain IntegratorVPRK
. If we want to use any of the projection methods, we have to explicitly specify the corresponding integrator type:
int = IntegratorVPRKpStandard(iode, tab, 0.1)
or
int = IntegratorVPRKpSymmetric(iode, tab, 0.1)
Once an integrator is obtained, we can just call the function
integrate(equation, integrator, ntime)
to perform the actual integration steps, where ntime
defines the number of steps to integrate:
tab = TableauExplicitEuler()
int = Integrator(ode, tab, 0.1)
sol = integrate(ode, int, 100)
The integrate
function returns a solution object that stores the solution for each of the ntime
time steps. There is also a convenience function that combines all of the above steps in one single call, namely
integrate(equation, tableau, Δt, ntime)
If the solution object is created manually, there exists a function
integrate!(integrator, solution)
that operates on an existing solution.