Context Creation
Lifecycle at a Glance ✨
Section titled “Lifecycle at a Glance ✨”The simulation context (ctx) is the core object managing state, operators, fields, and execution. Use the following functions to create and control contexts:
| Function | Parameters | Description |
|---|---|---|
create | [config] | Create a new simulation context with optional configuration. |
context_init_with_universe | [config], [universe] | Create a new context with an explicit universe (q/K/epsilon/poles). |
step | ctx | Advance the simulation by one timestep. |
on_step | ctx, fn | Register a callback to execute after each step (accepts nil to clear). |
run | ctx, [config] | Start a scheduling loop (GUI mode) with optional config. |
pause | ctx | Pause the scheduling loop. |
resume | ctx | Resume a paused scheduling loop. |
shutdown | ctx | Shutdown the simulation context, releasing resources. |
Quick Setup 💡
Section titled “Quick Setup 💡”- Create & configure — call
create()with optional config, then set your timestep. - Add state — allocate fields and operators, then attach an integrator with
set_integrator. - Drive the loop — step manually with
stepor hand off to a scheduler viarun. Useon_stepfor lightweight instrumentation.
Configuration Keys 🔑
Section titled “Configuration Keys 🔑”Top-level Config
Section titled “Top-level Config”| Key | Type | Notes |
|---|---|---|
worker_count | integer | Number of worker threads; defaults to the runtime’s autodetected value. |
enable_logging | boolean | Enable the async scheduler logger; uses log_path when set. |
enable_profiling | boolean | Enable per-operator profiling counters and snapshots. |
enable_timestep_heuristics | boolean | Enable adaptive timestep heuristics and timestep_decision. |
frame_time_budget_ms | double | Soft budget for per-frame work; used by schedulers that honor frame pacing. |
base_seed | integer | Seed for context RNG streams (noise, stochastic integrators, scripted RNG). |
backend | string | Backend request: auto, cpu, cuda, or metal. |
backend_fallback | string | Policy when the requested backend is unavailable: allow, warn, or fail. |
log_path | string | Optional log file path for the async logger (safe relative path only). |
continuity_override | table | Optional continuity guard applied across operators (see below). |
Continuity Override
Section titled “Continuity Override”| Key | Type | Allowed Values | Notes |
|---|---|---|---|
enabled | boolean | true/false | Toggles continuity guards globally. |
mode | string | none, strict, clamped, limited | Modes mirror operator schema defaults; strict preserves analytic continuity while clamped/limited bound singularities. |
clamp_min / clamp_max | double | any | Hard bounds applied when clamped or limited. |
tolerance | double | any | Blending window for limited mode. |
boundary | string | neumann, dirichlet, periodic, reflective | Inherits boundary policy definitions from operator schemas. |
spacing | double[] | positive | Optional array of spatial spacings; overrides default operator spacing. |
dx | double | positive | Optional scalar spacing override; dx is used when spacing is not an array. |
Runtime Continuity Controls
Section titled “Runtime Continuity Controls”You can update (or disable) the global continuity override at any time:
-- enable/replace overrideooc.context_set_continuity_override(ctx, true, { mode = "limited", tolerance = 1.0e-3, boundary = "neumann",})
-- disable override (keeps defaults from schemas)ooc.context_set_continuity_override(ctx, false)Example 📖
Section titled “Example 📖”local ctx = ooc.create({ worker_count = 2, log_path = "logs/run.log", continuity_override = { enabled = true, mode = "clamped", clamp_min = -4.0, clamp_max = 4.0, boundary = "neumann", }})
ooc.set_timestep(ctx, 0.025)
local field = ooc.add_field(ctx, {768}, { type = "complex_double", fill = {0.0, 0.0}})
local integrator = ooc.create_context_integrator(ctx, "rkf45", { initial_dt = 0.025, tolerance = 1.0e-3, safety = 0.9})
ooc.set_integrator(ctx, integrator)
ooc.on_step(ctx, function(c) local t = ooc.get_time(c) ooc.log("step %d at t=%.3f", ooc.get_step_index(c), t)end)
ooc.step(ctx) -- single-step driveooc.shutdown(ctx)Universe & Seeding (Advanced) 🧬
Section titled “Universe & Seeding (Advanced) 🧬”Most scripts should use create. If you need to control the special-function universe at context construction time, use:
context_init_with_universe([config], [universe]) -> ctxThe function accepts either order (config/universe are auto-detected by keys). universe may include:
q(number)K(integer, non-negative)epsilon(number)sieve_sigma(number)poles(array of{x,y,z,residue,type};typeis"digamma"|"trigamma"|"tetragamma")
You can read the normalized base seed used for deterministic RNG streams with:
context_seed(ctx) -> integerRepresentation & Time Model 🧭
Section titled “Representation & Time Model 🧭”Representation mode governs determinism guarantees and what kinds of operators/kernels are allowed:
context_set_representation_mode(ctx, mode)context_representation_mode(ctx) -> mode_value, mode_namemode accepts strict, relaxed, or exploration.
Common aliases are also accepted:
explore/experimentalforexploration
Time model controls whether dt refinement is treated as convergent (continuous flow) or as part of a discrete map:
context_set_time_model(ctx, "continuous" | "map")Aliases:
flowforcontinuousdiscreteformap
Backend Escape Hatch 🔌
Section titled “Backend Escape Hatch 🔌”Most scripts should use the backend / backend_fallback config keys. For lower-level host integration, the context also exposes its raw backend pointer:
context_backend(ctx) -> lightuserdata|nilcontext_set_backend(ctx, backend_ptr_or_nil)Passing nil detaches any explicitly assigned backend. This is primarily for embedders or tooling that already owns backend instances.
Drift Sandbox 🧪
Section titled “Drift Sandbox 🧪”Drift mode is a “no side effects” evaluation mode used by tooling to probe operators without updating continuity counters/warp masks. Some operators also implement optional save/restore hooks so state is reverted.
context_begin_drift(ctx)context_end_drift(ctx)context_in_drift(ctx) -> booleanContext Logger 🧾
Section titled “Context Logger 🧾”Attach a per-context logger callback (distinct from the scheduler’s async logger):
context_set_logger(ctx, fn_or_nil)fn_or_nil is called as fn(level_int, message_string).
Emit warnings through the context logger (falls back to stderr if no logger is set):
context_log_warning(ctx, fmt, ...)Determinism & Kernel Gating 🧷
Section titled “Determinism & Kernel Gating 🧷”These helpers let tooling decide whether a kernel-backed operator is allowed given the current backend and representation policy:
context_allows_determinism(ctx, flags) -> booleancontext_kernel_allowed(ctx, required_features, determinism_flags) -> booleancontext_kernel_allowed_mode(ctx, mode, required_features, determinism_flags) -> booleanflags / determinism_flags can be an integer bitmask or a table of strings:
"pure_time", "rewind_safe", "no_stateful_nodes", "deterministic_rng_only".
Memory Limits & Scratch Accounting 🧠
Section titled “Memory Limits & Scratch Accounting 🧠”Contexts track memory usage for fields and scratch allocations and enforce configurable limits:
context_set_memory_limits(ctx, limits_table)context_get_memory_limits(ctx) -> limits_tablecontext_memory_usage(ctx) -> {fields, scratch, total}context_check_field_limits(ctx, element_count, field_bytes) -> ok, result_codecontext_reserve_scratch(ctx, bytes) -> ok, result_codecontext_release_scratch(ctx, bytes)limits_table keys:
max_field_elementsmax_field_bytesmax_fieldsmax_total_field_bytesmax_scratch_bytes_per_operator
Diagnostics & Special-Function Flush 🩺
Section titled “Diagnostics & Special-Function Flush 🩺”Read the context diagnostics snapshot (fault counts, representation adjustments, etc.):
context_diagnostics(ctx) -> table|nilcontext_diagnostics_const(ctx) -> table|nilWhen compiled with SIM_DIAGNOSTICS, you can flush accumulated special-function diagnostics into the context:
context_flush_special_diagnostics(ctx)If diagnostics are disabled, the Lua binding returns false, "SIM_DIAGNOSTICS disabled".
Manual Operator Application 🧰
Section titled “Manual Operator Application 🧰”Apply a single operator immediately (bypassing step/integrators). Useful for debugging or tooling:
context_apply_operator(ctx, operator_or_index) -> ok, result_code