ERKStep

The ERKStep factory wraps a configurable explicit Runge–Kutta integrator. It accepts any ERKTableau and ships with PI step-control defaults tuned for the embedded Dormand–Prince pair. The factory performs staged right-hand-side evaluations on the GPU and supports optional driver and observable callbacks.

class cubie.integrators.algorithms.ERKStep(precision: type[float16] | type[float32] | type[float64] | dtype[float16] | dtype[float32] | dtype[float64], n: int, evaluate_f: Callable | None = None, evaluate_observables: Callable | None = None, evaluate_driver_at_t: Callable | None = None, get_solver_helper_fn: Callable | None = None, tableau: ERKTableau = ERKTableau(a=((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.075, 0.225, 0.0, 0.0, 0.0, 0.0, 0.0), (0.9777777777777777, -3.7333333333333334, 3.5555555555555554, 0.0, 0.0, 0.0, 0.0), (2.9525986892242035, -11.595793324188385, 9.822892851699436, -0.2908093278463649, 0.0, 0.0, 0.0), (2.8462752525252526, -10.757575757575758, 8.906422717743473, 0.2784090909090909, -0.2735313036020583, 0.0, 0.0), (0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0)), b=(0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0), c=(0.0, 0.2, 0.3, 0.8, 0.8888888888888888, 1.0, 1.0), order=5, b_hat=(0.08991319444444444, 0.0, 0.4534890685834082, 0.6140625, -0.2715123820754717, 0.08904761904761904, 0.025)), n_drivers: int = 0, **kwargs)[source]

Bases: ODEExplicitStep

Generic explicit Runge–Kutta step with configurable tableaus.

__init__(precision: type[float16] | type[float32] | type[float64] | dtype[float16] | dtype[float32] | dtype[float64], n: int, evaluate_f: Callable | None = None, evaluate_observables: Callable | None = None, evaluate_driver_at_t: Callable | None = None, get_solver_helper_fn: Callable | None = None, tableau: ERKTableau = ERKTableau(a=((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.075, 0.225, 0.0, 0.0, 0.0, 0.0, 0.0), (0.9777777777777777, -3.7333333333333334, 3.5555555555555554, 0.0, 0.0, 0.0, 0.0), (2.9525986892242035, -11.595793324188385, 9.822892851699436, -0.2908093278463649, 0.0, 0.0, 0.0), (2.8462752525252526, -10.757575757575758, 8.906422717743473, 0.2784090909090909, -0.2735313036020583, 0.0, 0.0), (0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0)), b=(0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0), c=(0.0, 0.2, 0.3, 0.8, 0.8888888888888888, 1.0, 1.0), order=5, b_hat=(0.08991319444444444, 0.0, 0.4534890685834082, 0.6140625, -0.2715123820754717, 0.08904761904761904, 0.025)), n_drivers: int = 0, **kwargs) None[source]

Initialise the Runge–Kutta step configuration.

This constructor creates an ERK step object and automatically selects appropriate default step controller settings based on whether the tableau has an embedded error estimate. Tableaus with error estimates default to adaptive stepping (PI controller), while errorless tableaus default to fixed stepping.

Parameters:
  • precision – Floating-point precision for CUDA computations (np.float32 or np.float64).

  • n – Number of state variables in the ODE system.

  • evaluate_f – Compiled CUDA device function computing state derivatives. Should match signature expected by the integration kernel.

  • evaluate_observables – Optional compiled CUDA device function computing observable quantities from the state.

  • evaluate_driver_at_t – Optional compiled CUDA device function computing time-varying driver inputs.

  • get_solver_helper_fn – Factory function returning solver helper for implicit stages (not used in explicit methods but included for interface consistency).

  • tableau – Explicit Runge–Kutta tableau describing the coefficients used by the integrator. Defaults to DEFAULT_ERK_TABLEAU (Dormand-Prince 5(4)).

  • n_drivers – Number of driver variables in the system.

  • **kwargs – Optional parameters passed to config classes. See ERKStepConfig for available parameters. None values are ignored.

Notes

The step controller defaults are selected dynamically:

  • If tableau.has_error_estimate is True: Uses ERK_ADAPTIVE_DEFAULTS (PI controller)

  • If tableau.has_error_estimate is False: Uses ERK_FIXED_DEFAULTS (fixed-step controller)

This automatic selection prevents incompatible configurations where an adaptive controller is paired with an errorless tableau. Users can still override these defaults by explicitly specifying step controller settings when creating a Solver or calling solve_ivp().

Examples

Create an ERK step with the default Dormand-Prince tableau:

>>> from cubie.integrators.algorithms.generic_erk import ERKStep
>>> import numpy as np
>>> step = ERKStep(precision=np.float32,n=3)
>>> step.controller_defaults.step_controller["step_controller"]
'pi'

Create an ERK step with Classical RK4 (errorless):

>>> from cubie.integrators.algorithms.generic_erk_tableaus import (
...     CLASSICAL_RK4_TABLEAU
... )
>>> step = ERKStep(precision=np.float32,n=3,tableau=CLASSICAL_RK4_TABLEAU)
>>> step.controller_defaults.step_controller["step_controller"]
'fixed'
build_step(evaluate_f: Callable, evaluate_observables: Callable, evaluate_driver_at_t: Callable | None, numba_precision: type, n: int, n_drivers: int) StepCache[source]

Compile the explicit Runge–Kutta device step.

property is_adaptive: bool

Return True if algorithm calculates an error estimate.

property is_multistage: bool

Return True when the method has multiple stages.

property order: int

Return the classical order of accuracy.

register_buffers() None[source]

Register buffers with buffer_registry.

property threads_per_step: int

Return the number of CUDA threads that advance one state.

class cubie.integrators.algorithms.generic_erk.ERKStepConfig(precision: type[float16] | type[float32] | type[float64] | dtype[float16] | dtype[float32] | dtype[float64], n: int = 1, n_drivers: int = 0, evaluate_f: Callable | None = None, evaluate_observables: Callable | None = None, evaluate_driver_at_t: Callable | None = None, get_solver_helper_fn: Callable | None = None, tableau: ERKTableau = ERKTableau(a=((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.075, 0.225, 0.0, 0.0, 0.0, 0.0, 0.0), (0.9777777777777777, -3.7333333333333334, 3.5555555555555554, 0.0, 0.0, 0.0, 0.0), (2.9525986892242035, -11.595793324188385, 9.822892851699436, -0.2908093278463649, 0.0, 0.0, 0.0), (2.8462752525252526, -10.757575757575758, 8.906422717743473, 0.2784090909090909, -0.2735313036020583, 0.0, 0.0), (0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0)), b=(0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0), c=(0.0, 0.2, 0.3, 0.8, 0.8888888888888888, 1.0, 1.0), order=5, b_hat=(0.08991319444444444, 0.0, 0.4534890685834082, 0.6140625, -0.2715123820754717, 0.08904761904761904, 0.025)), stage_rhs_location: str = 'local', stage_accumulator_location: str = 'local')[source]

Bases: ExplicitStepConfig

Configuration describing an explicit Runge–Kutta integrator.

property first_same_as_last: bool

Return True when the tableau shares the first and last stage.

stage_accumulator_location: str
stage_rhs_location: str
tableau: ERKTableau