Operator Calculus, Co.
Browse Studio documentation
On this page

GUI Examples

1) Travelling wave packet

Models a drifting Gaussian wave packet under dispersion,

∂tψ=iβ2∂xxψ.\partial_t \psi = i \beta_2 \partial_{xx} \psi.
local dt = 0.025
local N = 768
local ctx = ooc.create()

ooc.set_timestep(ctx, dt)
ooc.set_visual_mode(ctx, "polar")

local field = ooc.add_field(ctx, {N}, {
    type = "complex_double",
    fill = {0.0, 0.0}
})

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_traveling_wave_packet",
    amplitude = 0.25,
    sigma_u = 0.75,
    center_u = 6.0 * math.pi,
    velocity_u = 1.0,
    carrier_u = 1.0
})

ooc.add_dispersion_operator(ctx, field, {
    coefficient = 1.5,
    order = 2.0,
    spacing = 0.1
})

local integrator = ooc.create_context_integrator(ctx, "euler", {
    initial_dt = dt
})
ooc.set_integrator(ctx, integrator)

return ctx

CLI Examples

1) Heat diffusion on a line

Models 1D diffusion

∂tT=ν ∂xxT\partial_t T = \nu\,\partial_{xx} T

with a point hot spot so the Crank-Nicolson step damps the peak over time.

local ctx = ooc.create()
local dt = 0.01
local n = 256
local hot_index = 128

local temp = ooc.add_field(ctx, {n}, {
    type = "real_double",
    fill = 0.0
})

local data = {}
for i = 1, n do
    data[i] = 0.0
end
data[hot_index] = 1.0
temp:set_values(data)

ooc.add_linear_dissipative_operator(ctx, temp, {
    viscosity = 0.5,
    alpha = 2.0,
    spacing = 0.01
})

local integrator = ooc.create_context_integrator(ctx, "crank_nicolson", {
    initial_dt = dt
})
ooc.set_integrator(ctx, integrator)

for step = 1, 40 do
    ooc.integrator_step(ctx, integrator, dt)
end

local values = temp:values()
ooc.log("center after diffusion: %.6f", values[hot_index])

ooc.shutdown(ctx)
return ctx

2) Thermostat energy clamp

Drives the field energy toward Etarget=1.5E_{\text{target}} = 1.5 with a soft gain, acting like a discrete feedback loop

En+1≈En−λ(En−Etarget).E_{n+1} \approx E_n - \lambda(E_n - E_{\text{target}}).
local ctx = ooc.create()
local dt = 0.02

local state = ooc.add_field(ctx, {256}, {
    type = "complex_double",
    fill = {0.0, 0.0}
})

ooc.add_thermostat_operator(ctx, state, {
    mode = "soft_lambda",
    E_target = 1.5,
    lambda_soft_gain = 0.1
})

ooc.add_stimulus_operator(ctx, state, {
    type = "stimulus_sine",
    amplitude = 0.5,
    wavenumber = 1.0,
    omega = 0.2,
    scale_by_dt = true
})

local integrator = ooc.create_context_integrator(ctx, "euler", {
    initial_dt = dt
})
ooc.set_integrator(ctx, integrator)

for step = 1, 64 do
    ooc.integrator_step(ctx, integrator, dt)
end

local stats = ooc.field_stats(ctx, state)
ooc.log("rms=%.6f max_abs=%.6f", stats.rms, stats.max_abs)

ooc.shutdown(ctx)
return ctx