Advanced Examples
CLI Examples
Examples of more advanced Lua usage patterns, including custom operators for in-plan mutation and lightweight diagnostics.
1) Parameter sweep custom operator
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
2) Lua-defined diagnostics operator
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