Skip to content
Oakfield Operator Calculus Function Reference Site

Advanced Examples

Examples of more advanced Lua usage patterns, including custom operators for in-plan mutation and lightweight diagnostics.

Use a Lua-defined operator to sweep the wavenumber of an existing stimulus over time. This keeps the mutation inside the execution plan instead of trying to reconfigure operators from an observation callback.

local N = 768
local dt = 0.03
local ctx = ooc.create()
ooc.set_timestep(ctx, dt)
local carrier = ooc.add_field(ctx, {N}, {
type = "complex_double",
fill = {0.0, 0.0}
})
local modulator = ooc.add_field(ctx, {N}, {
type = "complex_double",
fill = {0.0, 0.0}
})
ooc.add_zero_field_operator(ctx, carrier)
local stim_mod_sine = ooc.add_stimulus_operator(ctx, modulator, {
type = "stimulus_sine",
amplitude = 0.41,
wavenumber = 1.0,
omega = -0.42,
rotation = math.pi / 2
})
local stim_mod_lines = ooc.add_stimulus_operator(ctx, modulator, {
type = "stimulus_spectral_lines",
amplitude = 0.19,
wavenumber = 1.0,
omega = 0.01,
phase = 4.8,
harmonic_power = 0.94,
harmonic_count = 2
})
ooc.add_stimulus_operator(ctx, carrier, {
type = "stimulus_sine",
amplitude = 1.0,
wavenumber = 1.0,
omega = -0.51,
phase = 0.36,
spacing_x = 0.14
})
ooc.add_mixer_operator(ctx, modulator, carrier, carrier, {
mode = "pm",
lhs_gain = 1.0,
rhs_gain = 1.8,
bias = 0.58
})
local integrator = ooc.create_context_integrator(ctx, "rkf45", {
initial_dt = dt
})
ooc.set_integrator(ctx, integrator)
local tick = 0
local sweep_rate = 0.0005
ooc.add_operator(ctx, "sweep_op", function(context)
tick = tick + 1
local sweep = math.sin(tick * sweep_rate)
ooc.operator_param_set(context, stim_mod_sine, "wavenumber", sweep)
ooc.operator_param_set(context, stim_mod_lines, "wavenumber", sweep)
return true
end)
return ctx

Defines a custom operator that logs the most recent step metrics every 50 ticks while the simulation is running.

local ctx = ooc.create()
local dt = 0.02
ooc.set_timestep(ctx, dt)
local field = ooc.add_field(ctx, {256}, {
type = "real_double",
fill = 0.0
})
ooc.add_stimulus_operator(ctx, field, {
type = "stimulus_sine",
amplitude = 0.2,
wavenumber = 0.5,
omega = 0.15,
scale_by_dt = true
})
local integrator = ooc.create_context_integrator(ctx, "rk4", {
initial_dt = dt
})
ooc.set_integrator(ctx, integrator)
local tick = 0
ooc.add_operator(ctx, "tick_counter", function(context)
tick = tick + 1
if tick % 50 == 0 then
local metrics = ooc.step_metrics_latest(context)
if metrics then
ooc.log("step=%d dt=%.6f accepted=%s dirty=%d",
tick,
metrics.accepted_dt,
tostring(metrics.accepted),
metrics.dirty_writes)
end
end
return true
end)
return ctx