Operator Calculus, Co.
Browse Studio documentation
On this page

Quick Reference 📌

  • create_context_integrator(ctx, name, config) — allocate an integrator bound to a context.
  • set_integrator(ctx, integrator) — attach a single integrator; replaces any prior attachment.
  • set_integrator_sequence(ctx, {int1, int2, ...}) — attach an ordered sequence of integrators stepped together each tick.
  • detach_integrator(ctx) — remove all integrators (single or sequence) from the context.
  • integrator_step(ctx, integrator[, dt[, auto_advance]]) — manually drive one integrator outside the main step loop.

Create 🧱

create_context_integrator(ctx, name[, config]) -> integrator

Returns: Integrator handle (userdata). Pass to set_integrator or set_integrator_sequence.

name must be one of the names listed in the Integrator Catalog below. Raises a Lua error if the name is unrecognized.

The context’s base_seed is used to auto-seed the integrator’s RNG when random_seed is not provided.

Caution

create_integrator (without the ctx argument) is deprecated and raises a Lua error. Always use create_context_integrator.


Attach & Detach 🔧

set_integrator(ctx, integrator)

Attaches a single integrator to the context, replacing any previous single or sequence attachment. The context holds a strong Lua reference to the handle so it cannot be garbage-collected while attached.

local rk4 = ooc.create_context_integrator(ctx, "rk4", { initial_dt = 0.01 })
ooc.set_integrator(ctx, rk4)

set_integrator_sequence(ctx, {int1, int2, ...})

Attaches an ordered array of integrators. Each call to ooc.step(ctx) steps every integrator in the array at the same requested dt. The simulation clock advances by the minimum accepted step across all integrators, and the reported RMS error is the maximum across all integrators. This is the conservative, safe combination rule.

local fast = ooc.create_context_integrator(ctx, "rk4", {
    initial_dt = 0.01, target_field = 0
})
local slow = ooc.create_context_integrator(ctx, "crank_nicolson", {
    initial_dt = 0.01, target_field = 1
})
ooc.set_integrator_sequence(ctx, { fast, slow })

Pass an empty table {} to clear the sequence without attaching a new one.

detach_integrator(ctx)

Removes all integrators (single or sequence) and releases their Lua references.

ooc.detach_integrator(ctx)

Integrator Catalog 📚

Name Order Type Adaptive Description
euler 1 Explicit No Forward Euler. Cheapest, least accurate; for prototyping or very stiff-safe operators.
heun 2 Explicit No Heun’s method (improved Euler). Two drift evaluations per step; twice the cost of Euler for double the order.
rk4 4 Explicit No Classical 4-stage Runge–Kutta. Excellent accuracy-per-cost for well-conditioned problems.
rkf45 4–5 Explicit Yes Six-stage Runge–Kutta–Fehlberg embedded pair. Writes the fifth-order state and controls step size using the fourth/fifth-order discrepancy; uses tolerance, safety, min_dt, max_dt.
etdrk4 4 Exponential No Fixed-step exponential time differencing RK4 for supported semilinear single-field complex plans with exact linear flow.
backward_euler 1 Implicit No L-stable implicit method. Unconditionally stable on linear stiff problems; requires operator linearity assumption.
crank_nicolson 2 Implicit No A-stable trapezoidal rule. Second-order accuracy with guaranteed stability on stiff linear systems.
subordination — Two-stage Optional Handles fractional/subordinated time clocks; supports stochastic noise injection via enable_stochastic.

Choosing a method:

  • General purpose, smooth fields → rk4
  • Semilinear complex spectral flows with supported exact-linear operators → etdrk4
  • Stiff diffusion-dominated PDEs → crank_nicolson or backward_euler
  • Adaptive step control needed → rkf45
  • Fractional dynamics or noise injection → subordination

Note

etdrk4 is specialized rather than universal. It is fixed-step only, requires a complex target field, and only supports scheduler plans that read and write that same target field. Exact-linear pieces must come from phase_rotate, dispersion, linear_dissipative, or linear_spectral_fusion. Same-field nonlinear operators are allowed, and selected stimulus/source operators participate when they are configured as additive dt-scaled updates, such as stimulus_sine, stimulus_chirp, stimulus_gaussian_pulse, stimulus_random_fourier, stimulus_spectral_lines, and the newer stimulus_* pattern/beam families with scale_by_dt = true. Plan-level noise operators are not supported.


Config Options 📋

All fields are optional; unspecified keys use the defaults shown.

Option Type Default Description
initial_dt double 0.1 Starting timestep. Also serves as the fixed step for non-adaptive methods.
min_dt double 1e-4 Minimum allowed timestep (adaptive methods only).
max_dt double 1.0 Maximum allowed timestep (adaptive methods only).
tolerance double 1e-3 Normalized embedded-error tolerance for rkf45: scaled infinity norm for real fields, scaled RMS magnitude for complex fields.
safety double 0.9 Safety factor applied to the predicted next step size (adaptive only). Typical range: 0.8–0.95.
adaptive boolean false Enable adaptive step-size control. At creation, forced to true for rkf45 and false for etdrk4.
target_field integer or field handle 0 Index (0-based) or handle of the field this integrator operates on. Required when using set_integrator_sequence with field-specific integrators.
enable_stochastic boolean false Inject stochastic noise into the drift term. Required for subordination noise.
stochastic_strength double 0.0 Amplitude of injected noise (effective when enable_stochastic = true).
noise string "gaussian" Noise distribution: "gaussian", "uniform", or "laplace".
random_seed integer auto RNG seed. Defaults to a deterministic seed derived from the context’s base_seed and the integrator name.
workspace_hint integer auto Pre-allocate workspace for this many elements. Inferred from target_field when omitted.

Best Practices 💡

  1. Create integrators before calling set_integrator or set_integrator_sequence; workspace is allocated at creation time.
  2. For sequences, assign each integrator its own target_field so operators on different fields are driven by the appropriate method.
  3. Use rkf45 with adaptive = true for exploratory runs; switch to rk4, etdrk4, or crank_nicolson with a fixed initial_dt for production runs with known stability constraints.
  4. detach_integrator must be called (or the context destroyed) before reassigning the same integrator handle to a different context.
  5. Fixed-step methods ignore min_dt/max_dt/tolerance/safety; setting them has no effect.