Skip to content
Oakfield Operator Calculus Function Reference Site

Basic Examples

Examples of using the simulation core API through a GUI-driven loop.

Create two complex fields, drive them with simple stimuli, and mix them into a phase-portrait view.

local N = 384
local dt = 0.05
local ctx = ooc.create()
ooc.set_timestep(ctx, dt)
ooc.set_visual_mode(ctx, "phase_portrait")
ooc.set_phase_mode(ctx, "scatter")
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)
ooc.add_stimulus_operator(ctx, carrier, {
type = "stimulus_sine",
amplitude = 0.6,
wavenumber = 0.025,
omega = 0.1
})
ooc.add_stimulus_operator(ctx, carrier, {
type = "stimulus_sine",
amplitude = 1.0,
wavenumber = 0.05,
omega = -0.2
})
ooc.add_stimulus_operator(ctx, modulator, {
type = "stimulus_spectral_lines",
harmonic_count = 1,
amplitude = 0.22,
wavenumber = 0.02,
omega = -0.1
})
ooc.add_mixer_operator(ctx, carrier, modulator, carrier, {
mode = "multiply",
lhs_gain = -1.0,
rhs_gain = 1.0
})
local integrator = ooc.create_context_integrator(ctx, "euler")
ooc.set_integrator(ctx, integrator)
return ctx

Applies a moving Gaussian pulse stimulus to a complex field.

local ctx = ooc.create()
local N = 1024
ooc.set_timestep(ctx, 0.02)
ooc.set_visual_mode(ctx, "phase_portrait")
local field = ooc.add_field(ctx, {N}, {
type = "complex_double",
fill = {0.0, 0.0}
})
ooc.add_stimulus_operator(ctx, field, {
type = "stimulus_gaussian_pulse",
amplitude = 0.25,
coord_center_x = 0.1,
sigma_x = 0.15,
spacing_x = 0.015,
rotation = math.pi / 3,
coord_velocity_x = 0.08
})
ooc.add_dispersion_operator(ctx, field, {
coefficient = 1.6,
order = 1.2,
spacing = 0.02
})
local integrator = ooc.create_context_integrator(ctx, "euler")
ooc.set_integrator(ctx, integrator)
return ctx

Attach an observation-only on_step hook that logs time as the context advances.

local ctx = ooc.create()
local dt = 0.01
ooc.set_timestep(ctx, dt)
local field = ooc.add_field(ctx, {64}, {
type = "real_double",
fill = 0.0
})
ooc.add_stimulus_operator(ctx, field, {
type = "stimulus_sine",
amplitude = 0.1,
wavenumber = 0.5,
omega = 0.2,
scale_by_dt = true
})
local integrator = ooc.create_context_integrator(ctx, "euler", {
initial_dt = dt
})
ooc.set_integrator(ctx, integrator)
ooc.on_step(ctx, function(c)
ooc.log("step=%d t=%.3f", ooc.get_step_index(c), ooc.get_time(c))
end)
return ctx

Example output in the log panel:

Terminal window
[INFO] step=1 t=0.010
[INFO] step=2 t=0.020
[INFO] step=3 t=0.030
...

Examples of using the simulation core API through oakcli.

Applies Asin(kxωt)A\sin(kx - \omega t) to a real field and takes 120 RK4 steps, matching the forced oscillator

u˙(t)=Asin(kxωt).\dot u(t) = A\sin(kx - \omega t).
local ctx = ooc.create()
local steps = 120
local N = 256
local dt = 0.02
ooc.log("Starting simulation with %d steps and dt = %.3f", steps, dt)
local field = ooc.add_field(ctx, {N}, {
type = "double",
fill = {0}
})
ooc.add_stimulus_operator(ctx, field, {
type = "stimulus_sine",
amplitude = 0.1,
wavenumber = 1.0,
omega = 0.2
})
local integrator = ooc.create_context_integrator(ctx, "rk4", {
initial_dt = dt
})
ooc.set_integrator(ctx, integrator)
for _ = 1, steps do
ooc.integrator_step(ctx, integrator, dt)
local values = field:values()
ooc.log("Field sample value: %.6f", values[1])
end
ooc.shutdown(ctx)
return ctx

Example output:

Terminal window
oakcli run --script fixed-step-sine.lua --steps 0
[INFO] Starting simulation with 120 steps and dt = 0.020
...
[INFO] Field sample value: -0.665682
[INFO] Field sample value: -0.687690
[INFO] Field sample value: -0.710105
[INFO] Field sample value: -0.732928
[INFO] Field sample value: -0.756163
[INFO] Field sample value: -0.779813
[INFO] Field sample value: -0.803878
[INFO] Field sample value: -0.828362
...